mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(extract): a C# operator declaration is a method with its own node
operator_declaration was no function kind, so `operator+` had no node and every call and usage in its body was attributed to the file. The resolver then published `Vec CALLS Vec2.Vec2` from a body that belongs to a named member. The operator is now a Method named by its token, spelled like C++'s `operator+`, through the one resolver the def side and the call scope share. Overloads merge into one node with variants, as other C# methods do. RED: mkc_c2_csharp_operator_plus reported scope=Vec for the constructor call. The binary operator site `a + b` still abstains, and conversion operators, property accessors and indexers still have no node of their own. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
1 parent
d6335b5239
commit
2840080f69
3 files changed
+27
-8
No files matched your search
@@ -866,6 +866,11 @@ TSNode cbm_resolve_func_name(TSNode node, CBMLanguage lang) {
|
||||
for (int tmpl_depth = 0; tmpl_depth < MAX_TEMPLATE_DEPTH; tmpl_depth++) {
|
||||
const char *kind = ts_node_type(node);
|
||||
|
||||
// C#: an overloaded operator has no name field, its token names it.
|
||||
if (lang == CBM_LANG_CSHARP && strcmp(kind, "operator_declaration") == 0) {
|
||||
return ts_node_child_by_field_name(node, TS_FIELD("operator"));
|
||||
}
|
||||
|
||||
if (lang == CBM_LANG_HASKELL && strcmp(kind, "signature") == 0) {
|
||||
TSNode null_node = {0};
|
||||
return null_node;
|
||||
@@ -9291,9 +9296,10 @@ static TSNode resolve_method_name(TSNode child, CBMLanguage lang) {
|
||||
|
||||
const char *ck = ts_node_type(child);
|
||||
|
||||
if ((lang == CBM_LANG_C || lang == CBM_LANG_CPP || lang == CBM_LANG_CUDA ||
|
||||
lang == CBM_LANG_GLSL) &&
|
||||
strcmp(ck, "function_definition") == 0) {
|
||||
if (((lang == CBM_LANG_C || lang == CBM_LANG_CPP || lang == CBM_LANG_CUDA ||
|
||||
lang == CBM_LANG_GLSL) &&
|
||||
strcmp(ck, "function_definition") == 0) ||
|
||||
(lang == CBM_LANG_CSHARP && strcmp(ck, "operator_declaration") == 0)) {
|
||||
return cbm_resolve_func_name(child, lang);
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -864,7 +864,8 @@ static const char *func_kinds_ocaml[] = {"value_definition", "let_binding", NULL
|
||||
static const char *func_kinds_zig[] = {"function_declaration", "test_declaration", NULL};
|
||||
static const char *func_kinds_bash[] = {"function_definition", NULL};
|
||||
static const char *func_kinds_erlang[] = {"function_clause", NULL};
|
||||
static const char *func_kinds_csharp[] = {"method_declaration", "constructor_declaration", NULL};
|
||||
static const char *func_kinds_csharp[] = {"method_declaration", "constructor_declaration",
|
||||
"operator_declaration", NULL};
|
||||
static const char *func_kinds_matlab[] = {"function_definition", NULL};
|
||||
static const char *func_kinds_lean[] = {"def", "theorem", "instance", "abbrev", NULL};
|
||||
static const char *func_kinds_form[] = {"procedure_definition", NULL};
|
||||
@@ -1203,6 +1204,13 @@ char *cbm_func_name_node_text(CBMArena *a, TSNode name_node, const char *source,
|
||||
*paren = '\0';
|
||||
}
|
||||
}
|
||||
/* C# `operator +` is named by its token alone, an anonymous node; any other C# name
|
||||
* is a named node. Spelled like C++'s `operator+` and `operator bool`, here so the
|
||||
* def name and the call-scope QN cannot disagree. */
|
||||
if (text && lang == CBM_LANG_CSHARP && !ts_node_is_named(name_node)) {
|
||||
bool word = text[0] >= 'a' && text[0] <= 'z'; /* operator true, operator false */
|
||||
return cbm_arena_sprintf(a, "operator%s%s", word ? " " : "", text);
|
||||
}
|
||||
/* Nix quoted attrpath segment: `"kebab-case" = a: a;` and `services."my.svc" = …`
|
||||
* are ordinary names that merely need quoting in source. The node text carries
|
||||
* the delimiters, so without this the def is named `"kebab-case"` — quotes and
|
||||
@@ -1493,6 +1501,11 @@ static const char *func_node_name(CBMArena *a, TSNode func_node, const char *sou
|
||||
if (!ts_node_is_null(name_node)) {
|
||||
return cbm_node_text(a, name_node, source);
|
||||
}
|
||||
// C#: an overloaded operator has no name field, its token names it.
|
||||
if (lang == CBM_LANG_CSHARP && strcmp(ts_node_type(func_node), "operator_declaration") == 0) {
|
||||
TSNode op = ts_node_child_by_field_name(func_node, TS_FIELD("operator"));
|
||||
return ts_node_is_null(op) ? NULL : cbm_func_name_node_text(a, op, source, lang);
|
||||
}
|
||||
// Arrow functions: check parent variable_declarator
|
||||
if (strcmp(ts_node_type(func_node), "arrow_function") == 0) {
|
||||
TSNode parent = ts_node_parent(func_node);
|
||||
|
||||
@@ -369,10 +369,10 @@ static const char *cpp_assign_types[] = {"assignment_expression", "update_expres
|
||||
static const char *cpp_throw_types[] = {"throw_statement", NULL};
|
||||
|
||||
// ==================== C# ====================
|
||||
static const char *cs_func_types[] = {"destructor_declaration", "local_function_statement",
|
||||
"function_pointer_type", "constructor_declaration",
|
||||
"anonymous_method_expression", "lambda_expression",
|
||||
"method_declaration", NULL};
|
||||
static const char *cs_func_types[] = {
|
||||
"destructor_declaration", "local_function_statement", "function_pointer_type",
|
||||
"constructor_declaration", "anonymous_method_expression", "lambda_expression",
|
||||
"method_declaration", "operator_declaration", NULL};
|
||||
static const char *cs_class_types[] = {"class_declaration",
|
||||
"struct_declaration",
|
||||
"enum_declaration",
|
||||
|
||||
Reference in new issue
Block a user