@descryy/adapter-java 0.2.0 → 0.3.1
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 +8 -0
- package/dist/adapter.d.ts +5 -7
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +80 -95
- package/dist/adapter.js.map +1 -1
- package/dist/client.d.ts +65 -119
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +121 -222
- package/dist/client.js.map +1 -1
- package/dist/extract.d.ts +13 -22
- package/dist/extract.d.ts.map +1 -1
- package/dist/extract.js +189 -288
- package/dist/extract.js.map +1 -1
- package/dist/jpa.d.ts +32 -73
- package/dist/jpa.d.ts.map +1 -1
- package/dist/jpa.js +72 -166
- package/dist/jpa.js.map +1 -1
- package/dist/parse.d.ts +83 -152
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +101 -183
- package/dist/parse.js.map +1 -1
- package/dist/spring.d.ts +24 -58
- package/dist/spring.d.ts.map +1 -1
- package/dist/spring.js +80 -209
- package/dist/spring.js.map +1 -1
- package/package.json +16 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
Copyright (c) 2026 Descry
|
|
2
|
+
|
|
3
|
+
All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software is proprietary and confidential. No license, express or
|
|
6
|
+
implied, to use, copy, modify, merge, publish, distribute, sublicense, or
|
|
7
|
+
sell copies of this software is granted without prior written permission
|
|
8
|
+
from the copyright holder.
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Java `LanguageAdapter` — all seven methods, breadth tier.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* be inferred from an empty result.
|
|
4
|
+
* Parses with tree-sitter's Java grammar over the shared WASM harness — no
|
|
5
|
+
* JDT, no SCIP, and `capabilities()` says so explicitly.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* and needs a runnable application, which no corpus here is.
|
|
7
|
+
* Spring (`spring.ts`) and JPA (`jpa.ts`) extractors are bound, reading
|
|
8
|
+
* declarations rather than names — the FLOOR under DEC-115, since framework
|
|
9
|
+
* introspection needs a runnable application, which no corpus here is.
|
|
12
10
|
*/
|
|
13
11
|
import { type LanguageAdapter, type ResolutionLevel } from "@descryy/ir";
|
|
14
12
|
import { toRepoRelative } from "@descryy/adapter-common";
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAML,KAAK,eAAe,EAGpB,KAAK,eAAe,EAIrB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAyB,cAAc,EAAwB,MAAM,yBAAyB,CAAC;AAItG,OAAO,EAA4B,QAAQ,EAAmB,MAAM,cAAc,CAAC;AAGnF,eAAO,MAAM,UAAU,iBAAiB,CAAC;AACzC,eAAO,MAAM,eAAe,UAAU,CAAC;AACvC,eAAO,MAAM,kBAAkB,wBAAyB,CAAC;AAsCzD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,eAAe,CAAC;CAC1C;AAYD,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAgO/E;AAED,2DAA2D;AAC3D,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC"}
|
package/dist/adapter.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The Java `LanguageAdapter` — all seven methods, breadth tier.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* be inferred from an empty result.
|
|
4
|
+
* Parses with tree-sitter's Java grammar over the shared WASM harness — no
|
|
5
|
+
* JDT, no SCIP, and `capabilities()` says so explicitly.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* and needs a runnable application, which no corpus here is.
|
|
7
|
+
* Spring (`spring.ts`) and JPA (`jpa.ts`) extractors are bound, reading
|
|
8
|
+
* declarations rather than names — the FLOOR under DEC-115, since framework
|
|
9
|
+
* introspection needs a runnable application, which no corpus here is.
|
|
12
10
|
*/
|
|
13
11
|
import { createHash } from "node:crypto";
|
|
14
12
|
import { createRequire } from "node:module";
|
|
@@ -25,12 +23,11 @@ export const ADAPTER_VERSION = "0.1.0";
|
|
|
25
23
|
export const DEFAULT_JAVA_GLOBS = ["**/*.java"];
|
|
26
24
|
const PRODUCED_BY = `${ADAPTER_ID}@${ADAPTER_VERSION}`;
|
|
27
25
|
/**
|
|
28
|
-
* The grammar,
|
|
26
|
+
* The grammar file, resolved the same way whether compiled or run from source.
|
|
29
27
|
*
|
|
30
|
-
* A copy
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* in `dist` — so the declared dependency is the fallback, and it is the one that
|
|
28
|
+
* A copy ships beside the compiled output for a resolved-at-runtime install.
|
|
29
|
+
* But `node --test` and the conformance runner load `src/*.ts` directly, where
|
|
30
|
+
* the copy sits in `dist` instead — so the npm dependency is the fallback that
|
|
34
31
|
* makes the source path work at all.
|
|
35
32
|
*/
|
|
36
33
|
function grammarPath() {
|
|
@@ -40,24 +37,17 @@ function grammarPath() {
|
|
|
40
37
|
return createRequire(import.meta.url).resolve("tree-sitter-java/tree-sitter-java.wasm");
|
|
41
38
|
}
|
|
42
39
|
/**
|
|
43
|
-
* Directories
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* own classes, and analysing both produces two declarations of one type — a
|
|
47
|
-
* duplicate node id, the failure DEC-077 records arriving by another road.
|
|
40
|
+
* Directories holding build output, not source. A repo often contains a
|
|
41
|
+
* generated/copied duplicate of its own classes; analysing both would double-
|
|
42
|
+
* declare one type — DEC-077's duplicate-node-id failure by another road.
|
|
48
43
|
*/
|
|
49
44
|
const BUILD_DIRECTORIES = ["/target/", "/build/", "/out/", "/bin/", "/.gradle/"];
|
|
50
45
|
/**
|
|
51
|
-
* Is this path build output rather than source?
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* A declared source root settles it — anything under `src/` is source no matter
|
|
57
|
-
* what its packages are called, and the name test applies only outside one.
|
|
58
|
-
*
|
|
59
|
-
* This is the general form of the rule rather than the one that happened to work
|
|
60
|
-
* on the repositories in front of it.
|
|
46
|
+
* Is this path build output rather than source? A bare directory-name match
|
|
47
|
+
* is unsafe — `build`/`bin`/`target` are legal package names, so
|
|
48
|
+
* `src/main/java/com/x/build/Cfg.java` would be wrongly dropped. Anything
|
|
49
|
+
* under `src/` is source regardless of package names; the name test applies
|
|
50
|
+
* only outside one.
|
|
61
51
|
*/
|
|
62
52
|
function isBuildOutput(file) {
|
|
63
53
|
const path = `/${file}`;
|
|
@@ -70,7 +60,17 @@ export function createJavaAdapter(options = {}) {
|
|
|
70
60
|
const ceiling = options.maxResolution ?? 2;
|
|
71
61
|
let session;
|
|
72
62
|
let parser;
|
|
73
|
-
|
|
63
|
+
let nestedCheckouts = [];
|
|
64
|
+
let ignoredByProject = [];
|
|
65
|
+
const filesUnder = (root) => {
|
|
66
|
+
const nested = [];
|
|
67
|
+
const found = discover(root.absolutePath, globs, {
|
|
68
|
+
onNestedCheckout: (dir) => nested.push(dir),
|
|
69
|
+
onIgnored: (names) => (ignoredByProject = names),
|
|
70
|
+
}).filter((file) => !isBuildOutput(file));
|
|
71
|
+
nestedCheckouts = nested;
|
|
72
|
+
return found;
|
|
73
|
+
};
|
|
74
74
|
return {
|
|
75
75
|
id: ADAPTER_ID,
|
|
76
76
|
version: ADAPTER_VERSION,
|
|
@@ -85,53 +85,45 @@ export function createJavaAdapter(options = {}) {
|
|
|
85
85
|
evidence.push(`${manifest} at the repository root`);
|
|
86
86
|
}
|
|
87
87
|
catch {
|
|
88
|
-
// Absent
|
|
89
|
-
// source tree with no manifest is still Java.
|
|
88
|
+
// Absent — a manifest corroborates but isn't required; a source tree with none is still Java.
|
|
90
89
|
}
|
|
91
90
|
}
|
|
91
|
+
for (const nested of nestedCheckouts) {
|
|
92
|
+
evidence.push(`skipped ${nested}: a separate checkout with its own .git`);
|
|
93
|
+
}
|
|
94
|
+
if (ignoredByProject.length > 0) {
|
|
95
|
+
evidence.push(`skipped ${ignoredByProject.length} director(ies) the project's own .gitignore excludes: ` +
|
|
96
|
+
`${ignoredByProject.slice(0, 12).join(", ")}`);
|
|
97
|
+
}
|
|
92
98
|
return { detected: files.length > 0, roots: files.length > 0 ? [root.absolutePath] : [], evidence };
|
|
93
99
|
},
|
|
94
100
|
capabilities() {
|
|
95
101
|
return {
|
|
96
102
|
maxResolution: ceiling,
|
|
97
103
|
/**
|
|
98
|
-
* `API_ROUTE
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
* DEC-043's objection was to the name heuristic, not to the node types.
|
|
104
|
+
* `API_ROUTE`/`API_ENDPOINT`/`MODEL` are claimed: Spring and JPA extractors
|
|
105
|
+
* earn them from declarations (annotations), not names — DEC-043 objected
|
|
106
|
+
* to the name heuristic, not the node types.
|
|
102
107
|
*
|
|
103
|
-
* `DTO` stays absent
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* nothing distinguishes the DTO, so nothing claims it.
|
|
108
|
+
* `DTO` stays absent (golden 07): `Order`/`CreateOrderRequest` are
|
|
109
|
+
* structurally identical, separable only by name — nothing distinguishes
|
|
110
|
+
* a DTO the way `@Entity` distinguishes a model.
|
|
107
111
|
*
|
|
108
|
-
* `frameworkExtractors
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* bound, so declaring early turns skips into failures.
|
|
112
|
+
* `frameworkExtractors`/`frameworkCapabilities` are declared together,
|
|
113
|
+
* only once bound, since declaring early turns `run.ts`'s capability-
|
|
114
|
+
* gated skips into failures.
|
|
112
115
|
*
|
|
113
|
-
* `USES_API
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* (0 edges, an honest zero — see DEC-260).
|
|
116
|
+
* `USES_API`/`client-call-extractor`: `client.ts` (D-FIX-3, DEC-241)
|
|
117
|
+
* extracts real edges from `RestTemplate`/`WebClient` literal-path
|
|
118
|
+
* calls — 9 edges on `shopizer`, an honest 0 on `spring-petclinic`
|
|
119
|
+
* (DEC-260).
|
|
118
120
|
*
|
|
119
|
-
* `CLIENT_CALL_EXTRACTOR` was
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* stood: golden pattern 08's caller role (`order_page`) requires a real
|
|
123
|
-
* HTTP call, and the Java fixture's `OrderPage.render()` called
|
|
124
|
-
* `routes.getOrder(id)` in-process, not through any HTTP client shape
|
|
125
|
-
* at all — no fixture change could earn a pass without inventing that
|
|
126
|
-
* shape. DEC-246 built it: `OrderPage.render()` now calls
|
|
127
|
-
* `restTemplate.getForObject("/orders/{id}", ...)`, the same URI-
|
|
128
|
-
* template form Python's and Kotlin's `order_page` already use for the
|
|
129
|
-
* identical role, and pattern 08 now **passes**, not merely skips.
|
|
121
|
+
* `CLIENT_CALL_EXTRACTOR` was reverted (DEC-262: golden 08's fixture had
|
|
122
|
+
* no real HTTP call to detect) then restored (DEC-246: the fixture now
|
|
123
|
+
* calls `restTemplate.getForObject(...)`, and pattern 08 passes).
|
|
130
124
|
*
|
|
131
|
-
* `client-base-extractor` stays absent —
|
|
132
|
-
*
|
|
133
|
-
* 08a/08b/08c (DEC-164's strict base-resolution contract) are a
|
|
134
|
-
* different, unaddressed row.
|
|
125
|
+
* `client-base-extractor` stays absent — no composed base URL is read,
|
|
126
|
+
* so DEC-164's strict patterns 08a/08b/08c are unaddressed.
|
|
135
127
|
*/
|
|
136
128
|
nodeTypes: ["MODULE", "CLASS", "FUNCTION", "TEST_CASE", "API_ROUTE", "API_ENDPOINT", "MODEL"],
|
|
137
129
|
edgeTypes: [
|
|
@@ -147,25 +139,17 @@ export function createJavaAdapter(options = {}) {
|
|
|
147
139
|
hasCallHierarchy: false,
|
|
148
140
|
hasTypeHierarchy: false,
|
|
149
141
|
/**
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* Declared from the build tools rather than from an existing exclusion, because
|
|
156
|
-
* this adapter has none — its file walk is source-root driven.
|
|
157
|
-
*
|
|
158
|
-
* Names only — the walk matches one path component, so a path or glob matches
|
|
159
|
-
* nothing. Nothing dotted — those are skipped structurally already.
|
|
142
|
+
* Dependency/build-output directories (DEC-110) — the engine no longer
|
|
143
|
+
* hardcodes `node_modules`/`vendor`/`target`, it consumes this instead.
|
|
144
|
+
* Maven writes `target/`, Gradle writes `build/`. Names only, not paths
|
|
145
|
+
* or globs, since the walk matches one path component; dotted dirs are
|
|
146
|
+
* already skipped structurally.
|
|
160
147
|
*/
|
|
161
148
|
noiseDirectories: ["target", "build"],
|
|
162
|
-
// `jaxrs`
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
// all; `spring-data-mongodb` names `jpa.ts`'s `@Document` admission
|
|
167
|
-
// rather than a new file, since the field/nullability machinery is
|
|
168
|
-
// shared verbatim with JPA.
|
|
149
|
+
// `jaxrs` gets its own route reader in `spring.ts` (`jaxrsRoutes`) — a
|
|
150
|
+
// materially different framework, reachable without Spring at all.
|
|
151
|
+
// `spring-data-mongodb` names `jpa.ts`'s `@Document` admission, since
|
|
152
|
+
// the field/nullability machinery is shared verbatim with JPA.
|
|
169
153
|
frameworkExtractors: ["spring", "jaxrs", "jpa", "spring-data-mongodb", "client-call-extractor"],
|
|
170
154
|
frameworkCapabilities: [ROUTE_EXTRACTOR, ORM_EXTRACTOR, CLIENT_CALL_EXTRACTOR],
|
|
171
155
|
};
|
|
@@ -194,7 +178,7 @@ export function createJavaAdapter(options = {}) {
|
|
|
194
178
|
failures.push(outcome.failure);
|
|
195
179
|
continue;
|
|
196
180
|
}
|
|
197
|
-
// Isolated
|
|
181
|
+
// Isolated so a throw during the walk costs one file, not the whole run.
|
|
198
182
|
const read = isolateFile(file, () => readUnit(outcome.tree.rootNode, file, outcome.tree.rootNode.hasError));
|
|
199
183
|
if (read.failure !== undefined) {
|
|
200
184
|
unfinished.push(read.failure);
|
|
@@ -202,9 +186,8 @@ export function createJavaAdapter(options = {}) {
|
|
|
202
186
|
continue;
|
|
203
187
|
}
|
|
204
188
|
const unit = read.value;
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
// root rather than per file.
|
|
189
|
+
// Build module/source set live on disk, not in the syntax — resolved
|
|
190
|
+
// and cached here, one `existsSync` walk per source root not per file.
|
|
208
191
|
const sourceRoot = sourceRootOf(file, unit.packageName);
|
|
209
192
|
let anchor = sourceRoot === undefined ? undefined : anchors.get(sourceRoot);
|
|
210
193
|
if (anchor === undefined && sourceRoot !== undefined) {
|
|
@@ -214,26 +197,23 @@ export function createJavaAdapter(options = {}) {
|
|
|
214
197
|
units.push({
|
|
215
198
|
...unit,
|
|
216
199
|
identityPackage: anchor === undefined
|
|
217
|
-
? //
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
// the resolver rather than hidden by a guess here.
|
|
200
|
+
? // Package declaration doesn't match the file's location; anchor
|
|
201
|
+
// on the package alone rather than invent a module — the
|
|
202
|
+
// resulting ambiguity is disclosed by the resolver, not guessed here.
|
|
221
203
|
unit.packageName === "" ? DEFAULT_PACKAGE : unit.packageName
|
|
222
204
|
: identityPackage(anchor, unit.packageName, DEFAULT_PACKAGE),
|
|
223
205
|
});
|
|
224
206
|
outcome.tree.delete();
|
|
225
207
|
}
|
|
226
|
-
// Every level
|
|
227
|
-
//
|
|
228
|
-
// no rung between 0 and the ceiling to fall back to.
|
|
208
|
+
// Every level here rests on the same parse — imports are in the source,
|
|
209
|
+
// so there's no rung between 0 and the ceiling to fall back to.
|
|
229
210
|
const reached = units.length === 0 ? 0 : ceiling;
|
|
230
211
|
session = { root: ctx.root, files, units, reached, failures, unfinished };
|
|
231
212
|
return reached;
|
|
232
213
|
},
|
|
233
214
|
async parseFiles(files) {
|
|
234
|
-
// Independent of `prepare` by contract
|
|
235
|
-
//
|
|
236
|
-
// placeholder otherwise, because the caller owns the file list.
|
|
215
|
+
// Independent of `prepare` by contract — R0 must work with nothing resolved.
|
|
216
|
+
// Empty placeholder when no parsed record exists; the caller owns the file list.
|
|
237
217
|
const byFile = new Map((session?.units ?? []).map((unit) => [unit.file, unit]));
|
|
238
218
|
return files.map((file) => ({ file, tree: byFile.get(file.path) ?? {} }));
|
|
239
219
|
},
|
|
@@ -290,8 +270,13 @@ export function hashOf(root, relative) {
|
|
|
290
270
|
try {
|
|
291
271
|
return createHash("sha256").update(readFileSync(join(root, relative))).digest("hex").slice(0, 32);
|
|
292
272
|
}
|
|
293
|
-
catch {
|
|
294
|
-
|
|
273
|
+
catch (error) {
|
|
274
|
+
// A read failure is disclosed, not hashed as "" — that would collide every
|
|
275
|
+
// unreadable file onto one value and hide a later readable/unreadable
|
|
276
|
+
// flip (C-F7). Can't equal a real 32-hex hash; keyed by path so two
|
|
277
|
+
// unreadable files never collide with each other.
|
|
278
|
+
const code = error instanceof Error && "code" in error ? String(error.code) : "UNKNOWN";
|
|
279
|
+
return `unreadable:${code}:${relative}`;
|
|
295
280
|
}
|
|
296
281
|
}
|
|
297
282
|
export { LANGUAGE, toRepoRelative };
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
CHANGED
|
@@ -1,103 +1,65 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The caller's half of the HTTP boundary: `USES_API`, golden pattern 08.
|
|
3
3
|
*
|
|
4
|
-
* `SERVES_API` is minted in `extract.ts` from a route's annotations
|
|
5
|
-
* the other end — an outbound call with a statically knowable path —
|
|
6
|
-
* the **same** `API_ENDPOINT` node from the same `endpointQsp`, so
|
|
7
|
-
* without either side knowing the other ran
|
|
8
|
-
* producers that mint different ids do not conflict, they silently fail to join.
|
|
4
|
+
* `SERVES_API` is minted in `extract.ts` from a route's annotations; this
|
|
5
|
+
* reads the other end — an outbound call with a statically knowable path —
|
|
6
|
+
* and mints the **same** `API_ENDPOINT` node from the same `endpointQsp`, so
|
|
7
|
+
* the two join without either side knowing the other ran (DEC-115).
|
|
9
8
|
*
|
|
10
9
|
* FUNCTION ──USES_API──▶ API_ENDPOINT ◀──SERVES_API── API_ROUTE
|
|
11
10
|
*
|
|
12
|
-
* ## What these edges
|
|
11
|
+
* ## What these edges mean
|
|
13
12
|
*
|
|
14
|
-
* Measured
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* is the **Verification status** axis (AI layer §20, §42), a separate axis from
|
|
24
|
-
* the confidence label. It is **not** service-to-service coupling, and a
|
|
25
|
-
* consumer reading it as "this service calls that service" would be wrong.
|
|
26
|
-
*
|
|
27
|
-
* The distinction therefore travels **in the edge**, as `attrs.callerKind`, not
|
|
28
|
-
* in a comment here. A count in a decision record is invisible to a consumer;
|
|
29
|
-
* `attrs` is what the edge carries. (`attrs` is not read above the IR — which is
|
|
30
|
-
* exactly why the same fact is also stated in the disclosure below, where a
|
|
31
|
-
* reader will see it.)
|
|
13
|
+
* Measured (`bench/client-call-census.mjs`, DEC-189): across `shopizer`,
|
|
14
|
+
* `mall`, `morphia`, `okhttp`, `spring-petclinic` there are 16 client call
|
|
15
|
+
* sites with a repo-relative literal path — 12 in test files, 4 on a mock
|
|
16
|
+
* transport, none production. So these edges are almost entirely
|
|
17
|
+
* `TEST_CASE`-shaped: integration tests driving `TestRestTemplate` at the
|
|
18
|
+
* app's own routes, useful for *Verification status* (which routes have
|
|
19
|
+
* integration coverage) — **not** service-to-service coupling. This travels
|
|
20
|
+
* in the edge as `attrs.callerKind`, since `attrs` (not comments) is what a
|
|
21
|
+
* consumer above the IR actually reads.
|
|
32
22
|
*
|
|
33
23
|
* ## Why the receiver's type is required
|
|
34
24
|
*
|
|
35
|
-
* `execute
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* The cost is disclosed rather than hidden: a chained builder
|
|
44
|
-
* (`new Request.Builder().url("/")`) has no receiver with a written type and is
|
|
45
|
-
* refused. All four such sites in the corpora are `mockWebServer`, so nothing
|
|
46
|
-
* real is lost today — but the refusal is a rule, not a measurement, and it will
|
|
47
|
-
* cost real call sites in a codebase that chains.
|
|
25
|
+
* `execute`/`put`/`delete`/`uri` are ordinary method names; admitting a call
|
|
26
|
+
* by name alone would wrongly emit `USES_API` for `list.put("/tmp/x")`. A
|
|
27
|
+
* call is admitted only when its receiver's **declared type** is a known
|
|
28
|
+
* client — R2 evidence, same as the rest of this adapter's receiver reads.
|
|
29
|
+
* Cost: a chained builder (`new Request.Builder().url("/")`) has no receiver
|
|
30
|
+
* with a written type and is refused — all 4 such sites in the corpora are
|
|
31
|
+
* `mockWebServer`, so nothing real is lost today, but a chaining codebase
|
|
32
|
+
* would lose real call sites to this rule.
|
|
48
33
|
*
|
|
49
34
|
* ## Ledger row D-FIX-3: a known client this reader does not extract
|
|
50
35
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* ### Why the trigger is receiver-type resolution, not a file-level import scan
|
|
76
|
-
*
|
|
77
|
-
* The population D-FIX-3 was scoped against is "a file that imports a known
|
|
78
|
-
* HTTP client and makes calls the extractor did not claim." Read literally,
|
|
79
|
-
* that would fire on **every** method call in a file that merely imports
|
|
80
|
-
* `okhttp3.OkHttpClient` anywhere — including calls with no relation to it —
|
|
81
|
-
* which is exactly the "fires on everything" failure the row warns against.
|
|
82
|
-
* This adapter already has a narrower, previously-measured discriminator for
|
|
83
|
-
* the identical question: `typeOfReceiver`, R2 evidence, a written declaration
|
|
84
|
-
* this reader can point at. Reusing it means the new population is *provably*
|
|
85
|
-
* bounded to calls whose receiver is declared as one of these types — no
|
|
86
|
-
* broader — and it costs nothing new: `writtenReceiverType` in `extract.ts`
|
|
87
|
-
* already resolves an arbitrary type name syntactically, whether or not this
|
|
88
|
-
* adapter goes on to model it, so `OkHttpClient` and `HttpClient` resolve
|
|
89
|
-
* exactly as `RestTemplate` does today.
|
|
90
|
-
*
|
|
91
|
-
* ### The reconciliation this row makes an assertion rather than a discipline
|
|
92
|
-
*
|
|
93
|
-
* `candidateClientRefs` (below) recomputes, independently of the loop in
|
|
94
|
-
* {@link clientCalls}, which references in a method are candidates at all —
|
|
95
|
-
* same predicate, factored out so a future edit to the loop cannot silently
|
|
96
|
-
* narrow what counts as a candidate without the test that calls both noticing.
|
|
36
|
+
* A call through a client this adapter doesn't recognise fell out of the loop
|
|
37
|
+
* via `continue` before any `refuse(...)` — zero edges and zero ledger rows,
|
|
38
|
+
* indistinguishable from a repo with no HTTP calls at all (the same shape
|
|
39
|
+
* Sherpa's TypeScript diagnosis found: 26 wrapped-`axios` sites across 14
|
|
40
|
+
* files, none reaching the refusal ledger).
|
|
41
|
+
*
|
|
42
|
+
* {@link BUILDER_CLIENT_TYPES} closes it for `okhttp3.OkHttpClient` and
|
|
43
|
+
* `java.net.http.HttpClient` (`bench/client-call-census.mjs`'s `CLIENTS.java`)
|
|
44
|
+
* — not by reading their calls (both pass the request as a separately
|
|
45
|
+
* constructed object, a different and larger extraction row, out of scope
|
|
46
|
+
* here), but by recognising the receiver type and filing a refusal for every
|
|
47
|
+
* call through it. Every call through one of these clients is now an edge or
|
|
48
|
+
* a ledger row, never neither.
|
|
49
|
+
*
|
|
50
|
+
* The trigger is receiver-type resolution (`typeOfReceiver`, R2 evidence),
|
|
51
|
+
* not a file-level import scan — a scan would fire on every call in a file
|
|
52
|
+
* that merely imports the client anywhere. Reusing `typeOfReceiver` bounds
|
|
53
|
+
* the population provably to calls whose receiver is declared as one of
|
|
54
|
+
* these types, at no extra cost: `writtenReceiverType` in `extract.ts`
|
|
55
|
+
* already resolves these names syntactically.
|
|
56
|
+
*
|
|
57
|
+
* `candidateClientRefs` (below) recomputes, independently of {@link
|
|
58
|
+
* clientCalls}'s loop, which references are candidates at all — factored out
|
|
59
|
+
* so a future edit to the loop can't silently narrow candidacy unnoticed.
|
|
97
60
|
* `test/client.test.ts` asserts `calls.length + refusals.length ===
|
|
98
|
-
* candidateClientRefs(method).length` on every fixture
|
|
99
|
-
*
|
|
100
|
-
* sites with no edge, no row, and no failing test.
|
|
61
|
+
* candidateClientRefs(method).length` on every fixture — DEC-098 found this
|
|
62
|
+
* missing the hard way, a guard that dropped 113 of 140 call sites silently.
|
|
101
63
|
*/
|
|
102
64
|
import { type IdentityScope, type IRNode } from "@descryy/ir";
|
|
103
65
|
import type { JavaMethod, JavaRef } from "./parse.ts";
|
|
@@ -120,52 +82,36 @@ export interface ClientRefusal {
|
|
|
120
82
|
readonly blockedBy: string | null;
|
|
121
83
|
/** DEC-242's `attrs.refusalClass` — `undefined` means unclassified, never askable. */
|
|
122
84
|
readonly refusalClass: BaseRefusalClass | "out-of-scope" | undefined;
|
|
123
|
-
/**
|
|
124
|
-
*
|
|
125
|
-
* own doc for what this is and why it is not shipped as part of the
|
|
126
|
-
* contract. Present only on the generic fallthrough of `diagnoseArgument`.
|
|
127
|
-
*/
|
|
85
|
+
/** Diagnostic only, not part of DEC-242 — see `adapter-rust/src/client.ts`.
|
|
86
|
+
* Present only on `diagnoseArgument`'s generic fallthrough. */
|
|
128
87
|
readonly argumentKind?: "field" | "call" | "concatenation" | "other";
|
|
129
88
|
}
|
|
130
89
|
export type BaseRefusalClass = "value-unknown" | "varies-per-call" | "capability-gap";
|
|
131
90
|
/**
|
|
132
|
-
* Every reference
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
* candidate here may still turn out to be a true silence in
|
|
143
|
-
* {@link clientCalls} if `typeOfReceiver` returns `undefined`. That is the
|
|
144
|
-
* one gap this reconciliation cannot close, and it is the same gap every
|
|
145
|
-
* other refusal ledger in this project discloses rather than guesses past:
|
|
146
|
-
* an unresolved receiver is not evidence the call is or is not a client.
|
|
91
|
+
* Every reference {@link clientCalls} will act on — an edge, a refusal, or a
|
|
92
|
+
* true silence past this point. Factored out so `test/client.test.ts`'s
|
|
93
|
+
* reconciliation assertion recomputes candidacy independently of the loop —
|
|
94
|
+
* a future edit that narrows the loop's filter fails the test instead of
|
|
95
|
+
* silently dropping sites, as DEC-098's `containerOf` guard once did.
|
|
96
|
+
*
|
|
97
|
+
* Receiver-type resolution is deliberately not done here (needs `extract.ts`'s
|
|
98
|
+
* scope tables) — a candidate may still be a true silence in
|
|
99
|
+
* {@link clientCalls} if `typeOfReceiver` returns `undefined`. An unresolved
|
|
100
|
+
* receiver is not evidence the call is or isn't a client.
|
|
147
101
|
*/
|
|
148
102
|
export declare function candidateClientRefs(method: JavaMethod): readonly (JavaRef & {
|
|
149
103
|
readonly receiver: string;
|
|
150
104
|
})[];
|
|
151
105
|
/**
|
|
152
|
-
* Read one method's calls for outbound HTTP.
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* and is supplied by the caller, because the scope rules for that live in
|
|
156
|
-
* `extract.ts` and a second copy of them would drift — the failure that
|
|
157
|
-
* `scopesFor`'s own header records.
|
|
106
|
+
* Read one method's calls for outbound HTTP. `typeOfReceiver` resolves a
|
|
107
|
+
* receiver to its declared type's simple name and is supplied by the caller
|
|
108
|
+
* — the scope rules live in `extract.ts`, and a second copy would drift.
|
|
158
109
|
*/
|
|
159
110
|
export declare function clientCalls(method: JavaMethod, fromId: string, typeOfReceiver: (name: string) => string | undefined, inTestSourceSet: boolean): {
|
|
160
111
|
readonly calls: readonly ClientCall[];
|
|
161
112
|
readonly refusals: readonly ClientRefusal[];
|
|
162
113
|
};
|
|
163
|
-
/**
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
* Shares `endpointQsp` with `extract.ts`'s `SERVES_API` block rather than
|
|
167
|
-
* recomputing the id, because the two must agree exactly and the failure when
|
|
168
|
-
* they do not is silent.
|
|
169
|
-
*/
|
|
114
|
+
/** The `API_ENDPOINT` a call joins to — minted identically to the route side,
|
|
115
|
+
* sharing `endpointQsp` with `extract.ts` since a mismatch fails silently. */
|
|
170
116
|
export declare function endpointFor(scope: IdentityScope, call: ClientCall, producedBy: string, normalise: (template: string) => string): IRNode;
|
|
171
117
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAEH,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnF,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AA0GtD,MAAM,WAAW,UAAU;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,gFAAgF;IAChF,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,sFAAsF;IACtF,QAAQ,CAAC,YAAY,EAAE,gBAAgB,GAAG,cAAc,GAAG,SAAS,CAAC;IACrE;oEACgE;IAChE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,eAAe,GAAG,OAAO,CAAC;CACtE;AAYD,MAAM,MAAM,gBAAgB,GAAG,eAAe,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAmEtF;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,GACjB,SAAS,CAAC,OAAO,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,CAQtD;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,EACpD,eAAe,EAAE,OAAO,GACvB;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,CAkJxF;AAED;+EAC+E;AAC/E,wBAAgB,WAAW,CACzB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GACtC,MAAM,CAaR"}
|