@codegraft/core 0.1.0-beta.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 +21 -0
- package/README.md +13 -0
- package/dist/assert.d.ts +8 -0
- package/dist/assert.d.ts.map +1 -0
- package/dist/assert.js +11 -0
- package/dist/assert.js.map +1 -0
- package/dist/collection.d.ts +164 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +570 -0
- package/dist/collection.js.map +1 -0
- package/dist/comment-attachment.d.ts +25 -0
- package/dist/comment-attachment.d.ts.map +1 -0
- package/dist/comment-attachment.js +94 -0
- package/dist/comment-attachment.js.map +1 -0
- package/dist/edit-collector.d.ts +31 -0
- package/dist/edit-collector.d.ts.map +1 -0
- package/dist/edit-collector.js +75 -0
- package/dist/edit-collector.js.map +1 -0
- package/dist/evaluate.d.ts +15 -0
- package/dist/evaluate.d.ts.map +1 -0
- package/dist/evaluate.js +95 -0
- package/dist/evaluate.js.map +1 -0
- package/dist/extensions.d.ts +3 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +19 -0
- package/dist/extensions.js.map +1 -0
- package/dist/generated/node-types.d.ts +31 -0
- package/dist/generated/node-types.d.ts.map +1 -0
- package/dist/generated/node-types.js +5 -0
- package/dist/generated/node-types.js.map +1 -0
- package/dist/helpers.d.ts +13 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +27 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +6 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +9 -0
- package/dist/internal.js.map +1 -0
- package/dist/parser.d.ts +30 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +125 -0
- package/dist/parser.js.map +1 -0
- package/dist/resolver.d.ts +27 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +241 -0
- package/dist/resolver.js.map +1 -0
- package/dist/rich-node.d.ts +5 -0
- package/dist/rich-node.d.ts.map +1 -0
- package/dist/rich-node.js +101 -0
- package/dist/rich-node.js.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/zone-splitter.d.ts +12 -0
- package/dist/zone-splitter.d.ts.map +1 -0
- package/dist/zone-splitter.js +23 -0
- package/dist/zone-splitter.js.map +1 -0
- package/package.json +62 -0
- package/wasm/tree-sitter-tsx.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
- package/wasm/tree-sitter-yaml.wasm +0 -0
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { assert } from './assert.js';
|
|
2
|
+
// TypeScript type-position navigation, so a rewrite needn't know tree-sitter field
|
|
3
|
+
// names. Public helpers a codemod body can call.
|
|
4
|
+
export function getPropertySignatures(objectType) {
|
|
5
|
+
return objectType.children.filter((child) => child.type === 'property_signature');
|
|
6
|
+
}
|
|
7
|
+
export function getPropertyName(signature) {
|
|
8
|
+
return signature.child('name')?.text ?? null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The `{ name, type }` branches of an object type, with each property's `: T` annotation
|
|
12
|
+
* unwrapped to `T`. The canonical use is collapsing a `BATI.If<{ featureA: T; default: U }>`
|
|
13
|
+
* conditional type to the branch whose name is an enabled feature (else `default`).
|
|
14
|
+
*/
|
|
15
|
+
export function getConditionalBranches(objectType) {
|
|
16
|
+
const branches = [];
|
|
17
|
+
for (const signature of getPropertySignatures(objectType)) {
|
|
18
|
+
const type = signature.child('type')?.children[0];
|
|
19
|
+
if (!type)
|
|
20
|
+
continue; // a property without a type annotation isn't a branch
|
|
21
|
+
const name = getPropertyName(signature);
|
|
22
|
+
assert(name !== null, 'a property_signature is always named');
|
|
23
|
+
branches.push({ name, type });
|
|
24
|
+
}
|
|
25
|
+
return branches;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,mFAAmF;AACnF,iDAAiD;AAEjD,MAAM,UAAU,qBAAqB,CAAC,UAAoB;IACxD,OAAO,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,oBAAoB,CAAC,CAAA;AACnF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAmB;IACjD,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,IAAI,IAAI,CAAA;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAoB;IACzD,MAAM,QAAQ,GAA4C,EAAE,CAAA;IAC5D,KAAK,MAAM,SAAS,IAAI,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;QACjD,IAAI,CAAC,IAAI;YAAE,SAAQ,CAAC,sDAAsD;QAC1E,MAAM,IAAI,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;QACvC,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,sCAAsC,CAAC,CAAA;QAC7D,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAC/B,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Collection, createCodemodTransformer } from './collection.js';
|
|
2
|
+
export { evaluate } from './evaluate.js';
|
|
3
|
+
export { getPropertySignatures, getPropertyName, getConditionalBranches } from './helpers.js';
|
|
4
|
+
export type { GrammarId, Point, ZoneSplitter, RichNode, Zone, SourceMap, Transformer, LazyTransformer, } from './types.js';
|
|
5
|
+
export type { NodeType, NodeTypeAll, FieldName, NodeTypeOf, NodeTypeAllOf, FieldNameOf, JavascriptNodeType, TypescriptNodeType, TsxNodeType, HtmlNodeType, CssNodeType, } from './generated/node-types.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC7F,YAAY,EACV,SAAS,EACT,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,IAAI,EACJ,SAAS,EACT,WAAW,EACX,eAAe,GAChB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,SAAS,EACT,UAAU,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,WAAW,GACZ,MAAM,2BAA2B,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Parser, grammarPackage } from './parser.js';
|
|
2
|
+
export { EXTENSION_GRAMMAR } from './extensions.js';
|
|
3
|
+
export { wrapNode } from './rich-node.js';
|
|
4
|
+
export { assert } from './assert.js';
|
|
5
|
+
export type { Node, Tree } from 'web-tree-sitter';
|
|
6
|
+
//# sourceMappingURL=internal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC,YAAY,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/internal.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Internal primitives for first-party build-time packages (@codegraft/cli, @codegraft/vue,
|
|
2
|
+
// @codegraft/unplugin). These are NOT part of the public consumer API — they are exposed only
|
|
3
|
+
// through the "@codegraft/core/internal" subpath (e.g. EXTENSION_GRAMMAR for the bundler plugin,
|
|
4
|
+
// grammarPackage for the CLI) so they need not duplicate the Parser/RichNode the runtime uses.
|
|
5
|
+
export { Parser, grammarPackage } from './parser.js';
|
|
6
|
+
export { EXTENSION_GRAMMAR } from './extensions.js';
|
|
7
|
+
export { wrapNode } from './rich-node.js';
|
|
8
|
+
export { assert } from './assert.js';
|
|
9
|
+
//# sourceMappingURL=internal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internal.js","sourceRoot":"","sources":["../src/internal.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAC3F,8FAA8F;AAC9F,iGAAiG;AACjG,+FAA+F;AAC/F,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Tree } from 'web-tree-sitter';
|
|
2
|
+
import type { GrammarId } from './types.js';
|
|
3
|
+
/** Idempotent. Loads the web-tree-sitter WASM runtime once per process. */
|
|
4
|
+
declare function init(): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Lazily load a grammar, idempotent per `id`. Built-in {@link GrammarId}s resolve
|
|
7
|
+
* their own `.wasm`; an external grammar (e.g. a {@link ZoneSplitter}'s shell
|
|
8
|
+
* grammar) passes its `wasmPath` and an arbitrary `id` used as the cache key.
|
|
9
|
+
*/
|
|
10
|
+
declare function loadGrammar(id: GrammarId | string, wasmPath?: string): Promise<void>;
|
|
11
|
+
/** The npm package a consumer must install for a built-in grammar, or `null` for a vendored
|
|
12
|
+
* grammar that ships with `@codegraft/core`. */
|
|
13
|
+
export declare function grammarPackage(id: GrammarId): string | null;
|
|
14
|
+
/** Parse `source` with an already-loaded grammar. Reuses one parser instance; safe
|
|
15
|
+
* because transforms run synchronously and trees are independent of the parser. */
|
|
16
|
+
declare function parse(source: string, id: GrammarId | string): Tree;
|
|
17
|
+
/** The subtypes of a grammar supertype, expanded transitively (`statement` → `declaration` →
|
|
18
|
+
* `lexical_declaration`, …), or `[]` if `typeName` is not a supertype. Intermediate supertype
|
|
19
|
+
* names are kept too — harmless, since only concrete types appear in a tree. Memoised per grammar,
|
|
20
|
+
* so a `find` can call it per node. */
|
|
21
|
+
declare function subtypesOf(id: GrammarId | string, typeName: string): string[];
|
|
22
|
+
/** Singleton confining every web-tree-sitter init/load concern to this module. */
|
|
23
|
+
export declare const Parser: {
|
|
24
|
+
init: typeof init;
|
|
25
|
+
loadGrammar: typeof loadGrammar;
|
|
26
|
+
parse: typeof parse;
|
|
27
|
+
subtypesOf: typeof subtypesOf;
|
|
28
|
+
};
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAsC3C,2EAA2E;AAC3E,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAGnC;AAED;;;;GAIG;AACH,iBAAe,WAAW,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnF;AAQD;iDACiD;AACjD,wBAAgB,cAAc,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAG3D;AAeD;oFACoF;AACpF,iBAAS,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAQ3D;AAED;;;wCAGwC;AACxC,iBAAS,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAsBtE;AAED,kFAAkF;AAClF,eAAO,MAAM,MAAM;;;;;CAA2C,CAAA"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { Language, Parser as TreeSitter } from 'web-tree-sitter';
|
|
5
|
+
import { assert } from './assert.js';
|
|
6
|
+
// web-tree-sitter resolves the grammar `.wasm` from its npm package at runtime; the
|
|
7
|
+
// engine wasm (`tree-sitter.wasm`) is self-located by `Parser.init()`.
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
/**
|
|
10
|
+
* The typescript/tsx grammars are **vendored** here (resolved relative to this module): the npm
|
|
11
|
+
* `tree-sitter-typescript` ships an ABI-14 wasm, which web-tree-sitter loads without supertype
|
|
12
|
+
* metadata (so `find` can't expand `expression` etc.). We ship an ABI-15 rebuild — see
|
|
13
|
+
* `scripts/regen-ts-wasm.sh` — so they impose no peer dependency.
|
|
14
|
+
*/
|
|
15
|
+
const VENDORED_WASM = {
|
|
16
|
+
typescript: 'tree-sitter-typescript.wasm',
|
|
17
|
+
tsx: 'tree-sitter-tsx.wasm',
|
|
18
|
+
// tree-sitter-yaml ships no prebuilt wasm on the bare `tree-sitter-yaml` package; we vendor the
|
|
19
|
+
// one from `@tree-sitter-grammars/tree-sitter-yaml` so YAML imposes no peer dependency.
|
|
20
|
+
yaml: 'tree-sitter-yaml.wasm',
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The npm specifier of each remaining built-in grammar's `.wasm` (these already ship the ABI we
|
|
24
|
+
* need). Optional peer dependencies: resolved only when the grammar is requested, and a missing
|
|
25
|
+
* package becomes an actionable error in `resolveBuiltinWasm`.
|
|
26
|
+
*/
|
|
27
|
+
const PEER_WASM = {
|
|
28
|
+
javascript: 'tree-sitter-javascript/tree-sitter-javascript.wasm',
|
|
29
|
+
html: 'tree-sitter-html/tree-sitter-html.wasm',
|
|
30
|
+
css: 'tree-sitter-css/tree-sitter-css.wasm',
|
|
31
|
+
};
|
|
32
|
+
let initPromise = null;
|
|
33
|
+
let parser = null;
|
|
34
|
+
const languages = new Map();
|
|
35
|
+
const loads = new Map();
|
|
36
|
+
const subtypeCache = new Map();
|
|
37
|
+
/** Idempotent. Loads the web-tree-sitter WASM runtime once per process. */
|
|
38
|
+
async function init() {
|
|
39
|
+
initPromise ??= TreeSitter.init();
|
|
40
|
+
await initPromise;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Lazily load a grammar, idempotent per `id`. Built-in {@link GrammarId}s resolve
|
|
44
|
+
* their own `.wasm`; an external grammar (e.g. a {@link ZoneSplitter}'s shell
|
|
45
|
+
* grammar) passes its `wasmPath` and an arbitrary `id` used as the cache key.
|
|
46
|
+
*/
|
|
47
|
+
async function loadGrammar(id, wasmPath) {
|
|
48
|
+
if (languages.has(id))
|
|
49
|
+
return;
|
|
50
|
+
let pending = loads.get(id);
|
|
51
|
+
if (!pending) {
|
|
52
|
+
pending = loadLanguage(id, wasmPath);
|
|
53
|
+
loads.set(id, pending);
|
|
54
|
+
}
|
|
55
|
+
languages.set(id, await pending);
|
|
56
|
+
}
|
|
57
|
+
async function loadLanguage(id, wasmPath) {
|
|
58
|
+
await init();
|
|
59
|
+
const path = wasmPath ?? resolveBuiltinWasm(id);
|
|
60
|
+
return Language.load(readFileSync(path));
|
|
61
|
+
}
|
|
62
|
+
/** The npm package a consumer must install for a built-in grammar, or `null` for a vendored
|
|
63
|
+
* grammar that ships with `@codegraft/core`. */
|
|
64
|
+
export function grammarPackage(id) {
|
|
65
|
+
const spec = PEER_WASM[id];
|
|
66
|
+
return spec ? spec.slice(0, spec.indexOf('/')) : null;
|
|
67
|
+
}
|
|
68
|
+
function resolveBuiltinWasm(id) {
|
|
69
|
+
const vendored = VENDORED_WASM[id];
|
|
70
|
+
if (vendored)
|
|
71
|
+
return fileURLToPath(new URL(`../wasm/${vendored}`, import.meta.url));
|
|
72
|
+
const spec = PEER_WASM[id];
|
|
73
|
+
assert(spec, `grammar '${id}' is not built in; a ZoneSplitter must pass its own wasmPath to loadGrammar`);
|
|
74
|
+
try {
|
|
75
|
+
return require.resolve(spec);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
const pkg = spec.slice(0, spec.indexOf('/'));
|
|
79
|
+
throw new Error(`[codegraft] grammar '${id}' requires the optional peer '${pkg}'; add it to your dependencies`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Parse `source` with an already-loaded grammar. Reuses one parser instance; safe
|
|
83
|
+
* because transforms run synchronously and trees are independent of the parser. */
|
|
84
|
+
function parse(source, id) {
|
|
85
|
+
const language = languages.get(id);
|
|
86
|
+
assert(language, `grammar '${id}' not loaded; call loadGrammar('${id}') first`);
|
|
87
|
+
parser ??= new TreeSitter();
|
|
88
|
+
parser.setLanguage(language);
|
|
89
|
+
const tree = parser.parse(source);
|
|
90
|
+
assert(tree, `parsing produced no tree for grammar '${id}'`);
|
|
91
|
+
return tree;
|
|
92
|
+
}
|
|
93
|
+
/** The subtypes of a grammar supertype, expanded transitively (`statement` → `declaration` →
|
|
94
|
+
* `lexical_declaration`, …), or `[]` if `typeName` is not a supertype. Intermediate supertype
|
|
95
|
+
* names are kept too — harmless, since only concrete types appear in a tree. Memoised per grammar,
|
|
96
|
+
* so a `find` can call it per node. */
|
|
97
|
+
function subtypesOf(id, typeName) {
|
|
98
|
+
const language = languages.get(id);
|
|
99
|
+
assert(language, `grammar '${id}' not loaded; call loadGrammar('${id}') first`);
|
|
100
|
+
let perGrammar = subtypeCache.get(id);
|
|
101
|
+
if (!perGrammar)
|
|
102
|
+
subtypeCache.set(id, (perGrammar = new Map()));
|
|
103
|
+
let names = perGrammar.get(typeName);
|
|
104
|
+
if (!names) {
|
|
105
|
+
const supertypes = new Set(language.supertypes);
|
|
106
|
+
const root = language.idForNodeType(typeName, true);
|
|
107
|
+
const out = new Set();
|
|
108
|
+
const queue = root !== null && supertypes.has(root) ? [root] : [];
|
|
109
|
+
for (let sym = queue.pop(); sym !== undefined; sym = queue.pop()) {
|
|
110
|
+
for (const sub of language.subtypes(sym)) {
|
|
111
|
+
const name = language.nodeTypeForId(sub);
|
|
112
|
+
if (!name || out.has(name))
|
|
113
|
+
continue;
|
|
114
|
+
out.add(name);
|
|
115
|
+
if (supertypes.has(sub))
|
|
116
|
+
queue.push(sub); // nested supertype — expand to its leaves
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
perGrammar.set(typeName, (names = [...out]));
|
|
120
|
+
}
|
|
121
|
+
return names;
|
|
122
|
+
}
|
|
123
|
+
/** Singleton confining every web-tree-sitter init/load concern to this module. */
|
|
124
|
+
export const Parser = { init, loadGrammar, parse, subtypesOf };
|
|
125
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { RichNode } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Lexical binding resolution for one parsed tree — **JS/TS/TSX only**, syntactic (no types).
|
|
4
|
+
*
|
|
5
|
+
* Confident-or-abstain: a query returns `null` whenever the tree contains a construct the
|
|
6
|
+
* resolver does not fully model (`with`, `eval`, a TS namespace/ambient module, an unknown binding
|
|
7
|
+
* form, or an occurrence that can't be renamed in place such as an object shorthand). A codemod
|
|
8
|
+
* treats `null` as "do not proceed", so a rename never fires on a guess. (A TS `enum` is modelled —
|
|
9
|
+
* its name binds like a class — so it does not force abstention.)
|
|
10
|
+
*
|
|
11
|
+
* Value vs type is mostly free here: tree-sitter spells type references `type_identifier`, so
|
|
12
|
+
* collecting `identifier` nodes naturally excludes them.
|
|
13
|
+
*/
|
|
14
|
+
export interface Resolver {
|
|
15
|
+
/** Every occurrence (declaration + value references) of the binding `decl` introduces; `null`
|
|
16
|
+
* to abstain. */
|
|
17
|
+
references(decl: RichNode): RichNode[] | null;
|
|
18
|
+
/** The declaration a value reference resolves to; `null` for a global or to abstain. */
|
|
19
|
+
definition(ref: RichNode): RichNode | null;
|
|
20
|
+
/** The declaration `name` resolves to from `at`'s position; `null` for a global or to abstain. */
|
|
21
|
+
lookup(at: RichNode, name: string): RichNode | null;
|
|
22
|
+
/** Every binding visible at `at` (inner shadows outer), or `null` to abstain. */
|
|
23
|
+
bindingsInScope(at: RichNode): RichNode[] | null;
|
|
24
|
+
}
|
|
25
|
+
/** A resolver for `root`'s tree, or `null` if the language has no binding model. */
|
|
26
|
+
export declare function createResolver(root: RichNode): Resolver | null;
|
|
27
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,QAAQ;IACvB;sBACkB;IAClB,UAAU,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAA;IAC7C,wFAAwF;IACxF,UAAU,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAAA;IAC1C,kGAAkG;IAClG,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAA;IACnD,iFAAiF;IACjF,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAA;CACjD;AAID,oFAAoF;AACpF,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAE9D"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
const SUPPORTED = new Set(['javascript', 'typescript', 'tsx']);
|
|
2
|
+
/** A resolver for `root`'s tree, or `null` if the language has no binding model. */
|
|
3
|
+
export function createResolver(root) {
|
|
4
|
+
return SUPPORTED.has(root.language) ? new ScopeResolver(root) : null;
|
|
5
|
+
}
|
|
6
|
+
class ScopeResolver {
|
|
7
|
+
#abstain = false;
|
|
8
|
+
#root;
|
|
9
|
+
/** scope-owning node → its scope (the only nodes recorded; `#scopeAt` walks up to them). */
|
|
10
|
+
#scopes = new Map();
|
|
11
|
+
constructor(root) {
|
|
12
|
+
this.#root = { node: root, parent: null, bindings: new Map() };
|
|
13
|
+
this.#scopes.set(root, this.#root);
|
|
14
|
+
this.#walk(root, this.#root, this.#root);
|
|
15
|
+
}
|
|
16
|
+
definition(ref) {
|
|
17
|
+
if (this.#abstain || ref.type !== 'identifier')
|
|
18
|
+
return null;
|
|
19
|
+
return this.lookup(ref, ref.text);
|
|
20
|
+
}
|
|
21
|
+
references(decl) {
|
|
22
|
+
if (this.#abstain || decl.type !== 'identifier')
|
|
23
|
+
return null;
|
|
24
|
+
const name = decl.text;
|
|
25
|
+
if (this.#scopeAt(decl).bindings.get(name) !== decl)
|
|
26
|
+
return null; // not a binding we own
|
|
27
|
+
const out = [];
|
|
28
|
+
let abstain = false;
|
|
29
|
+
const collect = (node) => {
|
|
30
|
+
if (abstain)
|
|
31
|
+
return;
|
|
32
|
+
if (node.text === name) {
|
|
33
|
+
// an object shorthand referencing this binding can't be renamed in place
|
|
34
|
+
if (node.type === 'shorthand_property_identifier' && this.lookup(node, name) === decl) {
|
|
35
|
+
abstain = true;
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (node.type === 'identifier' && this.lookup(node, name) === decl)
|
|
39
|
+
out.push(node);
|
|
40
|
+
}
|
|
41
|
+
for (const child of node.allChildren)
|
|
42
|
+
collect(child);
|
|
43
|
+
};
|
|
44
|
+
collect(this.#scopeAt(decl).node);
|
|
45
|
+
return abstain ? null : out;
|
|
46
|
+
}
|
|
47
|
+
lookup(at, name) {
|
|
48
|
+
if (this.#abstain)
|
|
49
|
+
return null;
|
|
50
|
+
for (let s = this.#scopeAt(at); s; s = s.parent) {
|
|
51
|
+
const binding = s.bindings.get(name);
|
|
52
|
+
if (binding)
|
|
53
|
+
return binding;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
bindingsInScope(at) {
|
|
58
|
+
if (this.#abstain)
|
|
59
|
+
return null;
|
|
60
|
+
const visible = new Map();
|
|
61
|
+
for (let s = this.#scopeAt(at); s; s = s.parent) {
|
|
62
|
+
for (const [name, decl] of s.bindings)
|
|
63
|
+
if (!visible.has(name))
|
|
64
|
+
visible.set(name, decl); // inner shadows outer
|
|
65
|
+
}
|
|
66
|
+
return [...visible.values()];
|
|
67
|
+
}
|
|
68
|
+
#scopeAt(node) {
|
|
69
|
+
for (let n = node; n; n = n.parent) {
|
|
70
|
+
const scope = this.#scopes.get(n);
|
|
71
|
+
if (scope)
|
|
72
|
+
return scope;
|
|
73
|
+
}
|
|
74
|
+
return this.#root;
|
|
75
|
+
}
|
|
76
|
+
#newScope(node, parent) {
|
|
77
|
+
const scope = { node, parent, bindings: new Map() };
|
|
78
|
+
this.#scopes.set(node, scope);
|
|
79
|
+
return scope;
|
|
80
|
+
}
|
|
81
|
+
#walk(node, scope, fnScope) {
|
|
82
|
+
if (this.#abstain)
|
|
83
|
+
return;
|
|
84
|
+
switch (node.type) {
|
|
85
|
+
// `with` makes any bare name a possible property; a TS namespace/ambient-module exposes its
|
|
86
|
+
// members as `X.m` (so a partial rename corrupts). Both are beyond syntactic resolution.
|
|
87
|
+
case 'with_statement':
|
|
88
|
+
case 'internal_module': // namespace X {}
|
|
89
|
+
case 'module': // module 'x' {}
|
|
90
|
+
this.#abstain = true;
|
|
91
|
+
return;
|
|
92
|
+
case 'call_expression':
|
|
93
|
+
if (node.child('function')?.text === 'eval') {
|
|
94
|
+
this.#abstain = true;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.#walkChildren(node, scope, fnScope);
|
|
98
|
+
return;
|
|
99
|
+
case 'function_declaration':
|
|
100
|
+
case 'generator_function_declaration': {
|
|
101
|
+
this.#bind(fnScope, node.child('name')); // hoisted to the enclosing function scope
|
|
102
|
+
const inner = this.#newScope(node, scope);
|
|
103
|
+
this.#bindParams(node, inner);
|
|
104
|
+
this.#walkChildren(node.child('body'), inner, inner);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
case 'function_expression':
|
|
108
|
+
case 'generator_function':
|
|
109
|
+
case 'arrow_function':
|
|
110
|
+
case 'method_definition': {
|
|
111
|
+
const inner = this.#newScope(node, scope);
|
|
112
|
+
this.#bind(inner, node.child('name')); // optional function-expression name
|
|
113
|
+
this.#bindParams(node, inner);
|
|
114
|
+
this.#walkChildren(node.child('body'), inner, inner);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
// A class/enum name binds in the enclosing scope; their members are `property_identifier`
|
|
118
|
+
// (reached as `X.member`), never free identifiers, so walking the body here is safe.
|
|
119
|
+
case 'class_declaration':
|
|
120
|
+
case 'enum_declaration': {
|
|
121
|
+
this.#bind(scope, node.child('name'));
|
|
122
|
+
this.#walkChildren(node.child('body'), scope, fnScope);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
case 'lexical_declaration': // let / const
|
|
126
|
+
for (const d of node.children) {
|
|
127
|
+
if (d.type !== 'variable_declarator')
|
|
128
|
+
continue;
|
|
129
|
+
this.#bindPattern(d.child('name'), scope);
|
|
130
|
+
this.#walkChildren(d.child('value'), scope, fnScope);
|
|
131
|
+
}
|
|
132
|
+
return;
|
|
133
|
+
case 'variable_declaration': // var → hoisted
|
|
134
|
+
for (const d of node.children) {
|
|
135
|
+
if (d.type !== 'variable_declarator')
|
|
136
|
+
continue;
|
|
137
|
+
this.#bindPattern(d.child('name'), fnScope);
|
|
138
|
+
this.#walkChildren(d.child('value'), scope, fnScope);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
case 'import_statement':
|
|
142
|
+
this.#bindImports(node);
|
|
143
|
+
return;
|
|
144
|
+
case 'statement_block': {
|
|
145
|
+
this.#walkChildren(node, this.#newScope(node, scope), fnScope);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
case 'for_statement':
|
|
149
|
+
case 'for_in_statement': {
|
|
150
|
+
this.#walkChildren(node, this.#newScope(node, scope), fnScope);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
case 'catch_clause': {
|
|
154
|
+
const inner = this.#newScope(node, scope);
|
|
155
|
+
this.#bindPattern(node.child('parameter'), inner);
|
|
156
|
+
this.#walkChildren(node.child('body'), inner, fnScope);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
default:
|
|
160
|
+
this.#walkChildren(node, scope, fnScope);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
#walkChildren(node, scope, fnScope) {
|
|
164
|
+
if (!node)
|
|
165
|
+
return;
|
|
166
|
+
for (const child of node.allChildren)
|
|
167
|
+
this.#walk(child, scope, fnScope);
|
|
168
|
+
}
|
|
169
|
+
#bind(scope, name) {
|
|
170
|
+
if (name?.type === 'identifier')
|
|
171
|
+
scope.bindings.set(name.text, name);
|
|
172
|
+
}
|
|
173
|
+
#bindParams(fn, scope) {
|
|
174
|
+
const params = fn.child('parameters');
|
|
175
|
+
if (params) {
|
|
176
|
+
for (const p of params.children)
|
|
177
|
+
this.#bindPattern(unwrapParameter(p), scope);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.#bindPattern(fn.child('parameter'), scope); // arrow `x => …`
|
|
181
|
+
}
|
|
182
|
+
#bindImports(node) {
|
|
183
|
+
const walk = (n) => {
|
|
184
|
+
if (n.type === 'identifier') {
|
|
185
|
+
this.#root.bindings.set(n.text, n); // default / namespace local
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
if (n.type === 'import_specifier') {
|
|
189
|
+
const local = n.child('alias') ?? n.child('name');
|
|
190
|
+
if (local?.type === 'identifier')
|
|
191
|
+
this.#root.bindings.set(local.text, local);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
for (const child of n.allChildren)
|
|
195
|
+
walk(child);
|
|
196
|
+
};
|
|
197
|
+
walk(node);
|
|
198
|
+
}
|
|
199
|
+
/** Bind every name a binding pattern introduces; abstain on an unknown pattern form. */
|
|
200
|
+
#bindPattern(node, scope) {
|
|
201
|
+
if (!node)
|
|
202
|
+
return;
|
|
203
|
+
switch (node.type) {
|
|
204
|
+
case 'identifier':
|
|
205
|
+
scope.bindings.set(node.text, node);
|
|
206
|
+
return;
|
|
207
|
+
case 'shorthand_property_identifier_pattern':
|
|
208
|
+
scope.bindings.set(node.text, node);
|
|
209
|
+
return;
|
|
210
|
+
case 'object_pattern':
|
|
211
|
+
for (const child of node.children) {
|
|
212
|
+
if (child.type === 'pair_pattern')
|
|
213
|
+
this.#bindPattern(child.child('value'), scope);
|
|
214
|
+
else
|
|
215
|
+
this.#bindPattern(child, scope);
|
|
216
|
+
}
|
|
217
|
+
return;
|
|
218
|
+
case 'array_pattern':
|
|
219
|
+
for (const child of node.children)
|
|
220
|
+
this.#bindPattern(child, scope);
|
|
221
|
+
return;
|
|
222
|
+
case 'rest_pattern':
|
|
223
|
+
this.#bindPattern(node.children[0] ?? null, scope);
|
|
224
|
+
return;
|
|
225
|
+
case 'assignment_pattern':
|
|
226
|
+
case 'object_assignment_pattern':
|
|
227
|
+
this.#bindPattern(node.child('left') ?? node.children[0] ?? null, scope);
|
|
228
|
+
return;
|
|
229
|
+
default:
|
|
230
|
+
this.#abstain = true; // a binding form we don't model — abstain rather than mis-resolve
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/** TS wraps params as `required_parameter`/`optional_parameter` { pattern }; JS is the bare pattern. */
|
|
235
|
+
function unwrapParameter(param) {
|
|
236
|
+
if (param.type === 'required_parameter' || param.type === 'optional_parameter') {
|
|
237
|
+
return param.child('pattern') ?? param.children[0] ?? param;
|
|
238
|
+
}
|
|
239
|
+
return param;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Node } from 'web-tree-sitter';
|
|
2
|
+
import type { GrammarId, RichNode } from './types.js';
|
|
3
|
+
/** Wrap a parsed tree's root. Children are created lazily as the tree is walked. */
|
|
4
|
+
export declare function wrapNode(node: Node, language: GrammarId, startOffset: number): RichNode;
|
|
5
|
+
//# sourceMappingURL=rich-node.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-node.d.ts","sourceRoot":"","sources":["../src/rich-node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAS,QAAQ,EAAE,MAAM,YAAY,CAAA;AA2G5D,oFAAoF;AACpF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,QAAQ,CAEvF"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { COMMENT_TYPES } from './comment-attachment.js';
|
|
3
|
+
import { assert } from './assert.js';
|
|
4
|
+
/**
|
|
5
|
+
* Lazy wrapper over a web-tree-sitter `Node`. Scalar accessors (type/text/positions)
|
|
6
|
+
* read straight through to the backing node; `allChildren` and `children` are built
|
|
7
|
+
* once and cached, so there is exactly one `RichNodeImpl` per backing node within a
|
|
8
|
+
* subtree — which is what lets the comment-attachment pass write onto the same
|
|
9
|
+
* instances that pattern matching and rewrites later see.
|
|
10
|
+
*
|
|
11
|
+
* The class is internal; callers receive the `RichNode` interface via `wrapNode`.
|
|
12
|
+
*/
|
|
13
|
+
class RichNodeImpl {
|
|
14
|
+
language;
|
|
15
|
+
// Filled in by the comment-attachment pass; the arrays are mutable, the bindings are not.
|
|
16
|
+
leadingComments = [];
|
|
17
|
+
trailingComments = [];
|
|
18
|
+
innerComments = [];
|
|
19
|
+
#node;
|
|
20
|
+
#startOffset;
|
|
21
|
+
#parent;
|
|
22
|
+
#allChildren;
|
|
23
|
+
#children;
|
|
24
|
+
constructor(node, language, startOffset, parent) {
|
|
25
|
+
this.#node = node;
|
|
26
|
+
this.language = language;
|
|
27
|
+
this.#startOffset = startOffset;
|
|
28
|
+
this.#parent = parent;
|
|
29
|
+
}
|
|
30
|
+
get type() {
|
|
31
|
+
// The grammar guarantees the raw string is one of its node types; assert it into the union.
|
|
32
|
+
return this.#node.type;
|
|
33
|
+
}
|
|
34
|
+
get isNamed() {
|
|
35
|
+
return this.#node.isNamed;
|
|
36
|
+
}
|
|
37
|
+
get text() {
|
|
38
|
+
return this.#node.text;
|
|
39
|
+
}
|
|
40
|
+
get startIndex() {
|
|
41
|
+
return this.#node.startIndex;
|
|
42
|
+
}
|
|
43
|
+
get endIndex() {
|
|
44
|
+
return this.#node.endIndex;
|
|
45
|
+
}
|
|
46
|
+
get startPosition() {
|
|
47
|
+
return this.#node.startPosition;
|
|
48
|
+
}
|
|
49
|
+
get endPosition() {
|
|
50
|
+
return this.#node.endPosition;
|
|
51
|
+
}
|
|
52
|
+
get parent() {
|
|
53
|
+
return this.#parent;
|
|
54
|
+
}
|
|
55
|
+
get documentStartIndex() {
|
|
56
|
+
return this.#node.startIndex + this.#startOffset;
|
|
57
|
+
}
|
|
58
|
+
get documentEndIndex() {
|
|
59
|
+
return this.#node.endIndex + this.#startOffset;
|
|
60
|
+
}
|
|
61
|
+
/** Full CST: every child, including anonymous punctuation and comments. */
|
|
62
|
+
get allChildren() {
|
|
63
|
+
return this.#computeAllChildren();
|
|
64
|
+
}
|
|
65
|
+
/** Named structural children with comments removed — the surface pattern matching
|
|
66
|
+
* walks, so neither punctuation nor comments can perturb a match. */
|
|
67
|
+
get children() {
|
|
68
|
+
const comments = COMMENT_TYPES[this.language];
|
|
69
|
+
this.#children ??= this.#computeAllChildren().filter((n) => n.isNamed && !comments.has(n.type));
|
|
70
|
+
return this.#children;
|
|
71
|
+
}
|
|
72
|
+
child(field) {
|
|
73
|
+
const target = this.#node.childForFieldName(field);
|
|
74
|
+
return target === null ? null : this.#wrapperFor(target, field);
|
|
75
|
+
}
|
|
76
|
+
childrenForField(field) {
|
|
77
|
+
return this.#node
|
|
78
|
+
.childrenForFieldName(field)
|
|
79
|
+
.filter((n) => n !== null)
|
|
80
|
+
.map((target) => this.#wrapperFor(target, field));
|
|
81
|
+
}
|
|
82
|
+
#computeAllChildren() {
|
|
83
|
+
this.#allChildren ??= this.#node.children
|
|
84
|
+
.filter((c) => c !== null)
|
|
85
|
+
.map((c) => new _a(c, this.language, this.#startOffset, this));
|
|
86
|
+
return this.#allChildren;
|
|
87
|
+
}
|
|
88
|
+
/** Map a backing field-child back to its cached wrapper, so identity (and any
|
|
89
|
+
* attached comments) is shared rather than re-wrapped. */
|
|
90
|
+
#wrapperFor(target, field) {
|
|
91
|
+
const wrapped = this.#computeAllChildren().find((c) => c.#node.equals(target));
|
|
92
|
+
assert(wrapped, `field '${field}' resolved to a node absent from allChildren`);
|
|
93
|
+
return wrapped;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
_a = RichNodeImpl;
|
|
97
|
+
/** Wrap a parsed tree's root. Children are created lazily as the tree is walked. */
|
|
98
|
+
export function wrapNode(node, language, startOffset) {
|
|
99
|
+
return new RichNodeImpl(node, language, startOffset, null);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=rich-node.js.map
|