MCPcopy Create free account
hub / github.com/colbymchenry/codegraph / extract_call

Method extract_call

codegraph-kernel/src/csharp.rs:1018–1072  ·  view source on GitHub ↗

extractCall — the C# branch (tree-sitter.ts:4502) + shared tail.

(&mut self, node: Node<'t>)

Source from the content-addressed store, hash-verified

1016
1017 /// extractCall — the C# branch (tree-sitter.ts:4502) + shared tail.
1018 fn extract_call(&mut self, node: Node<'t>) {
1019 if self.stack.is_empty() {
1020 return;
1021 }
1022 let caller = self.top_row();
1023 let func = node
1024 .child_by_field_name("function")
1025 .or_else(|| node.named_child(0));
1026 let Some(func) = func else { return };
1027
1028 let mut callee_name: String;
1029 if func.kind() == "member_access_expression" {
1030 let recv = func.child_by_field_name("expression");
1031 let name_node = func.child_by_field_name("name");
1032 let method_name = name_node.map(|n| self.text(n)).unwrap_or("");
1033 let chained = recv
1034 .map(|r| r.kind() == "invocation_expression" && !method_name.is_empty())
1035 .unwrap_or(false);
1036 if chained {
1037 // Chained factory `Foo.Create(args).Bar()` → `Foo.Create().Bar`
1038 // (inner whitespace stripped, EVERY call-receiver re-encodes —
1039 // no capitalization gate, unlike kotlin/scala).
1040 let inner_func = recv.unwrap().child_by_field_name("function");
1041 let inner_callee = inner_func.map(|f| strip_js_ws(self.text(f))).unwrap_or_default();
1042 callee_name = if inner_callee.is_empty() {
1043 method_name.to_string()
1044 } else {
1045 format!("{inner_callee}().{method_name}")
1046 };
1047 } else {
1048 // RAW full member-access text: `this.Run`, `base.Method`,
1049 // `"lit".ToUpper`, multi-line fluent chains with their
1050 // newlines — no SKIP_RECEIVERS, no literal filter (preserve).
1051 callee_name = self.text(func).to_string();
1052 }
1053 } else {
1054 // Bare `Helper()`, generic `Generic<int>` kept verbatim,
1055 // `nameof(...)` → a calls ref named `nameof`, `?.` chains raw,
1056 // `(myDel)(x)` → parenthesized text (normalized below).
1057 callee_name = self.text(func).to_string();
1058 }
1059
1060 // Shared parenthesized-conversion normalization — the one shared
1061 // normalization C# actually hits: `(myDel)(x)` → `myDel`.
1062 if !callee_name.is_empty() {
1063 if let Some(c) = util::paren_conversion().captures(&callee_name) {
1064 callee_name = c[1].to_string();
1065 }
1066 }
1067 // (template strip + fn-ptr fan-out are c/cpp-gated — not C#.)
1068
1069 if !callee_name.is_empty() {
1070 self.push_ref_at(caller, &callee_name.clone(), edge_kind_index("calls").unwrap(), node);
1071 }
1072 }
1073
1074 fn extract_instantiation(&mut self, node: Node<'t>) {
1075 if self.stack.is_empty() {

Callers 2

visit_nodeMethod · 0.45

Calls 6

edge_kind_indexFunction · 0.85
strip_js_wsFunction · 0.70
textMethod · 0.65
unwrapMethod · 0.60
top_rowMethod · 0.45
push_ref_atMethod · 0.45

Tested by

no test coverage detected