@opensip-cli/graph-java 0.1.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/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +31 -0
- package/dist/__tests__/cache-key.test.d.ts +5 -0
- package/dist/__tests__/cache-key.test.d.ts.map +1 -0
- package/dist/__tests__/cache-key.test.js +45 -0
- package/dist/__tests__/cache-key.test.js.map +1 -0
- package/dist/__tests__/coverage-edges.test.d.ts +19 -0
- package/dist/__tests__/coverage-edges.test.d.ts.map +1 -0
- package/dist/__tests__/coverage-edges.test.js +254 -0
- package/dist/__tests__/coverage-edges.test.js.map +1 -0
- package/dist/__tests__/depends-on-emission.test.d.ts +15 -0
- package/dist/__tests__/depends-on-emission.test.d.ts.map +1 -0
- package/dist/__tests__/depends-on-emission.test.js +229 -0
- package/dist/__tests__/depends-on-emission.test.js.map +1 -0
- package/dist/__tests__/discover.test.d.ts +5 -0
- package/dist/__tests__/discover.test.d.ts.map +1 -0
- package/dist/__tests__/discover.test.js +68 -0
- package/dist/__tests__/discover.test.js.map +1 -0
- package/dist/__tests__/parse.test.d.ts +5 -0
- package/dist/__tests__/parse.test.d.ts.map +1 -0
- package/dist/__tests__/parse.test.js +59 -0
- package/dist/__tests__/parse.test.js.map +1 -0
- package/dist/__tests__/resolve.test.d.ts +17 -0
- package/dist/__tests__/resolve.test.d.ts.map +1 -0
- package/dist/__tests__/resolve.test.js +201 -0
- package/dist/__tests__/resolve.test.js.map +1 -0
- package/dist/__tests__/walk.test.d.ts +11 -0
- package/dist/__tests__/walk.test.d.ts.map +1 -0
- package/dist/__tests__/walk.test.js +227 -0
- package/dist/__tests__/walk.test.js.map +1 -0
- package/dist/body-digest.d.ts +19 -0
- package/dist/body-digest.d.ts.map +1 -0
- package/dist/body-digest.js +140 -0
- package/dist/body-digest.js.map +1 -0
- package/dist/cache-key.d.ts +19 -0
- package/dist/cache-key.d.ts.map +1 -0
- package/dist/cache-key.js +20 -0
- package/dist/cache-key.js.map +1 -0
- package/dist/discover.d.ts +28 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +50 -0
- package/dist/discover.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/parse.d.ts +17 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +14 -0
- package/dist/parse.js.map +1 -0
- package/dist/resolve-dependencies.d.ts +38 -0
- package/dist/resolve-dependencies.d.ts.map +1 -0
- package/dist/resolve-dependencies.js +203 -0
- package/dist/resolve-dependencies.js.map +1 -0
- package/dist/resolve.d.ts +32 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +145 -0
- package/dist/resolve.js.map +1 -0
- package/dist/rule-hints.d.ts +13 -0
- package/dist/rule-hints.d.ts.map +1 -0
- package/dist/rule-hints.js +50 -0
- package/dist/rule-hints.js.map +1 -0
- package/dist/walk-dependencies.d.ts +25 -0
- package/dist/walk-dependencies.d.ts.map +1 -0
- package/dist/walk-dependencies.js +68 -0
- package/dist/walk-dependencies.js.map +1 -0
- package/dist/walk-metadata.d.ts +26 -0
- package/dist/walk-metadata.d.ts.map +1 -0
- package/dist/walk-metadata.js +134 -0
- package/dist/walk-metadata.js.map +1 -0
- package/dist/walk.d.ts +59 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +244 -0
- package/dist/walk.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Java import-declaration → dependency-site emission.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `walk.ts` so the main walker stays focused on
|
|
5
|
+
* function-occurrence construction.
|
|
6
|
+
*
|
|
7
|
+
* We detect `static` by scanning the anonymous (non-named) children for
|
|
8
|
+
* a token whose type is `'static'`, and detect the wildcard by checking
|
|
9
|
+
* for a named `asterisk` child. The dotted path is the single named
|
|
10
|
+
* `scoped_identifier` (or bare `identifier` in the degenerate
|
|
11
|
+
* `import Foo;` default-package case) child.
|
|
12
|
+
*
|
|
13
|
+
* Out of scope at v1:
|
|
14
|
+
* - `module-info.java` `requires` directives (Java 9+ Java Platform
|
|
15
|
+
* Module System) — declarative module deps live there, not here.
|
|
16
|
+
* - Implicit `java.lang.*` imports — every Java file imports these,
|
|
17
|
+
* but we don't synthesize edges for non-explicit imports.
|
|
18
|
+
* - Implicit same-package visibility — Java doesn't require imports
|
|
19
|
+
* for sibling types in the same package; we likewise don't
|
|
20
|
+
* synthesize them.
|
|
21
|
+
*/
|
|
22
|
+
import { namedChildrenOf } from '@opensip-cli/graph-adapter-common';
|
|
23
|
+
export function collectDependencySites(file, moduleInitHash, out) {
|
|
24
|
+
for (const stmt of namedChildrenOf(file.tree.rootNode)) {
|
|
25
|
+
if (stmt.type !== 'import_declaration')
|
|
26
|
+
continue;
|
|
27
|
+
const specifier = decodeImportSpecifier(stmt);
|
|
28
|
+
if (specifier === null)
|
|
29
|
+
continue;
|
|
30
|
+
out.push({
|
|
31
|
+
nodeRef: stmt,
|
|
32
|
+
sourceFileRef: file,
|
|
33
|
+
ownerHash: moduleInitHash,
|
|
34
|
+
specifier,
|
|
35
|
+
line: stmt.startPosition.row + 1,
|
|
36
|
+
column: stmt.startPosition.column,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function decodeImportSpecifier(decl) {
|
|
41
|
+
// `static` is an anonymous keyword child; scan all children (named +
|
|
42
|
+
// anonymous) for it.
|
|
43
|
+
let isStatic = false;
|
|
44
|
+
for (let i = 0; i < decl.childCount; i++) {
|
|
45
|
+
const c = decl.child(i);
|
|
46
|
+
if (c?.type === 'static') {
|
|
47
|
+
isStatic = true;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Named children hold the path (scoped_identifier or identifier) and
|
|
52
|
+
// the optional `asterisk` wildcard. Scan in order.
|
|
53
|
+
let path = null;
|
|
54
|
+
let wildcard = false;
|
|
55
|
+
for (const c of namedChildrenOf(decl)) {
|
|
56
|
+
if (c.type === 'scoped_identifier' || c.type === 'identifier') {
|
|
57
|
+
path = c.text;
|
|
58
|
+
}
|
|
59
|
+
else if (c.type === 'asterisk') {
|
|
60
|
+
wildcard = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (path === null) /* v8 ignore next */
|
|
64
|
+
return null;
|
|
65
|
+
const tail = wildcard ? `${path}.*` : path;
|
|
66
|
+
return isStatic ? `static ${tail}` : tail;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=walk-dependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-dependencies.js","sourceRoot":"","sources":["../src/walk-dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAMpE,MAAM,UAAU,sBAAsB,CACpC,IAAoB,EACpB,cAAsB,EACtB,GAA2B;IAE3B,KAAK,MAAM,IAAI,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvD,IAAI,IAAI,CAAC,IAAI,KAAK,oBAAoB;YAAE,SAAS;QACjD,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,SAAS,KAAK,IAAI;YAAE,SAAS;QACjC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,aAAa,EAAE,IAAI;YACnB,SAAS,EAAE,cAAc;YACzB,SAAS;YACT,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;YAChC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM;SAClC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAU;IACvC,qEAAqE;IACrE,qBAAqB;IACrB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACzB,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM;QACR,CAAC;IACH,CAAC;IACD,qEAAqE;IACrE,mDAAmD;IACnD,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,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,IAAI,KAAK,IAAI,EAAE,oBAAoB;QAAC,OAAO,IAAI,CAAC;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,OAAO,QAAQ,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Java-specific metadata extraction from tree-sitter nodes.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `walk.ts` to keep that module focused on the AST
|
|
5
|
+
* traversal. Owns name / package / visibility / annotation / parameter
|
|
6
|
+
* extraction — pure functions over tree-sitter nodes, no walker state.
|
|
7
|
+
*/
|
|
8
|
+
import type { JavaParsedFile } from './parse.js';
|
|
9
|
+
import type { FunctionOccurrence } from '@opensip-cli/graph';
|
|
10
|
+
import type { Node } from '@opensip-cli/tree-sitter';
|
|
11
|
+
export declare function packageQualifier(packageName: string, filePathProjectRel: string): string;
|
|
12
|
+
export declare function extractPackageName(file: JavaParsedFile): string;
|
|
13
|
+
export declare function classifyVisibility(node: Node): FunctionOccurrence['visibility'];
|
|
14
|
+
export declare function extractAnnotations(node: Node): readonly string[];
|
|
15
|
+
export declare function hasTestAnnotation(decorators: readonly string[]): boolean;
|
|
16
|
+
export declare function extractParams(node: Node): readonly {
|
|
17
|
+
name: string;
|
|
18
|
+
optional: boolean;
|
|
19
|
+
rest: boolean;
|
|
20
|
+
}[];
|
|
21
|
+
export declare function extractLambdaParams(node: Node): readonly {
|
|
22
|
+
name: string;
|
|
23
|
+
optional: boolean;
|
|
24
|
+
rest: boolean;
|
|
25
|
+
}[];
|
|
26
|
+
//# sourceMappingURL=walk-metadata.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-metadata.d.ts","sourceRoot":"","sources":["../src/walk-metadata.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAErD,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,MAAM,CAMxF;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAU/D;AAgBD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAc/E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,MAAM,EAAE,CAUhE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAUxE;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,GACT,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,CAgB/D;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,GACT,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,CAsB/D"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Java-specific metadata extraction from tree-sitter nodes.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `walk.ts` to keep that module focused on the AST
|
|
5
|
+
* traversal. Owns name / package / visibility / annotation / parameter
|
|
6
|
+
* extraction — pure functions over tree-sitter nodes, no walker state.
|
|
7
|
+
*/
|
|
8
|
+
import { childrenOf, namedChildrenOf } from '@opensip-cli/graph-adapter-common';
|
|
9
|
+
export function packageQualifier(packageName, filePathProjectRel) {
|
|
10
|
+
if (packageName.length > 0)
|
|
11
|
+
return packageName;
|
|
12
|
+
// Fallback: derive a path-based qualifier (e.g. `src/main/java/Foo.java` →
|
|
13
|
+
// `src.main.java.Foo`). Real Java files almost always have a `package`
|
|
14
|
+
// declaration, so this is only hit for hand-written one-off files.
|
|
15
|
+
return filePathProjectRel.replace(/\.java$/, '').replaceAll('/', '.');
|
|
16
|
+
}
|
|
17
|
+
export function extractPackageName(file) {
|
|
18
|
+
for (const child of childrenOf(file.tree.rootNode)) {
|
|
19
|
+
if (child.type === 'package_declaration') {
|
|
20
|
+
// package_declaration: `package` keyword + scoped/qualified identifier + `;`
|
|
21
|
+
for (const c of namedChildrenOf(child)) {
|
|
22
|
+
if (c.type === 'scoped_identifier' || c.type === 'identifier')
|
|
23
|
+
return c.text;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return '';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Find the `modifiers` named child of a method/constructor declaration.
|
|
31
|
+
*
|
|
32
|
+
* Note: tree-sitter-java exposes the modifier list as a named child of
|
|
33
|
+
* type `modifiers`, NOT as a named field. `childForFieldName('modifiers')`
|
|
34
|
+
* returns null — only iteration works.
|
|
35
|
+
*/
|
|
36
|
+
function findModifiersNode(node) {
|
|
37
|
+
for (const c of childrenOf(node)) {
|
|
38
|
+
if (c.type === 'modifiers')
|
|
39
|
+
return c;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
export function classifyVisibility(node) {
|
|
44
|
+
// Visibility keywords appear inside the `modifiers` node as anonymous
|
|
45
|
+
// children with type === 'public' / 'protected' / 'private'.
|
|
46
|
+
// public / protected → 'exported'
|
|
47
|
+
// private → 'module-local' (file-local in Java terms)
|
|
48
|
+
// none → 'module-local' (package-private)
|
|
49
|
+
const modifiers = findModifiersNode(node);
|
|
50
|
+
if (modifiers) {
|
|
51
|
+
for (const c of childrenOf(modifiers)) {
|
|
52
|
+
if (c.type === 'public' || c.type === 'protected')
|
|
53
|
+
return 'exported';
|
|
54
|
+
if (c.type === 'private')
|
|
55
|
+
return 'module-local';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return 'module-local';
|
|
59
|
+
}
|
|
60
|
+
export function extractAnnotations(node) {
|
|
61
|
+
const out = [];
|
|
62
|
+
const modifiers = findModifiersNode(node);
|
|
63
|
+
if (!modifiers)
|
|
64
|
+
return out;
|
|
65
|
+
for (const c of childrenOf(modifiers)) {
|
|
66
|
+
if (c.type === 'annotation' || c.type === 'marker_annotation') {
|
|
67
|
+
out.push(c.text.trim());
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
export function hasTestAnnotation(decorators) {
|
|
73
|
+
for (const d of decorators) {
|
|
74
|
+
// Matches `@Test`, `@org.junit.Test`, `@ParameterizedTest`, etc.
|
|
75
|
+
if (/@(?:[\w.]*\.)?(?:Test|ParameterizedTest|RepeatedTest|TestFactory|TestTemplate)\b/.test(d)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
export function extractParams(node) {
|
|
82
|
+
const params = node.childForFieldName('parameters');
|
|
83
|
+
if (!params)
|
|
84
|
+
return [];
|
|
85
|
+
const out = [];
|
|
86
|
+
for (const child of namedChildrenOf(params)) {
|
|
87
|
+
if (child.type === 'formal_parameter' || child.type === 'spread_parameter') {
|
|
88
|
+
const nameNode = child.childForFieldName('name') ?? findIdentifierChild(child);
|
|
89
|
+
if (!nameNode)
|
|
90
|
+
continue;
|
|
91
|
+
out.push({
|
|
92
|
+
name: nameNode.text,
|
|
93
|
+
optional: false,
|
|
94
|
+
rest: child.type === 'spread_parameter',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
export function extractLambdaParams(node) {
|
|
101
|
+
// tree-sitter-java's lambda_expression `parameters` can be:
|
|
102
|
+
// - identifier — `x -> x + 1`
|
|
103
|
+
// - formal_parameters — `(int x) -> x + 1`
|
|
104
|
+
// - inferred_parameters — `(x, y) -> x + y`
|
|
105
|
+
const params = node.childForFieldName('parameters');
|
|
106
|
+
if (!params)
|
|
107
|
+
return [];
|
|
108
|
+
if (params.type === 'identifier') {
|
|
109
|
+
return [{ name: params.text, optional: false, rest: false }];
|
|
110
|
+
}
|
|
111
|
+
if (params.type === 'inferred_parameters') {
|
|
112
|
+
const out = [];
|
|
113
|
+
for (const c of namedChildrenOf(params)) {
|
|
114
|
+
if (c.type === 'identifier')
|
|
115
|
+
out.push({ name: c.text, optional: false, rest: false });
|
|
116
|
+
}
|
|
117
|
+
return out;
|
|
118
|
+
}
|
|
119
|
+
// formal_parameters falls through to the standard extractor.
|
|
120
|
+
/* v8 ignore start */
|
|
121
|
+
if (params.type === 'formal_parameters')
|
|
122
|
+
return extractParams(node);
|
|
123
|
+
return [];
|
|
124
|
+
/* v8 ignore stop */
|
|
125
|
+
}
|
|
126
|
+
function findIdentifierChild(node) {
|
|
127
|
+
for (const c of namedChildrenOf(node)) {
|
|
128
|
+
if (c.type === 'identifier')
|
|
129
|
+
return c;
|
|
130
|
+
}
|
|
131
|
+
/* v8 ignore next */
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=walk-metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-metadata.js","sourceRoot":"","sources":["../src/walk-metadata.ts"],"names":[],"mappings":"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"}
|
package/dist/walk.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Java walkProject — emit FunctionOccurrences + CallSiteRecords.
|
|
3
|
+
*
|
|
4
|
+
* Identifies the callable shapes:
|
|
5
|
+
*
|
|
6
|
+
* - `method_declaration` inside a type body → 'method'
|
|
7
|
+
* - `enclosingClass` = immediate enclosing
|
|
8
|
+
* class/interface/record/enum/annotation_type name.
|
|
9
|
+
* - `constructor_declaration` → 'constructor'
|
|
10
|
+
* - `lambda_expression` → 'arrow'
|
|
11
|
+
* - one synthetic `<module-init>` per file owning the file's
|
|
12
|
+
* top-level structure (package, imports, type declarations).
|
|
13
|
+
*
|
|
14
|
+
* Note: Java doesn't have free-standing top-level functions. All
|
|
15
|
+
* methods live inside a type. The `'function-declaration'` kind is
|
|
16
|
+
* unused for Java; methods at any depth get kind='method' (or
|
|
17
|
+
* 'constructor' for ctor declarations).
|
|
18
|
+
*
|
|
19
|
+
* Body hashing: sha256 of normalized body text. Normalization:
|
|
20
|
+
* 1. Strip line comments (`// …` to end-of-line).
|
|
21
|
+
* 2. Strip block comments (`/* … *\/`). Java block comments do NOT
|
|
22
|
+
* nest (unlike Rust).
|
|
23
|
+
* 3. Strip Javadoc comments — they're a `/**` subset of block
|
|
24
|
+
* comments and the same scanner handles them.
|
|
25
|
+
* 4. Preserve string literals: both regular `"…"` and text blocks
|
|
26
|
+
* `"""…"""` (Java 15+). Their content is part of behavior.
|
|
27
|
+
* 5. Preserve char literals (`'x'`, `'\n'`).
|
|
28
|
+
* 6. Collapse whitespace.
|
|
29
|
+
*
|
|
30
|
+
* Call-site records:
|
|
31
|
+
* - `method_invocation` — `foo(...)`, `obj.foo(...)`,
|
|
32
|
+
* `Class.foo(...)`, `this.foo(...)`,
|
|
33
|
+
* `super.foo(...)`.
|
|
34
|
+
* - `object_creation_expression` — `new Foo(...)` invokes the
|
|
35
|
+
* constructor; resolver treats
|
|
36
|
+
* the type name as the target.
|
|
37
|
+
* - `explicit_constructor_invocation` — `super(...)` / `this(...)`
|
|
38
|
+
* inside a constructor body.
|
|
39
|
+
* - 'creation' edges for `lambda_expression` — reachability flows
|
|
40
|
+
* through closures even when their dispatch is unresolvable.
|
|
41
|
+
* - `method_reference` (`Foo::bar`) is NOT recorded — it creates a
|
|
42
|
+
* callable handle but doesn't invoke. Skipping avoids inflating
|
|
43
|
+
* the graph with edges that never fire at that source location.
|
|
44
|
+
*
|
|
45
|
+
* Test detection (file-level):
|
|
46
|
+
* - Path contains `/test/` (catches Maven/Gradle `src/test/java/`).
|
|
47
|
+
* - Filename ends with `Test.java`, `Tests.java`, or `IT.java`.
|
|
48
|
+
*
|
|
49
|
+
* Test detection (function-level):
|
|
50
|
+
* - Methods annotated `@Test` (JUnit 4/5) are tagged `inTestFile`
|
|
51
|
+
* even when the file path doesn't match. Inline test methods
|
|
52
|
+
* are a common pattern; this honors them.
|
|
53
|
+
*/
|
|
54
|
+
import type { JavaParsedProject } from './parse.js';
|
|
55
|
+
import type { WalkInput, WalkOutput } from '@opensip-cli/graph';
|
|
56
|
+
declare const isTestFile: (rel: string) => boolean;
|
|
57
|
+
export { isTestFile };
|
|
58
|
+
export declare function walkProject(input: WalkInput<JavaParsedProject>): WalkOutput;
|
|
59
|
+
//# sourceMappingURL=walk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AA0BH,OAAO,KAAK,EAAkB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EAAsC,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQpG,QAAA,MAAQ,UAAU,0BAIhB,CAAC;AAEH,OAAO,EAAE,UAAU,EAAE,CAAC;AAmBtB,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAE3E"}
|
package/dist/walk.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// @fitness-ignore-file context-mutation -- `ctx: WalkCtx` here is a function-scoped traversal accumulator (callSites array, occurrence sink, parser refs) threaded through the AST walk, NOT a shared request/execution context. `ctx.callSites.push(...)` is the intended local-accumulator append. The check's `LOCAL_DECLARATION_PATTERNS` heuristic doesn't see it because `ctx` arrives as a typed parameter, not via `const ctx = …`.
|
|
2
|
+
/**
|
|
3
|
+
* Java walkProject — emit FunctionOccurrences + CallSiteRecords.
|
|
4
|
+
*
|
|
5
|
+
* Identifies the callable shapes:
|
|
6
|
+
*
|
|
7
|
+
* - `method_declaration` inside a type body → 'method'
|
|
8
|
+
* - `enclosingClass` = immediate enclosing
|
|
9
|
+
* class/interface/record/enum/annotation_type name.
|
|
10
|
+
* - `constructor_declaration` → 'constructor'
|
|
11
|
+
* - `lambda_expression` → 'arrow'
|
|
12
|
+
* - one synthetic `<module-init>` per file owning the file's
|
|
13
|
+
* top-level structure (package, imports, type declarations).
|
|
14
|
+
*
|
|
15
|
+
* Note: Java doesn't have free-standing top-level functions. All
|
|
16
|
+
* methods live inside a type. The `'function-declaration'` kind is
|
|
17
|
+
* unused for Java; methods at any depth get kind='method' (or
|
|
18
|
+
* 'constructor' for ctor declarations).
|
|
19
|
+
*
|
|
20
|
+
* Body hashing: sha256 of normalized body text. Normalization:
|
|
21
|
+
* 1. Strip line comments (`// …` to end-of-line).
|
|
22
|
+
* 2. Strip block comments (`/* … *\/`). Java block comments do NOT
|
|
23
|
+
* nest (unlike Rust).
|
|
24
|
+
* 3. Strip Javadoc comments — they're a `/**` subset of block
|
|
25
|
+
* comments and the same scanner handles them.
|
|
26
|
+
* 4. Preserve string literals: both regular `"…"` and text blocks
|
|
27
|
+
* `"""…"""` (Java 15+). Their content is part of behavior.
|
|
28
|
+
* 5. Preserve char literals (`'x'`, `'\n'`).
|
|
29
|
+
* 6. Collapse whitespace.
|
|
30
|
+
*
|
|
31
|
+
* Call-site records:
|
|
32
|
+
* - `method_invocation` — `foo(...)`, `obj.foo(...)`,
|
|
33
|
+
* `Class.foo(...)`, `this.foo(...)`,
|
|
34
|
+
* `super.foo(...)`.
|
|
35
|
+
* - `object_creation_expression` — `new Foo(...)` invokes the
|
|
36
|
+
* constructor; resolver treats
|
|
37
|
+
* the type name as the target.
|
|
38
|
+
* - `explicit_constructor_invocation` — `super(...)` / `this(...)`
|
|
39
|
+
* inside a constructor body.
|
|
40
|
+
* - 'creation' edges for `lambda_expression` — reachability flows
|
|
41
|
+
* through closures even when their dispatch is unresolvable.
|
|
42
|
+
* - `method_reference` (`Foo::bar`) is NOT recorded — it creates a
|
|
43
|
+
* callable handle but doesn't invoke. Skipping avoids inflating
|
|
44
|
+
* the graph with edges that never fire at that source location.
|
|
45
|
+
*
|
|
46
|
+
* Test detection (file-level):
|
|
47
|
+
* - Path contains `/test/` (catches Maven/Gradle `src/test/java/`).
|
|
48
|
+
* - Filename ends with `Test.java`, `Tests.java`, or `IT.java`.
|
|
49
|
+
*
|
|
50
|
+
* Test detection (function-level):
|
|
51
|
+
* - Methods annotated `@Test` (JUnit 4/5) are tagged `inTestFile`
|
|
52
|
+
* even when the file path doesn't match. Inline test methods
|
|
53
|
+
* are a common pattern; this honors them.
|
|
54
|
+
*/
|
|
55
|
+
import { relative, sep } from 'node:path';
|
|
56
|
+
import { childrenOf, makeFileClassifier, nameOf, record, runWalk, synthesizeModuleInit as buildModuleInit, } from '@opensip-cli/graph-adapter-common';
|
|
57
|
+
import { digestJavaBody, digestSyntheticBody } from './body-digest.js';
|
|
58
|
+
import { collectDependencySites } from './walk-dependencies.js';
|
|
59
|
+
import { classifyVisibility, extractAnnotations, extractLambdaParams, extractPackageName, extractParams, hasTestAnnotation, packageQualifier, } from './walk-metadata.js';
|
|
60
|
+
const TEST_PATH_RE = /(?:^|\/)test\//;
|
|
61
|
+
const TEST_FILE_NAME_RE = /(?:^|\/)[^/]*(?:Test|Tests|IT)\.java$/;
|
|
62
|
+
const GENERATED_PATH_RE = /(?:\b(?:target|build|out|generated|generated-sources)\/)|(?:\$Pb\.java$)/;
|
|
63
|
+
const { isTestFile, isGeneratedFile } = makeFileClassifier({
|
|
64
|
+
testRe: TEST_FILE_NAME_RE,
|
|
65
|
+
generatedRe: GENERATED_PATH_RE,
|
|
66
|
+
testPathRe: TEST_PATH_RE,
|
|
67
|
+
});
|
|
68
|
+
export { isTestFile };
|
|
69
|
+
// Type declarations that introduce an enclosing-class context for the
|
|
70
|
+
// methods/constructors inside them.
|
|
71
|
+
const TYPE_DECL_NODES = new Set([
|
|
72
|
+
'class_declaration',
|
|
73
|
+
'interface_declaration',
|
|
74
|
+
'record_declaration',
|
|
75
|
+
'enum_declaration',
|
|
76
|
+
'annotation_type_declaration',
|
|
77
|
+
]);
|
|
78
|
+
// Call-site node kinds that the walk surfaces as 'call' records.
|
|
79
|
+
const CALL_NODES = new Set([
|
|
80
|
+
'method_invocation',
|
|
81
|
+
'object_creation_expression',
|
|
82
|
+
'explicit_constructor_invocation',
|
|
83
|
+
]);
|
|
84
|
+
export function walkProject(input) {
|
|
85
|
+
return runWalk({ input, walkFile });
|
|
86
|
+
}
|
|
87
|
+
function walkFile(absPath, file, projectDirAbs, sinks) {
|
|
88
|
+
const { occurrences: out, callSites, dependencySites } = sinks;
|
|
89
|
+
const filePathProjectRel = relative(projectDirAbs, absPath).split(sep).join('/');
|
|
90
|
+
const inTestFile = isTestFile(filePathProjectRel);
|
|
91
|
+
const definedInGenerated = isGeneratedFile(filePathProjectRel);
|
|
92
|
+
const packageName = extractPackageName(file);
|
|
93
|
+
const moduleInit = buildModuleInit({
|
|
94
|
+
file,
|
|
95
|
+
filePathProjectRel,
|
|
96
|
+
inTestFile,
|
|
97
|
+
definedInGenerated,
|
|
98
|
+
digestSyntheticBody,
|
|
99
|
+
qualifiedName: `${packageQualifier(packageName, filePathProjectRel)}.<module-init>`,
|
|
100
|
+
});
|
|
101
|
+
record(out, moduleInit);
|
|
102
|
+
// Phase 4 (DEC-498): walk top-level `import` declarations as dependency
|
|
103
|
+
// sites. Owner is the file's synthesized module-init occurrence.
|
|
104
|
+
// Implicit `java.lang.*` and same-package imports are NOT synthesized —
|
|
105
|
+
// only explicit `import_declaration` nodes are emitted.
|
|
106
|
+
collectDependencySites(file, moduleInit.bodyHash, dependencySites);
|
|
107
|
+
const ctx = {
|
|
108
|
+
file,
|
|
109
|
+
filePathProjectRel,
|
|
110
|
+
packageName,
|
|
111
|
+
fileInTestFile: inTestFile,
|
|
112
|
+
definedInGenerated,
|
|
113
|
+
out,
|
|
114
|
+
callSites,
|
|
115
|
+
};
|
|
116
|
+
const initialFrame = { ownerHash: moduleInit.bodyHash, enclosingClass: null };
|
|
117
|
+
for (const child of childrenOf(file.tree.rootNode))
|
|
118
|
+
visit(child, initialFrame, ctx);
|
|
119
|
+
}
|
|
120
|
+
// @graph-ignore-next-line graph:cycle -- intentional recursive-descent AST visitor; the cycle is the traversal (visit re-enters via the type/member helpers)
|
|
121
|
+
function visit(node, frame, ctx) {
|
|
122
|
+
if (TYPE_DECL_NODES.has(node.type)) {
|
|
123
|
+
visitTypeDeclaration(node, frame, ctx);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (node.type === 'method_declaration') {
|
|
127
|
+
visitMethodOrConstructor(node, frame, ctx, 'method');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (node.type === 'constructor_declaration') {
|
|
131
|
+
visitMethodOrConstructor(node, frame, ctx, 'constructor');
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (node.type === 'lambda_expression' && visitLambda(node, frame, ctx)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (CALL_NODES.has(node.type)) {
|
|
138
|
+
ctx.callSites.push({
|
|
139
|
+
nodeRef: node,
|
|
140
|
+
sourceFileRef: ctx.file,
|
|
141
|
+
ownerHash: frame.ownerHash,
|
|
142
|
+
kind: 'call',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
for (const child of childrenOf(node))
|
|
146
|
+
visit(child, frame, ctx);
|
|
147
|
+
}
|
|
148
|
+
function visitTypeDeclaration(node, frame, ctx) {
|
|
149
|
+
const typeName = nameOf(node) ?? '<anon-type>';
|
|
150
|
+
// Type declarations don't emit a function — their bodies' methods do.
|
|
151
|
+
// Keep the same owner hash but update enclosingClass for children.
|
|
152
|
+
const childFrame = { ownerHash: frame.ownerHash, enclosingClass: typeName };
|
|
153
|
+
for (const child of childrenOf(node))
|
|
154
|
+
visit(child, childFrame, ctx);
|
|
155
|
+
}
|
|
156
|
+
function visitMethodOrConstructor(node, frame, ctx, kind) {
|
|
157
|
+
const occ = buildMethodOccurrence(node, frame, ctx, kind);
|
|
158
|
+
if (!occ)
|
|
159
|
+
return;
|
|
160
|
+
record(ctx.out, occ);
|
|
161
|
+
const childFrame = { ownerHash: occ.bodyHash, enclosingClass: null };
|
|
162
|
+
const body = node.childForFieldName('body');
|
|
163
|
+
if (body) {
|
|
164
|
+
for (const child of childrenOf(body))
|
|
165
|
+
visit(child, childFrame, ctx);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
function visitLambda(node, frame, ctx) {
|
|
169
|
+
const occ = buildLambdaOccurrence(node, ctx);
|
|
170
|
+
if (!occ)
|
|
171
|
+
return false;
|
|
172
|
+
record(ctx.out, occ);
|
|
173
|
+
if (frame.ownerHash !== occ.bodyHash) {
|
|
174
|
+
ctx.callSites.push({
|
|
175
|
+
nodeRef: node,
|
|
176
|
+
sourceFileRef: ctx.file,
|
|
177
|
+
ownerHash: frame.ownerHash,
|
|
178
|
+
kind: 'creation',
|
|
179
|
+
childHash: occ.bodyHash,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const body = node.childForFieldName('body');
|
|
183
|
+
if (body) {
|
|
184
|
+
visit(body, { ownerHash: occ.bodyHash, enclosingClass: null }, ctx);
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
function buildMethodOccurrence(node, frame, ctx, kind) {
|
|
189
|
+
const name = nameOf(node) ?? '<anon-fn>';
|
|
190
|
+
const digest = digestJavaBody(ctx.file.source.slice(node.startIndex, node.endIndex));
|
|
191
|
+
const decorators = extractAnnotations(node);
|
|
192
|
+
const inTest = ctx.fileInTestFile || hasTestAnnotation(decorators);
|
|
193
|
+
const visibility = classifyVisibility(node);
|
|
194
|
+
const qualifiedBase = packageQualifier(ctx.packageName, ctx.filePathProjectRel);
|
|
195
|
+
const qualifiedName = frame.enclosingClass === null
|
|
196
|
+
? `${qualifiedBase}.${name}`
|
|
197
|
+
: `${qualifiedBase}.${frame.enclosingClass}.${name}`;
|
|
198
|
+
return {
|
|
199
|
+
bodyHash: digest.hash,
|
|
200
|
+
bodySize: digest.size,
|
|
201
|
+
simpleName: name,
|
|
202
|
+
qualifiedName,
|
|
203
|
+
filePath: ctx.filePathProjectRel,
|
|
204
|
+
line: node.startPosition.row + 1,
|
|
205
|
+
column: node.startPosition.column,
|
|
206
|
+
endLine: node.endPosition.row + 1,
|
|
207
|
+
kind,
|
|
208
|
+
params: extractParams(node),
|
|
209
|
+
returnType: null,
|
|
210
|
+
enclosingClass: frame.enclosingClass,
|
|
211
|
+
decorators,
|
|
212
|
+
visibility,
|
|
213
|
+
inTestFile: inTest,
|
|
214
|
+
definedInGenerated: ctx.definedInGenerated,
|
|
215
|
+
calls: [],
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function buildLambdaOccurrence(node, ctx) {
|
|
219
|
+
const digest = digestJavaBody(ctx.file.source.slice(node.startIndex, node.endIndex));
|
|
220
|
+
const startLine = node.startPosition.row + 1;
|
|
221
|
+
const startCol = node.startPosition.column;
|
|
222
|
+
const simpleName = `<arrow:${ctx.filePathProjectRel}:${String(startLine)}:${String(startCol)}>`;
|
|
223
|
+
const qualifiedBase = packageQualifier(ctx.packageName, ctx.filePathProjectRel);
|
|
224
|
+
return {
|
|
225
|
+
bodyHash: digest.hash,
|
|
226
|
+
bodySize: digest.size,
|
|
227
|
+
simpleName,
|
|
228
|
+
qualifiedName: `${qualifiedBase}.<lambda:${String(startLine)}:${String(startCol)}>`,
|
|
229
|
+
filePath: ctx.filePathProjectRel,
|
|
230
|
+
line: startLine,
|
|
231
|
+
column: startCol,
|
|
232
|
+
endLine: node.endPosition.row + 1,
|
|
233
|
+
kind: 'arrow',
|
|
234
|
+
params: extractLambdaParams(node),
|
|
235
|
+
returnType: null,
|
|
236
|
+
enclosingClass: null,
|
|
237
|
+
decorators: [],
|
|
238
|
+
visibility: 'private',
|
|
239
|
+
inTestFile: ctx.fileInTestFile,
|
|
240
|
+
definedInGenerated: ctx.definedInGenerated,
|
|
241
|
+
calls: [],
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=walk.js.map
|
package/dist/walk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opensip-cli/graph-java",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "Apache-2.0",
|
|
5
|
+
"description": "Java language adapter for the opensip graph engine",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"opensip-cli",
|
|
8
|
+
"static-analysis",
|
|
9
|
+
"code-quality",
|
|
10
|
+
"call-graph",
|
|
11
|
+
"dependency-graph",
|
|
12
|
+
"java"
|
|
13
|
+
],
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/opensip-ai/opensip-cli.git",
|
|
17
|
+
"directory": "packages/graph/graph-java"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://github.com/opensip-ai/opensip-cli",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/opensip-ai/opensip-cli/issues"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"main": "./dist/index.js",
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"opensipTools": {
|
|
30
|
+
"kind": "graph-adapter"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"LICENSE",
|
|
35
|
+
"NOTICE"
|
|
36
|
+
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@opensip-cli/core": "0.1.0",
|
|
39
|
+
"@opensip-cli/graph-adapter-common": "0.1.0",
|
|
40
|
+
"@opensip-cli/graph": "0.1.0",
|
|
41
|
+
"@opensip-cli/lang-java": "0.1.0",
|
|
42
|
+
"@opensip-cli/tree-sitter": "0.1.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^24.13.2",
|
|
46
|
+
"vitest": "^4.1.8"
|
|
47
|
+
},
|
|
48
|
+
"scripts": {
|
|
49
|
+
"build": "tsc",
|
|
50
|
+
"test": "vitest run --passWithNoTests",
|
|
51
|
+
"typecheck": "tsc --noEmit",
|
|
52
|
+
"clean": "rm -rf dist"
|
|
53
|
+
}
|
|
54
|
+
}
|