projscan 0.11.0 → 0.14.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 (278) hide show
  1. package/README.md +57 -33
  2. package/dist/analyzers/crossPackageImportCheck.d.ts +13 -0
  3. package/dist/analyzers/crossPackageImportCheck.js +136 -0
  4. package/dist/analyzers/crossPackageImportCheck.js.map +1 -0
  5. package/dist/analyzers/cycleCheck.d.ts +12 -0
  6. package/dist/analyzers/cycleCheck.js +65 -0
  7. package/dist/analyzers/cycleCheck.js.map +1 -0
  8. package/dist/analyzers/unusedDependencyCheck.js +69 -17
  9. package/dist/analyzers/unusedDependencyCheck.js.map +1 -1
  10. package/dist/cli/_shared.d.ts +16 -0
  11. package/dist/cli/_shared.js +210 -0
  12. package/dist/cli/_shared.js.map +1 -0
  13. package/dist/cli/commands/analyze.d.ts +1 -0
  14. package/dist/cli/commands/analyze.js +87 -0
  15. package/dist/cli/commands/analyze.js.map +1 -0
  16. package/dist/cli/commands/audit.d.ts +1 -0
  17. package/dist/cli/commands/audit.js +53 -0
  18. package/dist/cli/commands/audit.js.map +1 -0
  19. package/dist/cli/commands/badge.d.ts +1 -0
  20. package/dist/cli/commands/badge.js +45 -0
  21. package/dist/cli/commands/badge.js.map +1 -0
  22. package/dist/cli/commands/ci.d.ts +1 -0
  23. package/dist/cli/commands/ci.js +57 -0
  24. package/dist/cli/commands/ci.js.map +1 -0
  25. package/dist/cli/commands/coupling.d.ts +1 -0
  26. package/dist/cli/commands/coupling.js +83 -0
  27. package/dist/cli/commands/coupling.js.map +1 -0
  28. package/dist/cli/commands/coverage.d.ts +1 -0
  29. package/dist/cli/commands/coverage.js +63 -0
  30. package/dist/cli/commands/coverage.js.map +1 -0
  31. package/dist/cli/commands/dependencies.d.ts +1 -0
  32. package/dist/cli/commands/dependencies.js +46 -0
  33. package/dist/cli/commands/dependencies.js.map +1 -0
  34. package/dist/cli/commands/diagram.d.ts +1 -0
  35. package/dist/cli/commands/diagram.js +45 -0
  36. package/dist/cli/commands/diagram.js.map +1 -0
  37. package/dist/cli/commands/diff.d.ts +1 -0
  38. package/dist/cli/commands/diff.js +70 -0
  39. package/dist/cli/commands/diff.js.map +1 -0
  40. package/dist/cli/commands/doctor.d.ts +1 -0
  41. package/dist/cli/commands/doctor.js +62 -0
  42. package/dist/cli/commands/doctor.js.map +1 -0
  43. package/dist/cli/commands/explain.d.ts +1 -0
  44. package/dist/cli/commands/explain.js +42 -0
  45. package/dist/cli/commands/explain.js.map +1 -0
  46. package/dist/cli/commands/explainIssue.d.ts +1 -0
  47. package/dist/cli/commands/explainIssue.js +49 -0
  48. package/dist/cli/commands/explainIssue.js.map +1 -0
  49. package/dist/cli/commands/file.d.ts +1 -0
  50. package/dist/cli/commands/file.js +45 -0
  51. package/dist/cli/commands/file.js.map +1 -0
  52. package/dist/cli/commands/fix.d.ts +1 -0
  53. package/dist/cli/commands/fix.js +70 -0
  54. package/dist/cli/commands/fix.js.map +1 -0
  55. package/dist/cli/commands/fixSuggest.d.ts +1 -0
  56. package/dist/cli/commands/fixSuggest.js +71 -0
  57. package/dist/cli/commands/fixSuggest.js.map +1 -0
  58. package/dist/cli/commands/help.d.ts +1 -0
  59. package/dist/cli/commands/help.js +11 -0
  60. package/dist/cli/commands/help.js.map +1 -0
  61. package/dist/cli/commands/hotspots.d.ts +1 -0
  62. package/dist/cli/commands/hotspots.js +74 -0
  63. package/dist/cli/commands/hotspots.js.map +1 -0
  64. package/dist/cli/commands/mcp.d.ts +1 -0
  65. package/dist/cli/commands/mcp.js +21 -0
  66. package/dist/cli/commands/mcp.js.map +1 -0
  67. package/dist/cli/commands/outdated.d.ts +1 -0
  68. package/dist/cli/commands/outdated.js +51 -0
  69. package/dist/cli/commands/outdated.js.map +1 -0
  70. package/dist/cli/commands/prDiff.d.ts +1 -0
  71. package/dist/cli/commands/prDiff.js +59 -0
  72. package/dist/cli/commands/prDiff.js.map +1 -0
  73. package/dist/cli/commands/review.d.ts +1 -0
  74. package/dist/cli/commands/review.js +66 -0
  75. package/dist/cli/commands/review.js.map +1 -0
  76. package/dist/cli/commands/search.d.ts +1 -0
  77. package/dist/cli/commands/search.js +233 -0
  78. package/dist/cli/commands/search.js.map +1 -0
  79. package/dist/cli/commands/structure.d.ts +1 -0
  80. package/dist/cli/commands/structure.js +58 -0
  81. package/dist/cli/commands/structure.js.map +1 -0
  82. package/dist/cli/commands/upgrade.d.ts +1 -0
  83. package/dist/cli/commands/upgrade.js +44 -0
  84. package/dist/cli/commands/upgrade.js.map +1 -0
  85. package/dist/cli/commands/workspaces.d.ts +1 -0
  86. package/dist/cli/commands/workspaces.js +35 -0
  87. package/dist/cli/commands/workspaces.js.map +1 -0
  88. package/dist/cli/index.js +51 -1416
  89. package/dist/cli/index.js.map +1 -1
  90. package/dist/core/ast.d.ts +20 -0
  91. package/dist/core/ast.js +190 -0
  92. package/dist/core/ast.js.map +1 -1
  93. package/dist/core/auditRunner.d.ts +8 -0
  94. package/dist/core/auditRunner.js +50 -1
  95. package/dist/core/auditRunner.js.map +1 -1
  96. package/dist/core/codeGraph.d.ts +7 -1
  97. package/dist/core/codeGraph.js +2 -0
  98. package/dist/core/codeGraph.js.map +1 -1
  99. package/dist/core/couplingAnalyzer.d.ts +1 -1
  100. package/dist/core/couplingAnalyzer.js +3 -3
  101. package/dist/core/dependencyAnalyzer.d.ts +15 -1
  102. package/dist/core/dependencyAnalyzer.js +115 -18
  103. package/dist/core/dependencyAnalyzer.js.map +1 -1
  104. package/dist/core/explainIssue.d.ts +9 -0
  105. package/dist/core/explainIssue.js +106 -0
  106. package/dist/core/explainIssue.js.map +1 -0
  107. package/dist/core/fileInspector.js +12 -0
  108. package/dist/core/fileInspector.js.map +1 -1
  109. package/dist/core/fixSuggest.d.ts +41 -0
  110. package/dist/core/fixSuggest.js +327 -0
  111. package/dist/core/fixSuggest.js.map +1 -0
  112. package/dist/core/hotspotAnalyzer.js +2 -2
  113. package/dist/core/indexCache.js +5 -1
  114. package/dist/core/indexCache.js.map +1 -1
  115. package/dist/core/issueEngine.js +18 -0
  116. package/dist/core/issueEngine.js.map +1 -1
  117. package/dist/core/languages/LanguageAdapter.d.ts +1 -1
  118. package/dist/core/languages/goAdapter.js +12 -5
  119. package/dist/core/languages/goAdapter.js.map +1 -1
  120. package/dist/core/languages/goCallSites.d.ts +20 -0
  121. package/dist/core/languages/goCallSites.js +42 -0
  122. package/dist/core/languages/goCallSites.js.map +1 -0
  123. package/dist/core/languages/goCyclomatic.d.ts +1 -1
  124. package/dist/core/languages/goCyclomatic.js +2 -2
  125. package/dist/core/languages/goExports.d.ts +1 -1
  126. package/dist/core/languages/goExports.js +1 -1
  127. package/dist/core/languages/goFunctions.d.ts +24 -0
  128. package/dist/core/languages/goFunctions.js +99 -0
  129. package/dist/core/languages/goFunctions.js.map +1 -0
  130. package/dist/core/languages/goManifests.d.ts +1 -1
  131. package/dist/core/languages/goManifests.js +2 -2
  132. package/dist/core/languages/javaAdapter.d.ts +2 -0
  133. package/dist/core/languages/javaAdapter.js +153 -0
  134. package/dist/core/languages/javaAdapter.js.map +1 -0
  135. package/dist/core/languages/javaCallSites.d.ts +16 -0
  136. package/dist/core/languages/javaCallSites.js +45 -0
  137. package/dist/core/languages/javaCallSites.js.map +1 -0
  138. package/dist/core/languages/javaCyclomatic.d.ts +21 -0
  139. package/dist/core/languages/javaCyclomatic.js +49 -0
  140. package/dist/core/languages/javaCyclomatic.js.map +1 -0
  141. package/dist/core/languages/javaExports.d.ts +25 -0
  142. package/dist/core/languages/javaExports.js +80 -0
  143. package/dist/core/languages/javaExports.js.map +1 -0
  144. package/dist/core/languages/javaFunctions.d.ts +22 -0
  145. package/dist/core/languages/javaFunctions.js +87 -0
  146. package/dist/core/languages/javaFunctions.js.map +1 -0
  147. package/dist/core/languages/javaImports.d.ts +25 -0
  148. package/dist/core/languages/javaImports.js +49 -0
  149. package/dist/core/languages/javaImports.js.map +1 -0
  150. package/dist/core/languages/javaManifests.d.ts +25 -0
  151. package/dist/core/languages/javaManifests.js +86 -0
  152. package/dist/core/languages/javaManifests.js.map +1 -0
  153. package/dist/core/languages/pythonAdapter.js +8 -1
  154. package/dist/core/languages/pythonAdapter.js.map +1 -1
  155. package/dist/core/languages/pythonCallSites.d.ts +19 -0
  156. package/dist/core/languages/pythonCallSites.js +40 -0
  157. package/dist/core/languages/pythonCallSites.js.map +1 -0
  158. package/dist/core/languages/pythonFunctions.d.ts +23 -0
  159. package/dist/core/languages/pythonFunctions.js +87 -0
  160. package/dist/core/languages/pythonFunctions.js.map +1 -0
  161. package/dist/core/languages/registry.js +3 -1
  162. package/dist/core/languages/registry.js.map +1 -1
  163. package/dist/core/languages/rubyAdapter.d.ts +2 -0
  164. package/dist/core/languages/rubyAdapter.js +136 -0
  165. package/dist/core/languages/rubyAdapter.js.map +1 -0
  166. package/dist/core/languages/rubyCallSites.d.ts +16 -0
  167. package/dist/core/languages/rubyCallSites.js +34 -0
  168. package/dist/core/languages/rubyCallSites.js.map +1 -0
  169. package/dist/core/languages/rubyCyclomatic.d.ts +19 -0
  170. package/dist/core/languages/rubyCyclomatic.js +47 -0
  171. package/dist/core/languages/rubyCyclomatic.js.map +1 -0
  172. package/dist/core/languages/rubyExports.d.ts +24 -0
  173. package/dist/core/languages/rubyExports.js +53 -0
  174. package/dist/core/languages/rubyExports.js.map +1 -0
  175. package/dist/core/languages/rubyFunctions.d.ts +22 -0
  176. package/dist/core/languages/rubyFunctions.js +91 -0
  177. package/dist/core/languages/rubyFunctions.js.map +1 -0
  178. package/dist/core/languages/rubyImports.d.ts +12 -0
  179. package/dist/core/languages/rubyImports.js +75 -0
  180. package/dist/core/languages/rubyImports.js.map +1 -0
  181. package/dist/core/languages/rubyManifests.d.ts +20 -0
  182. package/dist/core/languages/rubyManifests.js +55 -0
  183. package/dist/core/languages/rubyManifests.js.map +1 -0
  184. package/dist/core/languages/treeSitterLoader.js +3 -1
  185. package/dist/core/languages/treeSitterLoader.js.map +1 -1
  186. package/dist/core/monorepo.js +5 -5
  187. package/dist/core/outdatedDetector.d.ts +13 -2
  188. package/dist/core/outdatedDetector.js +86 -16
  189. package/dist/core/outdatedDetector.js.map +1 -1
  190. package/dist/core/prDiff.d.ts +1 -1
  191. package/dist/core/prDiff.js +2 -2
  192. package/dist/core/review.d.ts +21 -0
  193. package/dist/core/review.js +457 -0
  194. package/dist/core/review.js.map +1 -0
  195. package/dist/grammars/tree-sitter-java.wasm +0 -0
  196. package/dist/grammars/tree-sitter-ruby.wasm +0 -0
  197. package/dist/index.d.ts +5 -1
  198. package/dist/index.js +3 -0
  199. package/dist/index.js.map +1 -1
  200. package/dist/mcp/server.js +0 -22
  201. package/dist/mcp/server.js.map +1 -1
  202. package/dist/mcp/tools/_shared.d.ts +24 -0
  203. package/dist/mcp/tools/_shared.js +82 -0
  204. package/dist/mcp/tools/_shared.js.map +1 -0
  205. package/dist/mcp/tools/analyze.d.ts +2 -0
  206. package/dist/mcp/tools/analyze.js +55 -0
  207. package/dist/mcp/tools/analyze.js.map +1 -0
  208. package/dist/mcp/tools/audit.d.ts +2 -0
  209. package/dist/mcp/tools/audit.js +37 -0
  210. package/dist/mcp/tools/audit.js.map +1 -0
  211. package/dist/mcp/tools/coupling.d.ts +2 -0
  212. package/dist/mcp/tools/coupling.js +67 -0
  213. package/dist/mcp/tools/coupling.js.map +1 -0
  214. package/dist/mcp/tools/coverage.d.ts +2 -0
  215. package/dist/mcp/tools/coverage.js +53 -0
  216. package/dist/mcp/tools/coverage.js.map +1 -0
  217. package/dist/mcp/tools/dependencies.d.ts +2 -0
  218. package/dist/mcp/tools/dependencies.js +22 -0
  219. package/dist/mcp/tools/dependencies.js.map +1 -0
  220. package/dist/mcp/tools/doctor.d.ts +2 -0
  221. package/dist/mcp/tools/doctor.js +30 -0
  222. package/dist/mcp/tools/doctor.js.map +1 -0
  223. package/dist/mcp/tools/explain.d.ts +2 -0
  224. package/dist/mcp/tools/explain.js +30 -0
  225. package/dist/mcp/tools/explain.js.map +1 -0
  226. package/dist/mcp/tools/explainIssue.d.ts +2 -0
  227. package/dist/mcp/tools/explainIssue.js +30 -0
  228. package/dist/mcp/tools/explainIssue.js.map +1 -0
  229. package/dist/mcp/tools/file.d.ts +2 -0
  230. package/dist/mcp/tools/file.js +22 -0
  231. package/dist/mcp/tools/file.js.map +1 -0
  232. package/dist/mcp/tools/fixSuggest.d.ts +2 -0
  233. package/dist/mcp/tools/fixSuggest.js +57 -0
  234. package/dist/mcp/tools/fixSuggest.js.map +1 -0
  235. package/dist/mcp/tools/graph.d.ts +2 -0
  236. package/dist/mcp/tools/graph.js +69 -0
  237. package/dist/mcp/tools/graph.js.map +1 -0
  238. package/dist/mcp/tools/hotspots.d.ts +2 -0
  239. package/dist/mcp/tools/hotspots.js +103 -0
  240. package/dist/mcp/tools/hotspots.js.map +1 -0
  241. package/dist/mcp/tools/outdated.d.ts +2 -0
  242. package/dist/mcp/tools/outdated.js +36 -0
  243. package/dist/mcp/tools/outdated.js.map +1 -0
  244. package/dist/mcp/tools/prDiff.d.ts +2 -0
  245. package/dist/mcp/tools/prDiff.js +38 -0
  246. package/dist/mcp/tools/prDiff.js.map +1 -0
  247. package/dist/mcp/tools/review.d.ts +2 -0
  248. package/dist/mcp/tools/review.js +54 -0
  249. package/dist/mcp/tools/review.js.map +1 -0
  250. package/dist/mcp/tools/search.d.ts +2 -0
  251. package/dist/mcp/tools/search.js +167 -0
  252. package/dist/mcp/tools/search.js.map +1 -0
  253. package/dist/mcp/tools/structure.d.ts +2 -0
  254. package/dist/mcp/tools/structure.js +34 -0
  255. package/dist/mcp/tools/structure.js.map +1 -0
  256. package/dist/mcp/tools/upgrade.d.ts +2 -0
  257. package/dist/mcp/tools/upgrade.js +38 -0
  258. package/dist/mcp/tools/upgrade.js.map +1 -0
  259. package/dist/mcp/tools/workspaces.d.ts +2 -0
  260. package/dist/mcp/tools/workspaces.js +13 -0
  261. package/dist/mcp/tools/workspaces.js.map +1 -0
  262. package/dist/mcp/tools.d.ts +12 -6
  263. package/dist/mcp/tools.js +46 -854
  264. package/dist/mcp/tools.js.map +1 -1
  265. package/dist/reporters/consoleReporter.d.ts +9 -1
  266. package/dist/reporters/consoleReporter.js +177 -0
  267. package/dist/reporters/consoleReporter.js.map +1 -1
  268. package/dist/reporters/jsonReporter.d.ts +9 -1
  269. package/dist/reporters/jsonReporter.js +9 -0
  270. package/dist/reporters/jsonReporter.js.map +1 -1
  271. package/dist/reporters/markdownReporter.d.ts +9 -1
  272. package/dist/reporters/markdownReporter.js +141 -0
  273. package/dist/reporters/markdownReporter.js.map +1 -1
  274. package/dist/tool-manifest.json +446 -0
  275. package/dist/types.d.ts +235 -5
  276. package/dist/utils/config.js +26 -9
  277. package/dist/utils/config.js.map +1 -1
  278. package/package.json +8 -3
@@ -15,7 +15,7 @@ interface TsNode {
15
15
  * communication_case +1 (each non-default arm of a select)
16
16
  * binary_expression with operator `&&` or `||` +1 each
17
17
  *
18
- * Goroutine `go` and `defer` are NOT branches they don't count.
18
+ * Goroutine `go` and `defer` are NOT branches - they don't count.
19
19
  */
20
20
  export declare function extractGoCyclomatic(root: TsNode): number;
21
21
  export {};
@@ -10,7 +10,7 @@
10
10
  * communication_case +1 (each non-default arm of a select)
11
11
  * binary_expression with operator `&&` or `||` +1 each
12
12
  *
13
- * Goroutine `go` and `defer` are NOT branches they don't count.
13
+ * Goroutine `go` and `defer` are NOT branches - they don't count.
14
14
  */
15
15
  export function extractGoCyclomatic(root) {
16
16
  let decisions = 0;
@@ -36,7 +36,7 @@ function isDecisionPoint(n) {
36
36
  // application, this is precise.
37
37
  const t = n.text;
38
38
  // Use small windows: an `&&` or `||` appears as two ASCII chars.
39
- // No false positives possible strings are themselves leaf nodes
39
+ // No false positives possible - strings are themselves leaf nodes
40
40
  // (interpreted_string_literal) and would parent-up through other paths.
41
41
  // Still, guard against operators inside string literals by checking
42
42
  // that this particular binary_expression's first/second child is not
@@ -12,7 +12,7 @@ interface TsNode {
12
12
  * Extract package-level "exports" from a Go AST.
13
13
  *
14
14
  * Go's export rule is mechanical: an identifier is exported iff it starts
15
- * with an uppercase letter. We scan top-level declarations only local
15
+ * with an uppercase letter. We scan top-level declarations only - local
16
16
  * symbols inside functions are not part of the package surface.
17
17
  *
18
18
  * Captured forms:
@@ -2,7 +2,7 @@
2
2
  * Extract package-level "exports" from a Go AST.
3
3
  *
4
4
  * Go's export rule is mechanical: an identifier is exported iff it starts
5
- * with an uppercase letter. We scan top-level declarations only local
5
+ * with an uppercase letter. We scan top-level declarations only - local
6
6
  * symbols inside functions are not part of the package surface.
7
7
  *
8
8
  * Captured forms:
@@ -0,0 +1,24 @@
1
+ import type { FunctionInfo } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ column: number;
8
+ };
9
+ endPosition: {
10
+ row: number;
11
+ column: number;
12
+ };
13
+ namedChildren: TsNode[];
14
+ childForFieldName?: (name: string) => TsNode | null;
15
+ }
16
+ /**
17
+ * Per-function McCabe CC for Go. Walks `function_declaration` (top-level
18
+ * funcs) and `method_declaration` (methods on a receiver). Methods are named
19
+ * `Receiver.Method`. Function literals (`func() { ... }`) are not extracted
20
+ * as separate functions in 0.13.0; they fold into the enclosing function's
21
+ * CC.
22
+ */
23
+ export declare function extractGoFunctions(root: TsNode): FunctionInfo[];
24
+ export {};
@@ -0,0 +1,99 @@
1
+ const GO_DECISION_NODES = new Set([
2
+ 'if_statement',
3
+ 'for_statement',
4
+ 'expression_case',
5
+ 'type_case',
6
+ 'communication_case',
7
+ ]);
8
+ /**
9
+ * Per-function McCabe CC for Go. Walks `function_declaration` (top-level
10
+ * funcs) and `method_declaration` (methods on a receiver). Methods are named
11
+ * `Receiver.Method`. Function literals (`func() { ... }`) are not extracted
12
+ * as separate functions in 0.13.0; they fold into the enclosing function's
13
+ * CC.
14
+ */
15
+ export function extractGoFunctions(root) {
16
+ const out = [];
17
+ walk(root, out);
18
+ return out;
19
+ }
20
+ function walk(node, out) {
21
+ if (node.type === 'function_declaration' || node.type === 'method_declaration') {
22
+ const fnName = nameOfGoFunction(node);
23
+ const line = node.startPosition.row + 1;
24
+ const endLine = node.endPosition.row + 1;
25
+ const cc = countDecisions(node);
26
+ out.push({ name: fnName, line, endLine, cyclomaticComplexity: cc });
27
+ // Don't recurse into the body for FunctionInfo - we don't track func
28
+ // literals separately in 0.13.0 (they're not addressable by name anyway).
29
+ return;
30
+ }
31
+ for (const child of node.namedChildren)
32
+ walk(child, out);
33
+ }
34
+ function nameOfGoFunction(node) {
35
+ // function_declaration has a `name` field (identifier).
36
+ if (node.type === 'function_declaration') {
37
+ const n = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'identifier');
38
+ return n?.text ?? '<anonymous>';
39
+ }
40
+ // method_declaration has `receiver` + `name`. Receiver is a parameter_list.
41
+ if (node.type === 'method_declaration') {
42
+ const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'field_identifier');
43
+ const fnName = nameNode?.text ?? '<anonymous>';
44
+ const receiver = node.childForFieldName ? node.childForFieldName('receiver') : null;
45
+ if (receiver) {
46
+ // Receiver text is like `(x *Foo)` or `(Foo)`. Extract the type name.
47
+ const recvType = extractReceiverType(receiver.text);
48
+ if (recvType)
49
+ return `${recvType}.${fnName}`;
50
+ }
51
+ return fnName;
52
+ }
53
+ return '<anonymous>';
54
+ }
55
+ function extractReceiverType(text) {
56
+ // Strip surrounding parens; extract the last identifier-shaped token (skipping `*`).
57
+ const inner = text.replace(/^\(|\)$/g, '').trim();
58
+ // forms: `Foo` | `f Foo` | `f *Foo` | `*Foo` | `Foo[T]` | `f Foo[T]`
59
+ const m = /(?:\*)?([A-Za-z_][A-Za-z0-9_]*)(?:\[[^\]]*\])?\s*$/.exec(inner);
60
+ return m ? m[1] : null;
61
+ }
62
+ function countDecisions(fnNode) {
63
+ let count = 0;
64
+ const body = fnNode.childForFieldName ? fnNode.childForFieldName('body') : null;
65
+ if (!body)
66
+ return 1;
67
+ walkSkipNested(body, (n) => {
68
+ if (GO_DECISION_NODES.has(n.type)) {
69
+ count++;
70
+ return;
71
+ }
72
+ if (n.type === 'binary_expression') {
73
+ if (/(\s|^)(\|\||&&)(\s|$)/.test(n.text))
74
+ count++;
75
+ }
76
+ });
77
+ return count + 1;
78
+ }
79
+ function walkSkipNested(node, visit) {
80
+ visit(node);
81
+ for (const child of node.namedChildren) {
82
+ if (child.type === 'function_declaration' ||
83
+ child.type === 'method_declaration' ||
84
+ child.type === 'func_literal') {
85
+ // Skip: nested function literals fold into their own implicit "function"
86
+ // but we don't emit them. The enclosing function's CC still counts the
87
+ // call/decision points around the literal but not those *inside* it.
88
+ continue;
89
+ }
90
+ walkSkipNested(child, visit);
91
+ }
92
+ }
93
+ function findChild(node, type) {
94
+ for (const c of node.namedChildren)
95
+ if (c.type === type)
96
+ return c;
97
+ return null;
98
+ }
99
+ //# sourceMappingURL=goFunctions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/goFunctions.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ export interface GoProjectInfo {
13
13
  * repository root first, then any directory that contains at least one .go
14
14
  * file (handles nested modules / examples directories).
15
15
  *
16
- * Returns null if no go.mod exists Go files outside any module are valid
16
+ * Returns null if no go.mod exists - Go files outside any module are valid
17
17
  * (e.g. snippets) but their imports can't be resolved to local files.
18
18
  */
19
19
  export declare function detectGoProject(rootPath: string, files: FileEntry[]): Promise<GoProjectInfo | null>;
@@ -5,11 +5,11 @@ import path from 'node:path';
5
5
  * repository root first, then any directory that contains at least one .go
6
6
  * file (handles nested modules / examples directories).
7
7
  *
8
- * Returns null if no go.mod exists Go files outside any module are valid
8
+ * Returns null if no go.mod exists - Go files outside any module are valid
9
9
  * (e.g. snippets) but their imports can't be resolved to local files.
10
10
  */
11
11
  export async function detectGoProject(rootPath, files) {
12
- // 1) Try repo root first by far the most common case.
12
+ // 1) Try repo root first - by far the most common case.
13
13
  const rootGoMod = await readGoMod(path.join(rootPath, 'go.mod'));
14
14
  if (rootGoMod)
15
15
  return { modulePath: rootGoMod, moduleRoot: rootPath };
@@ -0,0 +1,2 @@
1
+ import type { LanguageAdapter } from './LanguageAdapter.js';
2
+ export declare const javaAdapter: LanguageAdapter;
@@ -0,0 +1,153 @@
1
+ import path from 'node:path';
2
+ import { createParserFor } from './treeSitterLoader.js';
3
+ import { extractJavaImports } from './javaImports.js';
4
+ import { extractJavaExports } from './javaExports.js';
5
+ import { extractJavaCyclomatic } from './javaCyclomatic.js';
6
+ import { extractJavaFunctions } from './javaFunctions.js';
7
+ import { extractJavaCallSites } from './javaCallSites.js';
8
+ import { detectJavaProject } from './javaManifests.js';
9
+ const JAVA_EXTENSIONS = new Set(['.java']);
10
+ const MAX_JAVA_FILE = 1024 * 1024;
11
+ let parserPromise = null;
12
+ async function getParser() {
13
+ if (!parserPromise)
14
+ parserPromise = createParserFor('tree-sitter-java.wasm');
15
+ return parserPromise;
16
+ }
17
+ export const javaAdapter = {
18
+ id: 'java',
19
+ extensions: JAVA_EXTENSIONS,
20
+ sourceExtensions: JAVA_EXTENSIONS,
21
+ // Java has no barrel-file convention. A `package-info.java` file is metadata,
22
+ // not a re-export hub.
23
+ barrelBasenames: new Set(),
24
+ maxFileSize: MAX_JAVA_FILE,
25
+ async parse(_filePath, content) {
26
+ try {
27
+ const parser = await getParser();
28
+ const tree = parser.parse(content);
29
+ if (!tree || !tree.rootNode) {
30
+ return {
31
+ ok: false,
32
+ reason: 'tree-sitter returned null tree',
33
+ imports: [],
34
+ exports: [],
35
+ callSites: [],
36
+ lineCount: content ? content.split('\n').length : 0,
37
+ cyclomaticComplexity: 0,
38
+ functions: [],
39
+ };
40
+ }
41
+ const root = tree.rootNode;
42
+ const imports = extractJavaImports(root);
43
+ const exports = extractJavaExports(root);
44
+ const cyclomaticComplexity = extractJavaCyclomatic(root);
45
+ const callSites = extractJavaCallSites(root);
46
+ const functions = extractJavaFunctions(root);
47
+ return {
48
+ ok: true,
49
+ imports,
50
+ exports,
51
+ callSites,
52
+ lineCount: content ? content.split('\n').length : 0,
53
+ cyclomaticComplexity,
54
+ functions,
55
+ };
56
+ }
57
+ catch (err) {
58
+ const msg = err instanceof Error ? err.message : String(err);
59
+ return {
60
+ ok: false,
61
+ reason: `java parse failure: ${msg.slice(0, 120)}`,
62
+ imports: [],
63
+ exports: [],
64
+ callSites: [],
65
+ lineCount: content ? content.split('\n').length : 0,
66
+ cyclomaticComplexity: 0,
67
+ functions: [],
68
+ };
69
+ }
70
+ },
71
+ resolveImport(importingFile, source, graphFiles, context) {
72
+ return resolveJavaImport(importingFile, source, graphFiles, context);
73
+ },
74
+ toPackageName(source) {
75
+ if (!source)
76
+ return null;
77
+ if (source.startsWith('.'))
78
+ return null;
79
+ // Strip wildcard / static-tail to get the dotted package path.
80
+ const base = source.endsWith('.*') ? source.slice(0, -2) : source;
81
+ // Java imports typically end in a TypeName; drop the last segment to get
82
+ // the package. For wildcards the whole thing IS the package.
83
+ if (source.endsWith('.*'))
84
+ return base;
85
+ const lastDot = base.lastIndexOf('.');
86
+ return lastDot > 0 ? base.slice(0, lastDot) : base;
87
+ },
88
+ async preparePackageRoots(rootPath, files) {
89
+ const info = await detectJavaProject(rootPath, files);
90
+ if (!info)
91
+ return { packageRoots: [], meta: undefined };
92
+ return {
93
+ packageRoots: info.sourceRoots.map((r) => path.relative(rootPath, r) || '.'),
94
+ meta: { javaProject: info },
95
+ };
96
+ },
97
+ };
98
+ /**
99
+ * Resolve a Java import to a repo-local file path, or null if it refers to a
100
+ * stdlib / third-party type or otherwise cannot be resolved.
101
+ *
102
+ * import com.foo.Bar; → for each sourceRoot, probe `com/foo/Bar.java`
103
+ * import com.foo.*; → resolve to ANY file under `com/foo/` (rare; we
104
+ * just pick the first match for graph-edge purposes)
105
+ * import static com.foo.Bar.X; → resolves to `com/foo/Bar.java` (X is a member)
106
+ */
107
+ function resolveJavaImport(_importingFile, source, graphFiles, context) {
108
+ if (!source)
109
+ return null;
110
+ const javaProject = context.meta
111
+ ?.javaProject;
112
+ const sourceRootsRel = context.packageRoots ?? [];
113
+ if (sourceRootsRel.length === 0 && !javaProject)
114
+ return null;
115
+ const isWildcard = source.endsWith('.*');
116
+ const stripped = isWildcard ? source.slice(0, -2) : source;
117
+ const segments = stripped.split('.').filter(Boolean);
118
+ if (segments.length === 0)
119
+ return null;
120
+ // For type imports, the last segment is the type name (file basename).
121
+ // For wildcard imports, all segments form the package directory.
122
+ for (const root of sourceRootsRel) {
123
+ const rootSegs = root === '.' || root === '' ? [] : root.split('/').filter(Boolean);
124
+ if (isWildcard) {
125
+ const dir = [...rootSegs, ...segments].join('/');
126
+ const prefix = dir + '/';
127
+ // Pick the first .java file directly under that directory.
128
+ const matches = [];
129
+ for (const file of graphFiles.keys()) {
130
+ if (!file.endsWith('.java'))
131
+ continue;
132
+ if (file.startsWith(prefix)) {
133
+ const tail = file.slice(prefix.length);
134
+ if (!tail.includes('/'))
135
+ matches.push(file);
136
+ }
137
+ }
138
+ if (matches.length > 0) {
139
+ matches.sort();
140
+ return matches[0];
141
+ }
142
+ continue;
143
+ }
144
+ // Non-wildcard: last segment is the type, preceding segments are the path.
145
+ const typeName = segments[segments.length - 1];
146
+ const pkgPath = segments.slice(0, -1);
147
+ const candidate = [...rootSegs, ...pkgPath, `${typeName}.java`].join('/');
148
+ if (graphFiles.has(candidate))
149
+ return candidate;
150
+ }
151
+ return null;
152
+ }
153
+ //# sourceMappingURL=javaAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"javaAdapter.js","sourceRoot":"","sources":["../../../src/core/languages/javaAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Extract call-site identifiers from a tree-sitter-java AST.
3
+ *
4
+ * tree-sitter-java's call shape: `method_invocation` with field `name` for the
5
+ * called method and optional `object` (for `obj.method(...)`) or no object
6
+ * (for `method(...)` inside the same class). Constructor calls
7
+ * (`object_creation_expression`) are also recorded by the type name.
8
+ */
9
+ interface TsNode {
10
+ type: string;
11
+ text: string;
12
+ namedChildren: TsNode[];
13
+ childForFieldName?(name: string): TsNode | null;
14
+ }
15
+ export declare function extractJavaCallSites(root: TsNode): string[];
16
+ export {};
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Extract call-site identifiers from a tree-sitter-java AST.
3
+ *
4
+ * tree-sitter-java's call shape: `method_invocation` with field `name` for the
5
+ * called method and optional `object` (for `obj.method(...)`) or no object
6
+ * (for `method(...)` inside the same class). Constructor calls
7
+ * (`object_creation_expression`) are also recorded by the type name.
8
+ */
9
+ export function extractJavaCallSites(root) {
10
+ const seen = new Set();
11
+ walk(root, seen);
12
+ return [...seen];
13
+ }
14
+ function walk(node, out) {
15
+ if (node.type === 'method_invocation') {
16
+ const name = node.childForFieldName?.('name') ?? null;
17
+ if (name && (name.type === 'identifier' || name.type === 'field_identifier')) {
18
+ out.add(name.text);
19
+ }
20
+ }
21
+ else if (node.type === 'object_creation_expression') {
22
+ // `new Foo(...)` - record `Foo` so "who instantiates Foo?" works.
23
+ const type = node.childForFieldName?.('type') ?? null;
24
+ if (type) {
25
+ const last = lastIdentifier(type);
26
+ if (last)
27
+ out.add(last);
28
+ }
29
+ }
30
+ for (const child of node.namedChildren)
31
+ walk(child, out);
32
+ }
33
+ /** Pull the rightmost simple name from a type node (handles type_identifier and scoped_type_identifier). */
34
+ function lastIdentifier(node) {
35
+ if (node.type === 'type_identifier' || node.type === 'identifier')
36
+ return node.text;
37
+ // scoped_type_identifier carries a chain; walk to the last name.
38
+ let last = null;
39
+ for (const c of node.namedChildren) {
40
+ if (c.type === 'type_identifier' || c.type === 'identifier')
41
+ last = c.text;
42
+ }
43
+ return last;
44
+ }
45
+ //# sourceMappingURL=javaCallSites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"javaCallSites.js","sourceRoot":"","sources":["../../../src/core/languages/javaCallSites.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AACnB,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,GAAgB;IAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;QACtD,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,kBAAkB,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,KAAK,4BAA4B,EAAE,CAAC;QACtD,kEAAkE;QAClE,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;QACtD,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,IAAI;gBAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,4GAA4G;AAC5G,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IACpF,iEAAiE;IACjE,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,iBAAiB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY;YAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IAC7E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,21 @@
1
+ interface TsNode {
2
+ type: string;
3
+ text: string;
4
+ namedChildren: TsNode[];
5
+ }
6
+ /**
7
+ * File-level McCabe cyclomatic complexity for a tree-sitter-java AST.
8
+ *
9
+ * Decision points:
10
+ * if_statement, ternary_expression +1
11
+ * for_statement, enhanced_for_statement +1
12
+ * while_statement, do_statement +1
13
+ * switch_label (case ...; default does NOT count)
14
+ * catch_clause +1
15
+ * binary_expression with `&&` or `||` +1 each
16
+ *
17
+ * `else` does not count (it shares the if's decision). `try` and `finally`
18
+ * do not count.
19
+ */
20
+ export declare function extractJavaCyclomatic(root: TsNode): number;
21
+ export {};
@@ -0,0 +1,49 @@
1
+ /**
2
+ * File-level McCabe cyclomatic complexity for a tree-sitter-java AST.
3
+ *
4
+ * Decision points:
5
+ * if_statement, ternary_expression +1
6
+ * for_statement, enhanced_for_statement +1
7
+ * while_statement, do_statement +1
8
+ * switch_label (case ...; default does NOT count)
9
+ * catch_clause +1
10
+ * binary_expression with `&&` or `||` +1 each
11
+ *
12
+ * `else` does not count (it shares the if's decision). `try` and `finally`
13
+ * do not count.
14
+ */
15
+ export function extractJavaCyclomatic(root) {
16
+ let decisions = 0;
17
+ walk(root, (n) => {
18
+ if (isDecisionPoint(n))
19
+ decisions++;
20
+ });
21
+ return decisions + 1;
22
+ }
23
+ function isDecisionPoint(n) {
24
+ switch (n.type) {
25
+ case 'if_statement':
26
+ case 'ternary_expression':
27
+ case 'for_statement':
28
+ case 'enhanced_for_statement':
29
+ case 'while_statement':
30
+ case 'do_statement':
31
+ case 'catch_clause':
32
+ return true;
33
+ case 'switch_label': {
34
+ // The grammar uses `switch_label` for both `case X:` and `default:`.
35
+ // Default does not contribute a new branch (it's the fallthrough).
36
+ return !/^\s*default\b/.test(n.text);
37
+ }
38
+ case 'binary_expression':
39
+ return /(\s|^)(\|\||&&)(\s|$)/.test(n.text);
40
+ default:
41
+ return false;
42
+ }
43
+ }
44
+ function walk(node, visit) {
45
+ visit(node);
46
+ for (const child of node.namedChildren)
47
+ walk(child, visit);
48
+ }
49
+ //# sourceMappingURL=javaCyclomatic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"javaCyclomatic.js","sourceRoot":"","sources":["../../../src/core/languages/javaCyclomatic.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,IAAI,eAAe,CAAC,CAAC,CAAC;YAAE,SAAS,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,GAAG,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,cAAc,CAAC;QACpB,KAAK,oBAAoB,CAAC;QAC1B,KAAK,eAAe,CAAC;QACrB,KAAK,wBAAwB,CAAC;QAC9B,KAAK,iBAAiB,CAAC;QACvB,KAAK,cAAc,CAAC;QACpB,KAAK,cAAc;YACjB,OAAO,IAAI,CAAC;QACd,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,qEAAqE;YACrE,mEAAmE;YACnE,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,mBAAmB;YACtB,OAAO,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9C;YACE,OAAO,KAAK,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,IAAI,CAAC,IAAY,EAAE,KAA0B;IACpD,KAAK,CAAC,IAAI,CAAC,CAAC;IACZ,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { AstExport } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ };
8
+ namedChildren: TsNode[];
9
+ childForFieldName?(name: string): TsNode | null;
10
+ }
11
+ /**
12
+ * Extract package-level "exports" from a Java AST.
13
+ *
14
+ * Java visibility rules:
15
+ * public - visible everywhere
16
+ * protected - visible to package + subclasses
17
+ * (none) - package-private
18
+ * private - file-only
19
+ *
20
+ * We treat `public` as the export surface (the typical "API") and skip
21
+ * everything else. Top-level declarations only - nested types are part of
22
+ * their enclosing class's surface, not separate exports.
23
+ */
24
+ export declare function extractJavaExports(root: TsNode): AstExport[];
25
+ export {};
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Extract package-level "exports" from a Java AST.
3
+ *
4
+ * Java visibility rules:
5
+ * public - visible everywhere
6
+ * protected - visible to package + subclasses
7
+ * (none) - package-private
8
+ * private - file-only
9
+ *
10
+ * We treat `public` as the export surface (the typical "API") and skip
11
+ * everything else. Top-level declarations only - nested types are part of
12
+ * their enclosing class's surface, not separate exports.
13
+ */
14
+ export function extractJavaExports(root) {
15
+ const out = [];
16
+ for (const child of root.namedChildren) {
17
+ visitTopLevel(child, out);
18
+ }
19
+ return out;
20
+ }
21
+ function visitTopLevel(node, out) {
22
+ switch (node.type) {
23
+ case 'class_declaration':
24
+ addPublic(node, 'class', out);
25
+ return;
26
+ case 'interface_declaration':
27
+ addPublic(node, 'interface', out);
28
+ return;
29
+ case 'enum_declaration':
30
+ addPublic(node, 'enum', out);
31
+ return;
32
+ case 'record_declaration':
33
+ // Java 14+ records - treat as a class for our purposes.
34
+ addPublic(node, 'class', out);
35
+ return;
36
+ case 'annotation_type_declaration':
37
+ addPublic(node, 'type', out);
38
+ return;
39
+ default:
40
+ return;
41
+ }
42
+ }
43
+ function addPublic(node, kind, out) {
44
+ if (!hasModifier(node, 'public'))
45
+ return;
46
+ const nameNode = node.childForFieldName?.('name') ?? findChild(node, 'identifier');
47
+ if (!nameNode)
48
+ return;
49
+ out.push({
50
+ name: nameNode.text,
51
+ kind,
52
+ typeOnly: false,
53
+ line: node.startPosition.row + 1,
54
+ });
55
+ }
56
+ function hasModifier(node, mod) {
57
+ const modsNode = findChild(node, 'modifiers');
58
+ if (!modsNode)
59
+ return false;
60
+ // tree-sitter-java emits keyword modifiers (`public`, `private`, etc.) as
61
+ // anonymous children - they're not in `namedChildren`. Walk the full child
62
+ // list and match by token type or text.
63
+ for (const c of modsNode.namedChildren) {
64
+ if (c.type === mod || c.text === mod)
65
+ return true;
66
+ }
67
+ // Anonymous-keyword fallback: scan tokens via text match. Modifiers contain
68
+ // only the keyword tokens plus annotations; annotations start with `@` so
69
+ // exact-match against `mod` is unambiguous.
70
+ const tokens = modsNode.text.split(/\s+/);
71
+ return tokens.includes(mod);
72
+ }
73
+ function findChild(node, type) {
74
+ for (const c of node.namedChildren) {
75
+ if (c.type === type)
76
+ return c;
77
+ }
78
+ return null;
79
+ }
80
+ //# sourceMappingURL=javaExports.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"javaExports.js","sourceRoot":"","sources":["../../../src/core/languages/javaExports.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,IAAY,EAAE,GAAgB;IACnD,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,mBAAmB;YACtB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9B,OAAO;QACT,KAAK,uBAAuB;YAC1B,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;YAClC,OAAO;QACT,KAAK,kBAAkB;YACrB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC7B,OAAO;QACT,KAAK,oBAAoB;YACvB,wDAAwD;YACxD,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9B,OAAO;QACT,KAAK,6BAA6B;YAChC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;YAC7B,OAAO;QACT;YACE,OAAO;IACX,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,IAAgB,EAAE,GAAgB;IACjE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAE,OAAO;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACnF,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,GAAG,CAAC,IAAI,CAAC;QACP,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,IAAI;QACJ,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;KACjC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,GAAW;IAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAC9C,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,0EAA0E;IAC1E,2EAA2E;IAC3E,wCAAwC;IACxC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;QACvC,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,GAAG;YAAE,OAAO,IAAI,CAAC;IACpD,CAAC;IACD,4EAA4E;IAC5E,0EAA0E;IAC1E,4CAA4C;IAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,SAAS,CAAC,IAAY,EAAE,IAAY;IAC3C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { FunctionInfo } from '../ast.js';
2
+ interface TsNode {
3
+ type: string;
4
+ text: string;
5
+ startPosition: {
6
+ row: number;
7
+ column: number;
8
+ };
9
+ endPosition: {
10
+ row: number;
11
+ column: number;
12
+ };
13
+ namedChildren: TsNode[];
14
+ childForFieldName?: (name: string) => TsNode | null;
15
+ }
16
+ /**
17
+ * Per-method McCabe CC for Java. Walks `method_declaration` and
18
+ * `constructor_declaration`. Methods are named `Class.method`; constructors
19
+ * are named `Class.<init>`.
20
+ */
21
+ export declare function extractJavaFunctions(root: TsNode): FunctionInfo[];
22
+ export {};