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

Method extract_call

codegraph-kernel/src/csharp.rs:1009–1063  ·  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

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

Callers 2

visit_nodeMethod · 0.45

Calls 6

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

Tested by

no test coverage detected