projscan 0.10.0 → 0.12.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 +56 -19
- 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 +47 -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 +45 -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/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/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/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 +45 -1132
- package/dist/cli/index.js.map +1 -1
- package/dist/core/ast.d.ts +2 -0
- package/dist/core/ast.js +35 -2
- package/dist/core/ast.js.map +1 -1
- package/dist/core/codeGraph.d.ts +2 -0
- package/dist/core/codeGraph.js +2 -0
- package/dist/core/codeGraph.js.map +1 -1
- package/dist/core/couplingAnalyzer.d.ts +18 -0
- package/dist/core/couplingAnalyzer.js +174 -0
- package/dist/core/couplingAnalyzer.js.map +1 -0
- package/dist/core/fileInspector.d.ts +1 -1
- package/dist/core/fileInspector.js +31 -1
- package/dist/core/fileInspector.js.map +1 -1
- package/dist/core/hotspotAnalyzer.d.ts +13 -0
- package/dist/core/hotspotAnalyzer.js +29 -6
- package/dist/core/hotspotAnalyzer.js.map +1 -1
- package/dist/core/indexCache.js +6 -3
- package/dist/core/indexCache.js.map +1 -1
- package/dist/core/languages/LanguageAdapter.d.ts +1 -1
- package/dist/core/languages/goAdapter.d.ts +2 -0
- package/dist/core/languages/goAdapter.js +138 -0
- package/dist/core/languages/goAdapter.js.map +1 -0
- 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 +21 -0
- package/dist/core/languages/goCyclomatic.js +55 -0
- package/dist/core/languages/goCyclomatic.js.map +1 -0
- package/dist/core/languages/goExports.d.ts +26 -0
- package/dist/core/languages/goExports.js +89 -0
- package/dist/core/languages/goExports.js.map +1 -0
- package/dist/core/languages/goImports.d.ts +26 -0
- package/dist/core/languages/goImports.js +64 -0
- package/dist/core/languages/goImports.js.map +1 -0
- package/dist/core/languages/goManifests.d.ts +19 -0
- package/dist/core/languages/goManifests.js +56 -0
- package/dist/core/languages/goManifests.js.map +1 -0
- package/dist/core/languages/javaAdapter.d.ts +2 -0
- package/dist/core/languages/javaAdapter.js +148 -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/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/pythonCyclomatic.d.ts +18 -0
- package/dist/core/languages/pythonCyclomatic.js +45 -0
- package/dist/core/languages/pythonCyclomatic.js.map +1 -0
- package/dist/core/languages/registry.js +4 -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 +131 -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/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 +4 -1
- package/dist/core/languages/treeSitterLoader.js.map +1 -1
- package/dist/core/monorepo.d.ts +20 -0
- package/dist/core/monorepo.js +270 -0
- package/dist/core/monorepo.js.map +1 -0
- 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 +43 -0
- package/dist/core/prDiff.js +298 -0
- package/dist/core/prDiff.js.map +1 -0
- package/dist/core/telemetry.d.ts +90 -0
- package/dist/core/telemetry.js +199 -0
- package/dist/core/telemetry.js.map +1 -0
- package/dist/grammars/tree-sitter-go.wasm +0 -0
- package/dist/grammars/tree-sitter-java.wasm +0 -0
- package/dist/grammars/tree-sitter-ruby.wasm +0 -0
- 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 +32 -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 +16 -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/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/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 +64 -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/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 +40 -605
- package/dist/mcp/tools.js.map +1 -1
- package/dist/reporters/consoleReporter.d.ts +4 -1
- package/dist/reporters/consoleReporter.js +113 -0
- package/dist/reporters/consoleReporter.js.map +1 -1
- package/dist/reporters/jsonReporter.d.ts +4 -1
- package/dist/reporters/jsonReporter.js +9 -0
- package/dist/reporters/jsonReporter.js.map +1 -1
- package/dist/reporters/markdownReporter.d.ts +4 -1
- package/dist/reporters/markdownReporter.js +103 -3
- package/dist/reporters/markdownReporter.js.map +1 -1
- package/dist/tool-manifest.json +358 -0
- package/dist/types.d.ts +115 -0
- package/dist/utils/cache.d.ts +3 -0
- package/dist/utils/cache.js +51 -0
- package/dist/utils/cache.js.map +1 -0
- package/package.json +7 -3
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract package-level "exports" from a Go AST.
|
|
3
|
+
*
|
|
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
|
|
6
|
+
* symbols inside functions are not part of the package surface.
|
|
7
|
+
*
|
|
8
|
+
* Captured forms:
|
|
9
|
+
* func Foo() {} → function
|
|
10
|
+
* func (r *T) Foo() {} → function (method)
|
|
11
|
+
* type Foo struct {} | interface {} → type / interface
|
|
12
|
+
* var Foo = ... / var Foo Type → variable
|
|
13
|
+
* const Foo = ... → variable
|
|
14
|
+
*/
|
|
15
|
+
export function extractGoExports(root) {
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const child of root.namedChildren) {
|
|
18
|
+
visitTopLevel(child, out);
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
function visitTopLevel(node, out) {
|
|
23
|
+
switch (node.type) {
|
|
24
|
+
case 'function_declaration':
|
|
25
|
+
addIfExported(name(node), 'function', node, out);
|
|
26
|
+
return;
|
|
27
|
+
case 'method_declaration':
|
|
28
|
+
addIfExported(name(node), 'function', node, out);
|
|
29
|
+
return;
|
|
30
|
+
case 'type_declaration':
|
|
31
|
+
for (const spec of node.namedChildren) {
|
|
32
|
+
if (spec.type === 'type_spec' || spec.type === 'type_alias') {
|
|
33
|
+
const id = spec.childForFieldName?.('name') ?? firstIdent(spec);
|
|
34
|
+
const kind = detectTypeKind(spec);
|
|
35
|
+
addIfExported(id?.text, kind, spec, out);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
case 'var_declaration':
|
|
40
|
+
case 'const_declaration':
|
|
41
|
+
for (const spec of node.namedChildren) {
|
|
42
|
+
if (spec.type === 'var_spec' || spec.type === 'const_spec') {
|
|
43
|
+
// A spec can declare multiple names: `var X, Y int`.
|
|
44
|
+
for (const c of spec.namedChildren) {
|
|
45
|
+
if (c.type === 'identifier')
|
|
46
|
+
addIfExported(c.text, 'variable', spec, out);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return;
|
|
51
|
+
default:
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function name(node) {
|
|
56
|
+
return node.childForFieldName?.('name')?.text ?? firstIdent(node)?.text;
|
|
57
|
+
}
|
|
58
|
+
function firstIdent(node) {
|
|
59
|
+
for (const c of node.namedChildren) {
|
|
60
|
+
if (c.type === 'identifier' || c.type === 'field_identifier' || c.type === 'type_identifier')
|
|
61
|
+
return c;
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
function detectTypeKind(spec) {
|
|
66
|
+
// type_spec children: identifier + (struct_type | interface_type | ...).
|
|
67
|
+
for (const c of spec.namedChildren) {
|
|
68
|
+
if (c.type === 'interface_type')
|
|
69
|
+
return 'interface';
|
|
70
|
+
if (c.type === 'struct_type')
|
|
71
|
+
return 'class';
|
|
72
|
+
}
|
|
73
|
+
return 'type';
|
|
74
|
+
}
|
|
75
|
+
function addIfExported(name, kind, node, out) {
|
|
76
|
+
if (!name)
|
|
77
|
+
return;
|
|
78
|
+
// Go's export rule: leading character is an uppercase Unicode letter.
|
|
79
|
+
const first = name.charAt(0);
|
|
80
|
+
if (first !== first.toUpperCase() || first === first.toLowerCase())
|
|
81
|
+
return;
|
|
82
|
+
out.push({
|
|
83
|
+
name,
|
|
84
|
+
kind,
|
|
85
|
+
typeOnly: false,
|
|
86
|
+
line: node.startPosition.row + 1,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=goExports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goExports.js","sourceRoot":"","sources":["../../../src/core/languages/goExports.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
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 paths from a tree-sitter-go AST.
|
|
12
|
+
*
|
|
13
|
+
* Go imports come in two shapes:
|
|
14
|
+
* import "fmt"
|
|
15
|
+
* import (
|
|
16
|
+
* "fmt"
|
|
17
|
+
* "github.com/foo/bar"
|
|
18
|
+
* util "github.com/foo/util" // alias
|
|
19
|
+
* )
|
|
20
|
+
*
|
|
21
|
+
* The grammar emits `import_declaration` containing one or more
|
|
22
|
+
* `import_spec` nodes. Each spec has an `interpreted_string_literal` child
|
|
23
|
+
* holding the import path (with surrounding quotes that we strip).
|
|
24
|
+
*/
|
|
25
|
+
export declare function extractGoImports(root: TsNode): AstImport[];
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extract import paths from a tree-sitter-go AST.
|
|
3
|
+
*
|
|
4
|
+
* Go imports come in two shapes:
|
|
5
|
+
* import "fmt"
|
|
6
|
+
* import (
|
|
7
|
+
* "fmt"
|
|
8
|
+
* "github.com/foo/bar"
|
|
9
|
+
* util "github.com/foo/util" // alias
|
|
10
|
+
* )
|
|
11
|
+
*
|
|
12
|
+
* The grammar emits `import_declaration` containing one or more
|
|
13
|
+
* `import_spec` nodes. Each spec has an `interpreted_string_literal` child
|
|
14
|
+
* holding the import path (with surrounding quotes that we strip).
|
|
15
|
+
*/
|
|
16
|
+
export function extractGoImports(root) {
|
|
17
|
+
const out = [];
|
|
18
|
+
visit(root, out);
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
function visit(node, out) {
|
|
22
|
+
for (const child of node.namedChildren) {
|
|
23
|
+
if (child.type === 'import_declaration') {
|
|
24
|
+
handleImportDecl(child, out);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
// Imports must be top-level in Go, but we still descend through any
|
|
28
|
+
// top-level wrappers (e.g. source_file).
|
|
29
|
+
visit(child, out);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function handleImportDecl(node, out) {
|
|
34
|
+
const line = node.startPosition.row + 1;
|
|
35
|
+
for (const c of node.namedChildren) {
|
|
36
|
+
if (c.type === 'import_spec') {
|
|
37
|
+
addSpec(c, line, out);
|
|
38
|
+
}
|
|
39
|
+
else if (c.type === 'import_spec_list') {
|
|
40
|
+
for (const s of c.namedChildren) {
|
|
41
|
+
if (s.type === 'import_spec')
|
|
42
|
+
addSpec(s, line, out);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function addSpec(spec, line, out) {
|
|
48
|
+
// Path is the interpreted_string_literal; we strip the surrounding quotes.
|
|
49
|
+
const pathNode = spec.namedChildren.find((c) => c.type === 'interpreted_string_literal' || c.type === 'raw_string_literal');
|
|
50
|
+
if (!pathNode)
|
|
51
|
+
return;
|
|
52
|
+
const raw = pathNode.text;
|
|
53
|
+
const source = raw.replace(/^["`]|["`]$/g, '');
|
|
54
|
+
if (!source)
|
|
55
|
+
return;
|
|
56
|
+
out.push({
|
|
57
|
+
source,
|
|
58
|
+
kind: 'static',
|
|
59
|
+
specifiers: [],
|
|
60
|
+
typeOnly: false,
|
|
61
|
+
line,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=goImports.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goImports.js","sourceRoot":"","sources":["../../../src/core/languages/goImports.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjB,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,KAAK,CAAC,IAAY,EAAE,GAAgB;IAC3C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACxC,gBAAgB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,oEAAoE;YACpE,yCAAyC;YACzC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,GAAgB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,CAAC;IACxC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACxB,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACzC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;gBAChC,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa;oBAAE,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,IAAY,EAAE,IAAY,EAAE,GAAgB;IAC3D,2EAA2E;IAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,4BAA4B,IAAI,CAAC,CAAC,IAAI,KAAK,oBAAoB,CAClF,CAAC;IACF,IAAI,CAAC,QAAQ;QAAE,OAAO;IACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,GAAG,CAAC,IAAI,CAAC;QACP,MAAM;QACN,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,KAAK;QACf,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FileEntry } from '../../types.js';
|
|
2
|
+
export interface GoProjectInfo {
|
|
3
|
+
/**
|
|
4
|
+
* Module path declared in go.mod (e.g. "github.com/acme/widget"). Local
|
|
5
|
+
* imports starting with this prefix resolve into the repo.
|
|
6
|
+
*/
|
|
7
|
+
modulePath: string;
|
|
8
|
+
/** Absolute directory containing go.mod. Imports resolve relative to this. */
|
|
9
|
+
moduleRoot: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Find the closest go.mod and read its module declaration. Searches the
|
|
13
|
+
* repository root first, then any directory that contains at least one .go
|
|
14
|
+
* file (handles nested modules / examples directories).
|
|
15
|
+
*
|
|
16
|
+
* Returns null if no go.mod exists - Go files outside any module are valid
|
|
17
|
+
* (e.g. snippets) but their imports can't be resolved to local files.
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectGoProject(rootPath: string, files: FileEntry[]): Promise<GoProjectInfo | null>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Find the closest go.mod and read its module declaration. Searches the
|
|
5
|
+
* repository root first, then any directory that contains at least one .go
|
|
6
|
+
* file (handles nested modules / examples directories).
|
|
7
|
+
*
|
|
8
|
+
* Returns null if no go.mod exists - Go files outside any module are valid
|
|
9
|
+
* (e.g. snippets) but their imports can't be resolved to local files.
|
|
10
|
+
*/
|
|
11
|
+
export async function detectGoProject(rootPath, files) {
|
|
12
|
+
// 1) Try repo root first - by far the most common case.
|
|
13
|
+
const rootGoMod = await readGoMod(path.join(rootPath, 'go.mod'));
|
|
14
|
+
if (rootGoMod)
|
|
15
|
+
return { modulePath: rootGoMod, moduleRoot: rootPath };
|
|
16
|
+
// 2) Look for go.mod in any directory containing a .go file. Take the
|
|
17
|
+
// shortest path (closest-to-root) when multiple match.
|
|
18
|
+
const candidates = new Set();
|
|
19
|
+
for (const f of files) {
|
|
20
|
+
if (!f.relativePath.endsWith('.go'))
|
|
21
|
+
continue;
|
|
22
|
+
let dir = path.posix.dirname(f.relativePath);
|
|
23
|
+
while (dir && dir !== '.' && dir !== '/') {
|
|
24
|
+
candidates.add(dir);
|
|
25
|
+
dir = path.posix.dirname(dir);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const sorted = [...candidates].sort((a, b) => a.length - b.length);
|
|
29
|
+
for (const dir of sorted) {
|
|
30
|
+
const p = path.join(rootPath, dir, 'go.mod');
|
|
31
|
+
const mod = await readGoMod(p);
|
|
32
|
+
if (mod)
|
|
33
|
+
return { modulePath: mod, moduleRoot: path.join(rootPath, dir) };
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
async function readGoMod(absPath) {
|
|
38
|
+
let content;
|
|
39
|
+
try {
|
|
40
|
+
content = await fs.readFile(absPath, 'utf-8');
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// First non-comment `module <path>` line wins.
|
|
46
|
+
for (const raw of content.split('\n')) {
|
|
47
|
+
const line = raw.trim();
|
|
48
|
+
if (!line || line.startsWith('//'))
|
|
49
|
+
continue;
|
|
50
|
+
const m = /^module\s+(\S+)/.exec(line);
|
|
51
|
+
if (m)
|
|
52
|
+
return m[1];
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=goManifests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"goManifests.js","sourceRoot":"","sources":["../../../src/core/languages/goManifests.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAa7B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,KAAkB;IAElB,wDAAwD;IACxD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjE,IAAI,SAAS;QAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;IAEtE,sEAAsE;IACtE,uDAAuD;IACvD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QAC9C,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QAC7C,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;YACzC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpB,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IACnE,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,GAAG;YAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,OAAe;IACtC,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,+CAA+C;IAC/C,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAC7C,MAAM,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
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 { extractJavaCallSites } from './javaCallSites.js';
|
|
7
|
+
import { detectJavaProject } from './javaManifests.js';
|
|
8
|
+
const JAVA_EXTENSIONS = new Set(['.java']);
|
|
9
|
+
const MAX_JAVA_FILE = 1024 * 1024;
|
|
10
|
+
let parserPromise = null;
|
|
11
|
+
async function getParser() {
|
|
12
|
+
if (!parserPromise)
|
|
13
|
+
parserPromise = createParserFor('tree-sitter-java.wasm');
|
|
14
|
+
return parserPromise;
|
|
15
|
+
}
|
|
16
|
+
export const javaAdapter = {
|
|
17
|
+
id: 'java',
|
|
18
|
+
extensions: JAVA_EXTENSIONS,
|
|
19
|
+
sourceExtensions: JAVA_EXTENSIONS,
|
|
20
|
+
// Java has no barrel-file convention. A `package-info.java` file is metadata,
|
|
21
|
+
// not a re-export hub.
|
|
22
|
+
barrelBasenames: new Set(),
|
|
23
|
+
maxFileSize: MAX_JAVA_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
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const root = tree.rootNode;
|
|
40
|
+
const imports = extractJavaImports(root);
|
|
41
|
+
const exports = extractJavaExports(root);
|
|
42
|
+
const cyclomaticComplexity = extractJavaCyclomatic(root);
|
|
43
|
+
const callSites = extractJavaCallSites(root);
|
|
44
|
+
return {
|
|
45
|
+
ok: true,
|
|
46
|
+
imports,
|
|
47
|
+
exports,
|
|
48
|
+
callSites,
|
|
49
|
+
lineCount: content ? content.split('\n').length : 0,
|
|
50
|
+
cyclomaticComplexity,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
reason: `java parse failure: ${msg.slice(0, 120)}`,
|
|
58
|
+
imports: [],
|
|
59
|
+
exports: [],
|
|
60
|
+
callSites: [],
|
|
61
|
+
lineCount: content ? content.split('\n').length : 0,
|
|
62
|
+
cyclomaticComplexity: 0,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
resolveImport(importingFile, source, graphFiles, context) {
|
|
67
|
+
return resolveJavaImport(importingFile, source, graphFiles, context);
|
|
68
|
+
},
|
|
69
|
+
toPackageName(source) {
|
|
70
|
+
if (!source)
|
|
71
|
+
return null;
|
|
72
|
+
if (source.startsWith('.'))
|
|
73
|
+
return null;
|
|
74
|
+
// Strip wildcard / static-tail to get the dotted package path.
|
|
75
|
+
const base = source.endsWith('.*') ? source.slice(0, -2) : source;
|
|
76
|
+
// Java imports typically end in a TypeName; drop the last segment to get
|
|
77
|
+
// the package. For wildcards the whole thing IS the package.
|
|
78
|
+
if (source.endsWith('.*'))
|
|
79
|
+
return base;
|
|
80
|
+
const lastDot = base.lastIndexOf('.');
|
|
81
|
+
return lastDot > 0 ? base.slice(0, lastDot) : base;
|
|
82
|
+
},
|
|
83
|
+
async preparePackageRoots(rootPath, files) {
|
|
84
|
+
const info = await detectJavaProject(rootPath, files);
|
|
85
|
+
if (!info)
|
|
86
|
+
return { packageRoots: [], meta: undefined };
|
|
87
|
+
return {
|
|
88
|
+
packageRoots: info.sourceRoots.map((r) => path.relative(rootPath, r) || '.'),
|
|
89
|
+
meta: { javaProject: info },
|
|
90
|
+
};
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a Java import to a repo-local file path, or null if it refers to a
|
|
95
|
+
* stdlib / third-party type or otherwise cannot be resolved.
|
|
96
|
+
*
|
|
97
|
+
* import com.foo.Bar; → for each sourceRoot, probe `com/foo/Bar.java`
|
|
98
|
+
* import com.foo.*; → resolve to ANY file under `com/foo/` (rare; we
|
|
99
|
+
* just pick the first match for graph-edge purposes)
|
|
100
|
+
* import static com.foo.Bar.X; → resolves to `com/foo/Bar.java` (X is a member)
|
|
101
|
+
*/
|
|
102
|
+
function resolveJavaImport(_importingFile, source, graphFiles, context) {
|
|
103
|
+
if (!source)
|
|
104
|
+
return null;
|
|
105
|
+
const javaProject = context.meta
|
|
106
|
+
?.javaProject;
|
|
107
|
+
const sourceRootsRel = context.packageRoots ?? [];
|
|
108
|
+
if (sourceRootsRel.length === 0 && !javaProject)
|
|
109
|
+
return null;
|
|
110
|
+
const isWildcard = source.endsWith('.*');
|
|
111
|
+
const stripped = isWildcard ? source.slice(0, -2) : source;
|
|
112
|
+
const segments = stripped.split('.').filter(Boolean);
|
|
113
|
+
if (segments.length === 0)
|
|
114
|
+
return null;
|
|
115
|
+
// For type imports, the last segment is the type name (file basename).
|
|
116
|
+
// For wildcard imports, all segments form the package directory.
|
|
117
|
+
for (const root of sourceRootsRel) {
|
|
118
|
+
const rootSegs = root === '.' || root === '' ? [] : root.split('/').filter(Boolean);
|
|
119
|
+
if (isWildcard) {
|
|
120
|
+
const dir = [...rootSegs, ...segments].join('/');
|
|
121
|
+
const prefix = dir + '/';
|
|
122
|
+
// Pick the first .java file directly under that directory.
|
|
123
|
+
const matches = [];
|
|
124
|
+
for (const file of graphFiles.keys()) {
|
|
125
|
+
if (!file.endsWith('.java'))
|
|
126
|
+
continue;
|
|
127
|
+
if (file.startsWith(prefix)) {
|
|
128
|
+
const tail = file.slice(prefix.length);
|
|
129
|
+
if (!tail.includes('/'))
|
|
130
|
+
matches.push(file);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (matches.length > 0) {
|
|
134
|
+
matches.sort();
|
|
135
|
+
return matches[0];
|
|
136
|
+
}
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
// Non-wildcard: last segment is the type, preceding segments are the path.
|
|
140
|
+
const typeName = segments[segments.length - 1];
|
|
141
|
+
const pkgPath = segments.slice(0, -1);
|
|
142
|
+
const candidate = [...rootSegs, ...pkgPath, `${typeName}.java`].join('/');
|
|
143
|
+
if (graphFiles.has(candidate))
|
|
144
|
+
return candidate;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
//# 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 {};
|