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.
- package/README.md +57 -33
- package/dist/analyzers/crossPackageImportCheck.d.ts +13 -0
- package/dist/analyzers/crossPackageImportCheck.js +136 -0
- package/dist/analyzers/crossPackageImportCheck.js.map +1 -0
- package/dist/analyzers/cycleCheck.d.ts +12 -0
- package/dist/analyzers/cycleCheck.js +65 -0
- package/dist/analyzers/cycleCheck.js.map +1 -0
- package/dist/analyzers/unusedDependencyCheck.js +69 -17
- package/dist/analyzers/unusedDependencyCheck.js.map +1 -1
- package/dist/cli/_shared.d.ts +16 -0
- package/dist/cli/_shared.js +210 -0
- package/dist/cli/_shared.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +1 -0
- package/dist/cli/commands/analyze.js +87 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +1 -0
- package/dist/cli/commands/audit.js +53 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/badge.d.ts +1 -0
- package/dist/cli/commands/badge.js +45 -0
- package/dist/cli/commands/badge.js.map +1 -0
- package/dist/cli/commands/ci.d.ts +1 -0
- package/dist/cli/commands/ci.js +57 -0
- package/dist/cli/commands/ci.js.map +1 -0
- package/dist/cli/commands/coupling.d.ts +1 -0
- package/dist/cli/commands/coupling.js +83 -0
- package/dist/cli/commands/coupling.js.map +1 -0
- package/dist/cli/commands/coverage.d.ts +1 -0
- package/dist/cli/commands/coverage.js +63 -0
- package/dist/cli/commands/coverage.js.map +1 -0
- package/dist/cli/commands/dependencies.d.ts +1 -0
- package/dist/cli/commands/dependencies.js +46 -0
- package/dist/cli/commands/dependencies.js.map +1 -0
- package/dist/cli/commands/diagram.d.ts +1 -0
- package/dist/cli/commands/diagram.js +45 -0
- package/dist/cli/commands/diagram.js.map +1 -0
- package/dist/cli/commands/diff.d.ts +1 -0
- package/dist/cli/commands/diff.js +70 -0
- package/dist/cli/commands/diff.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +1 -0
- package/dist/cli/commands/doctor.js +62 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/explain.d.ts +1 -0
- package/dist/cli/commands/explain.js +42 -0
- package/dist/cli/commands/explain.js.map +1 -0
- package/dist/cli/commands/explainIssue.d.ts +1 -0
- package/dist/cli/commands/explainIssue.js +49 -0
- package/dist/cli/commands/explainIssue.js.map +1 -0
- package/dist/cli/commands/file.d.ts +1 -0
- package/dist/cli/commands/file.js +45 -0
- package/dist/cli/commands/file.js.map +1 -0
- package/dist/cli/commands/fix.d.ts +1 -0
- package/dist/cli/commands/fix.js +70 -0
- package/dist/cli/commands/fix.js.map +1 -0
- package/dist/cli/commands/fixSuggest.d.ts +1 -0
- package/dist/cli/commands/fixSuggest.js +71 -0
- package/dist/cli/commands/fixSuggest.js.map +1 -0
- package/dist/cli/commands/help.d.ts +1 -0
- package/dist/cli/commands/help.js +11 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/hotspots.d.ts +1 -0
- package/dist/cli/commands/hotspots.js +74 -0
- package/dist/cli/commands/hotspots.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +1 -0
- package/dist/cli/commands/mcp.js +21 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/outdated.d.ts +1 -0
- package/dist/cli/commands/outdated.js +51 -0
- package/dist/cli/commands/outdated.js.map +1 -0
- package/dist/cli/commands/prDiff.d.ts +1 -0
- package/dist/cli/commands/prDiff.js +59 -0
- package/dist/cli/commands/prDiff.js.map +1 -0
- package/dist/cli/commands/review.d.ts +1 -0
- package/dist/cli/commands/review.js +66 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/commands/search.d.ts +1 -0
- package/dist/cli/commands/search.js +233 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/structure.d.ts +1 -0
- package/dist/cli/commands/structure.js +58 -0
- package/dist/cli/commands/structure.js.map +1 -0
- package/dist/cli/commands/upgrade.d.ts +1 -0
- package/dist/cli/commands/upgrade.js +44 -0
- package/dist/cli/commands/upgrade.js.map +1 -0
- package/dist/cli/commands/workspaces.d.ts +1 -0
- package/dist/cli/commands/workspaces.js +35 -0
- package/dist/cli/commands/workspaces.js.map +1 -0
- package/dist/cli/index.js +51 -1416
- package/dist/cli/index.js.map +1 -1
- package/dist/core/ast.d.ts +20 -0
- package/dist/core/ast.js +190 -0
- package/dist/core/ast.js.map +1 -1
- package/dist/core/auditRunner.d.ts +8 -0
- package/dist/core/auditRunner.js +50 -1
- package/dist/core/auditRunner.js.map +1 -1
- package/dist/core/codeGraph.d.ts +7 -1
- package/dist/core/codeGraph.js +2 -0
- package/dist/core/codeGraph.js.map +1 -1
- package/dist/core/couplingAnalyzer.d.ts +1 -1
- package/dist/core/couplingAnalyzer.js +3 -3
- package/dist/core/dependencyAnalyzer.d.ts +15 -1
- package/dist/core/dependencyAnalyzer.js +115 -18
- package/dist/core/dependencyAnalyzer.js.map +1 -1
- package/dist/core/explainIssue.d.ts +9 -0
- package/dist/core/explainIssue.js +106 -0
- package/dist/core/explainIssue.js.map +1 -0
- package/dist/core/fileInspector.js +12 -0
- package/dist/core/fileInspector.js.map +1 -1
- package/dist/core/fixSuggest.d.ts +41 -0
- package/dist/core/fixSuggest.js +327 -0
- package/dist/core/fixSuggest.js.map +1 -0
- package/dist/core/hotspotAnalyzer.js +2 -2
- package/dist/core/indexCache.js +5 -1
- package/dist/core/indexCache.js.map +1 -1
- package/dist/core/issueEngine.js +18 -0
- package/dist/core/issueEngine.js.map +1 -1
- package/dist/core/languages/LanguageAdapter.d.ts +1 -1
- package/dist/core/languages/goAdapter.js +12 -5
- package/dist/core/languages/goAdapter.js.map +1 -1
- package/dist/core/languages/goCallSites.d.ts +20 -0
- package/dist/core/languages/goCallSites.js +42 -0
- package/dist/core/languages/goCallSites.js.map +1 -0
- package/dist/core/languages/goCyclomatic.d.ts +1 -1
- package/dist/core/languages/goCyclomatic.js +2 -2
- package/dist/core/languages/goExports.d.ts +1 -1
- package/dist/core/languages/goExports.js +1 -1
- package/dist/core/languages/goFunctions.d.ts +24 -0
- package/dist/core/languages/goFunctions.js +99 -0
- package/dist/core/languages/goFunctions.js.map +1 -0
- package/dist/core/languages/goManifests.d.ts +1 -1
- package/dist/core/languages/goManifests.js +2 -2
- package/dist/core/languages/javaAdapter.d.ts +2 -0
- package/dist/core/languages/javaAdapter.js +153 -0
- package/dist/core/languages/javaAdapter.js.map +1 -0
- package/dist/core/languages/javaCallSites.d.ts +16 -0
- package/dist/core/languages/javaCallSites.js +45 -0
- package/dist/core/languages/javaCallSites.js.map +1 -0
- package/dist/core/languages/javaCyclomatic.d.ts +21 -0
- package/dist/core/languages/javaCyclomatic.js +49 -0
- package/dist/core/languages/javaCyclomatic.js.map +1 -0
- package/dist/core/languages/javaExports.d.ts +25 -0
- package/dist/core/languages/javaExports.js +80 -0
- package/dist/core/languages/javaExports.js.map +1 -0
- package/dist/core/languages/javaFunctions.d.ts +22 -0
- package/dist/core/languages/javaFunctions.js +87 -0
- package/dist/core/languages/javaFunctions.js.map +1 -0
- package/dist/core/languages/javaImports.d.ts +25 -0
- package/dist/core/languages/javaImports.js +49 -0
- package/dist/core/languages/javaImports.js.map +1 -0
- package/dist/core/languages/javaManifests.d.ts +25 -0
- package/dist/core/languages/javaManifests.js +86 -0
- package/dist/core/languages/javaManifests.js.map +1 -0
- package/dist/core/languages/pythonAdapter.js +8 -1
- package/dist/core/languages/pythonAdapter.js.map +1 -1
- package/dist/core/languages/pythonCallSites.d.ts +19 -0
- package/dist/core/languages/pythonCallSites.js +40 -0
- package/dist/core/languages/pythonCallSites.js.map +1 -0
- package/dist/core/languages/pythonFunctions.d.ts +23 -0
- package/dist/core/languages/pythonFunctions.js +87 -0
- package/dist/core/languages/pythonFunctions.js.map +1 -0
- package/dist/core/languages/registry.js +3 -1
- package/dist/core/languages/registry.js.map +1 -1
- package/dist/core/languages/rubyAdapter.d.ts +2 -0
- package/dist/core/languages/rubyAdapter.js +136 -0
- package/dist/core/languages/rubyAdapter.js.map +1 -0
- package/dist/core/languages/rubyCallSites.d.ts +16 -0
- package/dist/core/languages/rubyCallSites.js +34 -0
- package/dist/core/languages/rubyCallSites.js.map +1 -0
- package/dist/core/languages/rubyCyclomatic.d.ts +19 -0
- package/dist/core/languages/rubyCyclomatic.js +47 -0
- package/dist/core/languages/rubyCyclomatic.js.map +1 -0
- package/dist/core/languages/rubyExports.d.ts +24 -0
- package/dist/core/languages/rubyExports.js +53 -0
- package/dist/core/languages/rubyExports.js.map +1 -0
- package/dist/core/languages/rubyFunctions.d.ts +22 -0
- package/dist/core/languages/rubyFunctions.js +91 -0
- package/dist/core/languages/rubyFunctions.js.map +1 -0
- package/dist/core/languages/rubyImports.d.ts +12 -0
- package/dist/core/languages/rubyImports.js +75 -0
- package/dist/core/languages/rubyImports.js.map +1 -0
- package/dist/core/languages/rubyManifests.d.ts +20 -0
- package/dist/core/languages/rubyManifests.js +55 -0
- package/dist/core/languages/rubyManifests.js.map +1 -0
- package/dist/core/languages/treeSitterLoader.js +3 -1
- package/dist/core/languages/treeSitterLoader.js.map +1 -1
- package/dist/core/monorepo.js +5 -5
- package/dist/core/outdatedDetector.d.ts +13 -2
- package/dist/core/outdatedDetector.js +86 -16
- package/dist/core/outdatedDetector.js.map +1 -1
- package/dist/core/prDiff.d.ts +1 -1
- package/dist/core/prDiff.js +2 -2
- package/dist/core/review.d.ts +21 -0
- package/dist/core/review.js +457 -0
- package/dist/core/review.js.map +1 -0
- package/dist/grammars/tree-sitter-java.wasm +0 -0
- package/dist/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +0 -22
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/_shared.d.ts +24 -0
- package/dist/mcp/tools/_shared.js +82 -0
- package/dist/mcp/tools/_shared.js.map +1 -0
- package/dist/mcp/tools/analyze.d.ts +2 -0
- package/dist/mcp/tools/analyze.js +55 -0
- package/dist/mcp/tools/analyze.js.map +1 -0
- package/dist/mcp/tools/audit.d.ts +2 -0
- package/dist/mcp/tools/audit.js +37 -0
- package/dist/mcp/tools/audit.js.map +1 -0
- package/dist/mcp/tools/coupling.d.ts +2 -0
- package/dist/mcp/tools/coupling.js +67 -0
- package/dist/mcp/tools/coupling.js.map +1 -0
- package/dist/mcp/tools/coverage.d.ts +2 -0
- package/dist/mcp/tools/coverage.js +53 -0
- package/dist/mcp/tools/coverage.js.map +1 -0
- package/dist/mcp/tools/dependencies.d.ts +2 -0
- package/dist/mcp/tools/dependencies.js +22 -0
- package/dist/mcp/tools/dependencies.js.map +1 -0
- package/dist/mcp/tools/doctor.d.ts +2 -0
- package/dist/mcp/tools/doctor.js +30 -0
- package/dist/mcp/tools/doctor.js.map +1 -0
- package/dist/mcp/tools/explain.d.ts +2 -0
- package/dist/mcp/tools/explain.js +30 -0
- package/dist/mcp/tools/explain.js.map +1 -0
- package/dist/mcp/tools/explainIssue.d.ts +2 -0
- package/dist/mcp/tools/explainIssue.js +30 -0
- package/dist/mcp/tools/explainIssue.js.map +1 -0
- package/dist/mcp/tools/file.d.ts +2 -0
- package/dist/mcp/tools/file.js +22 -0
- package/dist/mcp/tools/file.js.map +1 -0
- package/dist/mcp/tools/fixSuggest.d.ts +2 -0
- package/dist/mcp/tools/fixSuggest.js +57 -0
- package/dist/mcp/tools/fixSuggest.js.map +1 -0
- package/dist/mcp/tools/graph.d.ts +2 -0
- package/dist/mcp/tools/graph.js +69 -0
- package/dist/mcp/tools/graph.js.map +1 -0
- package/dist/mcp/tools/hotspots.d.ts +2 -0
- package/dist/mcp/tools/hotspots.js +103 -0
- package/dist/mcp/tools/hotspots.js.map +1 -0
- package/dist/mcp/tools/outdated.d.ts +2 -0
- package/dist/mcp/tools/outdated.js +36 -0
- package/dist/mcp/tools/outdated.js.map +1 -0
- package/dist/mcp/tools/prDiff.d.ts +2 -0
- package/dist/mcp/tools/prDiff.js +38 -0
- package/dist/mcp/tools/prDiff.js.map +1 -0
- package/dist/mcp/tools/review.d.ts +2 -0
- package/dist/mcp/tools/review.js +54 -0
- package/dist/mcp/tools/review.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +2 -0
- package/dist/mcp/tools/search.js +167 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/mcp/tools/structure.d.ts +2 -0
- package/dist/mcp/tools/structure.js +34 -0
- package/dist/mcp/tools/structure.js.map +1 -0
- package/dist/mcp/tools/upgrade.d.ts +2 -0
- package/dist/mcp/tools/upgrade.js +38 -0
- package/dist/mcp/tools/upgrade.js.map +1 -0
- package/dist/mcp/tools/workspaces.d.ts +2 -0
- package/dist/mcp/tools/workspaces.js +13 -0
- package/dist/mcp/tools/workspaces.js.map +1 -0
- package/dist/mcp/tools.d.ts +12 -6
- package/dist/mcp/tools.js +46 -854
- package/dist/mcp/tools.js.map +1 -1
- package/dist/reporters/consoleReporter.d.ts +9 -1
- package/dist/reporters/consoleReporter.js +177 -0
- package/dist/reporters/consoleReporter.js.map +1 -1
- package/dist/reporters/jsonReporter.d.ts +9 -1
- package/dist/reporters/jsonReporter.js +9 -0
- package/dist/reporters/jsonReporter.js.map +1 -1
- package/dist/reporters/markdownReporter.d.ts +9 -1
- package/dist/reporters/markdownReporter.js +141 -0
- package/dist/reporters/markdownReporter.js.map +1 -1
- package/dist/tool-manifest.json +446 -0
- package/dist/types.d.ts +235 -5
- package/dist/utils/config.js +26 -9
- package/dist/utils/config.js.map +1 -1
- package/package.json +8 -3
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const JAVA_DECISION_NODES = new Set([
|
|
2
|
+
'if_statement',
|
|
3
|
+
'ternary_expression',
|
|
4
|
+
'for_statement',
|
|
5
|
+
'enhanced_for_statement',
|
|
6
|
+
'while_statement',
|
|
7
|
+
'do_statement',
|
|
8
|
+
'catch_clause',
|
|
9
|
+
]);
|
|
10
|
+
/**
|
|
11
|
+
* Per-method McCabe CC for Java. Walks `method_declaration` and
|
|
12
|
+
* `constructor_declaration`. Methods are named `Class.method`; constructors
|
|
13
|
+
* are named `Class.<init>`.
|
|
14
|
+
*/
|
|
15
|
+
export function extractJavaFunctions(root) {
|
|
16
|
+
const out = [];
|
|
17
|
+
walk(root, null, out);
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function walk(node, className, out) {
|
|
21
|
+
if (node.type === 'class_declaration' ||
|
|
22
|
+
node.type === 'interface_declaration' ||
|
|
23
|
+
node.type === 'enum_declaration' ||
|
|
24
|
+
node.type === 'record_declaration' ||
|
|
25
|
+
node.type === 'annotation_type_declaration') {
|
|
26
|
+
const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'identifier');
|
|
27
|
+
const cls = nameNode?.text ?? null;
|
|
28
|
+
const body = node.childForFieldName ? node.childForFieldName('body') : null;
|
|
29
|
+
if (body) {
|
|
30
|
+
for (const child of body.namedChildren) {
|
|
31
|
+
walk(child, cls, out);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (node.type === 'method_declaration' || node.type === 'constructor_declaration') {
|
|
37
|
+
const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'identifier');
|
|
38
|
+
const baseName = node.type === 'constructor_declaration' ? '<init>' : (nameNode?.text ?? '<anonymous>');
|
|
39
|
+
const fnName = className ? `${className}.${baseName}` : baseName;
|
|
40
|
+
const line = node.startPosition.row + 1;
|
|
41
|
+
const endLine = node.endPosition.row + 1;
|
|
42
|
+
const cc = countDecisions(node);
|
|
43
|
+
out.push({ name: fnName, line, endLine, cyclomaticComplexity: cc });
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
for (const child of node.namedChildren)
|
|
47
|
+
walk(child, className, out);
|
|
48
|
+
}
|
|
49
|
+
function countDecisions(fnNode) {
|
|
50
|
+
let count = 0;
|
|
51
|
+
const body = fnNode.childForFieldName ? fnNode.childForFieldName('body') : null;
|
|
52
|
+
if (!body)
|
|
53
|
+
return 1;
|
|
54
|
+
walkSkipNested(body, (n) => {
|
|
55
|
+
if (JAVA_DECISION_NODES.has(n.type)) {
|
|
56
|
+
count++;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (n.type === 'switch_label' && !/^\s*default\b/.test(n.text)) {
|
|
60
|
+
count++;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (n.type === 'binary_expression' && /(\s|^)(\|\||&&)(\s|$)/.test(n.text)) {
|
|
64
|
+
count++;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
return count + 1;
|
|
68
|
+
}
|
|
69
|
+
function walkSkipNested(node, visit) {
|
|
70
|
+
visit(node);
|
|
71
|
+
for (const child of node.namedChildren) {
|
|
72
|
+
if (child.type === 'method_declaration' ||
|
|
73
|
+
child.type === 'constructor_declaration' ||
|
|
74
|
+
child.type === 'class_declaration' ||
|
|
75
|
+
child.type === 'lambda_expression') {
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
walkSkipNested(child, visit);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function findChild(node, type) {
|
|
82
|
+
for (const c of node.namedChildren)
|
|
83
|
+
if (c.type === type)
|
|
84
|
+
return c;
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=javaFunctions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javaFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/javaFunctions.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
+
};
|
|
8
|
+
namedChildren: TsNode[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Extract import declarations from a tree-sitter-java AST.
|
|
12
|
+
*
|
|
13
|
+
* Java imports come in three shapes:
|
|
14
|
+
* import java.util.List;
|
|
15
|
+
* import java.util.*; // wildcard
|
|
16
|
+
* import static foo.Bar.X; // static
|
|
17
|
+
*
|
|
18
|
+
* The grammar emits `import_declaration` at the top level. The dotted path is
|
|
19
|
+
* captured as `scoped_identifier`; a wildcard appears as an `asterisk` child.
|
|
20
|
+
* We record the package portion (everything before the last segment for type
|
|
21
|
+
* imports, the whole path for wildcards/static imports) as the import source -
|
|
22
|
+
* matching how a resolver will look up the target.
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractJavaImports(root: TsNode): AstImport[];
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract import declarations from a tree-sitter-java AST.
|
|
3
|
+
*
|
|
4
|
+
* Java imports come in three shapes:
|
|
5
|
+
* import java.util.List;
|
|
6
|
+
* import java.util.*; // wildcard
|
|
7
|
+
* import static foo.Bar.X; // static
|
|
8
|
+
*
|
|
9
|
+
* The grammar emits `import_declaration` at the top level. The dotted path is
|
|
10
|
+
* captured as `scoped_identifier`; a wildcard appears as an `asterisk` child.
|
|
11
|
+
* We record the package portion (everything before the last segment for type
|
|
12
|
+
* imports, the whole path for wildcards/static imports) as the import source -
|
|
13
|
+
* matching how a resolver will look up the target.
|
|
14
|
+
*/
|
|
15
|
+
export function extractJavaImports(root) {
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const child of root.namedChildren) {
|
|
18
|
+
if (child.type === 'import_declaration') {
|
|
19
|
+
handleImport(child, out);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
function handleImport(node, out) {
|
|
25
|
+
const line = node.startPosition.row + 1;
|
|
26
|
+
// Collect the dotted path text. With wildcards the asterisk node sits next
|
|
27
|
+
// to the scoped_identifier; we keep `.*` on the source so the resolver can
|
|
28
|
+
// distinguish.
|
|
29
|
+
let path = null;
|
|
30
|
+
let wildcard = false;
|
|
31
|
+
for (const c of node.namedChildren) {
|
|
32
|
+
if (c.type === 'scoped_identifier' || c.type === 'identifier') {
|
|
33
|
+
path = c.text;
|
|
34
|
+
}
|
|
35
|
+
else if (c.type === 'asterisk') {
|
|
36
|
+
wildcard = true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!path)
|
|
40
|
+
return;
|
|
41
|
+
out.push({
|
|
42
|
+
source: wildcard ? `${path}.*` : path,
|
|
43
|
+
kind: 'static',
|
|
44
|
+
specifiers: [],
|
|
45
|
+
typeOnly: false,
|
|
46
|
+
line,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=javaImports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javaImports.js","sourceRoot":"","sources":["../../../src/core/languages/javaImports.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACxC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,GAAgB;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;IACxC,2EAA2E;IAC3E,2EAA2E;IAC3E,eAAe;IACf,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9D,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACjC,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;IACH,CAAC;IACD,IAAI,CAAC,IAAI;QAAE,OAAO;IAClB,GAAG,CAAC,IAAI,CAAC;QACP,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI;QACrC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,KAAK;QACf,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { FileEntry } from '../../types.js';
|
|
2
|
+
export interface JavaProjectInfo {
|
|
3
|
+
/** Absolute paths to source roots - directories under which `package` paths resolve. */
|
|
4
|
+
sourceRoots: string[];
|
|
5
|
+
/** Build system detected, if any. Informational only. */
|
|
6
|
+
buildSystem: 'maven' | 'gradle' | 'unknown';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Detect a Java project layout.
|
|
10
|
+
*
|
|
11
|
+
* Maven: presence of `pom.xml`. Default source roots are
|
|
12
|
+
* src/main/java/, src/test/java/.
|
|
13
|
+
* Gradle: presence of `build.gradle` or `build.gradle.kts`. Same defaults.
|
|
14
|
+
*
|
|
15
|
+
* Real projects may override the source root via Maven's <sourceDirectory>
|
|
16
|
+
* or Gradle's `sourceSets`. Parsing those out is deferred - the conventional
|
|
17
|
+
* defaults cover ≈95% of repos. Custom roots can still be picked up because
|
|
18
|
+
* `inferRootsFromFiles` walks the file list and takes any directory that
|
|
19
|
+
* contains a top-level `.java` file with a `package` declaration matching its
|
|
20
|
+
* directory path.
|
|
21
|
+
*
|
|
22
|
+
* Returns `null` only when no `.java` files exist and no build manifest is
|
|
23
|
+
* found - i.e. this is not a Java project.
|
|
24
|
+
*/
|
|
25
|
+
export declare function detectJavaProject(rootPath: string, files: FileEntry[]): Promise<JavaProjectInfo | null>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const MAVEN_DEFAULT_ROOTS = ['src/main/java', 'src/test/java'];
|
|
4
|
+
const GRADLE_DEFAULT_ROOTS = ['src/main/java', 'src/test/java'];
|
|
5
|
+
/**
|
|
6
|
+
* Detect a Java project layout.
|
|
7
|
+
*
|
|
8
|
+
* Maven: presence of `pom.xml`. Default source roots are
|
|
9
|
+
* src/main/java/, src/test/java/.
|
|
10
|
+
* Gradle: presence of `build.gradle` or `build.gradle.kts`. Same defaults.
|
|
11
|
+
*
|
|
12
|
+
* Real projects may override the source root via Maven's <sourceDirectory>
|
|
13
|
+
* or Gradle's `sourceSets`. Parsing those out is deferred - the conventional
|
|
14
|
+
* defaults cover ≈95% of repos. Custom roots can still be picked up because
|
|
15
|
+
* `inferRootsFromFiles` walks the file list and takes any directory that
|
|
16
|
+
* contains a top-level `.java` file with a `package` declaration matching its
|
|
17
|
+
* directory path.
|
|
18
|
+
*
|
|
19
|
+
* Returns `null` only when no `.java` files exist and no build manifest is
|
|
20
|
+
* found - i.e. this is not a Java project.
|
|
21
|
+
*/
|
|
22
|
+
export async function detectJavaProject(rootPath, files) {
|
|
23
|
+
const hasPom = await fileExists(path.join(rootPath, 'pom.xml'));
|
|
24
|
+
const hasGradle = (await fileExists(path.join(rootPath, 'build.gradle'))) ||
|
|
25
|
+
(await fileExists(path.join(rootPath, 'build.gradle.kts')));
|
|
26
|
+
const javaFiles = files.filter((f) => f.relativePath.endsWith('.java'));
|
|
27
|
+
if (!hasPom && !hasGradle && javaFiles.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
const buildSystem = hasPom
|
|
30
|
+
? 'maven'
|
|
31
|
+
: hasGradle
|
|
32
|
+
? 'gradle'
|
|
33
|
+
: 'unknown';
|
|
34
|
+
// Start with conventional roots (only the ones that actually exist).
|
|
35
|
+
const conventional = hasPom ? MAVEN_DEFAULT_ROOTS : GRADLE_DEFAULT_ROOTS;
|
|
36
|
+
const roots = new Set();
|
|
37
|
+
for (const r of conventional) {
|
|
38
|
+
if (await fileExists(path.join(rootPath, r))) {
|
|
39
|
+
roots.add(r);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// If neither convention exists, fall back to inferring from file layout.
|
|
43
|
+
if (roots.size === 0) {
|
|
44
|
+
const inferred = inferRootsFromFiles(javaFiles);
|
|
45
|
+
for (const r of inferred)
|
|
46
|
+
roots.add(r);
|
|
47
|
+
if (roots.size === 0)
|
|
48
|
+
roots.add('.');
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
sourceRoots: [...roots].map((r) => path.join(rootPath, r)),
|
|
52
|
+
buildSystem,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Best-effort source-root inference: for each .java file, scan its content
|
|
57
|
+
* for a `package` declaration and back out the source root by stripping the
|
|
58
|
+
* package path from the file's directory. We can't read content here cheaply
|
|
59
|
+
* (FileEntry doesn't carry it), so we approximate by looking at the deepest
|
|
60
|
+
* common prefix of `.java` directories.
|
|
61
|
+
*/
|
|
62
|
+
function inferRootsFromFiles(files) {
|
|
63
|
+
if (files.length === 0)
|
|
64
|
+
return [];
|
|
65
|
+
const dirs = new Set(files.map((f) => path.posix.dirname(f.relativePath)));
|
|
66
|
+
// Find the shortest directory - that's the most likely package root.
|
|
67
|
+
let shortest = '';
|
|
68
|
+
let shortestLen = Infinity;
|
|
69
|
+
for (const d of dirs) {
|
|
70
|
+
if (d.length < shortestLen) {
|
|
71
|
+
shortest = d;
|
|
72
|
+
shortestLen = d.length;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return [shortest || '.'];
|
|
76
|
+
}
|
|
77
|
+
async function fileExists(p) {
|
|
78
|
+
try {
|
|
79
|
+
await fs.access(p);
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=javaManifests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"javaManifests.js","sourceRoot":"","sources":["../../../src/core/languages/javaManifests.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,8 @@ import { createParserFor } from './treeSitterLoader.js';
|
|
|
3
3
|
import { extractPythonImports } from './pythonImports.js';
|
|
4
4
|
import { extractPythonExports } from './pythonExports.js';
|
|
5
5
|
import { extractPythonCyclomatic } from './pythonCyclomatic.js';
|
|
6
|
+
import { extractPythonFunctions } from './pythonFunctions.js';
|
|
7
|
+
import { extractPythonCallSites } from './pythonCallSites.js';
|
|
6
8
|
import { detectPythonProject } from './pythonManifests.js';
|
|
7
9
|
// Pinned grammar: tree-sitter-python 0.25.0. See treeSitterLoader.ts.
|
|
8
10
|
const PY_EXTENSIONS = new Set(['.py', '.pyw', '.pyi']);
|
|
@@ -36,18 +38,22 @@ export const pythonAdapter = {
|
|
|
36
38
|
callSites: [],
|
|
37
39
|
lineCount: content ? content.split('\n').length : 0,
|
|
38
40
|
cyclomaticComplexity: 0,
|
|
41
|
+
functions: [],
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
44
|
const imports = extractPythonImports(tree.rootNode);
|
|
42
45
|
const exports = extractPythonExports(tree.rootNode);
|
|
43
46
|
const cyclomaticComplexity = extractPythonCyclomatic(tree.rootNode);
|
|
47
|
+
const callSites = extractPythonCallSites(tree.rootNode);
|
|
48
|
+
const functions = extractPythonFunctions(tree.rootNode);
|
|
44
49
|
return {
|
|
45
50
|
ok: true,
|
|
46
51
|
imports,
|
|
47
52
|
exports,
|
|
48
|
-
callSites
|
|
53
|
+
callSites,
|
|
49
54
|
lineCount: content ? content.split('\n').length : 0,
|
|
50
55
|
cyclomaticComplexity,
|
|
56
|
+
functions,
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
59
|
catch (err) {
|
|
@@ -60,6 +66,7 @@ export const pythonAdapter = {
|
|
|
60
66
|
callSites: [],
|
|
61
67
|
lineCount: content ? content.split('\n').length : 0,
|
|
62
68
|
cyclomaticComplexity: 0,
|
|
69
|
+
functions: [],
|
|
63
70
|
};
|
|
64
71
|
}
|
|
65
72
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pythonAdapter.js","sourceRoot":"","sources":["../../../src/core/languages/pythonAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAO3D,sEAAsE;AAEtE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AACvD,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhC,IAAI,aAAa,GAAqD,IAAI,CAAC;AAC3E,KAAK,UAAU,SAAS;IACtB,IAAI,CAAC,aAAa;QAAE,aAAa,GAAG,eAAe,CAAC,yBAAyB,CAAC,CAAC;IAC/E,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,EAAE,EAAE,QAAQ;IACZ,UAAU,EAAE,aAAa;IACzB,gBAAgB,EAAE,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC1C,eAAe,EAAE,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IACtC,WAAW,EAAE,WAAW;IAExB,KAAK,CAAC,KAAK,CAAC,SAAiB,EAAE,OAAe;QAC5C,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC5B,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,MAAM,EAAE,gCAAgC;oBACxC,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE,EAAE;oBACX,SAAS,EAAE,EAAE;oBACb,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;oBACnD,oBAAoB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"pythonAdapter.js","sourceRoot":"","sources":["../../../src/core/languages/pythonAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract call-site identifiers from a tree-sitter-python AST.
|
|
3
|
+
*
|
|
4
|
+
* For `foo(...)` we record `foo`. For `obj.method(...)` (attribute call) we
|
|
5
|
+
* record `method` (the rightmost name). For more complex callees (subscripts,
|
|
6
|
+
* lambdas-immediately-invoked, decorators acting as callees, etc.) we skip -
|
|
7
|
+
* a name is needed to be useful for "who calls X" lookups.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the JS/TS behaviour in `src/core/ast.ts`: identifiers and the final
|
|
10
|
+
* member-property name; uniqued before return.
|
|
11
|
+
*/
|
|
12
|
+
interface TsNode {
|
|
13
|
+
type: string;
|
|
14
|
+
text: string;
|
|
15
|
+
namedChildren: TsNode[];
|
|
16
|
+
childForFieldName?(name: string): TsNode | null;
|
|
17
|
+
}
|
|
18
|
+
export declare function extractPythonCallSites(root: TsNode): string[];
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract call-site identifiers from a tree-sitter-python AST.
|
|
3
|
+
*
|
|
4
|
+
* For `foo(...)` we record `foo`. For `obj.method(...)` (attribute call) we
|
|
5
|
+
* record `method` (the rightmost name). For more complex callees (subscripts,
|
|
6
|
+
* lambdas-immediately-invoked, decorators acting as callees, etc.) we skip -
|
|
7
|
+
* a name is needed to be useful for "who calls X" lookups.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors the JS/TS behaviour in `src/core/ast.ts`: identifiers and the final
|
|
10
|
+
* member-property name; uniqued before return.
|
|
11
|
+
*/
|
|
12
|
+
export function extractPythonCallSites(root) {
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
walk(root, seen);
|
|
15
|
+
return [...seen];
|
|
16
|
+
}
|
|
17
|
+
function walk(node, out) {
|
|
18
|
+
if (node.type === 'call') {
|
|
19
|
+
const fn = node.childForFieldName?.('function') ?? null;
|
|
20
|
+
const name = nameFromCallee(fn);
|
|
21
|
+
if (name)
|
|
22
|
+
out.add(name);
|
|
23
|
+
}
|
|
24
|
+
for (const child of node.namedChildren)
|
|
25
|
+
walk(child, out);
|
|
26
|
+
}
|
|
27
|
+
function nameFromCallee(node) {
|
|
28
|
+
if (!node)
|
|
29
|
+
return null;
|
|
30
|
+
if (node.type === 'identifier')
|
|
31
|
+
return node.text;
|
|
32
|
+
if (node.type === 'attribute') {
|
|
33
|
+
// `obj.method` - the rightmost identifier is the called name.
|
|
34
|
+
const last = node.childForFieldName?.('attribute') ?? null;
|
|
35
|
+
if (last && last.type === 'identifier')
|
|
36
|
+
return last.text;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=pythonCallSites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pythonCallSites.js","sourceRoot":"","sources":["../../../src/core/languages/pythonCallSites.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,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,MAAM,EAAE,CAAC;QACzB,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC;QACxD,MAAM,IAAI,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,IAAI;YAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa;QAAE,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,cAAc,CAAC,IAAmB;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,8DAA8D;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC;QAC3D,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC3D,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
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 Python. Walks function_definition nodes,
|
|
18
|
+
* including those nested inside class_definition. Methods are named
|
|
19
|
+
* `Class.method`. Nested functions emit their own entries; the parent's CC
|
|
20
|
+
* does not include nested-function decisions.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractPythonFunctions(root: TsNode): FunctionInfo[];
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const PY_FUNCTION_NODES = new Set(['function_definition']);
|
|
2
|
+
const PY_DECISION_NODES = new Set([
|
|
3
|
+
'if_statement',
|
|
4
|
+
'elif_clause',
|
|
5
|
+
'for_statement',
|
|
6
|
+
'while_statement',
|
|
7
|
+
'except_clause',
|
|
8
|
+
'conditional_expression',
|
|
9
|
+
'for_in_clause',
|
|
10
|
+
'if_clause',
|
|
11
|
+
'case_clause',
|
|
12
|
+
'boolean_operator',
|
|
13
|
+
]);
|
|
14
|
+
/**
|
|
15
|
+
* Per-function McCabe CC for Python. Walks function_definition nodes,
|
|
16
|
+
* including those nested inside class_definition. Methods are named
|
|
17
|
+
* `Class.method`. Nested functions emit their own entries; the parent's CC
|
|
18
|
+
* does not include nested-function decisions.
|
|
19
|
+
*/
|
|
20
|
+
export function extractPythonFunctions(root) {
|
|
21
|
+
const out = [];
|
|
22
|
+
walk(root, null, out);
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
function walk(node, className, out) {
|
|
26
|
+
if (PY_FUNCTION_NODES.has(node.type)) {
|
|
27
|
+
const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'identifier');
|
|
28
|
+
const fnName = nameNode?.text ?? '<anonymous>';
|
|
29
|
+
const qualifiedName = className ? `${className}.${fnName}` : fnName;
|
|
30
|
+
const line = node.startPosition.row + 1;
|
|
31
|
+
const endLine = node.endPosition.row + 1;
|
|
32
|
+
const cc = countDecisions(node);
|
|
33
|
+
out.push({ name: qualifiedName, line, endLine, cyclomaticComplexity: cc });
|
|
34
|
+
// Recurse into the body to find nested functions only - the CC for THIS
|
|
35
|
+
// function already correctly excluded them via the body-walker.
|
|
36
|
+
const body = node.childForFieldName ? node.childForFieldName('body') : null;
|
|
37
|
+
if (body) {
|
|
38
|
+
for (const child of body.namedChildren) {
|
|
39
|
+
walk(child, null, out);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (node.type === 'class_definition') {
|
|
45
|
+
const nameNode = node.childForFieldName ? node.childForFieldName('name') : findChild(node, 'identifier');
|
|
46
|
+
const cls = nameNode?.text ?? null;
|
|
47
|
+
const body = node.childForFieldName ? node.childForFieldName('body') : null;
|
|
48
|
+
if (body) {
|
|
49
|
+
for (const child of body.namedChildren) {
|
|
50
|
+
walk(child, cls, out);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
for (const child of node.namedChildren)
|
|
56
|
+
walk(child, className, out);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Count decision points inside a function body, skipping nested function /
|
|
60
|
+
* class definitions so they don't pollute the enclosing function's CC.
|
|
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 (PY_DECISION_NODES.has(n.type))
|
|
69
|
+
count++;
|
|
70
|
+
});
|
|
71
|
+
return count + 1;
|
|
72
|
+
}
|
|
73
|
+
function walkSkipNested(node, visit) {
|
|
74
|
+
visit(node);
|
|
75
|
+
for (const child of node.namedChildren) {
|
|
76
|
+
if (PY_FUNCTION_NODES.has(child.type) || child.type === 'class_definition')
|
|
77
|
+
continue;
|
|
78
|
+
walkSkipNested(child, visit);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function findChild(node, type) {
|
|
82
|
+
for (const c of node.namedChildren)
|
|
83
|
+
if (c.type === type)
|
|
84
|
+
return c;
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=pythonFunctions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pythonFunctions.js","sourceRoot":"","sources":["../../../src/core/languages/pythonFunctions.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,9 @@ import path from 'node:path';
|
|
|
2
2
|
import { javascriptAdapter } from './javascriptAdapter.js';
|
|
3
3
|
import { pythonAdapter } from './pythonAdapter.js';
|
|
4
4
|
import { goAdapter } from './goAdapter.js';
|
|
5
|
-
|
|
5
|
+
import { javaAdapter } from './javaAdapter.js';
|
|
6
|
+
import { rubyAdapter } from './rubyAdapter.js';
|
|
7
|
+
const adapters = [javascriptAdapter, pythonAdapter, goAdapter, javaAdapter, rubyAdapter];
|
|
6
8
|
const byExtension = new Map();
|
|
7
9
|
function rebuildIndex() {
|
|
8
10
|
byExtension.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/languages/registry.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/languages/registry.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAG/C,MAAM,QAAQ,GAAsB,CAAC,iBAAiB,EAAE,aAAa,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;AAC5G,MAAM,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;AAEvD,SAAS,YAAY;IACnB,WAAW,CAAC,KAAK,EAAE,CAAC;IACpB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACrC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;AACH,CAAC;AACD,YAAY,EAAE,CAAC;AAEf,MAAM,UAAU,eAAe,CAAC,OAAwB;IACtD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,YAAY,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|