@opensip-cli/lang-rust 0.1.7 β†’ 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,8 +23,8 @@ This package is published for the CLI and advanced plugin authors; most users sh
23
23
  ## Documentation
24
24
 
25
25
  - πŸ“š Project docs: https://opensip.ai/docs/opensip-cli/
26
- - 🧭 Package catalog (what every package does): https://github.com/opensip-ai/opensip-cli/blob/v0.1.7/docs/public/70-reference/02-package-catalog.md
27
- - πŸ“¦ Source: https://github.com/opensip-ai/opensip-cli/tree/v0.1.7/packages/languages/lang-rust
26
+ - 🧭 Package catalog (what every package does): https://github.com/opensip-ai/opensip-cli/blob/v0.1.9/docs/public/70-reference/02-package-catalog.md
27
+ - πŸ“¦ Source: https://github.com/opensip-ai/opensip-cli/tree/v0.1.9/packages/languages/lang-rust
28
28
 
29
29
  ## License
30
30
 
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=query.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/query.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,85 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { rustAdapter } from '../adapter.js';
3
+ function parse(src) {
4
+ const tree = rustAdapter.parse(src, 's.rs');
5
+ if (!tree)
6
+ throw new Error('no tree');
7
+ return tree;
8
+ }
9
+ const q = rustAdapter.query;
10
+ describe('rustQuery (LanguageQueryAPI)', () => {
11
+ it('is wired onto the adapter', () => {
12
+ expect(rustAdapter.query).toBeDefined();
13
+ });
14
+ it('findFunctions returns free fns, methods, and anonymous closures', () => {
15
+ const tree = parse('fn free() {}\nstruct S;\nimpl S { fn m(&self) {} }\nfn uses() { let c = |x| x + 1; let _ = c(1); }\n');
16
+ const fns = q.findFunctions(tree);
17
+ const names = fns.map((f) => f.name);
18
+ expect(names).toContain('free');
19
+ expect(names).toContain('m');
20
+ expect(names).toContain('uses');
21
+ // the closure |x| x + 1 has no name field
22
+ expect(names).toContain(null);
23
+ });
24
+ it('findImports expands use-lists, aliases, wildcards, self, and extern crate', () => {
25
+ const tree = parse([
26
+ 'pub use std::collections::HashMap;',
27
+ 'use std::io::{Read, Write};',
28
+ 'use foo::bar as baz;',
29
+ 'use std::prelude::v1::*;',
30
+ 'use crate::module::{self, Helper};',
31
+ 'extern crate serde;',
32
+ ].join('\n'));
33
+ const imports = q.findImports(tree);
34
+ const specs = imports.map((i) => i.specifier);
35
+ expect(specs).toContain('std::collections::HashMap');
36
+ expect(specs).toContain('std::io::Read');
37
+ expect(specs).toContain('std::io::Write');
38
+ expect(specs).toContain('foo::bar');
39
+ expect(specs).toContain('serde');
40
+ expect(specs.some((s) => s.endsWith('::*'))).toBe(true);
41
+ // `self` inside a use-list refers to the prefix path itself.
42
+ expect(specs).toContain('crate::module');
43
+ expect(specs).toContain('crate::module::Helper');
44
+ const hashMap = imports.find((i) => i.specifier === 'std::collections::HashMap');
45
+ expect(hashMap?.names).toEqual(['HashMap']);
46
+ });
47
+ it('findImports handles a bare wildcard and a glob-only use', () => {
48
+ const tree = parse('use std::io::prelude::*;\nuse other::*;\n');
49
+ const specs = q.findImports(tree).map((i) => i.specifier);
50
+ expect(specs).toContain('std::io::prelude::*');
51
+ expect(specs).toContain('other::*');
52
+ });
53
+ it('findCallsTo matches calls and macro invocations by leaf name', () => {
54
+ const tree = parse('fn f() { foo(); obj.bar(); Type::make(); println!("hi"); }\n');
55
+ expect(q.findCallsTo(tree, 'foo').length).toBe(1);
56
+ expect(q.findCallsTo(tree, 'bar').length).toBe(1);
57
+ expect(q.findCallsTo(tree, 'make').length).toBe(1);
58
+ expect(q.findCallsTo(tree, 'println').length).toBe(1);
59
+ expect(q.findCallsTo(tree, 'absent').length).toBe(0);
60
+ });
61
+ it('findCallsTo ignores non-named callee shapes (computed/closure calls)', () => {
62
+ // An immediately-invoked closure has no named callee β€” the extractor
63
+ // returns null, so it never matches any name.
64
+ const tree = parse('fn f() { let arr = [foo]; arr[0](); (|| 1)(); }\n');
65
+ expect(q.findCallsTo(tree, 'foo').length).toBe(0);
66
+ expect(q.findCallsTo(tree, 'arr').length).toBe(0);
67
+ });
68
+ it('findImports handles nested scoped use-lists (prefix + path segment)', () => {
69
+ const tree = parse('use root::{inner::{first, second}, sibling};\n');
70
+ const specs = q
71
+ .findImports(tree)
72
+ .map((i) => i.specifier)
73
+ .sort();
74
+ expect(specs).toEqual(['root::inner::first', 'root::inner::second', 'root::sibling']);
75
+ });
76
+ it('findStringLiterals returns literal values; getText/getLocation read nodes', () => {
77
+ const tree = parse('fn f() { let s = "hello"; }\n');
78
+ const strings = q.findStringLiterals(tree);
79
+ expect(strings.map((s) => s.value)).toContain('hello');
80
+ const fn = q.findFunctions(tree)[0];
81
+ expect(q.getText(tree, fn.node)).toContain('fn f()');
82
+ expect(q.getLocation(tree, fn.node).line).toBeGreaterThanOrEqual(1);
83
+ });
84
+ });
85
+ //# sourceMappingURL=query.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.test.js","sourceRoot":"","sources":["../../src/__tests__/query.test.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,9 @@ import { RunScope, runWithScopeSync } from '@opensip-cli/core';
2
2
  import { initParseCache, clearParseCache } from '@opensip-cli/core/languages/parse-cache.js';
3
3
  import { nameOf, walkNodes } from '@opensip-cli/tree-sitter';
4
4
  import { describe, expect, it } from 'vitest';
5
- import { findEnclosingFunction, getEnclosingFunctionName, isMethod } from '../enclosing.js';
5
+ import { findEnclosingFunction, getEnclosingFunctionName } from '../enclosing.js';
6
6
  import { parseRust } from '../parse.js';
7
- import { isComment, isConditional, isFunction, isImpl, isLoop, isString, isStruct, } from '../predicates.js';
7
+ import { isComment, isConditional, isFunction, isImpl, isLoop, isMethod, isString, isStruct, } from '../predicates.js';
8
8
  import { getSharedTree } from '../shared-tree.js';
9
9
  const SRC = [
10
10
  '// c',
@@ -1 +1 @@
1
- {"version":3,"file":"substrate.test.js","sourceRoot":"","sources":["../../src/__tests__/substrate.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"substrate.test.js","sourceRoot":"","sources":["../../src/__tests__/substrate.test.ts"],"names":[],"mappings":"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"}
package/dist/adapter.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { type RustTree } from './parse.js';
2
2
  import type { LanguageAdapter } from '@opensip-cli/core';
3
- export declare const rustAdapter: LanguageAdapter<RustTree>;
3
+ import type { Node } from '@opensip-cli/tree-sitter';
4
+ export declare const rustAdapter: LanguageAdapter<RustTree, Node>;
4
5
  /** Plugin contract β€” exported as the lang plugin's `adapters` array. */
5
- export declare const adapters: readonly [LanguageAdapter<import("@opensip-cli/tree-sitter").ParsedFile, unknown>];
6
+ export declare const adapters: readonly [LanguageAdapter<import("@opensip-cli/tree-sitter").ParsedFile, Node>];
6
7
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,eAAO,MAAM,WAAW,EAAE,eAAe,CAAC,QAAQ,CAOjD,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,QAAQ,oFAAyB,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAErD,eAAO,MAAM,WAAW,EAAE,eAAe,CAAC,QAAQ,EAAE,IAAI,CAQvD,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,QAAQ,iFAAyB,CAAC"}
package/dist/adapter.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { parseRust } from './parse.js';
2
+ import { rustQuery } from './query.js';
2
3
  import { stripComments, stripStrings } from './strip.js';
3
4
  export const rustAdapter = {
4
5
  id: 'rust',
@@ -7,6 +8,7 @@ export const rustAdapter = {
7
8
  parse: parseRust,
8
9
  stripStrings,
9
10
  stripComments,
11
+ query: rustQuery,
10
12
  };
11
13
  /** Plugin contract β€” exported as the lang plugin's `adapters` array. */
12
14
  export const adapters = [rustAdapter];
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIzD,MAAM,CAAC,MAAM,WAAW,GAA8B;IACpD,EAAE,EAAE,MAAM;IACV,cAAc,EAAE,CAAC,KAAK,CAAC;IACvB,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,KAAK,EAAE,SAAS;IAChB,YAAY;IACZ,aAAa;CACd,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAU,CAAC"}
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAKzD,MAAM,CAAC,MAAM,WAAW,GAAoC;IAC1D,EAAE,EAAE,MAAM;IACV,cAAc,EAAE,CAAC,KAAK,CAAC;IACvB,OAAO,EAAE,CAAC,IAAI,CAAC;IACf,KAAK,EAAE,SAAS;IAChB,YAAY;IACZ,aAAa;IACb,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,wEAAwE;AACxE,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,WAAW,CAAU,CAAC"}
@@ -1,16 +1,12 @@
1
1
  /**
2
2
  * Composed enclosing-scope helpers for Rust (ADR-0010) β€” the per-language layer
3
3
  * over the generic `findEnclosing`/`nameOf` from `@opensip-cli/tree-sitter`.
4
+ * `isMethod` lives in predicates.ts (normalized in M10), alongside the other
5
+ * node-kind predicates, in every tree-sitter adapter.
4
6
  */
5
7
  import { type Node } from '@opensip-cli/tree-sitter';
6
8
  /** The nearest enclosing `fn` of `node`, or `null` at module scope. */
7
9
  export declare function findEnclosingFunction(node: Node): Node | null;
8
10
  /** The name of the nearest enclosing `fn`, or `null`. */
9
11
  export declare function getEnclosingFunctionName(node: Node): string | null;
10
- /**
11
- * True when `node` is a method β€” a `fn` item whose nearest enclosing
12
- * function-or-impl is an `impl` block. A free function (or a `fn` nested in
13
- * another `fn`) is therefore not a method.
14
- */
15
- export declare function isMethod(node: Node): boolean;
16
12
  //# sourceMappingURL=enclosing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"enclosing.d.ts","sourceRoot":"","sources":["../src/enclosing.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAI5E,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED,yDAAyD;AACzD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAGlE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAI5C"}
1
+ {"version":3,"file":"enclosing.d.ts","sourceRoot":"","sources":["../src/enclosing.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAEH,OAAO,EAAyB,KAAK,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAI5E,uEAAuE;AACvE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAE7D;AAED,yDAAyD;AACzD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAGlE"}
package/dist/enclosing.js CHANGED
@@ -2,9 +2,11 @@
2
2
  /**
3
3
  * Composed enclosing-scope helpers for Rust (ADR-0010) β€” the per-language layer
4
4
  * over the generic `findEnclosing`/`nameOf` from `@opensip-cli/tree-sitter`.
5
+ * `isMethod` lives in predicates.ts (normalized in M10), alongside the other
6
+ * node-kind predicates, in every tree-sitter adapter.
5
7
  */
6
8
  import { findEnclosing, nameOf } from '@opensip-cli/tree-sitter';
7
- import { isFunction, isImpl } from './predicates.js';
9
+ import { isFunction } from './predicates.js';
8
10
  /** The nearest enclosing `fn` of `node`, or `null` at module scope. */
9
11
  export function findEnclosingFunction(node) {
10
12
  return findEnclosing(node, isFunction);
@@ -14,15 +16,4 @@ export function getEnclosingFunctionName(node) {
14
16
  const fn = findEnclosingFunction(node);
15
17
  return fn ? nameOf(fn) : null;
16
18
  }
17
- /**
18
- * True when `node` is a method β€” a `fn` item whose nearest enclosing
19
- * function-or-impl is an `impl` block. A free function (or a `fn` nested in
20
- * another `fn`) is therefore not a method.
21
- */
22
- export function isMethod(node) {
23
- if (!isFunction(node))
24
- return false;
25
- const enclosing = findEnclosing(node, (n) => isFunction(n) || isImpl(n));
26
- return enclosing !== null && isImpl(enclosing);
27
- }
28
19
  //# sourceMappingURL=enclosing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"enclosing.js","sourceRoot":"","sources":["../src/enclosing.ts"],"names":[],"mappings":"AAAA,gPAAgP;AAChP;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAa,MAAM,0BAA0B,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAErD,uEAAuE;AACvE,MAAM,UAAU,qBAAqB,CAAC,IAAU;IAC9C,OAAO,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,wBAAwB,CAAC,IAAU;IACjD,MAAM,EAAE,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAU;IACjC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,OAAO,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"enclosing.js","sourceRoot":"","sources":["../src/enclosing.ts"],"names":[],"mappings":"AAAA,gPAAgP;AAChP;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,EAAa,MAAM,0BAA0B,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,uEAAuE;AACvE,MAAM,UAAU,qBAAqB,CAAC,IAAU;IAC9C,OAAO,aAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACzC,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,wBAAwB,CAAC,IAAU;IACjD,MAAM,EAAE,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { rustAdapter, adapters } from './adapter.js';
2
2
  export { parseRust, type RustTree } from './parse.js';
3
3
  export { getSharedTree } from './shared-tree.js';
4
4
  export { stripStrings, stripComments } from './strip.js';
5
- export { isFunction, isStruct, isImpl, isComment, isString, isConditional, isLoop, } from './predicates.js';
6
- export { findEnclosingFunction, getEnclosingFunctionName, isMethod } from './enclosing.js';
5
+ export { rustQuery } from './query.js';
6
+ export { isFunction, isMethod, isStruct, isImpl, isComment, isString, isConditional, isLoop, } from './predicates.js';
7
+ export { findEnclosingFunction, getEnclosingFunctionName } from './enclosing.js';
8
+ export { childrenOf, findEnclosing, getColumn, getLineNumber, nameOf, namedChildrenOf, nodeText, walkNodes, type Node, } from '@opensip-cli/tree-sitter';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EACL,UAAU,EACV,QAAQ,EACR,MAAM,EACN,SAAS,EACT,QAAQ,EACR,aAAa,EACb,MAAM,GACP,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,QAAQ,EACR,aAAa,EACb,MAAM,GACP,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAOjF,OAAO,EACL,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,MAAM,EACN,eAAe,EACf,QAAQ,EACR,SAAS,EACT,KAAK,IAAI,GACV,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,13 @@ export { rustAdapter, adapters } from './adapter.js';
2
2
  export { parseRust } from './parse.js';
3
3
  export { getSharedTree } from './shared-tree.js';
4
4
  export { stripStrings, stripComments } from './strip.js';
5
- export { isFunction, isStruct, isImpl, isComment, isString, isConditional, isLoop, } from './predicates.js';
6
- export { findEnclosingFunction, getEnclosingFunctionName, isMethod } from './enclosing.js';
5
+ export { rustQuery } from './query.js';
6
+ export { isFunction, isMethod, isStruct, isImpl, isComment, isString, isConditional, isLoop, } from './predicates.js';
7
+ export { findEnclosingFunction, getEnclosingFunctionName } from './enclosing.js';
8
+ // Generic tree-sitter traversal/position vocabulary, re-exported so check
9
+ // packs reach the parser substrate THROUGH the language adapter (ADR-0039):
10
+ // the adapter owns the parser boundary; check packs depend on lang-rust +
11
+ // fitness only, never on @opensip-cli/tree-sitter directly (enforced by
12
+ // dependency-cruiser).
13
+ export { childrenOf, findEnclosing, getColumn, getLineNumber, nameOf, namedChildrenOf, nodeText, walkNodes, } from '@opensip-cli/tree-sitter';
7
14
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EACL,UAAU,EACV,QAAQ,EACR,MAAM,EACN,SAAS,EACT,QAAQ,EACR,aAAa,EACb,MAAM,GACP,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,SAAS,EACT,QAAQ,EACR,aAAa,EACb,MAAM,GACP,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAEjF,0EAA0E;AAC1E,4EAA4E;AAC5E,0EAA0E;AAC1E,wEAAwE;AACxE,uBAAuB;AACvB,OAAO,EACL,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,MAAM,EACN,eAAe,EACf,QAAQ,EACR,SAAS,GAEV,MAAM,0BAA0B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAOnG,gFAAgF;AAChF,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC;AAElC,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAG7E"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAqBnG,gFAAgF;AAChF,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC;AAElC,oFAAoF;AACpF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAK7E"}
package/dist/parse.js CHANGED
@@ -10,11 +10,29 @@
10
10
  * (non-null) rather than throwing.
11
11
  */
12
12
  import { fileURLToPath } from 'node:url';
13
+ import { logger } from '@opensip-cli/core';
13
14
  import { loadGrammar, createParser, parseToTree } from '@opensip-cli/tree-sitter';
14
- const grammar = await loadGrammar(fileURLToPath(new URL('../wasm/tree-sitter-rust.wasm', import.meta.url)));
15
- const parser = createParser(grammar);
15
+ // Load the grammar once at module top level (keeps parse() synchronous). A
16
+ // missing/corrupt/ABI-mismatched .wasm must NOT crash the whole CLI β€” contain
17
+ // the failure so Rust analysis degrades to "unavailable" (parse returns null).
18
+ let parser;
19
+ /* v8 ignore start -- grammar-load failure is environment-dependent (bad/missing .wasm); not reproducible under the test runner */
20
+ try {
21
+ const grammar = await loadGrammar(fileURLToPath(new URL('../wasm/tree-sitter-rust.wasm', import.meta.url)));
22
+ parser = createParser(grammar);
23
+ }
24
+ catch (error) {
25
+ logger.warn({
26
+ evt: 'lang.grammar.load_failed',
27
+ module: 'lang:rust',
28
+ msg: `Rust grammar failed to load β€” Rust analysis is unavailable this run: ${error instanceof Error ? error.message : String(error)}`,
29
+ });
30
+ }
16
31
  /** Parses Rust source into a {@link RustTree}, or null when no tree is produced. */
17
32
  export function parseRust(content, _filePath) {
33
+ /* v8 ignore next -- defensive: parser is undefined only when the grammar failed to load */
34
+ if (!parser)
35
+ return null;
18
36
  const tree = parseToTree(parser, content);
19
37
  return tree ? { tree, source: content } : null;
20
38
  }
package/dist/parse.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAmB,MAAM,0BAA0B,CAAC;AAEnG,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,aAAa,CAAC,IAAI,GAAG,CAAC,+BAA+B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CACzE,CAAC;AACF,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AAKrC,oFAAoF;AACpF,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,SAAiB;IAC1D,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC"}
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAmB,MAAM,0BAA0B,CAAC;AAEnG,2EAA2E;AAC3E,8EAA8E;AAC9E,+EAA+E;AAC/E,IAAI,MAAmD,CAAC;AACxD,kIAAkI;AAClI,IAAI,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAC/B,aAAa,CAAC,IAAI,GAAG,CAAC,+BAA+B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CACzE,CAAC;IACF,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,CAAC,IAAI,CAAC;QACV,GAAG,EAAE,0BAA0B;QAC/B,MAAM,EAAE,WAAW;QACnB,GAAG,EAAE,wEAAwE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;KACtI,CAAC,CAAC;AACL,CAAC;AAMD,oFAAoF;AACpF,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,SAAiB;IAC1D,2FAA2F;IAC3F,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACjD,CAAC"}
@@ -3,10 +3,10 @@
3
3
  * traversal/position helpers live in `@opensip-cli/tree-sitter`; only the
4
4
  * grammar-specific node `type` strings differ per language. Node types are from
5
5
  * the tree-sitter-rust grammar. Rust has no class or try/catch β€” methods are
6
- * `fn` items inside an `impl` block (see `isMethod` in enclosing.ts), and error
7
- * handling is `Result`/`?` rather than exceptions.
6
+ * `fn` items inside an `impl` block (see `isMethod` below), and error handling
7
+ * is `Result`/`?` rather than exceptions.
8
8
  */
9
- import type { Node } from '@opensip-cli/tree-sitter';
9
+ import { type Node } from '@opensip-cli/tree-sitter';
10
10
  /** A `fn` item β€” free functions and methods are both `function_item`. */
11
11
  export declare const isFunction: (node: Node) => boolean;
12
12
  /** A `struct` declaration. */
@@ -21,4 +21,11 @@ export declare const isString: (node: Node) => boolean;
21
21
  export declare const isConditional: (node: Node) => boolean;
22
22
  /** A `for`, `while`, or `loop` expression. */
23
23
  export declare const isLoop: (node: Node) => boolean;
24
+ /**
25
+ * True when `node` is a method β€” a `fn` item whose nearest enclosing
26
+ * function-or-impl is an `impl` block. A free function (or a `fn` nested in
27
+ * another `fn`) is therefore not a method. Normalized into predicates.ts
28
+ * (M10): `isMethod` lives in predicates.ts in every tree-sitter adapter.
29
+ */
30
+ export declare const isMethod: (node: Node) => boolean;
24
31
  //# sourceMappingURL=predicates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"predicates.d.ts","sourceRoot":"","sources":["../src/predicates.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAErD,yEAAyE;AACzE,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,KAAG,OAAwC,CAAC;AAEjF,8BAA8B;AAC9B,eAAO,MAAM,QAAQ,GAAI,MAAM,IAAI,KAAG,OAAsC,CAAC;AAE7E,uBAAuB;AACvB,eAAO,MAAM,MAAM,GAAI,MAAM,IAAI,KAAG,OAAoC,CAAC;AAEzE,yCAAyC;AACzC,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,KAAG,OACwB,CAAC;AAEhE,wBAAwB;AACxB,eAAO,MAAM,QAAQ,GAAI,MAAM,IAAI,KAAG,OAAyC,CAAC;AAEhF,0BAA0B;AAC1B,eAAO,MAAM,aAAa,GAAI,MAAM,IAAI,KAAG,OAAwC,CAAC;AAEpF,8CAA8C;AAC9C,eAAO,MAAM,MAAM,GAAI,MAAM,IAAI,KAAG,OAGH,CAAC"}
1
+ {"version":3,"file":"predicates.d.ts","sourceRoot":"","sources":["../src/predicates.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AAEH,OAAO,EAAiB,KAAK,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAEpE,yEAAyE;AACzE,eAAO,MAAM,UAAU,GAAI,MAAM,IAAI,KAAG,OAAwC,CAAC;AAEjF,8BAA8B;AAC9B,eAAO,MAAM,QAAQ,GAAI,MAAM,IAAI,KAAG,OAAsC,CAAC;AAE7E,uBAAuB;AACvB,eAAO,MAAM,MAAM,GAAI,MAAM,IAAI,KAAG,OAAoC,CAAC;AAEzE,yCAAyC;AACzC,eAAO,MAAM,SAAS,GAAI,MAAM,IAAI,KAAG,OACwB,CAAC;AAEhE,wBAAwB;AACxB,eAAO,MAAM,QAAQ,GAAI,MAAM,IAAI,KAAG,OAAyC,CAAC;AAEhF,0BAA0B;AAC1B,eAAO,MAAM,aAAa,GAAI,MAAM,IAAI,KAAG,OAAwC,CAAC;AAEpF,8CAA8C;AAC9C,eAAO,MAAM,MAAM,GAAI,MAAM,IAAI,KAAG,OAGH,CAAC;AAElC;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAI,MAAM,IAAI,KAAG,OAIrC,CAAC"}
@@ -4,9 +4,10 @@
4
4
  * traversal/position helpers live in `@opensip-cli/tree-sitter`; only the
5
5
  * grammar-specific node `type` strings differ per language. Node types are from
6
6
  * the tree-sitter-rust grammar. Rust has no class or try/catch β€” methods are
7
- * `fn` items inside an `impl` block (see `isMethod` in enclosing.ts), and error
8
- * handling is `Result`/`?` rather than exceptions.
7
+ * `fn` items inside an `impl` block (see `isMethod` below), and error handling
8
+ * is `Result`/`?` rather than exceptions.
9
9
  */
10
+ import { findEnclosing } from '@opensip-cli/tree-sitter';
10
11
  /** A `fn` item β€” free functions and methods are both `function_item`. */
11
12
  export const isFunction = (node) => node.type === 'function_item';
12
13
  /** A `struct` declaration. */
@@ -23,4 +24,16 @@ export const isConditional = (node) => node.type === 'if_expression';
23
24
  export const isLoop = (node) => node.type === 'for_expression' ||
24
25
  node.type === 'while_expression' ||
25
26
  node.type === 'loop_expression';
27
+ /**
28
+ * True when `node` is a method β€” a `fn` item whose nearest enclosing
29
+ * function-or-impl is an `impl` block. A free function (or a `fn` nested in
30
+ * another `fn`) is therefore not a method. Normalized into predicates.ts
31
+ * (M10): `isMethod` lives in predicates.ts in every tree-sitter adapter.
32
+ */
33
+ export const isMethod = (node) => {
34
+ if (!isFunction(node))
35
+ return false;
36
+ const enclosing = findEnclosing(node, (n) => isFunction(n) || isImpl(n));
37
+ return enclosing !== null && isImpl(enclosing);
38
+ };
26
39
  //# sourceMappingURL=predicates.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"predicates.js","sourceRoot":"","sources":["../src/predicates.ts"],"names":[],"mappings":"AAAA,gPAAgP;AAChP;;;;;;;GAOG;AAIH,yEAAyE;AACzE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AAEjF,8BAA8B;AAC9B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC;AAE7E,uBAAuB;AACvB,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;AAEzE,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAU,EAAW,EAAE,CAC/C,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AAEhE,wBAAwB;AACxB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC;AAEhF,0BAA0B;AAC1B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AAEpF,8CAA8C;AAC9C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAU,EAAW,EAAE,CAC5C,IAAI,CAAC,IAAI,KAAK,gBAAgB;IAC9B,IAAI,CAAC,IAAI,KAAK,kBAAkB;IAChC,IAAI,CAAC,IAAI,KAAK,iBAAiB,CAAC"}
1
+ {"version":3,"file":"predicates.js","sourceRoot":"","sources":["../src/predicates.ts"],"names":[],"mappings":"AAAA,gPAAgP;AAChP;;;;;;;GAOG;AAEH,OAAO,EAAE,aAAa,EAAa,MAAM,0BAA0B,CAAC;AAEpE,yEAAyE;AACzE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AAEjF,8BAA8B;AAC9B,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,aAAa,CAAC;AAE7E,uBAAuB;AACvB,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;AAEzE,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAU,EAAW,EAAE,CAC/C,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AAEhE,wBAAwB;AACxB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC;AAEhF,0BAA0B;AAC1B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAU,EAAW,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,eAAe,CAAC;AAEpF,8CAA8C;AAC9C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAU,EAAW,EAAE,CAC5C,IAAI,CAAC,IAAI,KAAK,gBAAgB;IAC9B,IAAI,CAAC,IAAI,KAAK,kBAAkB;IAChC,IAAI,CAAC,IAAI,KAAK,iBAAiB,CAAC;AAElC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAW,EAAE;IAC9C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IACzE,OAAO,SAAS,KAAK,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;AACjD,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Rust {@link LanguageQueryAPI} (ADR-0010, M10) β€” the grammar config for the
3
+ * shared `createTreeSitterQuery` factory. Node types are from tree-sitter-rust;
4
+ * the callee/import extractors mirror `graph-rust`'s resolver + use-declaration
5
+ * walker so the query agrees with the call graph. The `/* v8 ignore *\/`
6
+ * markers follow the graph adapters' convention: they guard AST shapes that
7
+ * only a malformed/partial tree (error recovery) produces, which well-formed
8
+ * Rust source never reaches.
9
+ */
10
+ import { type LanguageQueryAPI, type Node, type ParsedFile } from '@opensip-cli/tree-sitter';
11
+ export declare const rustQuery: LanguageQueryAPI<ParsedFile, Node>;
12
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAEH,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,IAAI,EACT,KAAK,UAAU,EAChB,MAAM,0BAA0B,CAAC;AAsLlC,eAAO,MAAM,SAAS,EAAE,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAKvD,CAAC"}
package/dist/query.js ADDED
@@ -0,0 +1,194 @@
1
+ // @fitness-ignore-file duplicate-utility-functions -- ADR-0010/M10: the per-language tree-sitter query config intentionally shares helper names (callee/import/string extractors) across lang-* with grammar-specific implementations; consolidating would defeat the substrate design.
2
+ /**
3
+ * Rust {@link LanguageQueryAPI} (ADR-0010, M10) β€” the grammar config for the
4
+ * shared `createTreeSitterQuery` factory. Node types are from tree-sitter-rust;
5
+ * the callee/import extractors mirror `graph-rust`'s resolver + use-declaration
6
+ * walker so the query agrees with the call graph. The `/* v8 ignore *\/`
7
+ * markers follow the graph adapters' convention: they guard AST shapes that
8
+ * only a malformed/partial tree (error recovery) produces, which well-formed
9
+ * Rust source never reaches.
10
+ */
11
+ import { createTreeSitterQuery, namedChildrenOf, } from '@opensip-cli/tree-sitter';
12
+ /** Leaf callee name of a `call_expression` / `macro_invocation`. */
13
+ function calleeName(node) {
14
+ if (node.type === 'macro_invocation') {
15
+ const m = node.childForFieldName('macro') ?? node.namedChild(0);
16
+ /* v8 ignore next -- a macro_invocation always exposes its macro path */
17
+ if (!m)
18
+ return null;
19
+ return m.text.split('::').pop() ?? m.text;
20
+ }
21
+ const fn = node.childForFieldName('function');
22
+ /* v8 ignore next -- a call_expression always exposes its `function` field */
23
+ if (!fn)
24
+ return null;
25
+ if (fn.type === 'identifier')
26
+ return fn.text;
27
+ if (fn.type === 'field_expression') {
28
+ const field = fn.childForFieldName('field');
29
+ return field ? field.text : null;
30
+ }
31
+ if (fn.type === 'scoped_identifier') {
32
+ const name = fn.childForFieldName('name') ?? fn.namedChild(fn.namedChildCount - 1);
33
+ return name ? name.text : null;
34
+ }
35
+ // Other callee shapes (index/closure/parenthesized) β€” unresolved by name.
36
+ return null;
37
+ }
38
+ /** The `::`-joined segments of a path-bearing node, or null for unknown shapes. */
39
+ function pathText(node) {
40
+ if (node.type === 'identifier' ||
41
+ node.type === 'crate' ||
42
+ node.type === 'super' ||
43
+ node.type === 'self' ||
44
+ node.type === 'scoped_identifier') {
45
+ return node.text;
46
+ }
47
+ return null;
48
+ }
49
+ /** Last `::` segment of a path string β€” the "named import" for the SPI. */
50
+ function leafName(path) {
51
+ return path.split('::').pop() ?? path;
52
+ }
53
+ /**
54
+ * Expand a `use_declaration` / `extern_crate_declaration` into import targets.
55
+ * `use a::b::{x, y}` β†’ specifier `a::b`, names `[x, y]`. A single path
56
+ * (`use a::b::C`) β†’ specifier `a::b::C`, names `[C]`. Wildcards/aliases keep the
57
+ * underlying path and use the terminal segment as the name.
58
+ */
59
+ function extractImport(node) {
60
+ if (node.type === 'extern_crate_declaration') {
61
+ for (const c of namedChildrenOf(node)) {
62
+ if (c.type === 'identifier')
63
+ return [{ specifier: c.text, names: [c.text] }];
64
+ }
65
+ /* v8 ignore next -- extern_crate always has the crate identifier */
66
+ return [];
67
+ }
68
+ // use_declaration: take the last non-visibility named child as the path body.
69
+ let body = null;
70
+ for (let i = node.namedChildCount - 1; i >= 0; i--) {
71
+ const c = node.namedChild(i);
72
+ if (c && c.type !== 'visibility_modifier') {
73
+ body = c;
74
+ break;
75
+ }
76
+ }
77
+ /* v8 ignore next -- a use_declaration always has a path-bearing body */
78
+ if (!body)
79
+ return [];
80
+ return expandUseTree(body, '');
81
+ }
82
+ /** Join a path prefix and a segment with `::`, dropping empty parts. */
83
+ function joinPath(prefix, segment) {
84
+ if (!prefix)
85
+ return segment;
86
+ if (!segment)
87
+ return prefix;
88
+ return `${prefix}::${segment}`;
89
+ }
90
+ /**
91
+ * Single self-recursive walker over a `use`-tree node. Mirrors the Rust
92
+ * grammar's nesting (`use a::{b, c::{d}}`) by dispatching on the node type and
93
+ * recursing into list items / aliased inner paths with the accumulated `prefix`:
94
+ *
95
+ * - simple path (`identifier`/`crate`/`super`/`self`/`scoped_identifier`)
96
+ * β†’ one import `prefix::<path>` named by its terminal segment.
97
+ * - `use_as_clause` (`p as q`) β†’ recurse into the underlying path (the alias
98
+ * name is dropped; the terminal segment of the path is the import name).
99
+ * - `use_wildcard` (`p::*`) β†’ one glob import with no names.
100
+ * - `scoped_use_list` (`p::{…}`) β†’ recurse each list item under `prefix::p`.
101
+ * - bare `use_list` (`{…}`) β†’ recurse each list item under `prefix`.
102
+ * - `self` AS A LIST ITEM refers to the enclosing prefix path itself.
103
+ *
104
+ * Consolidated from the former mutual recursion (`expandUseSegment` ↔
105
+ * `expandScopedUseList` ↔ `expandUseListItems`) into one function so the static
106
+ * call graph sees a single self-recursive walker (no inter-function cycle); the
107
+ * behaviour is byte-identical.
108
+ */
109
+ function expandUseTree(node, prefix) {
110
+ const join = (seg) => (prefix ? `${prefix}::${seg}` : seg);
111
+ const simple = pathText(node);
112
+ if (simple !== null) {
113
+ const full = join(simple);
114
+ return [{ specifier: full, names: [leafName(full)] }];
115
+ }
116
+ if (node.type === 'use_as_clause') {
117
+ const inner = node.namedChild(0);
118
+ /* v8 ignore next -- a use_as_clause always wraps a path node */
119
+ return inner ? expandUseTree(inner, prefix) : [];
120
+ }
121
+ if (node.type === 'use_wildcard') {
122
+ const inner = node.namedChild(0);
123
+ const base = inner ? pathText(inner) : null;
124
+ const full = base === null ? join('*') : `${join(base)}::*`;
125
+ return [{ specifier: full, names: [] }];
126
+ }
127
+ // Both list shapes resolve to (a `use_list` node, the prefix its items extend)
128
+ // and then iterate those items β€” recursing into each via this same walker.
129
+ // `scoped_use_list` (`p::{…}`) carries a path segment ahead of its list, so its
130
+ // items extend `prefix::p`; a bare `use_list` (`{…}`) extends `prefix` unchanged.
131
+ // The list iteration is inlined (no helper) so the call graph sees ONE
132
+ // self-recursive walker rather than the former mutual recursion.
133
+ const { list, listPrefix } = resolveUseList(node, prefix);
134
+ if (!list)
135
+ return [];
136
+ // `self` AS A LIST ITEM refers to the enclosing prefix path itself
137
+ // (`use a::{self}` β†’ import `a`); every other item recurses under `listPrefix`.
138
+ const out = [];
139
+ for (const item of namedChildrenOf(list)) {
140
+ if (item.type === 'self') {
141
+ out.push({ specifier: listPrefix, names: [leafName(listPrefix)] });
142
+ continue;
143
+ }
144
+ out.push(...expandUseTree(item, listPrefix));
145
+ }
146
+ return out;
147
+ }
148
+ /**
149
+ * Resolve a use-tree node to its `use_list` and the prefix that list's items
150
+ * extend, or `{ list: null }` for a non-list node. Split out (a pure node→data
151
+ * helper that does NOT recurse) so {@link expandUseTree} stays a single
152
+ * self-recursive walker with no cross-function cycle.
153
+ */
154
+ function resolveUseList(node, prefix) {
155
+ if (node.type === 'scoped_use_list') {
156
+ let pathSeg = '';
157
+ let list = null;
158
+ for (const c of namedChildrenOf(node)) {
159
+ if (c.type === 'use_list')
160
+ list = c;
161
+ else if (list === null)
162
+ pathSeg = pathText(c) ?? '';
163
+ }
164
+ /* v8 ignore next -- a scoped_use_list always contains its use_list */
165
+ if (!list)
166
+ return { list: null, listPrefix: prefix };
167
+ return { list, listPrefix: joinPath(prefix, pathSeg) };
168
+ }
169
+ /* v8 ignore next 3 -- a bare top-level use_list (or any other shape) is not
170
+ produced for well-formed source the walker reaches */
171
+ if (node.type === 'use_list') {
172
+ return { list: node, listPrefix: prefix };
173
+ }
174
+ return { list: null, listPrefix: prefix };
175
+ }
176
+ const FUNCTION_NODE_TYPES = new Set(['function_item', 'closure_expression']);
177
+ const CALL_NODE_TYPES = new Set(['call_expression', 'macro_invocation']);
178
+ const IMPORT_NODE_TYPES = new Set(['use_declaration', 'extern_crate_declaration']);
179
+ const STRING_NODE_TYPES = new Set(['string_literal', 'raw_string_literal']);
180
+ /** A `closure_expression` has no name field β€” keep `findFunctions` faithful. */
181
+ function rustFunctionName(node) {
182
+ if (node.type === 'closure_expression')
183
+ return null;
184
+ const name = node.childForFieldName('name');
185
+ /* v8 ignore next -- a function_item always exposes its name field */
186
+ return name ? name.text : null;
187
+ }
188
+ export const rustQuery = createTreeSitterQuery({
189
+ functions: { nodeTypes: FUNCTION_NODE_TYPES, nameOf: rustFunctionName },
190
+ calls: { nodeTypes: CALL_NODE_TYPES, calleeName },
191
+ imports: { nodeTypes: IMPORT_NODE_TYPES, extract: extractImport },
192
+ strings: { nodeTypes: STRING_NODE_TYPES },
193
+ });
194
+ //# sourceMappingURL=query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensip-cli/lang-rust",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Rust language adapter for opensip-cli",
6
6
  "keywords": [
@@ -34,8 +34,8 @@
34
34
  "NOTICE"
35
35
  ],
36
36
  "dependencies": {
37
- "@opensip-cli/core": "0.1.7",
38
- "@opensip-cli/tree-sitter": "0.1.7"
37
+ "@opensip-cli/core": "0.1.9",
38
+ "@opensip-cli/tree-sitter": "0.1.9"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^24.13.2",