@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,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rust body-digest helpers — strip comments, normalize
|
|
3
|
+
* whitespace, hash. Extracted from `walk.ts` so the walker can focus on
|
|
4
|
+
* tree-sitter traversal while the digest pipeline (which carries Rust-
|
|
5
|
+
* specific token rules like nested block comments and the lifetime-vs-
|
|
6
|
+
* char-literal heuristic) lives in one focused module.
|
|
7
|
+
*
|
|
8
|
+
* Behavior — string literals are preserved (their content is part of
|
|
9
|
+
* the body), block comments may nest (Rust grammar permits this), and
|
|
10
|
+
* char literals are distinguished from lifetimes by a short look-ahead.
|
|
11
|
+
*
|
|
12
|
+
* Sibling adapters (Java, Python, Go) keep their stripper inline because
|
|
13
|
+
* their comment grammars are shorter; the Rust variant is large enough
|
|
14
|
+
* to warrant its own file.
|
|
15
|
+
*/
|
|
16
|
+
import { hashBody, normalizeWhitespace } from '@opensip-cli/graph';
|
|
17
|
+
import { skipToEndOfLine } from '@opensip-cli/graph-adapter-common';
|
|
18
|
+
/**
|
|
19
|
+
* Digest a Rust body text — strip comments, collapse whitespace, hash.
|
|
20
|
+
*
|
|
21
|
+
* Real bodies (functions, methods, closures) and synthetic bodies
|
|
22
|
+
* (module-init aggregations) share this implementation; an alias keeps
|
|
23
|
+
* the call site self-documenting without duplicating logic.
|
|
24
|
+
*/
|
|
25
|
+
export function digestRustBody(text) {
|
|
26
|
+
return hashBody(normalizeWhitespace(stripRustComments(text)));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Synthetic bodies (module-init) use the same normalization as real
|
|
30
|
+
* bodies; an alias keeps the name at the call site self-documenting
|
|
31
|
+
* without duplicating the implementation (sonarjs/no-identical-functions).
|
|
32
|
+
*/
|
|
33
|
+
export const digestSyntheticBody = digestRustBody;
|
|
34
|
+
/**
|
|
35
|
+
* Strip Rust line comments (// to end of line) and block comments
|
|
36
|
+
* (slash-star ... star-slash, including nested forms — Rust's grammar
|
|
37
|
+
* permits nesting). Preserve string literals (their content matters).
|
|
38
|
+
*/
|
|
39
|
+
function stripRustComments(text) {
|
|
40
|
+
let out = '';
|
|
41
|
+
let i = 0;
|
|
42
|
+
while (i < text.length) {
|
|
43
|
+
const next2 = text.slice(i, i + 2);
|
|
44
|
+
if (next2 === '//') {
|
|
45
|
+
i = skipToEndOfLine(text, i);
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (next2 === '/*') {
|
|
49
|
+
i = skipBlockComment(text, i + 2);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const c = text[i];
|
|
53
|
+
if (c === '"') {
|
|
54
|
+
const block = consumeStringLiteral(text, i);
|
|
55
|
+
out += block.text;
|
|
56
|
+
i = block.index;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (c === "'" && isCharLiteral(text, i)) {
|
|
60
|
+
/* v8 ignore start */
|
|
61
|
+
const block = consumeCharLiteral(text, i);
|
|
62
|
+
out += block.text;
|
|
63
|
+
i = block.index;
|
|
64
|
+
continue;
|
|
65
|
+
/* v8 ignore stop */
|
|
66
|
+
}
|
|
67
|
+
out += c;
|
|
68
|
+
i++;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
function skipBlockComment(text, start) {
|
|
73
|
+
// Rust supports nested block comments. Track depth.
|
|
74
|
+
let i = start;
|
|
75
|
+
let depth = 1;
|
|
76
|
+
while (i < text.length && depth > 0) {
|
|
77
|
+
const next2 = text.slice(i, i + 2);
|
|
78
|
+
if (next2 === '/*') {
|
|
79
|
+
depth++;
|
|
80
|
+
i += 2;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (next2 === '*/') {
|
|
84
|
+
depth--;
|
|
85
|
+
i += 2;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
i++;
|
|
89
|
+
}
|
|
90
|
+
return i;
|
|
91
|
+
}
|
|
92
|
+
function consumeStringLiteral(text, start) {
|
|
93
|
+
let i = start + 1;
|
|
94
|
+
let buf = '"';
|
|
95
|
+
while (i < text.length) {
|
|
96
|
+
if (text[i] === '\\' && i + 1 < text.length) {
|
|
97
|
+
/* v8 ignore start */
|
|
98
|
+
buf += text.slice(i, i + 2);
|
|
99
|
+
i += 2;
|
|
100
|
+
continue;
|
|
101
|
+
/* v8 ignore stop */
|
|
102
|
+
}
|
|
103
|
+
if (text[i] === '"') {
|
|
104
|
+
buf += '"';
|
|
105
|
+
i++;
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
buf += text[i];
|
|
109
|
+
i++;
|
|
110
|
+
}
|
|
111
|
+
return { text: buf, index: i };
|
|
112
|
+
}
|
|
113
|
+
/* v8 ignore start */
|
|
114
|
+
function isCharLiteral(text, i) {
|
|
115
|
+
// Heuristic: a `'` followed by a single char or escape, then another
|
|
116
|
+
// `'`, with nothing alphanumeric immediately following the closing
|
|
117
|
+
// `'` (otherwise it's a lifetime: `'static`, `'a`).
|
|
118
|
+
if (text[i] !== "'")
|
|
119
|
+
return false;
|
|
120
|
+
const slice = text.slice(i, i + 4);
|
|
121
|
+
// `'a'`, `'\n'`, `'\\''` patterns. Lifetimes don't have a closing
|
|
122
|
+
// `'`, so we look for one within ~3 chars.
|
|
123
|
+
if (slice.length < 3)
|
|
124
|
+
return false;
|
|
125
|
+
const escape = slice[1] === '\\';
|
|
126
|
+
const closeIdx = escape ? 3 : 2;
|
|
127
|
+
return slice[closeIdx] === "'";
|
|
128
|
+
}
|
|
129
|
+
function consumeCharLiteral(text, start) {
|
|
130
|
+
// Already verified by isCharLiteral.
|
|
131
|
+
const escape = text[start + 1] === '\\';
|
|
132
|
+
const len = escape ? 4 : 3;
|
|
133
|
+
return { text: text.slice(start, start + len), index: start + len };
|
|
134
|
+
}
|
|
135
|
+
/* v8 ignore stop */
|
|
136
|
+
//# sourceMappingURL=body-digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body-digest.js","sourceRoot":"","sources":["../src/body-digest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust cacheKey implementation.
|
|
3
|
+
*
|
|
4
|
+
* Produces `rs-${cargoLockHash || cargoTomlHash || 'no-config'}`.
|
|
5
|
+
*
|
|
6
|
+
* Prefers Cargo.lock over Cargo.toml when both are present —
|
|
7
|
+
* Cargo.lock holds the resolved dependency graph, so changing a dep
|
|
8
|
+
* version (which can change call-graph topology indirectly through
|
|
9
|
+
* trait-impl changes) reliably flips the key. Cargo.toml is the
|
|
10
|
+
* fallback when Cargo.lock isn't checked in (the typical pattern for
|
|
11
|
+
* library crates). The precedence is encoded in `discover.ts`'s
|
|
12
|
+
* config-candidate list; this module just fingerprints whichever anchor
|
|
13
|
+
* discover picked.
|
|
14
|
+
*
|
|
15
|
+
* Per contract invariant I-6: pure function of `(config content)`.
|
|
16
|
+
* Per I-8: emits `rs-`, distinct from `ts-` and `py-`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const cacheKey: (input: import("@opensip-cli/graph").CacheKeyInput) => string;
|
|
19
|
+
//# sourceMappingURL=cache-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-key.d.ts","sourceRoot":"","sources":["../src/cache-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,eAAO,MAAM,QAAQ,+DAAuC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust cacheKey implementation.
|
|
3
|
+
*
|
|
4
|
+
* Produces `rs-${cargoLockHash || cargoTomlHash || 'no-config'}`.
|
|
5
|
+
*
|
|
6
|
+
* Prefers Cargo.lock over Cargo.toml when both are present —
|
|
7
|
+
* Cargo.lock holds the resolved dependency graph, so changing a dep
|
|
8
|
+
* version (which can change call-graph topology indirectly through
|
|
9
|
+
* trait-impl changes) reliably flips the key. Cargo.toml is the
|
|
10
|
+
* fallback when Cargo.lock isn't checked in (the typical pattern for
|
|
11
|
+
* library crates). The precedence is encoded in `discover.ts`'s
|
|
12
|
+
* config-candidate list; this module just fingerprints whichever anchor
|
|
13
|
+
* discover picked.
|
|
14
|
+
*
|
|
15
|
+
* Per contract invariant I-6: pure function of `(config content)`.
|
|
16
|
+
* Per I-8: emits `rs-`, distinct from `ts-` and `py-`.
|
|
17
|
+
*/
|
|
18
|
+
import { makeConfigCacheKey } from '@opensip-cli/graph-adapter-common';
|
|
19
|
+
export const cacheKey = makeConfigCacheKey({ prefix: 'rs' });
|
|
20
|
+
//# sourceMappingURL=cache-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-key.js","sourceRoot":"","sources":["../src/cache-key.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAEvE,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust file discovery — Stage 0 for the Rust adapter.
|
|
3
|
+
*
|
|
4
|
+
* Strategy:
|
|
5
|
+
* 1. Locate `Cargo.toml`. We do NOT parse it to honor
|
|
6
|
+
* `[workspace] members = [...]` or `[lib]` / `[[bin]]` paths —
|
|
7
|
+
* that's a deliberate punt. Instead we recurse all `.rs` files from
|
|
8
|
+
* the project root excluding `target/`, which covers single crates
|
|
9
|
+
* and most workspace layouts. Workspace-aware discovery is a
|
|
10
|
+
* follow-up.
|
|
11
|
+
* 2. If no `Cargo.toml` is present, the configPath is undefined and
|
|
12
|
+
* `cacheKey` falls back to the literal `no-config`.
|
|
13
|
+
* 3. Records `Cargo.lock` (if present) as a sibling fingerprint —
|
|
14
|
+
* `cacheKey` prefers Cargo.lock since it's the resolved-dep hash;
|
|
15
|
+
* falls back to Cargo.toml.
|
|
16
|
+
*
|
|
17
|
+
* The collect-loop / realpath-dedup / config-precedence scaffolding lives
|
|
18
|
+
* in `@opensip-cli/graph-adapter-common`; this module supplies only the
|
|
19
|
+
* Rust-specific inputs.
|
|
20
|
+
*/
|
|
21
|
+
export declare const discoverFiles: (input: import("@opensip-cli/graph").DiscoverInput) => import("@opensip-cli/graph").DiscoverOutput;
|
|
22
|
+
//# sourceMappingURL=discover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,eAAO,MAAM,aAAa,oGAKxB,CAAC"}
|
package/dist/discover.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust file discovery — Stage 0 for the Rust adapter.
|
|
3
|
+
*
|
|
4
|
+
* Strategy:
|
|
5
|
+
* 1. Locate `Cargo.toml`. We do NOT parse it to honor
|
|
6
|
+
* `[workspace] members = [...]` or `[lib]` / `[[bin]]` paths —
|
|
7
|
+
* that's a deliberate punt. Instead we recurse all `.rs` files from
|
|
8
|
+
* the project root excluding `target/`, which covers single crates
|
|
9
|
+
* and most workspace layouts. Workspace-aware discovery is a
|
|
10
|
+
* follow-up.
|
|
11
|
+
* 2. If no `Cargo.toml` is present, the configPath is undefined and
|
|
12
|
+
* `cacheKey` falls back to the literal `no-config`.
|
|
13
|
+
* 3. Records `Cargo.lock` (if present) as a sibling fingerprint —
|
|
14
|
+
* `cacheKey` prefers Cargo.lock since it's the resolved-dep hash;
|
|
15
|
+
* falls back to Cargo.toml.
|
|
16
|
+
*
|
|
17
|
+
* The collect-loop / realpath-dedup / config-precedence scaffolding lives
|
|
18
|
+
* in `@opensip-cli/graph-adapter-common`; this module supplies only the
|
|
19
|
+
* Rust-specific inputs.
|
|
20
|
+
*/
|
|
21
|
+
import { createDiscover } from '@opensip-cli/graph-adapter-common';
|
|
22
|
+
const EXCLUDED_DIR_GLOBS = ['**/target/**', '**/node_modules/**', '**/.git/**'];
|
|
23
|
+
// Prefer Cargo.lock (resolved deps) over Cargo.toml (intent), since
|
|
24
|
+
// changing a dep version invalidates the call-graph more reliably than
|
|
25
|
+
// editing the manifest.
|
|
26
|
+
const CONFIG_CANDIDATES = ['Cargo.lock', 'Cargo.toml'];
|
|
27
|
+
export const discoverFiles = createDiscover({
|
|
28
|
+
extension: 'rs',
|
|
29
|
+
excludedDirGlobs: EXCLUDED_DIR_GLOBS,
|
|
30
|
+
configCandidates: CONFIG_CANDIDATES,
|
|
31
|
+
languageId: 'rust',
|
|
32
|
+
});
|
|
33
|
+
//# sourceMappingURL=discover.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../src/discover.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEnE,MAAM,kBAAkB,GAAsB,CAAC,cAAc,EAAE,oBAAoB,EAAE,YAAY,CAAC,CAAC;AAEnG,oEAAoE;AACpE,uEAAuE;AACvE,wBAAwB;AACxB,MAAM,iBAAiB,GAAsB,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,aAAa,GAAG,cAAc,CAAC;IAC1C,SAAS,EAAE,IAAI;IACf,gBAAgB,EAAE,kBAAkB;IACpC,gBAAgB,EAAE,iBAAiB;IACnC,UAAU,EAAE,MAAM;CACnB,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opensip-cli/graph — Rust language adapter.
|
|
3
|
+
*
|
|
4
|
+
* Lands in PR 6 of plan docs/plans/10-graph-language-pluggability.md.
|
|
5
|
+
* Exposes `rustGraphAdapter`, a `GraphLanguageAdapter` backed by
|
|
6
|
+
* tree-sitter-rust.
|
|
7
|
+
*
|
|
8
|
+
* Per-rule fidelity: same as Python (mostly `'medium'`; `'low'` for
|
|
9
|
+
* ambiguous matches). The adapter has no symbol table, so trait
|
|
10
|
+
* dispatch and method-on-generic resolution degrade to name-only.
|
|
11
|
+
* Receiver-type narrowing (e.g. `Foo::method(...)`) is best-effort
|
|
12
|
+
* and slightly lifts confidence when the receiver type is statically
|
|
13
|
+
* present in the call expression itself.
|
|
14
|
+
*
|
|
15
|
+
* File layout mirrors `lang-python/`:
|
|
16
|
+
* discoverFiles → ./discover.ts (Cargo.toml / Cargo.lock + glob fallback)
|
|
17
|
+
* parseProject → ./parse.ts
|
|
18
|
+
* walkProject → ./walk.ts
|
|
19
|
+
* resolveCallSites → ./resolve.ts
|
|
20
|
+
* cacheKey → ./cache-key.ts (`rs-…`)
|
|
21
|
+
* ruleHints → ./rule-hints.ts
|
|
22
|
+
*
|
|
23
|
+
* Production graph adapters are forbidden from importing `web-tree-sitter`
|
|
24
|
+
* directly; the ADR-0010 restricted-import rule in the shared ESLint config
|
|
25
|
+
* enforces it.
|
|
26
|
+
*/
|
|
27
|
+
import { resolveCallSites as rustResolveCallSites } from './resolve.js';
|
|
28
|
+
import { walkProject as rustWalkProject } from './walk.js';
|
|
29
|
+
export declare const rustGraphAdapter: {
|
|
30
|
+
id: string;
|
|
31
|
+
fileExtensions: string[];
|
|
32
|
+
displayName: string;
|
|
33
|
+
discoverFiles: (input: import("@opensip-cli/graph").DiscoverInput) => import("@opensip-cli/graph").DiscoverOutput;
|
|
34
|
+
parseProject: (input: import("@opensip-cli/graph").ParseInput) => import("@opensip-cli/graph").ParseOutput<import("@opensip-cli/graph-adapter-common").TreeSitterParsedProject>;
|
|
35
|
+
walkProject: typeof rustWalkProject;
|
|
36
|
+
resolveCallSites: typeof rustResolveCallSites;
|
|
37
|
+
cacheKey: (input: import("@opensip-cli/graph").CacheKeyInput) => string;
|
|
38
|
+
ruleHints: import("@opensip-cli/graph").RuleHints;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Discovery contract: external adapter packs export `adapter` (the
|
|
42
|
+
* GraphLanguageAdapter) and `metadata`. The CLI bootstrap registers
|
|
43
|
+
* `adapter` into the adapter registry after a successful `import()`.
|
|
44
|
+
*/
|
|
45
|
+
export { rustGraphAdapter as adapter };
|
|
46
|
+
export declare const metadata: {
|
|
47
|
+
readonly id: string;
|
|
48
|
+
readonly displayName: string;
|
|
49
|
+
readonly fileExtensions: string[];
|
|
50
|
+
};
|
|
51
|
+
export type { RustParsedProject } from './parse.js';
|
|
52
|
+
export { rustRuleHints } from './rule-hints.js';
|
|
53
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAKH,OAAO,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAExE,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,WAAW,CAAC;AAK3D,eAAO,MAAM,gBAAgB;;;;;;;;;;CAUsB,CAAC;AAEpD;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,IAAI,OAAO,EAAE,CAAC;AACvC,eAAO,MAAM,QAAQ;;;;CAIX,CAAC;AAMX,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @opensip-cli/graph — Rust language adapter.
|
|
3
|
+
*
|
|
4
|
+
* Lands in PR 6 of plan docs/plans/10-graph-language-pluggability.md.
|
|
5
|
+
* Exposes `rustGraphAdapter`, a `GraphLanguageAdapter` backed by
|
|
6
|
+
* tree-sitter-rust.
|
|
7
|
+
*
|
|
8
|
+
* Per-rule fidelity: same as Python (mostly `'medium'`; `'low'` for
|
|
9
|
+
* ambiguous matches). The adapter has no symbol table, so trait
|
|
10
|
+
* dispatch and method-on-generic resolution degrade to name-only.
|
|
11
|
+
* Receiver-type narrowing (e.g. `Foo::method(...)`) is best-effort
|
|
12
|
+
* and slightly lifts confidence when the receiver type is statically
|
|
13
|
+
* present in the call expression itself.
|
|
14
|
+
*
|
|
15
|
+
* File layout mirrors `lang-python/`:
|
|
16
|
+
* discoverFiles → ./discover.ts (Cargo.toml / Cargo.lock + glob fallback)
|
|
17
|
+
* parseProject → ./parse.ts
|
|
18
|
+
* walkProject → ./walk.ts
|
|
19
|
+
* resolveCallSites → ./resolve.ts
|
|
20
|
+
* cacheKey → ./cache-key.ts (`rs-…`)
|
|
21
|
+
* ruleHints → ./rule-hints.ts
|
|
22
|
+
*
|
|
23
|
+
* Production graph adapters are forbidden from importing `web-tree-sitter`
|
|
24
|
+
* directly; the ADR-0010 restricted-import rule in the shared ESLint config
|
|
25
|
+
* enforces it.
|
|
26
|
+
*/
|
|
27
|
+
import { cacheKey as rustCacheKey } from './cache-key.js';
|
|
28
|
+
import { discoverFiles as rustDiscoverFiles } from './discover.js';
|
|
29
|
+
import { parseProject as rustParseProject } from './parse.js';
|
|
30
|
+
import { resolveCallSites as rustResolveCallSites } from './resolve.js';
|
|
31
|
+
import { rustRuleHints } from './rule-hints.js';
|
|
32
|
+
import { walkProject as rustWalkProject } from './walk.js';
|
|
33
|
+
export const rustGraphAdapter = {
|
|
34
|
+
id: 'rust',
|
|
35
|
+
fileExtensions: ['.rs'],
|
|
36
|
+
displayName: 'Rust',
|
|
37
|
+
discoverFiles: rustDiscoverFiles,
|
|
38
|
+
parseProject: rustParseProject,
|
|
39
|
+
walkProject: rustWalkProject,
|
|
40
|
+
resolveCallSites: rustResolveCallSites,
|
|
41
|
+
cacheKey: rustCacheKey,
|
|
42
|
+
ruleHints: rustRuleHints,
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Discovery contract: external adapter packs export `adapter` (the
|
|
46
|
+
* GraphLanguageAdapter) and `metadata`. The CLI bootstrap registers
|
|
47
|
+
* `adapter` into the adapter registry after a successful `import()`.
|
|
48
|
+
*/
|
|
49
|
+
export { rustGraphAdapter as adapter };
|
|
50
|
+
export const metadata = {
|
|
51
|
+
id: rustGraphAdapter.id,
|
|
52
|
+
displayName: rustGraphAdapter.displayName,
|
|
53
|
+
fileExtensions: rustGraphAdapter.fileExtensions,
|
|
54
|
+
};
|
|
55
|
+
export { rustRuleHints } from './rule-hints.js';
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,WAAW,CAAC;AAK3D,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,EAAE,EAAE,MAAM;IACV,cAAc,EAAE,CAAC,KAAK,CAAC;IACvB,WAAW,EAAE,MAAM;IACnB,aAAa,EAAE,iBAAiB;IAChC,YAAY,EAAE,gBAAgB;IAC9B,WAAW,EAAE,eAAe;IAC5B,gBAAgB,EAAE,oBAAoB;IACtC,QAAQ,EAAE,YAAY;IACtB,SAAS,EAAE,aAAa;CACyB,CAAC;AAEpD;;;;GAIG;AACH,OAAO,EAAE,gBAAgB,IAAI,OAAO,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,EAAE,EAAE,gBAAgB,CAAC,EAAE;IACvB,WAAW,EAAE,gBAAgB,CAAC,WAAW;IACzC,cAAc,EAAE,gBAAgB,CAAC,cAAc;CACvC,CAAC;AAOX,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/parse.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust parseProject — consumes `@opensip-cli/lang-rust` (ADR-0010).
|
|
3
|
+
*
|
|
4
|
+
* `lang-rust` is the canonical Rust parse substrate: it owns the vendored
|
|
5
|
+
* tree-sitter-rust grammar and produces the `{ tree, source }` parsed-file
|
|
6
|
+
* shape. The graph adapter no longer loads a grammar of its own; it binds the
|
|
7
|
+
* shared `createParseProjectFromAdapter` driver to `rustAdapter`. The
|
|
8
|
+
* parsed-project shape and the downstream walk/resolve are unchanged.
|
|
9
|
+
*/
|
|
10
|
+
import { type TreeSitterParsedFile, type TreeSitterParsedProject } from '@opensip-cli/graph-adapter-common';
|
|
11
|
+
/** Parsed Rust source file: tree-sitter parse tree plus original source text. */
|
|
12
|
+
export type RustParsedFile = TreeSitterParsedFile;
|
|
13
|
+
/** Parsed Rust project: map of file path → {@link RustParsedFile}. */
|
|
14
|
+
export type RustParsedProject = TreeSitterParsedProject<RustParsedFile>;
|
|
15
|
+
/** Parses every Rust source file in the input set into a {@link RustParsedProject}. */
|
|
16
|
+
export declare const parseProject: (input: import("@opensip-cli/graph").ParseInput) => import("@opensip-cli/graph").ParseOutput<TreeSitterParsedProject>;
|
|
17
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC7B,MAAM,mCAAmC,CAAC;AAG3C,iFAAiF;AACjF,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC;AAElD,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,cAAc,CAAC,CAAC;AAExE,uFAAuF;AACvF,eAAO,MAAM,YAAY,uHAA6C,CAAC"}
|
package/dist/parse.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rust parseProject — consumes `@opensip-cli/lang-rust` (ADR-0010).
|
|
3
|
+
*
|
|
4
|
+
* `lang-rust` is the canonical Rust parse substrate: it owns the vendored
|
|
5
|
+
* tree-sitter-rust grammar and produces the `{ tree, source }` parsed-file
|
|
6
|
+
* shape. The graph adapter no longer loads a grammar of its own; it binds the
|
|
7
|
+
* shared `createParseProjectFromAdapter` driver to `rustAdapter`. The
|
|
8
|
+
* parsed-project shape and the downstream walk/resolve are unchanged.
|
|
9
|
+
*/
|
|
10
|
+
import { createParseProjectFromAdapter, } from '@opensip-cli/graph-adapter-common';
|
|
11
|
+
import { rustAdapter } from '@opensip-cli/lang-rust';
|
|
12
|
+
/** Parses every Rust source file in the input set into a {@link RustParsedProject}. */
|
|
13
|
+
export const parseProject = createParseProjectFromAdapter(rustAdapter);
|
|
14
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,6BAA6B,GAG9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAQrD,uFAAuF;AACvF,MAAM,CAAC,MAAM,YAAY,GAAG,6BAA6B,CAAC,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Rust `use`-path → dependency-edge resolution.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from `resolve.ts` so the call-site resolver and the
|
|
5
|
+
* dependency resolver each live in a focused module. This file owns the
|
|
6
|
+
* Rust-specific module-path logic (Cargo.toml lookup, `crate`/`self`/
|
|
7
|
+
* `super`/`<pkg-name>` rewriting, file-path → module-path mapping).
|
|
8
|
+
*
|
|
9
|
+
* Phase 4 of opensip's substrate consolidation (DEC-498).
|
|
10
|
+
*/
|
|
11
|
+
import type { Catalog, DependencyEdge, DependencySiteRecord } from '@opensip-cli/graph';
|
|
12
|
+
export declare function resolveDependencies(sites: readonly DependencySiteRecord[], catalog: Catalog, projectDirAbs: string): ReadonlyMap<string, readonly DependencyEdge[]>;
|
|
13
|
+
//# sourceMappingURL=resolve-dependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-dependencies.d.ts","sourceRoot":"","sources":["../src/resolve-dependencies.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAExF,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,GACpB,WAAW,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC,CAehD"}
|