projscan 1.6.2 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/core/languages/LanguageAdapter.d.ts +1 -1
  2. package/dist/core/languages/cppAdapter.d.ts +2 -0
  3. package/dist/core/languages/cppAdapter.js +145 -0
  4. package/dist/core/languages/cppAdapter.js.map +1 -0
  5. package/dist/core/languages/cppCallSites.d.ts +13 -0
  6. package/dist/core/languages/cppCallSites.js +62 -0
  7. package/dist/core/languages/cppCallSites.js.map +1 -0
  8. package/dist/core/languages/cppCyclomatic.d.ts +25 -0
  9. package/dist/core/languages/cppCyclomatic.js +82 -0
  10. package/dist/core/languages/cppCyclomatic.js.map +1 -0
  11. package/dist/core/languages/cppExports.d.ts +13 -0
  12. package/dist/core/languages/cppExports.js +120 -0
  13. package/dist/core/languages/cppExports.js.map +1 -0
  14. package/dist/core/languages/cppFunctions.d.ts +30 -0
  15. package/dist/core/languages/cppFunctions.js +242 -0
  16. package/dist/core/languages/cppFunctions.js.map +1 -0
  17. package/dist/core/languages/cppImports.d.ts +25 -0
  18. package/dist/core/languages/cppImports.js +77 -0
  19. package/dist/core/languages/cppImports.js.map +1 -0
  20. package/dist/core/languages/cppManifests.d.ts +18 -0
  21. package/dist/core/languages/cppManifests.js +41 -0
  22. package/dist/core/languages/cppManifests.js.map +1 -0
  23. package/dist/core/languages/kotlinAdapter.d.ts +2 -0
  24. package/dist/core/languages/kotlinAdapter.js +141 -0
  25. package/dist/core/languages/kotlinAdapter.js.map +1 -0
  26. package/dist/core/languages/kotlinCallSites.d.ts +15 -0
  27. package/dist/core/languages/kotlinCallSites.js +62 -0
  28. package/dist/core/languages/kotlinCallSites.js.map +1 -0
  29. package/dist/core/languages/kotlinCyclomatic.d.ts +24 -0
  30. package/dist/core/languages/kotlinCyclomatic.js +54 -0
  31. package/dist/core/languages/kotlinCyclomatic.js.map +1 -0
  32. package/dist/core/languages/kotlinExports.d.ts +13 -0
  33. package/dist/core/languages/kotlinExports.js +103 -0
  34. package/dist/core/languages/kotlinExports.js.map +1 -0
  35. package/dist/core/languages/kotlinFunctions.d.ts +27 -0
  36. package/dist/core/languages/kotlinFunctions.js +147 -0
  37. package/dist/core/languages/kotlinFunctions.js.map +1 -0
  38. package/dist/core/languages/kotlinImports.d.ts +25 -0
  39. package/dist/core/languages/kotlinImports.js +74 -0
  40. package/dist/core/languages/kotlinImports.js.map +1 -0
  41. package/dist/core/languages/kotlinManifests.d.ts +20 -0
  42. package/dist/core/languages/kotlinManifests.js +46 -0
  43. package/dist/core/languages/kotlinManifests.js.map +1 -0
  44. package/dist/core/languages/registry.js +14 -1
  45. package/dist/core/languages/registry.js.map +1 -1
  46. package/dist/core/languages/treeSitterLoader.js +19 -1
  47. package/dist/core/languages/treeSitterLoader.js.map +1 -1
  48. package/dist/core/memory.d.ts +30 -0
  49. package/dist/core/memory.js +42 -0
  50. package/dist/core/memory.js.map +1 -1
  51. package/dist/core/session.d.ts +5 -0
  52. package/dist/core/session.js +8 -3
  53. package/dist/core/session.js.map +1 -1
  54. package/dist/grammars/tree-sitter-cpp.wasm +0 -0
  55. package/dist/grammars/tree-sitter-kotlin.wasm +0 -0
  56. package/dist/mcp/server.js +47 -10
  57. package/dist/mcp/server.js.map +1 -1
  58. package/dist/mcp/sessionTouchScanner.js +8 -2
  59. package/dist/mcp/sessionTouchScanner.js.map +1 -1
  60. package/dist/mcp/tools/costSummary.d.ts +26 -0
  61. package/dist/mcp/tools/costSummary.js +143 -0
  62. package/dist/mcp/tools/costSummary.js.map +1 -0
  63. package/dist/mcp/tools/fixSuggest.js +23 -2
  64. package/dist/mcp/tools/fixSuggest.js.map +1 -1
  65. package/dist/mcp/tools/memory.js +37 -4
  66. package/dist/mcp/tools/memory.js.map +1 -1
  67. package/dist/mcp/tools.js +2 -0
  68. package/dist/mcp/tools.js.map +1 -1
  69. package/dist/tool-manifest.json +18 -4
  70. package/package.json +5 -2
@@ -0,0 +1,242 @@
1
+ const CPP_DECISION_NODES = new Set([
2
+ 'if_statement',
3
+ 'for_statement',
4
+ 'for_range_loop',
5
+ 'while_statement',
6
+ 'do_statement',
7
+ 'try_statement',
8
+ 'catch_clause',
9
+ ]);
10
+ const CPP_STATEMENT_NODES = new Set([
11
+ 'return_statement',
12
+ 'break_statement',
13
+ 'continue_statement',
14
+ 'expression_statement',
15
+ 'compound_statement',
16
+ 'if_statement',
17
+ 'for_statement',
18
+ 'while_statement',
19
+ 'do_statement',
20
+ 'switch_statement',
21
+ 'goto_statement',
22
+ 'declaration',
23
+ 'labeled_statement',
24
+ ]);
25
+ /**
26
+ * Per-function McCabe CC for C++. Walks `function_definition` nodes
27
+ * (free functions, methods defined out-of-line, lambdas are NOT
28
+ * extracted as separate entries; their decisions fold into the
29
+ * enclosing function — matches the convention used elsewhere).
30
+ *
31
+ * Member functions defined inside a class body are named `Class.method`.
32
+ * Out-of-line definitions (`void Foo::bar() { ... }`) are also named
33
+ * `Foo.bar` based on the qualified declarator.
34
+ *
35
+ * `case` labels each contribute +1; `default:` does not. Ternaries (`?:`)
36
+ * count as +1. Logical `&&` and `||` each count.
37
+ */
38
+ export function extractCppFunctions(root) {
39
+ const out = [];
40
+ walk(root, null, out);
41
+ return out;
42
+ }
43
+ function walk(node, ownerName, out) {
44
+ if (node.type === 'class_specifier' ||
45
+ node.type === 'struct_specifier' ||
46
+ node.type === 'union_specifier') {
47
+ const name = nameOfDecl(node) ?? ownerName;
48
+ const body = bodyOf(node);
49
+ if (body) {
50
+ for (const child of body.namedChildren)
51
+ walk(child, name, out);
52
+ }
53
+ return;
54
+ }
55
+ if (node.type === 'namespace_definition' || node.type === 'linkage_specification') {
56
+ const body = bodyOf(node);
57
+ if (body) {
58
+ for (const child of body.namedChildren)
59
+ walk(child, ownerName, out);
60
+ }
61
+ return;
62
+ }
63
+ if (node.type === 'function_definition') {
64
+ const baseName = functionName(node) ?? '<anonymous>';
65
+ // If the name already has `::` (out-of-line method), translate to dot form
66
+ // and use that as the qualified name. Otherwise prepend ownerName if any.
67
+ let fnName;
68
+ if (baseName.includes('::')) {
69
+ fnName = baseName.replace(/::/g, '.');
70
+ }
71
+ else {
72
+ fnName = ownerName ? `${ownerName}.${baseName}` : baseName;
73
+ }
74
+ const line = node.startPosition.row + 1;
75
+ const endLine = node.endPosition.row + 1;
76
+ const { cc, callSites } = analyzeBody(node);
77
+ out.push({ name: fnName, line, endLine, cyclomaticComplexity: cc, callSites });
78
+ return;
79
+ }
80
+ for (const child of node.namedChildren)
81
+ walk(child, ownerName, out);
82
+ }
83
+ function functionName(fn) {
84
+ // Walk into the function_declarator to find the identifier / qualified_identifier.
85
+ if (fn.childForFieldName) {
86
+ const dec = fn.childForFieldName('declarator');
87
+ if (dec)
88
+ return declaratorName(dec);
89
+ }
90
+ for (const c of fn.namedChildren) {
91
+ if (c.type === 'function_declarator')
92
+ return declaratorName(c);
93
+ }
94
+ return null;
95
+ }
96
+ function declaratorName(node) {
97
+ if (node.type === 'identifier' ||
98
+ node.type === 'field_identifier' ||
99
+ node.type === 'type_identifier' ||
100
+ node.type === 'destructor_name') {
101
+ return node.text;
102
+ }
103
+ if (node.type === 'qualified_identifier') {
104
+ // e.g., `Foo::bar` — emit as-is; caller will translate `::` → `.`.
105
+ const text = node.text.replace(/\s+/g, '');
106
+ return text;
107
+ }
108
+ if (node.type === 'operator_name') {
109
+ return node.text.replace(/\s+/g, '');
110
+ }
111
+ if (node.childForFieldName) {
112
+ const inner = node.childForFieldName('declarator');
113
+ if (inner)
114
+ return declaratorName(inner);
115
+ }
116
+ for (const c of node.namedChildren) {
117
+ const r = declaratorName(c);
118
+ if (r)
119
+ return r;
120
+ }
121
+ return null;
122
+ }
123
+ function nameOfDecl(node) {
124
+ if (node.childForFieldName) {
125
+ const id = node.childForFieldName('name');
126
+ if (id && id.text)
127
+ return id.text;
128
+ }
129
+ for (const c of node.namedChildren) {
130
+ if (c.type === 'type_identifier' || c.type === 'identifier')
131
+ return c.text;
132
+ }
133
+ return null;
134
+ }
135
+ function bodyOf(node) {
136
+ if (node.childForFieldName) {
137
+ const b = node.childForFieldName('body');
138
+ if (b)
139
+ return b;
140
+ }
141
+ for (const c of node.namedChildren) {
142
+ if (c.type === 'compound_statement' ||
143
+ c.type === 'field_declaration_list' ||
144
+ c.type === 'declaration_list' ||
145
+ c.type === 'enumerator_list') {
146
+ return c;
147
+ }
148
+ }
149
+ return null;
150
+ }
151
+ function analyzeBody(fnNode) {
152
+ let count = 0;
153
+ const calls = new Set();
154
+ const body = bodyOf(fnNode);
155
+ if (!body)
156
+ return { cc: 1, callSites: [] };
157
+ walkSkipNested(body, (n) => {
158
+ if (CPP_DECISION_NODES.has(n.type)) {
159
+ count++;
160
+ return;
161
+ }
162
+ if (n.type === 'case_statement') {
163
+ // `case X:` has a `value` field; `default:` does not. Field-based
164
+ // detection avoids text-regex fragility around comments / whitespace.
165
+ const hasValue = n.childForFieldName ? !!n.childForFieldName('value') : false;
166
+ if (hasValue) {
167
+ count++;
168
+ }
169
+ else {
170
+ // Fallback for grammar versions without the field: the first named
171
+ // child of a `case X:` is the value node (literal / identifier);
172
+ // `default:` puts the statement first instead.
173
+ const first = n.namedChildren[0];
174
+ if (first && !CPP_STATEMENT_NODES.has(first.type))
175
+ count++;
176
+ }
177
+ return;
178
+ }
179
+ if (n.type === 'conditional_expression') {
180
+ count++;
181
+ return;
182
+ }
183
+ if (n.type === 'binary_expression') {
184
+ // tree-sitter-cpp exposes the operator via a child node typed
185
+ // `binary_expression`'s text. Look for `&&` / `||` directly.
186
+ if (/(\s|^)(\|\||&&)(\s|$)/.test(n.text))
187
+ count++;
188
+ return;
189
+ }
190
+ if (n.type === 'call_expression') {
191
+ const fn = n.childForFieldName ? n.childForFieldName('function') : n.namedChildren[0] ?? null;
192
+ const name = bareName(fn);
193
+ if (name)
194
+ calls.add(name);
195
+ }
196
+ });
197
+ return { cc: count + 1, callSites: [...calls] };
198
+ }
199
+ function bareName(node) {
200
+ if (!node)
201
+ return null;
202
+ switch (node.type) {
203
+ case 'identifier':
204
+ case 'field_identifier':
205
+ case 'type_identifier':
206
+ return node.text;
207
+ case 'qualified_identifier': {
208
+ // `Foo::bar` — take the last segment.
209
+ const named = node.namedChildren;
210
+ const last = named[named.length - 1];
211
+ return last ? bareName(last) : null;
212
+ }
213
+ case 'field_expression': {
214
+ const f = node.childForFieldName ? node.childForFieldName('field') : null;
215
+ if (f)
216
+ return bareName(f);
217
+ const named = node.namedChildren;
218
+ return named.length > 0 ? bareName(named[named.length - 1]) : null;
219
+ }
220
+ case 'template_function': {
221
+ const f = node.childForFieldName ? node.childForFieldName('name') : null;
222
+ if (f)
223
+ return bareName(f);
224
+ return null;
225
+ }
226
+ default:
227
+ return null;
228
+ }
229
+ }
230
+ function walkSkipNested(node, visit) {
231
+ visit(node);
232
+ for (const child of node.namedChildren) {
233
+ if (child.type === 'function_definition' ||
234
+ child.type === 'class_specifier' ||
235
+ child.type === 'struct_specifier' ||
236
+ child.type === 'lambda_expression') {
237
+ continue;
238
+ }
239
+ walkSkipNested(child, visit);
240
+ }
241
+ }
242
+ //# sourceMappingURL=cppFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cppFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/cppFunctions.ts"],"names":[],"mappings":"AAWA,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC;IACjC,cAAc;IACd,eAAe;IACf,gBAAgB;IAChB,iBAAiB;IACjB,cAAc;IACd,eAAe;IACf,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,kBAAkB;IAClB,iBAAiB;IACjB,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,cAAc;IACd,eAAe;IACf,iBAAiB;IACjB,cAAc;IACd,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,mBAAmB;CACpB,CAAC,CAAC;AAEH;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,GAAG,GAAmB,EAAE,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;IACtB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,SAAwB,EAAE,GAAmB;IACvE,IACE,IAAI,CAAC,IAAI,KAAK,iBAAiB;QAC/B,IAAI,CAAC,IAAI,KAAK,kBAAkB;QAChC,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAC/B,CAAC;QACD,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;gBAAE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACjE,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB,IAAI,IAAI,CAAC,IAAI,KAAK,uBAAuB,EAAE,CAAC;QAClF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,IAAI,EAAE,CAAC;YACT,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;gBAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC;QACrD,2EAA2E;QAC3E,0EAA0E;QAC1E,IAAI,MAAc,CAAC;QACnB,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACxC,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,IAAI,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC7D,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,CAAC;QACzC,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAC/E,OAAO;IACT,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,YAAY,CAAC,EAAU;IAC9B,mFAAmF;IACnF,IAAI,EAAE,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAC/C,IAAI,GAAG;YAAE,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,aAAa,EAAE,CAAC;QACjC,IAAI,CAAC,CAAC,IAAI,KAAK,qBAAqB;YAAE,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,IACE,IAAI,CAAC,IAAI,KAAK,YAAY;QAC1B,IAAI,CAAC,IAAI,KAAK,kBAAkB;QAChC,IAAI,CAAC,IAAI,KAAK,iBAAiB;QAC/B,IAAI,CAAC,IAAI,KAAK,iBAAiB,EAC/B,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB,EAAE,CAAC;QACzC,mEAAmE;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QACnD,IAAI,KAAK;YAAE,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC,IAAI,CAAC;IACpC,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC;IAC7E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC1B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC;IAClB,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IACE,CAAC,CAAC,IAAI,KAAK,oBAAoB;YAC/B,CAAC,CAAC,IAAI,KAAK,wBAAwB;YACnC,CAAC,CAAC,IAAI,KAAK,kBAAkB;YAC7B,CAAC,CAAC,IAAI,KAAK,iBAAiB,EAC5B,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,WAAW,CAAC,MAAc;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAC3C,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACzB,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,KAAK,EAAE,CAAC;YACR,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YAChC,kEAAkE;YAClE,sEAAsE;YACtE,MAAM,QAAQ,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAC9E,IAAI,QAAQ,EAAE,CAAC;gBACb,KAAK,EAAE,CAAC;YACV,CAAC;iBAAM,CAAC;gBACN,mEAAmE;gBACnE,iEAAiE;gBACjE,+CAA+C;gBAC/C,MAAM,KAAK,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;gBACjC,IAAI,KAAK,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,KAAK,EAAE,CAAC;YAC7D,CAAC;YACD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;YACxC,KAAK,EAAE,CAAC;YACR,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACnC,8DAA8D;YAC9D,6DAA6D;YAC7D,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,KAAK,EAAE,CAAC;YAClD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACjC,MAAM,EAAE,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;YAC9F,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC1B,IAAI,IAAI;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,EAAE,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC;AAClD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAmB;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,YAAY,CAAC;QAClB,KAAK,kBAAkB,CAAC;QACxB,KAAK,iBAAiB;YACpB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,KAAK,sBAAsB,CAAC,CAAC,CAAC;YAC5B,sCAAsC;YACtC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACtC,CAAC;QACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;YACxB,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAC1E,IAAI,CAAC;gBAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC;YACjC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACrE,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACzE,IAAI,CAAC;gBAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QACD;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,KAA0B;IAC9D,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IACE,KAAK,CAAC,IAAI,KAAK,qBAAqB;YACpC,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAChC,KAAK,CAAC,IAAI,KAAK,kBAAkB;YACjC,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAClC,CAAC;YACD,SAAS;QACX,CAAC;QACD,cAAc,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { AstImport } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ column: number;
8
+ };
9
+ namedChildren: TsNode[];
10
+ childForFieldName?: (name: string) => TsNode | null;
11
+ }
12
+ /**
13
+ * Extract C++ `#include` directives from a tree-sitter-cpp AST.
14
+ *
15
+ * Handled forms:
16
+ * #include "foo.h" → source = "foo.h" (project-local convention)
17
+ * #include <vector> → source = "vector" (system / library header)
18
+ * #include "../bar/baz.hpp" → source = "../bar/baz.hpp"
19
+ *
20
+ * Modules (C++20 `import std;` / `import :foo;`) are also captured as
21
+ * static imports when the grammar recognises them. Specifiers are not
22
+ * extracted (C++ #include is whole-file inclusion, not symbol binding).
23
+ */
24
+ export declare function extractCppImports(root: TsNode): AstImport[];
25
+ export {};
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Extract C++ `#include` directives from a tree-sitter-cpp AST.
3
+ *
4
+ * Handled forms:
5
+ * #include "foo.h" → source = "foo.h" (project-local convention)
6
+ * #include <vector> → source = "vector" (system / library header)
7
+ * #include "../bar/baz.hpp" → source = "../bar/baz.hpp"
8
+ *
9
+ * Modules (C++20 `import std;` / `import :foo;`) are also captured as
10
+ * static imports when the grammar recognises them. Specifiers are not
11
+ * extracted (C++ #include is whole-file inclusion, not symbol binding).
12
+ */
13
+ export function extractCppImports(root) {
14
+ const imports = [];
15
+ walk(root, (n) => {
16
+ if (n.type === 'preproc_include') {
17
+ const path = readIncludePath(n);
18
+ if (!path)
19
+ return;
20
+ imports.push({
21
+ source: path.value,
22
+ kind: 'static',
23
+ specifiers: [],
24
+ typeOnly: false,
25
+ line: n.startPosition.row + 1,
26
+ });
27
+ return;
28
+ }
29
+ if (n.type === 'import_declaration' || n.type === 'module_import') {
30
+ const m = /^\s*(?:export\s+)?import\s+([^;]+);/.exec(n.text);
31
+ if (m) {
32
+ imports.push({
33
+ source: m[1].trim(),
34
+ kind: 'static',
35
+ specifiers: [],
36
+ typeOnly: false,
37
+ line: n.startPosition.row + 1,
38
+ });
39
+ }
40
+ }
41
+ });
42
+ return imports;
43
+ }
44
+ function readIncludePath(node) {
45
+ // tree-sitter-cpp typically exposes the included path as either a
46
+ // `string_literal` (quoted) or a `system_lib_string` (angle-bracketed)
47
+ // child. Some grammar versions use `path` field; we fall back to text.
48
+ if (node.childForFieldName) {
49
+ const p = node.childForFieldName('path');
50
+ if (p)
51
+ return classify(p.text);
52
+ }
53
+ for (const c of node.namedChildren) {
54
+ if (c.type === 'string_literal' || c.type === 'system_lib_string') {
55
+ return classify(c.text);
56
+ }
57
+ }
58
+ // Fallback: parse from the node's full text.
59
+ const m = /#\s*include\s*([<"][^>"]*[>"])/.exec(node.text);
60
+ return m ? classify(m[1]) : null;
61
+ }
62
+ function classify(raw) {
63
+ const text = raw.trim();
64
+ if (text.startsWith('"') && text.endsWith('"')) {
65
+ return { value: text.slice(1, -1), isQuoted: true };
66
+ }
67
+ if (text.startsWith('<') && text.endsWith('>')) {
68
+ return { value: text.slice(1, -1), isQuoted: false };
69
+ }
70
+ return null;
71
+ }
72
+ function walk(node, visit) {
73
+ visit(node);
74
+ for (const child of node.namedChildren)
75
+ walk(child, visit);
76
+ }
77
+ //# sourceMappingURL=cppImports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cppImports.js","sourceRoot":"","sources":["../../../src/core/languages/cppImports.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { FileEntry } from '../../types.js';
2
+ export interface CppProjectInfo {
3
+ /**
4
+ * Detected C++ source / include roots. We use these to resolve quoted
5
+ * `#include "foo.h"` directives — quoted includes start their search
6
+ * from the same directory as the including file, then fall back to
7
+ * project-wide include directories.
8
+ */
9
+ includeRoots: string[];
10
+ hasCMake: boolean;
11
+ hasMakefile: boolean;
12
+ }
13
+ /**
14
+ * Detect C++ source roots. We don't parse CMakeLists / Make files; we
15
+ * survey .cpp/.cc/.cxx/.h/.hpp file paths and pick whichever conventional
16
+ * roots actually contain sources.
17
+ */
18
+ export declare function detectCppProject(rootPath: string, files: FileEntry[]): Promise<CppProjectInfo | null>;
@@ -0,0 +1,41 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ const COMMON_CPP_ROOTS = ['include', 'src', 'lib', '.'];
4
+ /**
5
+ * Detect C++ source roots. We don't parse CMakeLists / Make files; we
6
+ * survey .cpp/.cc/.cxx/.h/.hpp file paths and pick whichever conventional
7
+ * roots actually contain sources.
8
+ */
9
+ export async function detectCppProject(rootPath, files) {
10
+ const cppFiles = files.filter((f) => isCppExtension(f.relativePath));
11
+ if (cppFiles.length === 0)
12
+ return null;
13
+ const hasCMake = await fileExists(path.join(rootPath, 'CMakeLists.txt'));
14
+ const hasMakefile = await fileExists(path.join(rootPath, 'Makefile'));
15
+ const includeRoots = [];
16
+ for (const candidate of COMMON_CPP_ROOTS) {
17
+ if (candidate === '.') {
18
+ if (cppFiles.some((f) => !f.relativePath.includes('/')))
19
+ includeRoots.push('.');
20
+ }
21
+ else if (cppFiles.some((f) => f.relativePath.startsWith(candidate + '/'))) {
22
+ includeRoots.push(candidate);
23
+ }
24
+ }
25
+ if (includeRoots.length === 0)
26
+ includeRoots.push('.');
27
+ return { includeRoots, hasCMake, hasMakefile };
28
+ }
29
+ async function fileExists(p) {
30
+ try {
31
+ await fs.access(p);
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ function isCppExtension(p) {
39
+ return /\.(cpp|cc|cxx|c\+\+|c|h|hpp|hxx|h\+\+)$/.test(p);
40
+ }
41
+ //# sourceMappingURL=cppManifests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cppManifests.js","sourceRoot":"","sources":["../../../src/core/languages/cppManifests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAe7B,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,KAAkB;IAElB,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACrE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;IACtE,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;QACzC,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YACtB,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClF,CAAC;aAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5E,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,CAAS;IACjC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,yCAAyC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { LanguageAdapter } from './LanguageAdapter.js';
2
+ export declare const kotlinAdapter: LanguageAdapter;
@@ -0,0 +1,141 @@
1
+ import path from 'node:path';
2
+ import { createParserFor } from './treeSitterLoader.js';
3
+ import { extractKotlinImports } from './kotlinImports.js';
4
+ import { extractKotlinExports } from './kotlinExports.js';
5
+ import { extractKotlinCyclomatic } from './kotlinCyclomatic.js';
6
+ import { extractKotlinFunctions } from './kotlinFunctions.js';
7
+ import { extractKotlinCallSites } from './kotlinCallSites.js';
8
+ import { detectKotlinProject } from './kotlinManifests.js';
9
+ const KOTLIN_EXTENSIONS = new Set(['.kt', '.kts']);
10
+ const MAX_KOTLIN_FILE = 1024 * 1024;
11
+ let parserPromise = null;
12
+ async function getParser() {
13
+ if (!parserPromise)
14
+ parserPromise = createParserFor('tree-sitter-kotlin.wasm');
15
+ return parserPromise;
16
+ }
17
+ export const kotlinAdapter = {
18
+ id: 'kotlin',
19
+ extensions: KOTLIN_EXTENSIONS,
20
+ sourceExtensions: KOTLIN_EXTENSIONS,
21
+ // Kotlin has no "barrel-file" idiom; entry-points are .kt files with `fun main`.
22
+ barrelBasenames: new Set(),
23
+ maxFileSize: MAX_KOTLIN_FILE,
24
+ async parse(_filePath, content) {
25
+ try {
26
+ const parser = await getParser();
27
+ const tree = parser.parse(content);
28
+ if (!tree || !tree.rootNode) {
29
+ return {
30
+ ok: false,
31
+ reason: 'tree-sitter returned null tree',
32
+ imports: [],
33
+ exports: [],
34
+ callSites: [],
35
+ lineCount: content ? content.split('\n').length : 0,
36
+ cyclomaticComplexity: 0,
37
+ functions: [],
38
+ };
39
+ }
40
+ const root = tree.rootNode;
41
+ const imports = extractKotlinImports(root);
42
+ const exports = extractKotlinExports(root);
43
+ const cyclomaticComplexity = extractKotlinCyclomatic(root);
44
+ const callSites = extractKotlinCallSites(root);
45
+ const functions = extractKotlinFunctions(root);
46
+ return {
47
+ ok: true,
48
+ imports,
49
+ exports,
50
+ callSites,
51
+ lineCount: content ? content.split('\n').length : 0,
52
+ cyclomaticComplexity,
53
+ functions,
54
+ };
55
+ }
56
+ catch (err) {
57
+ const msg = err instanceof Error ? err.message : String(err);
58
+ return {
59
+ ok: false,
60
+ reason: `kotlin parse failure: ${msg.slice(0, 120)}`,
61
+ imports: [],
62
+ exports: [],
63
+ callSites: [],
64
+ lineCount: content ? content.split('\n').length : 0,
65
+ cyclomaticComplexity: 0,
66
+ functions: [],
67
+ };
68
+ }
69
+ },
70
+ resolveImport(importingFile, source, graphFiles, context) {
71
+ return resolveKotlinImport(importingFile, source, graphFiles, context);
72
+ },
73
+ toPackageName(source) {
74
+ if (!source)
75
+ return null;
76
+ // Heuristic: a Kotlin import that begins with the project's own
77
+ // detected source-root directory shouldn't be a "package" — but at
78
+ // graph-build time we don't have project info here. Defer to
79
+ // resolveImport: anything that resolveImport can't pin to a local
80
+ // file falls through as external.
81
+ return source.split('.')[0] || null;
82
+ },
83
+ async preparePackageRoots(rootPath, files) {
84
+ const info = await detectKotlinProject(rootPath, files);
85
+ return {
86
+ packageRoots: info ? info.packageRoots.map((r) => path.relative(rootPath, path.join(rootPath, r)) || '.') : [],
87
+ meta: info ? { kotlinProject: info } : undefined,
88
+ };
89
+ },
90
+ };
91
+ /**
92
+ * Resolve a Kotlin `import com.foo.Bar` to a repo-local file. The path
93
+ * `com.foo.Bar` becomes `com/foo/Bar.kt` under each known package root.
94
+ * Wildcard imports (`com.foo.*`) resolve to `com/foo/<any>.kt` and we
95
+ * pick the first match if any. Non-local (stdlib, third-party) imports
96
+ * return null.
97
+ */
98
+ function resolveKotlinImport(_importingFile, source, graphFiles, context) {
99
+ if (!source)
100
+ return null;
101
+ const project = context.meta?.kotlinProject;
102
+ const packageRoots = context.packageRoots ?? project?.packageRoots ?? [];
103
+ if (packageRoots.length === 0)
104
+ return null;
105
+ const isWildcard = source.endsWith('.*');
106
+ const cleanedSegments = (isWildcard ? source.slice(0, -2) : source).split('.').filter(Boolean);
107
+ if (cleanedSegments.length === 0)
108
+ return null;
109
+ for (const root of packageRoots) {
110
+ const rootSegs = root === '.' || root === '' ? [] : root.split('/').filter(Boolean);
111
+ if (isWildcard) {
112
+ const dirParts = [...rootSegs, ...cleanedSegments];
113
+ const prefix = dirParts.join('/') + '/';
114
+ // Pick any file under that package directory.
115
+ for (const key of graphFiles.keys()) {
116
+ if (key.startsWith(prefix) && (key.endsWith('.kt') || key.endsWith('.kts'))) {
117
+ return key;
118
+ }
119
+ }
120
+ continue;
121
+ }
122
+ // Non-wildcard: try each segment count from full → 1, since the last segment
123
+ // could be a class name OR a file name. Try `com/foo/Bar.kt`, then if not
124
+ // found try `com/foo.kt` (top-level decl in Foo.kt).
125
+ for (let drop = 0; drop <= 1; drop++) {
126
+ const segs = cleanedSegments.slice(0, cleanedSegments.length - drop);
127
+ if (segs.length === 0)
128
+ break;
129
+ const baseSegs = [...rootSegs, ...segs.slice(0, -1)];
130
+ const fileName = segs[segs.length - 1];
131
+ const asKt = [...baseSegs, `${fileName}.kt`].join('/');
132
+ if (graphFiles.has(asKt))
133
+ return asKt;
134
+ const asKts = [...baseSegs, `${fileName}.kts`].join('/');
135
+ if (graphFiles.has(asKts))
136
+ return asKts;
137
+ }
138
+ }
139
+ return null;
140
+ }
141
+ //# sourceMappingURL=kotlinAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kotlinAdapter.js","sourceRoot":"","sources":["../../../src/core/languages/kotlinAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ interface TsNode {
2
+ type: string;
3
+ text: string;
4
+ namedChildren: TsNode[];
5
+ childForFieldName?: (name: string) => TsNode | null;
6
+ }
7
+ /**
8
+ * Extract the called identifier from each `call_expression` in a
9
+ * tree-sitter-kotlin AST. Mirrors the existing adapter behaviour: we
10
+ * deduplicate names and strip qualification so that `foo.bar()` and `bar()`
11
+ * both produce `bar`. Constructor calls (`Foo()`) and infix-form calls are
12
+ * captured the same way.
13
+ */
14
+ export declare function extractKotlinCallSites(root: TsNode): string[];
15
+ export {};
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Extract the called identifier from each `call_expression` in a
3
+ * tree-sitter-kotlin AST. Mirrors the existing adapter behaviour: we
4
+ * deduplicate names and strip qualification so that `foo.bar()` and `bar()`
5
+ * both produce `bar`. Constructor calls (`Foo()`) and infix-form calls are
6
+ * captured the same way.
7
+ */
8
+ export function extractKotlinCallSites(root) {
9
+ const seen = new Set();
10
+ walk(root, (n) => {
11
+ if (n.type !== 'call_expression')
12
+ return;
13
+ const fn = pickCallee(n);
14
+ if (!fn)
15
+ return;
16
+ const name = bareName(fn);
17
+ if (name)
18
+ seen.add(name);
19
+ });
20
+ return [...seen];
21
+ }
22
+ function pickCallee(node) {
23
+ if (node.childForFieldName) {
24
+ const f = node.childForFieldName('function');
25
+ if (f)
26
+ return f;
27
+ }
28
+ return node.namedChildren[0] ?? null;
29
+ }
30
+ function bareName(node) {
31
+ switch (node.type) {
32
+ case 'simple_identifier':
33
+ case 'identifier':
34
+ case 'type_identifier':
35
+ return node.text;
36
+ case 'navigation_expression': {
37
+ const last = node.namedChildren[node.namedChildren.length - 1];
38
+ return last ? bareName(last) : null;
39
+ }
40
+ case 'navigation_suffix': {
41
+ for (const c of node.namedChildren) {
42
+ const n = bareName(c);
43
+ if (n)
44
+ return n;
45
+ }
46
+ return null;
47
+ }
48
+ case 'call_expression': {
49
+ // Foo()() — a chained invocation; recurse on the inner callee.
50
+ const inner = pickCallee(node);
51
+ return inner ? bareName(inner) : null;
52
+ }
53
+ default:
54
+ return null;
55
+ }
56
+ }
57
+ function walk(node, visit) {
58
+ visit(node);
59
+ for (const child of node.namedChildren)
60
+ walk(child, visit);
61
+ }
62
+ //# sourceMappingURL=kotlinCallSites.js.map