@opensip-cli/tree-sitter 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/tree-sitter
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/tree-sitter
28
28
 
29
29
  ## License
30
30
 
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Unit tests for the shared `createTreeSitterQuery` factory (ADR-0010, M10).
3
+ *
4
+ * The tree-sitter package ships no grammar (the `.wasm` lives in each `lang-*`
5
+ * adapter), so these tests drive the factory over a hand-built minimal `Node`
6
+ * mock that implements only the surface the factory + `nodes.ts` helpers touch:
7
+ * `type`, `text`, `startPosition`, `namedChildren`, and `childForFieldName`.
8
+ * The per-language extractors are supplied by the config under test, so the
9
+ * generic traversal/assembly is exercised end-to-end. Each `lang-*` adapter
10
+ * additionally exercises the factory through its real grammar in its own
11
+ * `query.test.ts`.
12
+ */
13
+ export {};
14
+ //# 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":"AAAA;;;;;;;;;;;GAWG"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Unit tests for the shared `createTreeSitterQuery` factory (ADR-0010, M10).
3
+ *
4
+ * The tree-sitter package ships no grammar (the `.wasm` lives in each `lang-*`
5
+ * adapter), so these tests drive the factory over a hand-built minimal `Node`
6
+ * mock that implements only the surface the factory + `nodes.ts` helpers touch:
7
+ * `type`, `text`, `startPosition`, `namedChildren`, and `childForFieldName`.
8
+ * The per-language extractors are supplied by the config under test, so the
9
+ * generic traversal/assembly is exercised end-to-end. Each `lang-*` adapter
10
+ * additionally exercises the factory through its real grammar in its own
11
+ * `query.test.ts`.
12
+ */
13
+ import { describe, expect, it } from 'vitest';
14
+ import { createTreeSitterQuery, stripSurroundingQuotes } from '../query.js';
15
+ class MockNode {
16
+ type;
17
+ text;
18
+ startPosition;
19
+ namedChildren;
20
+ namedChildCount;
21
+ fields;
22
+ constructor(spec) {
23
+ this.type = spec.type;
24
+ this.text = spec.text ?? '';
25
+ this.startPosition = { row: spec.row ?? 0, column: spec.column ?? 0 };
26
+ this.namedChildren = spec.children ?? [];
27
+ this.namedChildCount = this.namedChildren.length;
28
+ this.fields = spec.fields ?? {};
29
+ }
30
+ childForFieldName(name) {
31
+ return this.fields[name] ?? null;
32
+ }
33
+ namedChild(i) {
34
+ return this.namedChildren[i] ?? null;
35
+ }
36
+ }
37
+ // The mock implements only the Node surface the factory + nodes.ts touch; cast
38
+ // at construction so call sites see a real `Node`.
39
+ function node(spec) {
40
+ return new MockNode(spec);
41
+ }
42
+ /** Wrap a root node as a ParsedFile (only `.tree.rootNode` is read). */
43
+ function asTree(root) {
44
+ return { tree: { rootNode: root }, source: '' };
45
+ }
46
+ const baseConfig = {
47
+ functions: { nodeTypes: new Set(['fn']) },
48
+ calls: {
49
+ nodeTypes: new Set(['call']),
50
+ calleeName: (n) => n.childForFieldName('name')?.text ?? null,
51
+ },
52
+ imports: {
53
+ nodeTypes: new Set(['import']),
54
+ extract: (n) => [{ specifier: n.text, names: [n.text.split('.').pop() ?? n.text] }],
55
+ },
56
+ strings: { nodeTypes: new Set(['str']) },
57
+ };
58
+ describe('stripSurroundingQuotes', () => {
59
+ it('strips matched double, single, and backtick quotes', () => {
60
+ expect(stripSurroundingQuotes('"abc"')).toBe('abc');
61
+ expect(stripSurroundingQuotes("'abc'")).toBe('abc');
62
+ expect(stripSurroundingQuotes('`abc`')).toBe('abc');
63
+ });
64
+ it('leaves unquoted / mismatched / too-short text untouched', () => {
65
+ expect(stripSurroundingQuotes('abc')).toBe('abc');
66
+ expect(stripSurroundingQuotes('"abc')).toBe('"abc');
67
+ expect(stripSurroundingQuotes('"')).toBe('"');
68
+ expect(stripSurroundingQuotes('')).toBe('');
69
+ });
70
+ });
71
+ describe('createTreeSitterQuery', () => {
72
+ it('findFunctions returns each function node with its name (null when absent)', () => {
73
+ const named = node({ type: 'fn', row: 1, fields: { name: node({ type: 'id', text: 'foo' }) } });
74
+ const anon = node({ type: 'fn', row: 2 });
75
+ const root = node({ type: 'root', children: [named, anon] });
76
+ const q = createTreeSitterQuery(baseConfig);
77
+ const fns = q.findFunctions(asTree(root));
78
+ expect(fns.map((f) => f.name)).toEqual(['foo', null]);
79
+ expect(fns[0].location).toEqual({ file: '', line: 2, column: 0 });
80
+ expect(fns[0].node).toBe(named);
81
+ });
82
+ it('findFunctions honours a custom nameOf', () => {
83
+ const fn = node({ type: 'fn', text: 'lambda' });
84
+ const root = node({ type: 'root', children: [fn] });
85
+ const q = createTreeSitterQuery({
86
+ ...baseConfig,
87
+ functions: { nodeTypes: new Set(['fn']), nameOf: () => null },
88
+ });
89
+ expect(q.findFunctions(asTree(root))[0].name).toBeNull();
90
+ });
91
+ it('findImports expands each import node into targets', () => {
92
+ const imp = node({ type: 'import', text: 'a.b.C', row: 3, column: 2 });
93
+ const root = node({ type: 'root', children: [imp] });
94
+ const q = createTreeSitterQuery(baseConfig);
95
+ const imports = q.findImports(asTree(root));
96
+ expect(imports).toEqual([
97
+ { specifier: 'a.b.C', names: ['C'], location: { file: '', line: 4, column: 2 } },
98
+ ]);
99
+ });
100
+ it('findCallsTo matches the leaf callee name', () => {
101
+ const call1 = node({ type: 'call', fields: { name: node({ type: 'id', text: 'foo' }) } });
102
+ const call2 = node({ type: 'call', fields: { name: node({ type: 'id', text: 'bar' }) } });
103
+ const root = node({ type: 'root', children: [call1, call2] });
104
+ const q = createTreeSitterQuery(baseConfig);
105
+ expect(q.findCallsTo(asTree(root), 'foo')).toEqual([call1]);
106
+ expect(q.findCallsTo(asTree(root), 'absent')).toEqual([]);
107
+ });
108
+ it('findStringLiterals uses the default quote-stripping value extractor', () => {
109
+ const str = node({ type: 'str', text: '"hello"', row: 0, column: 5 });
110
+ const root = node({ type: 'root', children: [str] });
111
+ const q = createTreeSitterQuery(baseConfig);
112
+ expect(q.findStringLiterals(asTree(root))).toEqual([
113
+ { value: 'hello', location: { file: '', line: 1, column: 5 } },
114
+ ]);
115
+ });
116
+ it('findStringLiterals honours a custom stringValue', () => {
117
+ const str = node({ type: 'str', text: 'RAW' });
118
+ const root = node({ type: 'root', children: [str] });
119
+ const q = createTreeSitterQuery({
120
+ ...baseConfig,
121
+ strings: { nodeTypes: new Set(['str']), stringValue: (n) => `<${n.text}>` },
122
+ });
123
+ expect(q.findStringLiterals(asTree(root))[0].value).toBe('<RAW>');
124
+ });
125
+ it('getLocation / getText read position and text from the node', () => {
126
+ const n = node({ type: 'x', text: 'body', row: 7, column: 3 });
127
+ const q = createTreeSitterQuery(baseConfig);
128
+ const tree = asTree(node({ type: 'root' }));
129
+ expect(q.getLocation(tree, n)).toEqual({ file: '', line: 8, column: 3 });
130
+ expect(q.getText(tree, n)).toBe('body');
131
+ });
132
+ });
133
+ //# 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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"}
package/dist/index.d.ts CHANGED
@@ -13,4 +13,5 @@
13
13
  export * from './types.js';
14
14
  export * from './lifecycle.js';
15
15
  export * from './nodes.js';
16
+ export * from './query.js';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -13,4 +13,5 @@
13
13
  export * from './types.js';
14
14
  export * from './lifecycle.js';
15
15
  export * from './nodes.js';
16
+ export * from './query.js';
16
17
  //# 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;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
@@ -15,7 +15,13 @@
15
15
  * adapter's own top-level `await loadGrammar(<wasm>)`.
16
16
  */
17
17
  import { Parser, Language, type Tree } from 'web-tree-sitter';
18
- /** Load a tree-sitter grammar from a `.wasm` path (adapter module top level). */
18
+ /**
19
+ * Load a tree-sitter grammar from a `.wasm` path (adapter module top level).
20
+ *
21
+ * @throws {Error} When the web-tree-sitter runtime failed to initialize (the
22
+ * contained `Parser.init()` above) — lang-* adapters catch this and degrade
23
+ * that language to "unavailable" rather than crashing the CLI.
24
+ */
19
25
  export declare function loadGrammar(wasmPath: string): Promise<Language>;
20
26
  /**
21
27
  * Create a parser bound to `grammar`. Adapters create one per grammar at
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAO9D,iFAAiF;AACjF,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAErE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAItD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEvE"}
1
+ {"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAmB9D;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAIrE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAItD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEvE"}
package/dist/lifecycle.js CHANGED
@@ -18,9 +18,31 @@ import { Parser, Language } from 'web-tree-sitter';
18
18
  // One-time WASM runtime init. Top-level await — every consumer statically
19
19
  // imports this module — guarantees the runtime is ready before any adapter's
20
20
  // `loadGrammar(<wasm>)` (which also runs at module top level).
21
- await Parser.init();
22
- /** Load a tree-sitter grammar from a `.wasm` path (adapter module top level). */
21
+ // Contained: if the WASM runtime fails to initialize (a broken/incompatible
22
+ // web-tree-sitter build), this module still LOADS `loadGrammar` then throws,
23
+ // and each lang-* adapter degrades its language to "unavailable" rather than
24
+ // crashing the whole CLI on import.
25
+ let runtimeReady = false;
26
+ /* v8 ignore start -- runtime-init failure is environment-dependent; not reproducible under the test runner */
27
+ try {
28
+ await Parser.init();
29
+ runtimeReady = true;
30
+ }
31
+ catch {
32
+ /* @swallow-ok runtime init failed → loadGrammar throws → adapters degrade per-language */
33
+ }
34
+ /* v8 ignore stop */
35
+ /**
36
+ * Load a tree-sitter grammar from a `.wasm` path (adapter module top level).
37
+ *
38
+ * @throws {Error} When the web-tree-sitter runtime failed to initialize (the
39
+ * contained `Parser.init()` above) — lang-* adapters catch this and degrade
40
+ * that language to "unavailable" rather than crashing the CLI.
41
+ */
23
42
  export async function loadGrammar(wasmPath) {
43
+ /* v8 ignore next -- only reachable when Parser.init() failed above */
44
+ if (!runtimeReady)
45
+ throw new Error('web-tree-sitter runtime is not initialized');
24
46
  return Language.load(wasmPath);
25
47
  }
26
48
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAa,MAAM,iBAAiB,CAAC;AAE9D,0EAA0E;AAC1E,6EAA6E;AAC7E,+DAA+D;AAC/D,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;AAEpB,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAiB;IAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,MAAc;IACxD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAa,MAAM,iBAAiB,CAAC;AAE9D,0EAA0E;AAC1E,6EAA6E;AAC7E,+DAA+D;AAC/D,4EAA4E;AAC5E,+EAA+E;AAC/E,6EAA6E;AAC7E,oCAAoC;AACpC,IAAI,YAAY,GAAG,KAAK,CAAC;AACzB,8GAA8G;AAC9G,IAAI,CAAC;IACH,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACpB,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAAC,MAAM,CAAC;IACP,0FAA0F;AAC5F,CAAC;AACD,oBAAoB;AAEpB;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB;IAChD,sEAAsE;IACtE,IAAI,CAAC,YAAY;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IACjF,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAiB;IAC5C,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;IAC5B,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc,EAAE,MAAc;IACxD,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * `createTreeSitterQuery` — the shared, grammar-agnostic implementation of
3
+ * core's {@link LanguageQueryAPI} for every tree-sitter `lang-*` adapter
4
+ * (ADR-0010, M10). The traversal is written once here; each adapter supplies a
5
+ * tiny {@link TreeSitterQueryConfig} naming its grammar's node types plus the
6
+ * handful of extractors a grammar genuinely differs on (callee name, import
7
+ * shape, string value).
8
+ *
9
+ * The query operates over the adapter's parse result — a {@link ParsedFile}
10
+ * (`{ tree, source }`), the same value `adapter.parse()` returns — so it slots
11
+ * straight onto `LanguageAdapter<ParsedFile, Node>.query` exactly the way
12
+ * `typescriptQuery` slots onto `LanguageAdapter<ts.SourceFile, ts.Node>`.
13
+ *
14
+ * The semantics mirror `lang-typescript`'s reference `typescriptQuery` so the
15
+ * equivalence cross-language checks expect holds:
16
+ *
17
+ * - `findFunctions` — every function/method/lambda declaration node,
18
+ * `name` via the grammar `name` field (`null` for
19
+ * anonymous lambdas/closures), matching TS's mix of
20
+ * function declarations + arrow/method nodes.
21
+ * - `findImports` — one {@link Import} per import target. `names` is
22
+ * populated where the grammar exposes named imports
23
+ * (Rust `use a::{x, y}`, Python `from m import x`);
24
+ * empty where the language has no named-import concept
25
+ * (Go/Java import a whole package/type by path — the
26
+ * faithful equivalent, not a silent gap).
27
+ * - `findCallsTo` — call/macro/invocation nodes whose *leaf* callee name
28
+ * equals `name` (the same leaf-name match TS uses for
29
+ * `foo()` and `obj.bar()`), via the per-grammar
30
+ * `calleeName` extractor.
31
+ * - `findStringLiterals`— every string-literal node, value via the per-grammar
32
+ * `stringValue` extractor (default strips one matching
33
+ * pair of surrounding quotes).
34
+ * - `getLocation` / `getText` — `{ file, line(1-based), column(0-based) }` and
35
+ * `node.text`, matching the TS shapes.
36
+ *
37
+ * Faithful-equivalent note: a tree-sitter `Tree` carries no source filename
38
+ * (unlike a `ts.SourceFile`, whose `fileName` `typescriptQuery` uses), so
39
+ * `Location.file` is the empty string. Cross-language checks key on
40
+ * `line`/`column`/`value`, not on `file`.
41
+ *
42
+ * Traversal uses the package's {@link walkNodes} (named descendants only —
43
+ * punctuation/anonymous tokens are never functions, calls, imports, or string
44
+ * literals, so visiting them would only waste cycles).
45
+ */
46
+ import type { Node, ParsedFile } from './types.js';
47
+ import type { LanguageQueryAPI } from '@opensip-cli/core/languages';
48
+ export type { GenericFunction, Import, LanguageQueryAPI, Location, } from '@opensip-cli/core/languages';
49
+ /**
50
+ * One import target extracted from an import-declaration node. A single node
51
+ * can yield several (e.g. Go's grouped `import ( … )`, Rust's `use a::{x, y}`),
52
+ * so {@link TreeSitterQueryConfig.imports.extract} returns an array.
53
+ */
54
+ export interface ExtractedImport {
55
+ /** The import specifier as written (module path / crate path), no quotes. */
56
+ readonly specifier: string;
57
+ /** Named imports where the grammar supports them; empty otherwise. */
58
+ readonly names: readonly string[];
59
+ }
60
+ /** Per-language grammar configuration for {@link createTreeSitterQuery}. */
61
+ export interface TreeSitterQueryConfig {
62
+ readonly functions: {
63
+ /** Grammar node types that declare a callable (function/method/lambda). */
64
+ readonly nodeTypes: ReadonlySet<string>;
65
+ /**
66
+ * The declared name of a function node, or `null` for anonymous shapes.
67
+ * Defaults to {@link nameOf} (reads the grammar `name` field).
68
+ */
69
+ readonly nameOf?: (node: Node) => string | null;
70
+ };
71
+ readonly calls: {
72
+ /** Grammar node types for a call/invocation (call_expression, call, …). */
73
+ readonly nodeTypes: ReadonlySet<string>;
74
+ /**
75
+ * The leaf callee name of a call node, or `null` when the shape isn't a
76
+ * simple named call (e.g. an index/computed callee). Mirrors each graph
77
+ * adapter's `extractCallTargetName`.
78
+ */
79
+ readonly calleeName: (node: Node) => string | null;
80
+ };
81
+ readonly imports: {
82
+ /** Grammar node types for an import/use declaration. */
83
+ readonly nodeTypes: ReadonlySet<string>;
84
+ /** Expand one import-declaration node into zero or more import targets. */
85
+ readonly extract: (node: Node) => readonly ExtractedImport[];
86
+ };
87
+ readonly strings: {
88
+ /** Grammar node types for a string literal. */
89
+ readonly nodeTypes: ReadonlySet<string>;
90
+ /**
91
+ * The literal's value. Defaults to {@link stripSurroundingQuotes} over
92
+ * `node.text` (handles the common `"…"` / `'…'` / backtick cases).
93
+ * Named `stringValue` (not `valueOf`) to avoid colliding with
94
+ * `Object.prototype.valueOf` in structural assignability.
95
+ */
96
+ readonly stringValue?: (node: Node) => string;
97
+ };
98
+ }
99
+ /** Strip one matched pair of surrounding `"`, `'`, or backtick quotes. */
100
+ export declare function stripSurroundingQuotes(text: string): string;
101
+ /**
102
+ * Build a {@link LanguageQueryAPI} over a {@link ParsedFile} from a per-language
103
+ * {@link TreeSitterQueryConfig}. The result is assignable to
104
+ * `LanguageAdapter<ParsedFile, Node>.query`.
105
+ */
106
+ export declare function createTreeSitterQuery(config: TreeSitterQueryConfig): LanguageQueryAPI<ParsedFile, Node>;
107
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAIH,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAGV,gBAAgB,EAEjB,MAAM,6BAA6B,CAAC;AAKrC,YAAY,EACV,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,QAAQ,GACT,MAAM,6BAA6B,CAAC;AAErC;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,4EAA4E;AAC5E,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE;QAClB,2EAA2E;QAC3E,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC;;;WAGG;QACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC;KACjD,CAAC;IACF,QAAQ,CAAC,KAAK,EAAE;QACd,2EAA2E;QAC3E,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC;;;;WAIG;QACH,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC;KACpD,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,wDAAwD;QACxD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,2EAA2E;QAC3E,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,eAAe,EAAE,CAAC;KAC9D,CAAC;IACF,QAAQ,CAAC,OAAO,EAAE;QAChB,+CAA+C;QAC/C,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC;;;;;WAKG;QACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;KAC/C,CAAC;CACH;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS3D;AAUD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,qBAAqB,GAC5B,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAmDpC"}
package/dist/query.js ADDED
@@ -0,0 +1,120 @@
1
+ /**
2
+ * `createTreeSitterQuery` — the shared, grammar-agnostic implementation of
3
+ * core's {@link LanguageQueryAPI} for every tree-sitter `lang-*` adapter
4
+ * (ADR-0010, M10). The traversal is written once here; each adapter supplies a
5
+ * tiny {@link TreeSitterQueryConfig} naming its grammar's node types plus the
6
+ * handful of extractors a grammar genuinely differs on (callee name, import
7
+ * shape, string value).
8
+ *
9
+ * The query operates over the adapter's parse result — a {@link ParsedFile}
10
+ * (`{ tree, source }`), the same value `adapter.parse()` returns — so it slots
11
+ * straight onto `LanguageAdapter<ParsedFile, Node>.query` exactly the way
12
+ * `typescriptQuery` slots onto `LanguageAdapter<ts.SourceFile, ts.Node>`.
13
+ *
14
+ * The semantics mirror `lang-typescript`'s reference `typescriptQuery` so the
15
+ * equivalence cross-language checks expect holds:
16
+ *
17
+ * - `findFunctions` — every function/method/lambda declaration node,
18
+ * `name` via the grammar `name` field (`null` for
19
+ * anonymous lambdas/closures), matching TS's mix of
20
+ * function declarations + arrow/method nodes.
21
+ * - `findImports` — one {@link Import} per import target. `names` is
22
+ * populated where the grammar exposes named imports
23
+ * (Rust `use a::{x, y}`, Python `from m import x`);
24
+ * empty where the language has no named-import concept
25
+ * (Go/Java import a whole package/type by path — the
26
+ * faithful equivalent, not a silent gap).
27
+ * - `findCallsTo` — call/macro/invocation nodes whose *leaf* callee name
28
+ * equals `name` (the same leaf-name match TS uses for
29
+ * `foo()` and `obj.bar()`), via the per-grammar
30
+ * `calleeName` extractor.
31
+ * - `findStringLiterals`— every string-literal node, value via the per-grammar
32
+ * `stringValue` extractor (default strips one matching
33
+ * pair of surrounding quotes).
34
+ * - `getLocation` / `getText` — `{ file, line(1-based), column(0-based) }` and
35
+ * `node.text`, matching the TS shapes.
36
+ *
37
+ * Faithful-equivalent note: a tree-sitter `Tree` carries no source filename
38
+ * (unlike a `ts.SourceFile`, whose `fileName` `typescriptQuery` uses), so
39
+ * `Location.file` is the empty string. Cross-language checks key on
40
+ * `line`/`column`/`value`, not on `file`.
41
+ *
42
+ * Traversal uses the package's {@link walkNodes} (named descendants only —
43
+ * punctuation/anonymous tokens are never functions, calls, imports, or string
44
+ * literals, so visiting them would only waste cycles).
45
+ */
46
+ import { getColumn, getLineNumber, nameOf, walkNodes } from './nodes.js';
47
+ /** Strip one matched pair of surrounding `"`, `'`, or backtick quotes. */
48
+ export function stripSurroundingQuotes(text) {
49
+ if (text.length >= 2) {
50
+ const first = text[0];
51
+ const last = text.at(-1);
52
+ if ((first === '"' || first === "'" || first === '`') && last === first) {
53
+ return text.slice(1, -1);
54
+ }
55
+ }
56
+ return text;
57
+ }
58
+ // tree-sitter trees carry no source path; Location.file is empty (see the
59
+ // factory docstring). Checks key on line/column/value, not file.
60
+ const NO_FILE = '';
61
+ function locationOf(node) {
62
+ return { file: NO_FILE, line: getLineNumber(node), column: getColumn(node) };
63
+ }
64
+ /**
65
+ * Build a {@link LanguageQueryAPI} over a {@link ParsedFile} from a per-language
66
+ * {@link TreeSitterQueryConfig}. The result is assignable to
67
+ * `LanguageAdapter<ParsedFile, Node>.query`.
68
+ */
69
+ export function createTreeSitterQuery(config) {
70
+ const functionName = config.functions.nameOf ?? nameOf;
71
+ const stringValue = config.strings.stringValue ?? ((node) => stripSurroundingQuotes(node.text));
72
+ return {
73
+ findFunctions(tree) {
74
+ const out = [];
75
+ walkNodes(tree.tree.rootNode, (node) => {
76
+ if (config.functions.nodeTypes.has(node.type)) {
77
+ out.push({ name: functionName(node), location: locationOf(node), node });
78
+ }
79
+ });
80
+ return out;
81
+ },
82
+ findImports(tree) {
83
+ const out = [];
84
+ walkNodes(tree.tree.rootNode, (node) => {
85
+ if (!config.imports.nodeTypes.has(node.type))
86
+ return;
87
+ const location = locationOf(node);
88
+ for (const imp of config.imports.extract(node)) {
89
+ out.push({ specifier: imp.specifier, names: imp.names, location });
90
+ }
91
+ });
92
+ return out;
93
+ },
94
+ findCallsTo(tree, name) {
95
+ const out = [];
96
+ walkNodes(tree.tree.rootNode, (node) => {
97
+ if (config.calls.nodeTypes.has(node.type) && config.calls.calleeName(node) === name) {
98
+ out.push(node);
99
+ }
100
+ });
101
+ return out;
102
+ },
103
+ findStringLiterals(tree) {
104
+ const out = [];
105
+ walkNodes(tree.tree.rootNode, (node) => {
106
+ if (config.strings.nodeTypes.has(node.type)) {
107
+ out.push({ value: stringValue(node), location: locationOf(node) });
108
+ }
109
+ });
110
+ return out;
111
+ },
112
+ getLocation(_tree, node) {
113
+ return locationOf(node);
114
+ },
115
+ getText(_tree, node) {
116
+ return node.text;
117
+ },
118
+ };
119
+ }
120
+ //# 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/tree-sitter",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Grammar-agnostic tree-sitter substrate (parser lifecycle + node accessors) shared by lang-* and the graph adapters",
6
6
  "keywords": [
@@ -32,7 +32,8 @@
32
32
  "NOTICE"
33
33
  ],
34
34
  "dependencies": {
35
- "web-tree-sitter": "0.26.9"
35
+ "web-tree-sitter": "0.26.9",
36
+ "@opensip-cli/core": "0.1.9"
36
37
  },
37
38
  "devDependencies": {
38
39
  "@types/node": "^24.13.2",