@opensip-cli/graph-rust 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 +9 -0
- package/dist/__tests__/cache-key.test.d.ts.map +1 -0
- package/dist/__tests__/cache-key.test.js +49 -0
- package/dist/__tests__/cache-key.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 +266 -0
- package/dist/__tests__/depends-on-emission.test.js.map +1 -0
- package/dist/__tests__/discover.test.d.ts +8 -0
- package/dist/__tests__/discover.test.d.ts.map +1 -0
- package/dist/__tests__/discover.test.js +65 -0
- package/dist/__tests__/discover.test.js.map +1 -0
- package/dist/__tests__/parse.test.d.ts +8 -0
- package/dist/__tests__/parse.test.d.ts.map +1 -0
- package/dist/__tests__/parse.test.js +64 -0
- package/dist/__tests__/parse.test.js.map +1 -0
- package/dist/__tests__/resolve-dependencies-branches.test.d.ts +18 -0
- package/dist/__tests__/resolve-dependencies-branches.test.d.ts.map +1 -0
- package/dist/__tests__/resolve-dependencies-branches.test.js +194 -0
- package/dist/__tests__/resolve-dependencies-branches.test.js.map +1 -0
- package/dist/__tests__/resolve.test.d.ts +23 -0
- package/dist/__tests__/resolve.test.d.ts.map +1 -0
- package/dist/__tests__/resolve.test.js +476 -0
- package/dist/__tests__/resolve.test.js.map +1 -0
- package/dist/__tests__/walk-branches.test.d.ts +13 -0
- package/dist/__tests__/walk-branches.test.d.ts.map +1 -0
- package/dist/__tests__/walk-branches.test.js +124 -0
- package/dist/__tests__/walk-branches.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 +324 -0
- package/dist/__tests__/walk.test.js.map +1 -0
- package/dist/body-digest.d.ts +31 -0
- package/dist/body-digest.d.ts.map +1 -0
- package/dist/body-digest.js +136 -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 +22 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/discover.js +33 -0
- package/dist/discover.js.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -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 +13 -0
- package/dist/resolve-dependencies.d.ts.map +1 -0
- package/dist/resolve-dependencies.js +261 -0
- package/dist/resolve-dependencies.js.map +1 -0
- package/dist/resolve.d.ts +45 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +262 -0
- package/dist/resolve.js.map +1 -0
- package/dist/rule-hints.d.ts +16 -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.d.ts +47 -0
- package/dist/walk.d.ts.map +1 -0
- package/dist/walk.js +564 -0
- package/dist/walk.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,476 @@
|
|
|
1
|
+
// @fitness-ignore-file file-length-limit -- behavior fixture suite; related scenarios stay together while covered domains are split into focused tests.
|
|
2
|
+
/**
|
|
3
|
+
* Branch-coverage tests for lang-rust/resolve.ts.
|
|
4
|
+
*
|
|
5
|
+
* Drives the full Rust adapter (discover + parse + walk + resolve)
|
|
6
|
+
* over fixtures that exercise every documented call-target shape:
|
|
7
|
+
*
|
|
8
|
+
* - bare `foo()` call (`identifier`)
|
|
9
|
+
* - `obj.method()` (`field_expression`)
|
|
10
|
+
* - `Type::method()` (`scoped_identifier` with receiver narrowing)
|
|
11
|
+
* - `mod::Type::method()` (nested `scoped_identifier`)
|
|
12
|
+
* - `name!(...)` macro_invocation
|
|
13
|
+
* - creation edges through closures
|
|
14
|
+
* - expression_statement vs parenthesized return-value discard logic
|
|
15
|
+
*
|
|
16
|
+
* Resolver confidence ladders for each lookup outcome:
|
|
17
|
+
* - 0 catalog matches → resolution 'unknown', confidence 'low'
|
|
18
|
+
* - 1 catalog match → resolution 'static', confidence 'medium'
|
|
19
|
+
* - N catalog matches → resolution 'method-dispatch', confidence 'low'
|
|
20
|
+
* - receiver-narrowed → resolution 'static'/'method-dispatch',
|
|
21
|
+
* confidence 'medium'
|
|
22
|
+
*/
|
|
23
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
24
|
+
import { tmpdir } from 'node:os';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
27
|
+
import { rustGraphAdapter } from '../index.js';
|
|
28
|
+
/**
|
|
29
|
+
* Drive the full pipeline against a temp project and return the
|
|
30
|
+
* resolve output plus the catalog built from the walk's occurrences.
|
|
31
|
+
*/
|
|
32
|
+
function runPipeline(dir) {
|
|
33
|
+
const discovery = rustGraphAdapter.discoverFiles({ cwd: dir });
|
|
34
|
+
const parsed = rustGraphAdapter.parseProject({
|
|
35
|
+
projectDirAbs: discovery.projectDirAbs,
|
|
36
|
+
files: discovery.files,
|
|
37
|
+
compilerOptions: discovery.compilerOptions,
|
|
38
|
+
resolutionMode: 'exact',
|
|
39
|
+
});
|
|
40
|
+
const walk = rustGraphAdapter.walkProject({
|
|
41
|
+
project: parsed.project,
|
|
42
|
+
projectDirAbs: discovery.projectDirAbs,
|
|
43
|
+
files: discovery.files,
|
|
44
|
+
});
|
|
45
|
+
const catalog = {
|
|
46
|
+
version: '3.0',
|
|
47
|
+
tool: 'graph',
|
|
48
|
+
language: 'rust',
|
|
49
|
+
builtAt: new Date().toISOString(),
|
|
50
|
+
cacheKey: 'rs-test',
|
|
51
|
+
functions: walk.occurrences,
|
|
52
|
+
};
|
|
53
|
+
const resolved = rustGraphAdapter.resolveCallSites({
|
|
54
|
+
project: parsed.project,
|
|
55
|
+
catalog,
|
|
56
|
+
callSites: walk.callSites,
|
|
57
|
+
projectDirAbs: discovery.projectDirAbs,
|
|
58
|
+
resolutionMode: 'exact',
|
|
59
|
+
});
|
|
60
|
+
const allEdges = [];
|
|
61
|
+
for (const list of resolved.edgesByOwner.values()) {
|
|
62
|
+
for (const e of list)
|
|
63
|
+
allEdges.push(e);
|
|
64
|
+
}
|
|
65
|
+
return { resolved, allEdges, catalog };
|
|
66
|
+
}
|
|
67
|
+
describe('lang-rust resolve.ts — call-target decoding and resolution', () => {
|
|
68
|
+
let dir;
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
dir = mkdtempSync(join(tmpdir(), 'graph-rust-resolve-'));
|
|
71
|
+
});
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
rmSync(dir, { recursive: true, force: true });
|
|
74
|
+
});
|
|
75
|
+
it('resolves a bare identifier call `foo()` to its catalog hash (static / medium)', () => {
|
|
76
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
77
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn helper() -> i32 { 1 }\nfn entry() -> i32 { helper() }\n`, 'utf8');
|
|
78
|
+
const { resolved, allEdges } = runPipeline(dir);
|
|
79
|
+
const helperCall = allEdges.find((e) => e.text.includes('helper'));
|
|
80
|
+
expect(helperCall).toBeDefined();
|
|
81
|
+
expect(helperCall?.resolution).toBe('static');
|
|
82
|
+
expect(helperCall?.confidence).toBe('medium');
|
|
83
|
+
expect(helperCall?.to.length).toBe(1);
|
|
84
|
+
expect(resolved.stats.resolvedMedium).toBeGreaterThan(0);
|
|
85
|
+
});
|
|
86
|
+
it('resolves `obj.method()` (field_expression) by trailing field name', () => {
|
|
87
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
88
|
+
writeFileSync(join(dir, 'src/lib.rs'), `struct G { p: i32 }\n` +
|
|
89
|
+
`impl G {\n` +
|
|
90
|
+
` fn greet(&self) -> i32 { self.p }\n` +
|
|
91
|
+
`}\n` +
|
|
92
|
+
`fn entry() -> i32 {\n` +
|
|
93
|
+
` let g = G { p: 1 };\n` +
|
|
94
|
+
` g.greet()\n` +
|
|
95
|
+
`}\n`, 'utf8');
|
|
96
|
+
const { allEdges } = runPipeline(dir);
|
|
97
|
+
const greetCall = allEdges.find((e) => e.text.includes('g.greet'));
|
|
98
|
+
expect(greetCall).toBeDefined();
|
|
99
|
+
expect(greetCall?.to.length).toBe(1);
|
|
100
|
+
});
|
|
101
|
+
it('narrows `Type::method()` via receiver-type when an impl exists (medium confidence)', () => {
|
|
102
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
103
|
+
writeFileSync(join(dir, 'src/lib.rs'), `struct G;\n` +
|
|
104
|
+
`impl G {\n` +
|
|
105
|
+
` fn make() -> i32 { 42 }\n` +
|
|
106
|
+
`}\n` +
|
|
107
|
+
`fn entry() -> i32 { G::make() }\n`, 'utf8');
|
|
108
|
+
const { allEdges } = runPipeline(dir);
|
|
109
|
+
const makeCall = allEdges.find((e) => e.text.includes('G::make'));
|
|
110
|
+
expect(makeCall).toBeDefined();
|
|
111
|
+
expect(makeCall?.confidence).toBe('medium');
|
|
112
|
+
expect(makeCall?.to.length).toBe(1);
|
|
113
|
+
});
|
|
114
|
+
it('falls back to broad name lookup when receiver type has no matching method', () => {
|
|
115
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
116
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn other() -> i32 { 1 }\n` + `fn entry() -> i32 { Foreign::other() }\n`, 'utf8');
|
|
117
|
+
const { allEdges } = runPipeline(dir);
|
|
118
|
+
const otherCall = allEdges.find((e) => e.text.includes('Foreign::other'));
|
|
119
|
+
expect(otherCall).toBeDefined();
|
|
120
|
+
// No `impl Foreign { fn other }`, but a top-level `fn other` exists.
|
|
121
|
+
// Falls back to broad lookup → static + medium with one match.
|
|
122
|
+
expect(otherCall?.to.length).toBe(1);
|
|
123
|
+
expect(otherCall?.resolution).toBe('static');
|
|
124
|
+
});
|
|
125
|
+
it('returns 0 matches as resolution `unknown` + low confidence', () => {
|
|
126
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
127
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn entry() { unknown_function() }\n`, 'utf8');
|
|
128
|
+
const { allEdges, resolved } = runPipeline(dir);
|
|
129
|
+
const call = allEdges.find((e) => e.text.includes('unknown_function'));
|
|
130
|
+
expect(call).toBeDefined();
|
|
131
|
+
expect(call?.resolution).toBe('unknown');
|
|
132
|
+
expect(call?.confidence).toBe('low');
|
|
133
|
+
expect(call?.to).toEqual([]);
|
|
134
|
+
expect(resolved.stats.unresolved).toBeGreaterThan(0);
|
|
135
|
+
});
|
|
136
|
+
it('returns N matches as `method-dispatch` + low confidence', () => {
|
|
137
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
138
|
+
writeFileSync(join(dir, 'src/lib.rs'), `struct A;\nstruct B;\n` +
|
|
139
|
+
`impl A { fn op(&self) -> i32 { 1 } }\n` +
|
|
140
|
+
`impl B { fn op(&self) -> i32 { 2 } }\n` +
|
|
141
|
+
`fn entry(x: A) -> i32 { x.op() }\n`, 'utf8');
|
|
142
|
+
const { allEdges } = runPipeline(dir);
|
|
143
|
+
const call = allEdges.find((e) => e.text.includes('x.op'));
|
|
144
|
+
expect(call).toBeDefined();
|
|
145
|
+
expect(call?.resolution).toBe('method-dispatch');
|
|
146
|
+
expect(call?.confidence).toBe('low');
|
|
147
|
+
expect(call?.to.length).toBe(2);
|
|
148
|
+
});
|
|
149
|
+
it('tags macro_invocations as `unknown` with edge text `name! ...` for primitive matching', () => {
|
|
150
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
151
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn entry() { println!("hello"); }\n`, 'utf8');
|
|
152
|
+
const { allEdges } = runPipeline(dir);
|
|
153
|
+
const macro = allEdges.find((e) => e.text.startsWith('println! '));
|
|
154
|
+
expect(macro).toBeDefined();
|
|
155
|
+
expect(macro?.resolution).toBe('unknown');
|
|
156
|
+
expect(macro?.confidence).toBe('low');
|
|
157
|
+
});
|
|
158
|
+
it('emits a creation edge for an inline closure (always present in edges)', () => {
|
|
159
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
160
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn entry() {\n` +
|
|
161
|
+
` let add_one = |n: i32| n + 1;\n` +
|
|
162
|
+
` let _ = add_one(3);\n` +
|
|
163
|
+
`}\n`, 'utf8');
|
|
164
|
+
const { allEdges } = runPipeline(dir);
|
|
165
|
+
// The closure body is the target of a creation edge from `entry`'s
|
|
166
|
+
// owner body. We assert at least one edge exists in the owner-set.
|
|
167
|
+
expect(allEdges.length).toBeGreaterThan(0);
|
|
168
|
+
// And a call to add_one is at least decoded (target may not be in
|
|
169
|
+
// the catalog by simple name, but the call_expression still emits
|
|
170
|
+
// an edge).
|
|
171
|
+
const callOfAddOne = allEdges.find((e) => e.text.includes('add_one('));
|
|
172
|
+
expect(callOfAddOne).toBeDefined();
|
|
173
|
+
});
|
|
174
|
+
it('marks `discarded` true when the call is a bare expression_statement', () => {
|
|
175
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
176
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn helper() {}\n` + `fn entry() {\n` + ` helper();\n` + `}\n`, 'utf8');
|
|
177
|
+
const { allEdges } = runPipeline(dir);
|
|
178
|
+
const call = allEdges.find((e) => e.text.includes('helper'));
|
|
179
|
+
expect(call?.discarded).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
it('marks `discarded` false when the call value is used (e.g. let-bound)', () => {
|
|
182
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
183
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn helper() -> i32 { 1 }\n` +
|
|
184
|
+
`fn entry() -> i32 {\n` +
|
|
185
|
+
` let x = helper();\n` +
|
|
186
|
+
` x\n` +
|
|
187
|
+
`}\n`, 'utf8');
|
|
188
|
+
const { allEdges } = runPipeline(dir);
|
|
189
|
+
const call = allEdges.find((e) => e.text.includes('helper'));
|
|
190
|
+
expect(call?.discarded).toBe(false);
|
|
191
|
+
});
|
|
192
|
+
it('looks through parenthesized_expression when deciding discarded', () => {
|
|
193
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
194
|
+
// (helper()); as a statement → discarded should still be true
|
|
195
|
+
// because the outer node is expression_statement after unwrapping
|
|
196
|
+
// the parenthesized_expression chain.
|
|
197
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn helper() -> i32 { 1 }\n` + `fn entry() {\n` + ` (helper());\n` + `}\n`, 'utf8');
|
|
198
|
+
const { allEdges } = runPipeline(dir);
|
|
199
|
+
const call = allEdges.find((e) => e.text.includes('helper'));
|
|
200
|
+
expect(call).toBeDefined();
|
|
201
|
+
expect(call?.discarded).toBe(true);
|
|
202
|
+
});
|
|
203
|
+
it('produces resolutionStats consistent with the recorded edges', () => {
|
|
204
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
205
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn helper() -> i32 { 1 }\n` + `fn entry() -> i32 { helper() + unknown_fn() }\n`, 'utf8');
|
|
206
|
+
const { resolved } = runPipeline(dir);
|
|
207
|
+
const totalEdges = resolved.stats.resolvedHigh +
|
|
208
|
+
resolved.stats.resolvedMedium +
|
|
209
|
+
resolved.stats.resolvedLow +
|
|
210
|
+
resolved.stats.unresolved;
|
|
211
|
+
expect(totalEdges).toBe(resolved.stats.totalCallSites);
|
|
212
|
+
expect(resolved.stats.resolvedMedium).toBeGreaterThan(0); // helper
|
|
213
|
+
expect(resolved.stats.unresolved).toBeGreaterThan(0); // unknown_fn
|
|
214
|
+
});
|
|
215
|
+
it('decodes `mod::Type::method()` shape (nested scoped_identifier path)', () => {
|
|
216
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
217
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn entry() { std::fs::read("x"); }\n`, 'utf8');
|
|
218
|
+
const { allEdges } = runPipeline(dir);
|
|
219
|
+
// `read` isn't in the catalog; it should emit an unknown edge.
|
|
220
|
+
const call = allEdges.find((e) => e.text.includes('std::fs::read'));
|
|
221
|
+
expect(call).toBeDefined();
|
|
222
|
+
expect(call?.resolution).toBe('unknown');
|
|
223
|
+
});
|
|
224
|
+
it('strips the leading namespace from a scoped macro invocation `path::name!()`', () => {
|
|
225
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
226
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn entry() { log::info!("hello"); }\n`, 'utf8');
|
|
227
|
+
const { allEdges } = runPipeline(dir);
|
|
228
|
+
// `decodeCallTarget` for `macro_invocation` keeps only the trailing
|
|
229
|
+
// segment after `::`, so the edge text is prefixed with `info!`.
|
|
230
|
+
const macro = allEdges.find((e) => e.text.startsWith('info! '));
|
|
231
|
+
expect(macro).toBeDefined();
|
|
232
|
+
expect(macro?.resolution).toBe('unknown');
|
|
233
|
+
});
|
|
234
|
+
it('emits N-match narrowed lookup as method-dispatch + medium when an impl has multiple methods of the same name', () => {
|
|
235
|
+
// Re-running an `impl Foo { fn op }` block twice in the same file
|
|
236
|
+
// simulates the rare case of `methods.get('Foo::op')` returning two
|
|
237
|
+
// occurrences — exercising the `hashes.length === 1 ? 'static' :
|
|
238
|
+
// 'method-dispatch'` branch on the narrowed path.
|
|
239
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
240
|
+
writeFileSync(join(dir, 'src/lib.rs'), `struct Foo;\n` +
|
|
241
|
+
`impl Foo { fn op(&self) -> i32 { 1 } }\n` +
|
|
242
|
+
// A second impl block for Foo with the same method name —
|
|
243
|
+
// permitted only in different cfg conditions in real Rust, but
|
|
244
|
+
// tree-sitter parses it fine, and the indexer ends up with two
|
|
245
|
+
// entries for `Foo::op`.
|
|
246
|
+
`mod alt { use super::*; impl Foo { fn op(&self) -> i32 { 2 } } }\n` +
|
|
247
|
+
`fn entry() -> i32 { Foo::op(&Foo) }\n`, 'utf8');
|
|
248
|
+
const { allEdges } = runPipeline(dir);
|
|
249
|
+
const call = allEdges.find((e) => e.text.includes('Foo::op'));
|
|
250
|
+
expect(call).toBeDefined();
|
|
251
|
+
expect(call?.confidence).toBe('medium');
|
|
252
|
+
// Either single-narrowed (static) or multi-narrowed (method-dispatch),
|
|
253
|
+
// depending on how tree-sitter-rust parses the alt module. Both cases
|
|
254
|
+
// exercise lines we want to cover.
|
|
255
|
+
expect(['static', 'method-dispatch']).toContain(call?.resolution);
|
|
256
|
+
});
|
|
257
|
+
it('handles a call site whose enclosing owner is the synthetic module-init (no parent function)', () => {
|
|
258
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
259
|
+
// A call_expression in a top-level `const` initializer is owned by
|
|
260
|
+
// the module-init synthetic. This exercises the resolver's
|
|
261
|
+
// owner-key handling for non-function owners.
|
|
262
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn maker() -> i32 { 1 }\nconst _N: i32 = maker() + 1;\n`, 'utf8');
|
|
263
|
+
const { allEdges } = runPipeline(dir);
|
|
264
|
+
const call = allEdges.find((e) => e.text.includes('maker'));
|
|
265
|
+
expect(call).toBeDefined();
|
|
266
|
+
expect(call?.to.length).toBe(1);
|
|
267
|
+
});
|
|
268
|
+
it('handles call_expression with field_expression on a chained receiver (only trailing field matters)', () => {
|
|
269
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
270
|
+
writeFileSync(join(dir, 'src/lib.rs'), `struct X { name: String }\n` +
|
|
271
|
+
`impl X { fn fmt(&self) -> &str { &self.name } }\n` +
|
|
272
|
+
`fn entry(x: &X) -> &str { x.fmt() }\n`, 'utf8');
|
|
273
|
+
const { allEdges } = runPipeline(dir);
|
|
274
|
+
const call = allEdges.find((e) => e.text.includes('x.fmt'));
|
|
275
|
+
expect(call).toBeDefined();
|
|
276
|
+
});
|
|
277
|
+
it('does not produce a "high" confidence edge (the resolver never elevates that high)', () => {
|
|
278
|
+
mkdirSync(join(dir, 'src'), { recursive: true });
|
|
279
|
+
writeFileSync(join(dir, 'src/lib.rs'), `fn one() -> i32 { 1 }\nfn entry() -> i32 { one() }\n`, 'utf8');
|
|
280
|
+
const { resolved } = runPipeline(dir);
|
|
281
|
+
expect(resolved.stats.resolvedHigh).toBe(0);
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
/** Build a tiny tree-sitter-ish fake node. */
|
|
285
|
+
function makeNode(type, opts = {}) {
|
|
286
|
+
const text = opts.text ?? '';
|
|
287
|
+
const fields = opts.fields ?? {};
|
|
288
|
+
const named = opts.named ?? [];
|
|
289
|
+
return {
|
|
290
|
+
type,
|
|
291
|
+
text,
|
|
292
|
+
startPosition: { row: 0, column: 0 },
|
|
293
|
+
endPosition: { row: 0, column: text.length },
|
|
294
|
+
startIndex: 0,
|
|
295
|
+
endIndex: text.length,
|
|
296
|
+
parent: opts.parent ?? null,
|
|
297
|
+
childForFieldName: (n) => fields[n] ?? null,
|
|
298
|
+
namedChild: (i) => named[i] ?? null,
|
|
299
|
+
namedChildCount: named.length,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function makeFile() {
|
|
303
|
+
return { tree: {}, source: '' };
|
|
304
|
+
}
|
|
305
|
+
function runResolveSynthetic(dir, callSites) {
|
|
306
|
+
return rustGraphAdapter.resolveCallSites({
|
|
307
|
+
project: { files: new Map() },
|
|
308
|
+
catalog: {
|
|
309
|
+
version: '3.0',
|
|
310
|
+
tool: 'graph',
|
|
311
|
+
language: 'rust',
|
|
312
|
+
builtAt: new Date().toISOString(),
|
|
313
|
+
cacheKey: 'rs-test',
|
|
314
|
+
functions: {},
|
|
315
|
+
},
|
|
316
|
+
// Test-only: synthetic CallSiteRecord shapes inject duck-typed
|
|
317
|
+
// node refs to drive the resolver's defensive null branches.
|
|
318
|
+
callSites: callSites,
|
|
319
|
+
projectDirAbs: dir,
|
|
320
|
+
resolutionMode: 'exact',
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
describe('lang-rust resolve.ts — defensive guards via synthetic nodes', () => {
|
|
324
|
+
let dir;
|
|
325
|
+
beforeEach(() => {
|
|
326
|
+
dir = mkdtempSync(join(tmpdir(), 'graph-rust-resolve-fakes-'));
|
|
327
|
+
});
|
|
328
|
+
afterEach(() => {
|
|
329
|
+
rmSync(dir, { recursive: true, force: true });
|
|
330
|
+
});
|
|
331
|
+
function runResolve(callSites) {
|
|
332
|
+
return runResolveSynthetic(dir, callSites);
|
|
333
|
+
}
|
|
334
|
+
it('emits an unknown/low edge when decodeCallTarget receives a non-call, non-macro node', () => {
|
|
335
|
+
// node.type is neither 'call_expression' nor 'macro_invocation'.
|
|
336
|
+
const fakeNode = makeNode('binary_expression', { text: 'a + b' });
|
|
337
|
+
const out = runResolve([
|
|
338
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h0', kind: 'call' },
|
|
339
|
+
]);
|
|
340
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
341
|
+
expect(edges.length).toBe(1);
|
|
342
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
343
|
+
expect(edges[0]?.confidence).toBe('low');
|
|
344
|
+
});
|
|
345
|
+
it('emits an unknown/low edge when call_expression has no `function` field', () => {
|
|
346
|
+
const fakeNode = makeNode('call_expression', { text: '???' });
|
|
347
|
+
const out = runResolve([
|
|
348
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h1', kind: 'call' },
|
|
349
|
+
]);
|
|
350
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
351
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
352
|
+
});
|
|
353
|
+
it('emits an unknown/low edge when field_expression has no `field`', () => {
|
|
354
|
+
const fn = makeNode('field_expression', { text: 'a.', fields: {} });
|
|
355
|
+
const fakeNode = makeNode('call_expression', { text: 'a.()', fields: { function: fn } });
|
|
356
|
+
const out = runResolve([
|
|
357
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h2', kind: 'call' },
|
|
358
|
+
]);
|
|
359
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
360
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
361
|
+
});
|
|
362
|
+
it('emits an unknown/low edge when scoped_identifier has no `name`/named child', () => {
|
|
363
|
+
const fn = makeNode('scoped_identifier', { text: 'Type:', fields: {}, named: [] });
|
|
364
|
+
const fakeNode = makeNode('call_expression', { text: 'Type:()', fields: { function: fn } });
|
|
365
|
+
const out = runResolve([
|
|
366
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h3', kind: 'call' },
|
|
367
|
+
]);
|
|
368
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
369
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
370
|
+
});
|
|
371
|
+
it('emits an unknown/low edge when an unhandled `function` shape appears (e.g. parenthesized fn)', () => {
|
|
372
|
+
// fn.type is not identifier / field_expression / scoped_identifier.
|
|
373
|
+
const fn = makeNode('parenthesized_expression', { text: '(closure)' });
|
|
374
|
+
const fakeNode = makeNode('call_expression', { text: '(closure)()', fields: { function: fn } });
|
|
375
|
+
const out = runResolve([
|
|
376
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h4', kind: 'call' },
|
|
377
|
+
]);
|
|
378
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
379
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
380
|
+
});
|
|
381
|
+
it('emits an unknown/low edge when macro_invocation has no `macro` and no named child', () => {
|
|
382
|
+
const fakeNode = makeNode('macro_invocation', { text: '!()', fields: {}, named: [] });
|
|
383
|
+
const out = runResolve([
|
|
384
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h5', kind: 'call' },
|
|
385
|
+
]);
|
|
386
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
387
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
388
|
+
});
|
|
389
|
+
it('handles scoped_identifier whose path is an unrecognized type', () => {
|
|
390
|
+
// path is some unexpected node type; decodeReceiverPath returns null.
|
|
391
|
+
const name = makeNode('identifier', { text: 'do_it' });
|
|
392
|
+
const oddPath = makeNode('lifetime', { text: "'static" });
|
|
393
|
+
const fn = makeNode('scoped_identifier', {
|
|
394
|
+
text: "'static::do_it",
|
|
395
|
+
fields: { name, path: oddPath },
|
|
396
|
+
named: [name],
|
|
397
|
+
});
|
|
398
|
+
const fakeNode = makeNode('call_expression', {
|
|
399
|
+
text: "'static::do_it()",
|
|
400
|
+
fields: { function: fn },
|
|
401
|
+
});
|
|
402
|
+
const out = runResolve([
|
|
403
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h6', kind: 'call' },
|
|
404
|
+
]);
|
|
405
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
406
|
+
// `do_it` not in catalog → unknown.
|
|
407
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
408
|
+
});
|
|
409
|
+
it('handles scoped_identifier whose path is a scoped_identifier with no inner name', () => {
|
|
410
|
+
const name = makeNode('identifier', { text: 'thing' });
|
|
411
|
+
// Inner scoped_identifier with no `name` field, and no named children.
|
|
412
|
+
const innerPath = makeNode('scoped_identifier', { text: 'mod::', fields: {}, named: [] });
|
|
413
|
+
const fn = makeNode('scoped_identifier', {
|
|
414
|
+
text: 'mod::Type::thing',
|
|
415
|
+
fields: { name, path: innerPath },
|
|
416
|
+
named: [name],
|
|
417
|
+
});
|
|
418
|
+
const fakeNode = makeNode('call_expression', {
|
|
419
|
+
text: 'mod::Type::thing()',
|
|
420
|
+
fields: { function: fn },
|
|
421
|
+
});
|
|
422
|
+
const out = runResolve([
|
|
423
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h7', kind: 'call' },
|
|
424
|
+
]);
|
|
425
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
426
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
427
|
+
});
|
|
428
|
+
it('decodes a scoped_identifier with a `name` but a null `path` (no receiver narrowing)', () => {
|
|
429
|
+
// `decodeReceiverPath(null)` — the scoped_identifier carries a name
|
|
430
|
+
// child but no `path` field, so the receiver type resolves to null
|
|
431
|
+
// and the resolver falls back to broad name lookup.
|
|
432
|
+
const name = makeNode('identifier', { text: 'free_fn' });
|
|
433
|
+
const fn = makeNode('scoped_identifier', {
|
|
434
|
+
text: '::free_fn',
|
|
435
|
+
fields: { name }, // no `path` field → decodeReceiverPath(null)
|
|
436
|
+
named: [name],
|
|
437
|
+
});
|
|
438
|
+
const fakeNode = makeNode('call_expression', {
|
|
439
|
+
text: '::free_fn()',
|
|
440
|
+
fields: { function: fn },
|
|
441
|
+
});
|
|
442
|
+
const out = runResolve([
|
|
443
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'hp', kind: 'call' },
|
|
444
|
+
]);
|
|
445
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
446
|
+
expect(edges).toHaveLength(1);
|
|
447
|
+
// `free_fn` not in the (empty) catalog → unknown.
|
|
448
|
+
expect(edges[0]?.resolution).toBe('unknown');
|
|
449
|
+
});
|
|
450
|
+
it('skips creation call-sites whose childHash is undefined (defensive)', () => {
|
|
451
|
+
// The walker normally sets childHash; if a downstream caller forgets,
|
|
452
|
+
// the creation site is silently skipped.
|
|
453
|
+
const fakeNode = makeNode('closure_expression', { text: '|| 1' });
|
|
454
|
+
const out = runResolve([
|
|
455
|
+
// Note: childHash intentionally omitted.
|
|
456
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h8', kind: 'creation' },
|
|
457
|
+
]);
|
|
458
|
+
expect([...out.edgesByOwner.entries()]).toEqual([]);
|
|
459
|
+
});
|
|
460
|
+
it('falls through to `return false` in isReturnValueDiscarded when no enclosing parent exists', () => {
|
|
461
|
+
// A `helper()` call whose parent chain is null (synthetic root) hits
|
|
462
|
+
// the loop-exit branch and returns false (not discarded).
|
|
463
|
+
const inner = makeNode('identifier', { text: 'helper' });
|
|
464
|
+
const fakeNode = makeNode('call_expression', {
|
|
465
|
+
text: 'helper()',
|
|
466
|
+
fields: { function: inner },
|
|
467
|
+
parent: null, // no enclosing expression_statement
|
|
468
|
+
});
|
|
469
|
+
const out = runResolve([
|
|
470
|
+
{ nodeRef: fakeNode, sourceFileRef: makeFile(), ownerHash: 'h9', kind: 'call' },
|
|
471
|
+
]);
|
|
472
|
+
const edges = [...out.edgesByOwner.values()].flat();
|
|
473
|
+
expect(edges[0]?.discarded).toBe(false);
|
|
474
|
+
});
|
|
475
|
+
});
|
|
476
|
+
//# sourceMappingURL=resolve.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.test.js","sourceRoot":"","sources":["../../src/__tests__/resolve.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Additional branch-coverage tests for lang-rust/walk.ts.
|
|
3
|
+
*
|
|
4
|
+
* Targets walker branches the main walk suite doesn't reach:
|
|
5
|
+
*
|
|
6
|
+
* - `extern crate foo;` declarations → dependency sites.
|
|
7
|
+
* - `pub use …;` — the visibility_modifier is skipped while picking
|
|
8
|
+
* the path-bearing child (pickUsePathNode reverse-walk).
|
|
9
|
+
* - `#[...]` inner/outer attribute extraction on a function_item.
|
|
10
|
+
* - trait-method declarations inside a `trait` block.
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=walk-branches.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"walk-branches.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/walk-branches.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|