circle-ir 4.16.1 → 4.18.1
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/dist/analysis/advisories.d.ts +186 -0
- package/dist/analysis/advisories.d.ts.map +1 -0
- package/dist/analysis/advisories.js +391 -0
- package/dist/analysis/advisories.js.map +1 -0
- package/dist/analysis/comment-lines.d.ts +14 -0
- package/dist/analysis/comment-lines.d.ts.map +1 -0
- package/dist/analysis/comment-lines.js +34 -0
- package/dist/analysis/comment-lines.js.map +1 -0
- package/dist/analysis/config-loader.d.ts.map +1 -1
- package/dist/analysis/config-loader.js +59 -5
- package/dist/analysis/config-loader.js.map +1 -1
- package/dist/analysis/constant-caller-gate.d.ts +2 -2
- package/dist/analysis/constant-caller-gate.d.ts.map +1 -1
- package/dist/analysis/constant-caller-gate.js +205 -29
- package/dist/analysis/constant-caller-gate.js.map +1 -1
- package/dist/analysis/constant-propagation/index.d.ts +2 -0
- package/dist/analysis/constant-propagation/index.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/index.js +10 -0
- package/dist/analysis/constant-propagation/index.js.map +1 -1
- package/dist/analysis/constant-propagation/propagator.d.ts +15 -0
- package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
- package/dist/analysis/constant-propagation/propagator.js +224 -20
- package/dist/analysis/constant-propagation/propagator.js.map +1 -1
- package/dist/analysis/constant-propagation/types.d.ts +2 -0
- package/dist/analysis/constant-propagation/types.d.ts.map +1 -1
- package/dist/analysis/constant-propagation.d.ts +1 -1
- package/dist/analysis/constant-propagation.d.ts.map +1 -1
- package/dist/analysis/constant-propagation.js +1 -1
- package/dist/analysis/constant-propagation.js.map +1 -1
- package/dist/analysis/entry-point-detection.d.ts.map +1 -1
- package/dist/analysis/entry-point-detection.js +72 -0
- package/dist/analysis/entry-point-detection.js.map +1 -1
- package/dist/analysis/interprocedural.d.ts.map +1 -1
- package/dist/analysis/interprocedural.js +75 -8
- package/dist/analysis/interprocedural.js.map +1 -1
- package/dist/analysis/maven-declared.d.ts +72 -0
- package/dist/analysis/maven-declared.d.ts.map +1 -0
- package/dist/analysis/maven-declared.js +216 -0
- package/dist/analysis/maven-declared.js.map +1 -0
- package/dist/analysis/maven-version.d.ts +28 -0
- package/dist/analysis/maven-version.d.ts.map +1 -0
- package/dist/analysis/maven-version.js +172 -0
- package/dist/analysis/maven-version.js.map +1 -0
- package/dist/analysis/passes/constant-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/constant-propagation-pass.js +29 -1
- package/dist/analysis/passes/constant-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
- package/dist/analysis/passes/cross-file-pass.js +84 -2
- package/dist/analysis/passes/cross-file-pass.js.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +7 -0
- package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js +44 -1
- package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -1
- package/dist/analysis/passes/insecure-cookie-pass.d.ts +2 -0
- package/dist/analysis/passes/insecure-cookie-pass.d.ts.map +1 -1
- package/dist/analysis/passes/insecure-cookie-pass.js +25 -3
- package/dist/analysis/passes/insecure-cookie-pass.js.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.d.ts +11 -14
- package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
- package/dist/analysis/passes/interprocedural-pass.js +562 -0
- package/dist/analysis/passes/interprocedural-pass.js.map +1 -1
- package/dist/analysis/passes/language-sources-pass.d.ts +18 -1
- package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
- package/dist/analysis/passes/language-sources-pass.js +1079 -14
- package/dist/analysis/passes/language-sources-pass.js.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.d.ts.map +1 -1
- package/dist/analysis/passes/param-source-flow-gate-pass.js +82 -3
- package/dist/analysis/passes/param-source-flow-gate-pass.js.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.d.ts +44 -2
- package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
- package/dist/analysis/passes/sink-filter-pass.js +690 -12
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
- package/dist/analysis/passes/taint-propagation-pass.js +298 -19
- package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
- package/dist/analysis/passes/tls-verify-disabled-pass.d.ts +18 -0
- package/dist/analysis/passes/tls-verify-disabled-pass.d.ts.map +1 -1
- package/dist/analysis/passes/tls-verify-disabled-pass.js +161 -0
- package/dist/analysis/passes/tls-verify-disabled-pass.js.map +1 -1
- package/dist/analysis/passes/weak-random-pass.d.ts +6 -0
- package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -1
- package/dist/analysis/passes/weak-random-pass.js +29 -0
- package/dist/analysis/passes/weak-random-pass.js.map +1 -1
- package/dist/analysis/promote-cross-file-flows.d.ts +17 -0
- package/dist/analysis/promote-cross-file-flows.d.ts.map +1 -0
- package/dist/analysis/promote-cross-file-flows.js +32 -0
- package/dist/analysis/promote-cross-file-flows.js.map +1 -0
- package/dist/analysis/rust-literal-guard.d.ts.map +1 -1
- package/dist/analysis/rust-literal-guard.js +100 -1
- package/dist/analysis/rust-literal-guard.js.map +1 -1
- package/dist/analysis/sbom.d.ts +100 -0
- package/dist/analysis/sbom.d.ts.map +1 -1
- package/dist/analysis/sbom.js +514 -3
- package/dist/analysis/sbom.js.map +1 -1
- package/dist/analysis/semver-version.d.ts +30 -0
- package/dist/analysis/semver-version.d.ts.map +1 -0
- package/dist/analysis/semver-version.js +76 -0
- package/dist/analysis/semver-version.js.map +1 -0
- package/dist/analysis/taint-matcher.d.ts +5 -0
- package/dist/analysis/taint-matcher.d.ts.map +1 -1
- package/dist/analysis/taint-matcher.js +226 -4
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analyzer.d.ts +57 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +69 -6
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +3360 -314
- package/dist/core/circle-ir-core.cjs +783 -220
- package/dist/core/circle-ir-core.js +783 -220
- package/dist/core/extractors/dfg.js +205 -2
- package/dist/core/extractors/dfg.js.map +1 -1
- package/dist/core/extractors/ts-declaration-detail.d.ts +39 -0
- package/dist/core/extractors/ts-declaration-detail.d.ts.map +1 -0
- package/dist/core/extractors/ts-declaration-detail.js +266 -0
- package/dist/core/extractors/ts-declaration-detail.js.map +1 -0
- package/dist/core/extractors/types.js +53 -9
- package/dist/core/extractors/types.js.map +1 -1
- package/dist/graph/analysis-pass.d.ts +4 -1
- package/dist/graph/analysis-pass.d.ts.map +1 -1
- package/dist/graph/analysis-pass.js +4 -1
- package/dist/graph/analysis-pass.js.map +1 -1
- package/dist/graph-facts/dead-code.d.ts +62 -0
- package/dist/graph-facts/dead-code.d.ts.map +1 -0
- package/dist/graph-facts/dead-code.js +90 -0
- package/dist/graph-facts/dead-code.js.map +1 -0
- package/dist/graph-facts/dependency-calls.d.ts +86 -0
- package/dist/graph-facts/dependency-calls.d.ts.map +1 -0
- package/dist/graph-facts/dependency-calls.js +93 -0
- package/dist/graph-facts/dependency-calls.js.map +1 -0
- package/dist/graph-facts/index.d.ts +10 -0
- package/dist/graph-facts/index.d.ts.map +1 -0
- package/dist/graph-facts/index.js +10 -0
- package/dist/graph-facts/index.js.map +1 -0
- package/dist/graph-facts/maven-packages.d.ts +42 -0
- package/dist/graph-facts/maven-packages.d.ts.map +1 -0
- package/dist/graph-facts/maven-packages.js +133 -0
- package/dist/graph-facts/maven-packages.js.map +1 -0
- package/dist/graph-facts/reach.d.ts +203 -0
- package/dist/graph-facts/reach.d.ts.map +1 -0
- package/dist/graph-facts/reach.js +219 -0
- package/dist/graph-facts/reach.js.map +1 -0
- package/dist/graph-facts/removal-reach.d.ts +73 -0
- package/dist/graph-facts/removal-reach.d.ts.map +1 -0
- package/dist/graph-facts/removal-reach.js +64 -0
- package/dist/graph-facts/removal-reach.js.map +1 -0
- package/dist/index.d.ts +21 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -3
- package/dist/index.js.map +1 -1
- package/dist/navigation/go-graph.d.ts +68 -0
- package/dist/navigation/go-graph.d.ts.map +1 -0
- package/dist/navigation/go-graph.js +753 -0
- package/dist/navigation/go-graph.js.map +1 -0
- package/dist/navigation/index.d.ts +7 -1
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +6 -0
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/java-entry-tables.d.ts +43 -0
- package/dist/navigation/java-entry-tables.d.ts.map +1 -0
- package/dist/navigation/java-entry-tables.js +56 -0
- package/dist/navigation/java-entry-tables.js.map +1 -0
- package/dist/navigation/java-graph.d.ts +64 -0
- package/dist/navigation/java-graph.d.ts.map +1 -0
- package/dist/navigation/java-graph.js +466 -0
- package/dist/navigation/java-graph.js.map +1 -0
- package/dist/navigation/navigation-index.d.ts +91 -2
- package/dist/navigation/navigation-index.d.ts.map +1 -1
- package/dist/navigation/navigation-index.js +372 -45
- package/dist/navigation/navigation-index.js.map +1 -1
- package/dist/navigation/python-graph.d.ts +73 -0
- package/dist/navigation/python-graph.d.ts.map +1 -0
- package/dist/navigation/python-graph.js +867 -0
- package/dist/navigation/python-graph.js.map +1 -0
- package/dist/navigation/ts-call-edges.d.ts +193 -0
- package/dist/navigation/ts-call-edges.d.ts.map +1 -0
- package/dist/navigation/ts-call-edges.js +2089 -0
- package/dist/navigation/ts-call-edges.js.map +1 -0
- package/dist/navigation/ts-entry-tables.d.ts +88 -0
- package/dist/navigation/ts-entry-tables.d.ts.map +1 -0
- package/dist/navigation/ts-entry-tables.js +50 -0
- package/dist/navigation/ts-entry-tables.js.map +1 -0
- package/dist/path-set/branches.d.ts +52 -0
- package/dist/path-set/branches.d.ts.map +1 -0
- package/dist/path-set/branches.js +124 -0
- package/dist/path-set/branches.js.map +1 -0
- package/dist/path-set/finding-diff.d.ts +63 -0
- package/dist/path-set/finding-diff.d.ts.map +1 -0
- package/dist/path-set/finding-diff.js +150 -0
- package/dist/path-set/finding-diff.js.map +1 -0
- package/dist/path-set/index.d.ts +18 -0
- package/dist/path-set/index.d.ts.map +1 -0
- package/dist/path-set/index.js +12 -0
- package/dist/path-set/index.js.map +1 -0
- package/dist/path-set/line-diff.d.ts +19 -0
- package/dist/path-set/line-diff.d.ts.map +1 -0
- package/dist/path-set/line-diff.js +98 -0
- package/dist/path-set/line-diff.js.map +1 -0
- package/dist/path-set/path-set.d.ts +88 -0
- package/dist/path-set/path-set.d.ts.map +1 -0
- package/dist/path-set/path-set.js +716 -0
- package/dist/path-set/path-set.js.map +1 -0
- package/dist/path-set/templates.d.ts +42 -0
- package/dist/path-set/templates.d.ts.map +1 -0
- package/dist/path-set/templates.js +119 -0
- package/dist/path-set/templates.js.map +1 -0
- package/dist/path-set/types.d.ts +195 -0
- package/dist/path-set/types.d.ts.map +1 -0
- package/dist/path-set/types.js +8 -0
- package/dist/path-set/types.js.map +1 -0
- package/dist/remedy-class/index.d.ts +12 -0
- package/dist/remedy-class/index.d.ts.map +1 -0
- package/dist/remedy-class/index.js +9 -0
- package/dist/remedy-class/index.js.map +1 -0
- package/dist/remedy-class/match.d.ts +165 -0
- package/dist/remedy-class/match.d.ts.map +1 -0
- package/dist/remedy-class/match.js +705 -0
- package/dist/remedy-class/match.js.map +1 -0
- package/dist/remedy-class/output-context.d.ts +25 -0
- package/dist/remedy-class/output-context.d.ts.map +1 -0
- package/dist/remedy-class/output-context.js +150 -0
- package/dist/remedy-class/output-context.js.map +1 -0
- package/dist/remedy-class/sha256.d.ts +18 -0
- package/dist/remedy-class/sha256.d.ts.map +1 -0
- package/dist/remedy-class/sha256.js +89 -0
- package/dist/remedy-class/sha256.js.map +1 -0
- package/dist/remedy-class/table.d.ts +130 -0
- package/dist/remedy-class/table.d.ts.map +1 -0
- package/dist/remedy-class/table.js +457 -0
- package/dist/remedy-class/table.js.map +1 -0
- package/dist/resolution/cross-file.d.ts +18 -0
- package/dist/resolution/cross-file.d.ts.map +1 -1
- package/dist/resolution/cross-file.js +194 -5
- package/dist/resolution/cross-file.js.map +1 -1
- package/dist/stable-ids/builder.d.ts +20 -0
- package/dist/stable-ids/builder.d.ts.map +1 -0
- package/dist/stable-ids/builder.js +65 -0
- package/dist/stable-ids/builder.js.map +1 -0
- package/dist/stable-ids/diff.d.ts +18 -0
- package/dist/stable-ids/diff.d.ts.map +1 -0
- package/dist/stable-ids/diff.js +37 -0
- package/dist/stable-ids/diff.js.map +1 -0
- package/dist/stable-ids/go.d.ts +28 -0
- package/dist/stable-ids/go.d.ts.map +1 -0
- package/dist/stable-ids/go.js +160 -0
- package/dist/stable-ids/go.js.map +1 -0
- package/dist/stable-ids/hash.d.ts +22 -0
- package/dist/stable-ids/hash.d.ts.map +1 -0
- package/dist/stable-ids/hash.js +167 -0
- package/dist/stable-ids/hash.js.map +1 -0
- package/dist/stable-ids/index.d.ts +30 -0
- package/dist/stable-ids/index.d.ts.map +1 -0
- package/dist/stable-ids/index.js +59 -0
- package/dist/stable-ids/index.js.map +1 -0
- package/dist/stable-ids/java.d.ts +28 -0
- package/dist/stable-ids/java.d.ts.map +1 -0
- package/dist/stable-ids/java.js +224 -0
- package/dist/stable-ids/java.js.map +1 -0
- package/dist/stable-ids/moves.d.ts +87 -0
- package/dist/stable-ids/moves.d.ts.map +1 -0
- package/dist/stable-ids/moves.js +222 -0
- package/dist/stable-ids/moves.js.map +1 -0
- package/dist/stable-ids/nodes.d.ts +32 -0
- package/dist/stable-ids/nodes.d.ts.map +1 -0
- package/dist/stable-ids/nodes.js +92 -0
- package/dist/stable-ids/nodes.js.map +1 -0
- package/dist/stable-ids/normalize.d.ts +35 -0
- package/dist/stable-ids/normalize.d.ts.map +1 -0
- package/dist/stable-ids/normalize.js +174 -0
- package/dist/stable-ids/normalize.js.map +1 -0
- package/dist/stable-ids/parse-errors.d.ts +24 -0
- package/dist/stable-ids/parse-errors.d.ts.map +1 -0
- package/dist/stable-ids/parse-errors.js +46 -0
- package/dist/stable-ids/parse-errors.js.map +1 -0
- package/dist/stable-ids/python.d.ts +27 -0
- package/dist/stable-ids/python.d.ts.map +1 -0
- package/dist/stable-ids/python.js +212 -0
- package/dist/stable-ids/python.js.map +1 -0
- package/dist/stable-ids/ts-parse-errors.d.ts +27 -0
- package/dist/stable-ids/ts-parse-errors.d.ts.map +1 -0
- package/dist/stable-ids/ts-parse-errors.js +75 -0
- package/dist/stable-ids/ts-parse-errors.js.map +1 -0
- package/dist/stable-ids/types.d.ts +106 -0
- package/dist/stable-ids/types.d.ts.map +1 -0
- package/dist/stable-ids/types.js +16 -0
- package/dist/stable-ids/types.js.map +1 -0
- package/dist/stable-ids/typescript.d.ts +30 -0
- package/dist/stable-ids/typescript.d.ts.map +1 -0
- package/dist/stable-ids/typescript.js +362 -0
- package/dist/stable-ids/typescript.js.map +1 -0
- package/dist/types/config.d.ts +9 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.d.ts +53 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `node` ids for `ids@0.1`: a body id plus a local index.
|
|
3
|
+
*
|
|
4
|
+
* Today's CFG blocks, DFG defs and uses and call sites carry sequential ids
|
|
5
|
+
* per file, so an edit anywhere shifts every id after it. Here each IR node
|
|
6
|
+
* is assigned to the innermost declaration whose span encloses it, and its
|
|
7
|
+
* index counts only the nodes of the same array inside that same body. An
|
|
8
|
+
* edit to one function therefore leaves every other function's node ids
|
|
9
|
+
* unchanged, and the index is safe because a body id names one body version.
|
|
10
|
+
*/
|
|
11
|
+
/** Position compare on (line, column); `column` absent means the whole line. */
|
|
12
|
+
function encloses(d, line, column) {
|
|
13
|
+
if (line < d.start_line || line > d.end_line)
|
|
14
|
+
return false;
|
|
15
|
+
if (column === undefined)
|
|
16
|
+
return true;
|
|
17
|
+
if (line === d.start_line && column < d.start_column)
|
|
18
|
+
return false;
|
|
19
|
+
if (line === d.end_line && column >= d.end_column)
|
|
20
|
+
return false;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
/** Ranks spans so the innermost declaration wins; on a tie, the later one in source order. */
|
|
24
|
+
function spanSize(d) {
|
|
25
|
+
return (d.end_line - d.start_line) * 1_000_000 + (d.end_column - d.start_column);
|
|
26
|
+
}
|
|
27
|
+
class Locator {
|
|
28
|
+
spans;
|
|
29
|
+
constructor(file) {
|
|
30
|
+
this.spans = file.decls
|
|
31
|
+
.filter(d => d.body_hash !== '')
|
|
32
|
+
.map(decl => ({ decl, size: spanSize(decl) }));
|
|
33
|
+
}
|
|
34
|
+
/** Innermost declaration enclosing the position. */
|
|
35
|
+
at(line, column) {
|
|
36
|
+
let best = null;
|
|
37
|
+
for (const s of this.spans) {
|
|
38
|
+
if (!encloses(s.decl, line, column))
|
|
39
|
+
continue;
|
|
40
|
+
if (best === null || s.size <= best.size)
|
|
41
|
+
best = s;
|
|
42
|
+
}
|
|
43
|
+
return best?.decl ?? null;
|
|
44
|
+
}
|
|
45
|
+
/** Innermost declaration enclosing a whole line range. */
|
|
46
|
+
range(start, end) {
|
|
47
|
+
let best = null;
|
|
48
|
+
for (const s of this.spans) {
|
|
49
|
+
if (start < s.decl.start_line || end > s.decl.end_line)
|
|
50
|
+
continue;
|
|
51
|
+
if (best === null || s.size <= best.size)
|
|
52
|
+
best = s;
|
|
53
|
+
}
|
|
54
|
+
return best?.decl ?? null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The innermost declaration (with a body) enclosing a 1-based line and a
|
|
59
|
+
* 0-based column, or `null`.
|
|
60
|
+
*/
|
|
61
|
+
export function declLocator(file) {
|
|
62
|
+
const loc = new Locator(file);
|
|
63
|
+
return (line, column) => loc.at(line, column);
|
|
64
|
+
}
|
|
65
|
+
function keyAll(items, tag, find) {
|
|
66
|
+
const counters = new Map();
|
|
67
|
+
return items.map(item => {
|
|
68
|
+
const decl = find(item);
|
|
69
|
+
if (!decl)
|
|
70
|
+
return null;
|
|
71
|
+
const n = counters.get(decl.body_id) ?? 0;
|
|
72
|
+
counters.set(decl.body_id, n + 1);
|
|
73
|
+
return `${decl.body_id}/${tag}${n}`;
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Node ids parallel to the IR arrays: `<body_id>/b<n>` for CFG blocks,
|
|
78
|
+
* `/d<n>` and `/u<n>` for DFG defs and uses, `/c<n>` for call sites, where
|
|
79
|
+
* `n` counts that kind inside that body in array order. Positions are
|
|
80
|
+
* matched by line and, where the IR carries one, column; a CFG block goes to
|
|
81
|
+
* the innermost declaration that encloses all of its lines.
|
|
82
|
+
*/
|
|
83
|
+
export function assignNodeIds(file, ir) {
|
|
84
|
+
const loc = new Locator(file);
|
|
85
|
+
return {
|
|
86
|
+
cfg_blocks: keyAll(ir.cfg?.blocks ?? [], 'b', b => loc.range(b.start_line, b.end_line)),
|
|
87
|
+
dfg_defs: keyAll(ir.dfg?.defs ?? [], 'd', d => loc.at(d.line, d.column)),
|
|
88
|
+
dfg_uses: keyAll(ir.dfg?.uses ?? [], 'u', u => loc.at(u.line, u.column)),
|
|
89
|
+
calls: keyAll(ir.calls ?? [], 'c', c => loc.at(c.location.line, c.location.column)),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=nodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodes.js","sourceRoot":"","sources":["../../src/stable-ids/nodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH,gFAAgF;AAChF,SAAS,QAAQ,CAAC,CAAa,EAAE,IAAY,EAAE,MAA0B;IACvE,IAAI,IAAI,GAAG,CAAC,CAAC,UAAU,IAAI,IAAI,GAAG,CAAC,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC3D,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACtC,IAAI,IAAI,KAAK,CAAC,CAAC,UAAU,IAAI,MAAM,GAAG,CAAC,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IACnE,IAAI,IAAI,KAAK,CAAC,CAAC,QAAQ,IAAI,MAAM,IAAI,CAAC,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAChE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8FAA8F;AAC9F,SAAS,QAAQ,CAAC,CAAa;IAC7B,OAAO,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,OAAO;IACM,KAAK,CAAS;IAE/B,YAAY,IAAkB;QAC5B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK;aACpB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC;aAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,oDAAoD;IACpD,EAAE,CAAC,IAAY,EAAE,MAAe;QAC9B,IAAI,IAAI,GAAgB,IAAI,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC;gBAAE,SAAS;YAC9C,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;gBAAE,IAAI,GAAG,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;IAC5B,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,KAAa,EAAE,GAAW;QAC9B,IAAI,IAAI,GAAgB,IAAI,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ;gBAAE,SAAS;YACjE,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI;gBAAE,IAAI,GAAG,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;IAC5B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,MAAM,CAAI,KAAmB,EAAE,GAAW,EAAE,IAAoC;IACvF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAClC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAkB,EAAE,EAAgB;IAChE,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvF,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACxE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACxE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;KACpF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body normalization for `ids@0.1`: the leaf tokens of a syntax subtree with
|
|
3
|
+
* whitespace, comments and formatting removed, identifiers and literals kept.
|
|
4
|
+
*
|
|
5
|
+
* Formatting a formatter may change and that cannot change meaning is
|
|
6
|
+
* dropped: statement-terminating `;`, a trailing `,` before a closing bracket,
|
|
7
|
+
* the quote style of a plain string, the parentheses around a lone untyped
|
|
8
|
+
* arrow-function parameter, and whitespace inside JSX text.
|
|
9
|
+
*/
|
|
10
|
+
import type { Node } from '../core/parser.js';
|
|
11
|
+
export interface EmitOptions {
|
|
12
|
+
/** Subtrees left out entirely (by `node.id`). */
|
|
13
|
+
skip?: ReadonlySet<number>;
|
|
14
|
+
/** Subtrees replaced by one placeholder token (`''` drops the subtree). */
|
|
15
|
+
replace?: ReadonlyMap<number, string>;
|
|
16
|
+
/**
|
|
17
|
+
* Node types whose extent is marked with `⟨` … `⟩` — for grammars where
|
|
18
|
+
* indentation carries the structure (a Python `block`), which leaf tokens
|
|
19
|
+
* alone would lose.
|
|
20
|
+
*/
|
|
21
|
+
wrap?: ReadonlySet<string>;
|
|
22
|
+
}
|
|
23
|
+
/** Named children, comments excluded. */
|
|
24
|
+
export declare function namedChildren(node: Node): Node[];
|
|
25
|
+
/** The normalized token stream of `nodes`, in order. */
|
|
26
|
+
export declare function bodyTokens(nodes: readonly Node[], opts?: EmitOptions): string[];
|
|
27
|
+
/** Concatenate tokens, keeping a space only where two words would fuse. */
|
|
28
|
+
export declare function joinTokens(parts: readonly string[]): string;
|
|
29
|
+
/**
|
|
30
|
+
* A type annotation serialized canonically: object-type members and the arms
|
|
31
|
+
* of a union or intersection are sorted, so `{b: string; a: number}` and
|
|
32
|
+
* `{a: number, b: string}` — or `A | B` and `B | A` — serialize the same.
|
|
33
|
+
*/
|
|
34
|
+
export declare function canonicalType(node: Node): string;
|
|
35
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/stable-ids/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC5B;AAqBD,yCAAyC;AACzC,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,CAOhD;AAmCD,wDAAwD;AACxD,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,MAAM,EAAE,CAenF;AAKD,2EAA2E;AAC3E,wBAAgB,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAQ3D;AASD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CA4ChD"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Body normalization for `ids@0.1`: the leaf tokens of a syntax subtree with
|
|
3
|
+
* whitespace, comments and formatting removed, identifiers and literals kept.
|
|
4
|
+
*
|
|
5
|
+
* Formatting a formatter may change and that cannot change meaning is
|
|
6
|
+
* dropped: statement-terminating `;`, a trailing `,` before a closing bracket,
|
|
7
|
+
* the quote style of a plain string, the parentheses around a lone untyped
|
|
8
|
+
* arrow-function parameter, and whitespace inside JSX text.
|
|
9
|
+
*/
|
|
10
|
+
const CLOSERS = new Set([')', ']', '}', '>']);
|
|
11
|
+
/** Comment node types across the grammars (`comment`; Java's `line_comment` and `block_comment`). */
|
|
12
|
+
const COMMENTS = new Set(['comment', 'line_comment', 'block_comment']);
|
|
13
|
+
/** True for a parenthesised parameter list that holds one bare, untyped identifier. */
|
|
14
|
+
function isLoneArrowParam(node) {
|
|
15
|
+
if (node.type !== 'formal_parameters' || node.parent?.type !== 'arrow_function')
|
|
16
|
+
return null;
|
|
17
|
+
const params = namedChildren(node);
|
|
18
|
+
if (params.length !== 1)
|
|
19
|
+
return null;
|
|
20
|
+
const p = params[0];
|
|
21
|
+
if (p.type === 'identifier')
|
|
22
|
+
return p;
|
|
23
|
+
if (p.type === 'required_parameter' && p.namedChildCount === 1) {
|
|
24
|
+
const pattern = p.childForFieldName('pattern');
|
|
25
|
+
if (pattern?.type === 'identifier')
|
|
26
|
+
return pattern;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
/** Named children, comments excluded. */
|
|
31
|
+
export function namedChildren(node) {
|
|
32
|
+
const out = [];
|
|
33
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
34
|
+
const c = node.namedChild(i);
|
|
35
|
+
if (c && !COMMENTS.has(c.type))
|
|
36
|
+
out.push(c);
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
function emit(node, opts, out) {
|
|
41
|
+
const replaced = opts.replace?.get(node.id);
|
|
42
|
+
if (replaced !== undefined) {
|
|
43
|
+
if (replaced !== '')
|
|
44
|
+
out.push(replaced);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (opts.skip?.has(node.id))
|
|
48
|
+
return;
|
|
49
|
+
const type = node.type;
|
|
50
|
+
if (COMMENTS.has(type) || type === 'hash_bang_line')
|
|
51
|
+
return;
|
|
52
|
+
const lone = isLoneArrowParam(node);
|
|
53
|
+
if (lone) {
|
|
54
|
+
emit(lone, opts, out);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (node.childCount === 0) {
|
|
58
|
+
let text = node.text;
|
|
59
|
+
if (type === 'jsx_text')
|
|
60
|
+
text = text.replace(/\s+/g, ' ').trim();
|
|
61
|
+
if (text === '')
|
|
62
|
+
return;
|
|
63
|
+
if ((text === "'" || text === '"') && node.parent?.type === 'string')
|
|
64
|
+
text = '"';
|
|
65
|
+
out.push(text);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const wrapped = opts.wrap?.has(type) === true;
|
|
69
|
+
if (wrapped)
|
|
70
|
+
out.push('⟨');
|
|
71
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
72
|
+
const c = node.child(i);
|
|
73
|
+
if (c)
|
|
74
|
+
emit(c, opts, out);
|
|
75
|
+
}
|
|
76
|
+
if (wrapped)
|
|
77
|
+
out.push('⟩');
|
|
78
|
+
}
|
|
79
|
+
/** The normalized token stream of `nodes`, in order. */
|
|
80
|
+
export function bodyTokens(nodes, opts = {}) {
|
|
81
|
+
const raw = [];
|
|
82
|
+
for (const n of nodes)
|
|
83
|
+
emit(n, opts, raw);
|
|
84
|
+
const out = [];
|
|
85
|
+
for (let i = 0; i < raw.length; i++) {
|
|
86
|
+
const t = raw[i];
|
|
87
|
+
if (t === ';')
|
|
88
|
+
continue;
|
|
89
|
+
if (t === ',') {
|
|
90
|
+
let j = i + 1;
|
|
91
|
+
while (j < raw.length && raw[j] === ';')
|
|
92
|
+
j++;
|
|
93
|
+
if (j < raw.length && CLOSERS.has(raw[j]))
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
out.push(t);
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
const WORD_END = /[\w$#]$/;
|
|
101
|
+
const WORD_START = /^[\w$#]/;
|
|
102
|
+
/** Concatenate tokens, keeping a space only where two words would fuse. */
|
|
103
|
+
export function joinTokens(parts) {
|
|
104
|
+
let s = '';
|
|
105
|
+
for (const p of parts) {
|
|
106
|
+
if (p === '')
|
|
107
|
+
continue;
|
|
108
|
+
if (s !== '' && WORD_END.test(s) && WORD_START.test(p))
|
|
109
|
+
s += ' ';
|
|
110
|
+
s += p;
|
|
111
|
+
}
|
|
112
|
+
return s;
|
|
113
|
+
}
|
|
114
|
+
function flatten(node, type, acc) {
|
|
115
|
+
for (const c of namedChildren(node)) {
|
|
116
|
+
if (c.type === type)
|
|
117
|
+
flatten(c, type, acc);
|
|
118
|
+
else
|
|
119
|
+
acc.push(c);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* A type annotation serialized canonically: object-type members and the arms
|
|
124
|
+
* of a union or intersection are sorted, so `{b: string; a: number}` and
|
|
125
|
+
* `{a: number, b: string}` — or `A | B` and `B | A` — serialize the same.
|
|
126
|
+
*/
|
|
127
|
+
export function canonicalType(node) {
|
|
128
|
+
switch (node.type) {
|
|
129
|
+
case 'type_annotation':
|
|
130
|
+
case 'opting_type_annotation':
|
|
131
|
+
case 'omitting_type_annotation': {
|
|
132
|
+
const inner = namedChildren(node);
|
|
133
|
+
return inner.length === 1 ? canonicalType(inner[0]) : joinTokens(bodyTokens([node]));
|
|
134
|
+
}
|
|
135
|
+
case 'formal_parameters': {
|
|
136
|
+
// Parameters of a function or constructor type: types only, never names.
|
|
137
|
+
const params = namedChildren(node).map(p => {
|
|
138
|
+
const type = p.childForFieldName('type');
|
|
139
|
+
const pattern = p.childForFieldName('pattern');
|
|
140
|
+
const rest = pattern?.type === 'rest_pattern' || p.type === 'rest_pattern' ? '...' : '';
|
|
141
|
+
const optional = p.type === 'optional_parameter' ? '?' : '';
|
|
142
|
+
return rest + (type ? canonicalType(type) : '_') + optional;
|
|
143
|
+
});
|
|
144
|
+
return '(' + params.join(',') + ')';
|
|
145
|
+
}
|
|
146
|
+
case 'object_type': {
|
|
147
|
+
const members = namedChildren(node).map(canonicalType);
|
|
148
|
+
members.sort();
|
|
149
|
+
return '{' + members.join(';') + '}';
|
|
150
|
+
}
|
|
151
|
+
case 'union_type':
|
|
152
|
+
case 'intersection_type': {
|
|
153
|
+
const arms = [];
|
|
154
|
+
flatten(node, node.type, arms);
|
|
155
|
+
const parts = arms.map(canonicalType).sort();
|
|
156
|
+
return parts.join(node.type === 'union_type' ? '|' : '&');
|
|
157
|
+
}
|
|
158
|
+
default: {
|
|
159
|
+
if (node.childCount === 0)
|
|
160
|
+
return node.text;
|
|
161
|
+
const parts = [];
|
|
162
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
163
|
+
const c = node.child(i);
|
|
164
|
+
if (!c || COMMENTS.has(c.type))
|
|
165
|
+
continue;
|
|
166
|
+
parts.push(c.isNamed ? canonicalType(c) : c.text);
|
|
167
|
+
}
|
|
168
|
+
// A trailing comma before a closer is formatting.
|
|
169
|
+
const kept = parts.filter((p, i) => !(p === ',' && CLOSERS.has(parts[i + 1] ?? '')));
|
|
170
|
+
return joinTokens(kept);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/stable-ids/normalize.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first parse error in a tree, in source order, as a `ParseErrorSite`.
|
|
3
|
+
*
|
|
4
|
+
* Stable ids call this for `StableIdFile.parseError`, so a consumer that
|
|
5
|
+
* withholds an answer because a file is partial can say which file, where,
|
|
6
|
+
* and what the parser could not read (cognium-dev#1004).
|
|
7
|
+
*/
|
|
8
|
+
import type { Node } from '../core/parser.js';
|
|
9
|
+
import type { ParseErrorSite } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* The first `ERROR` or `MISSING` node for which `ignore` is false, in source
|
|
12
|
+
* order, or `undefined` when there is none.
|
|
13
|
+
*/
|
|
14
|
+
export declare function firstParseErrorNode(root: Node, ignore?: (n: Node) => boolean): Node | undefined;
|
|
15
|
+
/** A tree node as a `ParseErrorSite`. */
|
|
16
|
+
export declare function parseErrorSite(n: Node): ParseErrorSite;
|
|
17
|
+
/** The first parse error in the tree, or `undefined` for a clean parse. */
|
|
18
|
+
export declare function firstParseError(root: Node, ignore?: (n: Node) => boolean): ParseErrorSite | undefined;
|
|
19
|
+
/** `partial` and, when set, `parseError` for a `StableIdFile`, from any error in the tree. */
|
|
20
|
+
export declare function partialOf(root: Node): {
|
|
21
|
+
partial: boolean;
|
|
22
|
+
parseError?: ParseErrorSite;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=parse-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-errors.d.ts","sourceRoot":"","sources":["../../src/stable-ids/parse-errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,GAAE,CAAC,CAAC,EAAE,IAAI,KAAK,OAAqB,GAAG,IAAI,GAAG,SAAS,CAiB5G;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,CAAC,EAAE,IAAI,GAAG,cAAc,CAQtD;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,OAAO,GAAG,cAAc,GAAG,SAAS,CAGrG;AAED,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAA;CAAE,CAGvF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first `ERROR` or `MISSING` node for which `ignore` is false, in source
|
|
3
|
+
* order, or `undefined` when there is none.
|
|
4
|
+
*/
|
|
5
|
+
export function firstParseErrorNode(root, ignore = () => false) {
|
|
6
|
+
if (!root.hasError)
|
|
7
|
+
return undefined;
|
|
8
|
+
const stack = [root];
|
|
9
|
+
while (stack.length > 0) {
|
|
10
|
+
const n = stack.pop();
|
|
11
|
+
// A root the grammar gave up on is itself an ERROR; the useful site is inside it.
|
|
12
|
+
if ((n.type === 'ERROR' || n.isMissing) && n !== root) {
|
|
13
|
+
if (!ignore(n))
|
|
14
|
+
return n;
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
// Push in reverse so the leftmost child is visited first.
|
|
18
|
+
for (let i = n.childCount - 1; i >= 0; i--) {
|
|
19
|
+
const c = n.child(i);
|
|
20
|
+
if (c && (c.hasError || c.isMissing))
|
|
21
|
+
stack.push(c);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return root.type === 'ERROR' && !ignore(root) ? root : undefined;
|
|
25
|
+
}
|
|
26
|
+
/** A tree node as a `ParseErrorSite`. */
|
|
27
|
+
export function parseErrorSite(n) {
|
|
28
|
+
return {
|
|
29
|
+
line: n.startPosition.row + 1,
|
|
30
|
+
column: n.startPosition.column + 1,
|
|
31
|
+
nodeKind: n.isMissing ? `MISSING ${n.type}` : 'ERROR',
|
|
32
|
+
// Directly under the root (even a root the grammar gave up on): the program.
|
|
33
|
+
parent: n.parent && n.parent.parent ? n.parent.type : 'program',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** The first parse error in the tree, or `undefined` for a clean parse. */
|
|
37
|
+
export function firstParseError(root, ignore) {
|
|
38
|
+
const n = firstParseErrorNode(root, ignore);
|
|
39
|
+
return n ? parseErrorSite(n) : undefined;
|
|
40
|
+
}
|
|
41
|
+
/** `partial` and, when set, `parseError` for a `StableIdFile`, from any error in the tree. */
|
|
42
|
+
export function partialOf(root) {
|
|
43
|
+
const parseError = firstParseError(root);
|
|
44
|
+
return parseError ? { partial: true, parseError } : { partial: false };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=parse-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-errors.js","sourceRoot":"","sources":["../../src/stable-ids/parse-errors.ts"],"names":[],"mappings":"AAUA;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAU,EAAE,MAAM,GAAyB,GAAG,EAAE,CAAC,KAAK;IACxF,IAAI,CAAC,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,KAAK,GAAW,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,EAAG,CAAC;QACvB,kFAAkF;QAClF,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACtD,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;gBAAE,OAAO,CAAC,CAAC;YACzB,SAAS;QACX,CAAC;QACD,0DAA0D;QAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3C,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;AACnE,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,cAAc,CAAC,CAAO;IACpC,OAAO;QACL,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC;QAC7B,MAAM,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QAClC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO;QACrD,6EAA6E;QAC7E,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;KAChE,CAAC;AACJ,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,MAA6B;IACvE,MAAM,CAAC,GAAG,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5C,OAAO,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,SAAS,CAAC,IAAU;IAClC,MAAM,UAAU,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ids@0.1` declaration and body ids for Python.
|
|
3
|
+
*
|
|
4
|
+
* Declarations: the module (its dotted name); functions; classes (kind
|
|
5
|
+
* `type`); methods; module- and class-level assignments to a plain name
|
|
6
|
+
* (kind `field`). Functions, classes and lambdas inside a body are keyed by
|
|
7
|
+
* their enclosing declaration plus a structural path and flagged
|
|
8
|
+
* `unstable:anonymous`.
|
|
9
|
+
*
|
|
10
|
+
* Module name: the file's dotted path — `src/` dropped, `__init__` naming
|
|
11
|
+
* its package — unless the caller passes one. Signature: arity plus
|
|
12
|
+
* annotations, parameter names never — `(_,int?,*_,_?,**_)->str` — so a
|
|
13
|
+
* parameter rename does not re-key a function. Decorators are body.
|
|
14
|
+
*
|
|
15
|
+
* Bodies: leaf tokens as in the other languages, with each `block` marked so
|
|
16
|
+
* that indentation, which carries Python's structure, is not lost; comments
|
|
17
|
+
* and docstrings are not body.
|
|
18
|
+
*/
|
|
19
|
+
import type { Node, Tree } from '../core/parser.js';
|
|
20
|
+
import { type StableIdFile, type StableIdOptions } from './types.js';
|
|
21
|
+
/** The dotted module name for a repository-relative `.py` path. */
|
|
22
|
+
export declare function pythonModuleName(filePath: string): string;
|
|
23
|
+
/** `(_,int?,*_,**_)->T` — names never, annotations and defaults (as `?`) always. */
|
|
24
|
+
export declare function pythonSignature(fn: Node): string;
|
|
25
|
+
/** Derive `ids@0.1` ids from an already-parsed Python tree. */
|
|
26
|
+
export declare function derivePythonIds(tree: Tree, filePath: string, options?: StableIdOptions): StableIdFile;
|
|
27
|
+
//# sourceMappingURL=python.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/stable-ids/python.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAA0D,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAK7H,mEAAmE;AACnE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMzD;AAMD,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,EAAE,EAAE,IAAI,GAAG,MAAM,CAuBhD;AAyHD,+DAA+D;AAC/D,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,YAAY,CAMzG"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ids@0.1` declaration and body ids for Python.
|
|
3
|
+
*
|
|
4
|
+
* Declarations: the module (its dotted name); functions; classes (kind
|
|
5
|
+
* `type`); methods; module- and class-level assignments to a plain name
|
|
6
|
+
* (kind `field`). Functions, classes and lambdas inside a body are keyed by
|
|
7
|
+
* their enclosing declaration plus a structural path and flagged
|
|
8
|
+
* `unstable:anonymous`.
|
|
9
|
+
*
|
|
10
|
+
* Module name: the file's dotted path — `src/` dropped, `__init__` naming
|
|
11
|
+
* its package — unless the caller passes one. Signature: arity plus
|
|
12
|
+
* annotations, parameter names never — `(_,int?,*_,_?,**_)->str` — so a
|
|
13
|
+
* parameter rename does not re-key a function. Decorators are body.
|
|
14
|
+
*
|
|
15
|
+
* Bodies: leaf tokens as in the other languages, with each `block` marked so
|
|
16
|
+
* that indentation, which carries Python's structure, is not lost; comments
|
|
17
|
+
* and docstrings are not body.
|
|
18
|
+
*/
|
|
19
|
+
import { partialOf } from './parse-errors.js';
|
|
20
|
+
import { Builder, placeholder } from './builder.js';
|
|
21
|
+
import { bodyTokens, namedChildren } from './normalize.js';
|
|
22
|
+
import { STABLE_ID_SCHEME } from './types.js';
|
|
23
|
+
const WRAP = new Set(['block']);
|
|
24
|
+
const NESTED = new Set(['function_definition', 'class_definition', 'lambda']);
|
|
25
|
+
/** The dotted module name for a repository-relative `.py` path. */
|
|
26
|
+
export function pythonModuleName(filePath) {
|
|
27
|
+
let p = filePath.replace(/\\/g, '/').replace(/^\.\//, '').replace(/\.pyi?$/, '');
|
|
28
|
+
if (p.startsWith('src/'))
|
|
29
|
+
p = p.slice(4);
|
|
30
|
+
const parts = p.split('/').filter(x => x !== '');
|
|
31
|
+
if (parts[parts.length - 1] === '__init__')
|
|
32
|
+
parts.pop();
|
|
33
|
+
return parts.join('.') || '__main__';
|
|
34
|
+
}
|
|
35
|
+
function compact(text) {
|
|
36
|
+
return text.replace(/\s+/g, '');
|
|
37
|
+
}
|
|
38
|
+
/** `(_,int?,*_,**_)->T` — names never, annotations and defaults (as `?`) always. */
|
|
39
|
+
export function pythonSignature(fn) {
|
|
40
|
+
const params = fn.childForFieldName('parameters');
|
|
41
|
+
const out = [];
|
|
42
|
+
for (const p of params ? namedChildren(params) : []) {
|
|
43
|
+
switch (p.type) {
|
|
44
|
+
case 'identifier':
|
|
45
|
+
out.push('_');
|
|
46
|
+
break;
|
|
47
|
+
case 'typed_parameter': {
|
|
48
|
+
const inner = namedChildren(p)[0];
|
|
49
|
+
const t = compact(p.childForFieldName('type')?.text ?? '_');
|
|
50
|
+
out.push(inner?.type === 'list_splat_pattern' ? `*${t}` : inner?.type === 'dictionary_splat_pattern' ? `**${t}` : t);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case 'default_parameter':
|
|
54
|
+
out.push('_?');
|
|
55
|
+
break;
|
|
56
|
+
case 'typed_default_parameter':
|
|
57
|
+
out.push(compact(p.childForFieldName('type')?.text ?? '_') + '?');
|
|
58
|
+
break;
|
|
59
|
+
case 'list_splat_pattern':
|
|
60
|
+
out.push('*_');
|
|
61
|
+
break;
|
|
62
|
+
case 'dictionary_splat_pattern':
|
|
63
|
+
out.push('**_');
|
|
64
|
+
break;
|
|
65
|
+
case 'keyword_separator':
|
|
66
|
+
out.push('*');
|
|
67
|
+
break;
|
|
68
|
+
case 'positional_separator':
|
|
69
|
+
out.push('/');
|
|
70
|
+
break;
|
|
71
|
+
default: out.push('_');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const ret = fn.childForFieldName('return_type');
|
|
75
|
+
return '(' + out.join(',') + ')' + (ret ? '->' + compact(ret.text) : '');
|
|
76
|
+
}
|
|
77
|
+
/** The docstring statement of a block, if it opens with one. */
|
|
78
|
+
function docstring(block) {
|
|
79
|
+
const first = block ? namedChildren(block)[0] : undefined;
|
|
80
|
+
if (first?.type !== 'expression_statement')
|
|
81
|
+
return null;
|
|
82
|
+
const inner = namedChildren(first);
|
|
83
|
+
return inner.length === 1 && inner[0].type === 'string' ? first : null;
|
|
84
|
+
}
|
|
85
|
+
/** The definition a statement holds, and the node that carries its decorators. */
|
|
86
|
+
function definitionOf(stmt) {
|
|
87
|
+
if (stmt.type === 'decorated_definition') {
|
|
88
|
+
const def = stmt.childForFieldName('definition');
|
|
89
|
+
return def ? { def, holder: stmt } : null;
|
|
90
|
+
}
|
|
91
|
+
if (stmt.type === 'function_definition' || stmt.type === 'class_definition')
|
|
92
|
+
return { def: stmt, holder: stmt };
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
class PythonExtractor {
|
|
96
|
+
b;
|
|
97
|
+
constructor(b) {
|
|
98
|
+
this.b = b;
|
|
99
|
+
}
|
|
100
|
+
tokens(nodes, skip, replace) {
|
|
101
|
+
return bodyTokens(nodes, { skip, replace, wrap: WRAP });
|
|
102
|
+
}
|
|
103
|
+
/** `self` is the declaration's own definition under its decorators: walked through, not declared again. */
|
|
104
|
+
nested(node, enclosing, exclude, path = '', self = null) {
|
|
105
|
+
const kids = namedChildren(node);
|
|
106
|
+
for (let i = 0; i < kids.length; i++) {
|
|
107
|
+
const c = kids[i];
|
|
108
|
+
if (exclude.has(c.id))
|
|
109
|
+
continue;
|
|
110
|
+
const p = path === '' ? `${i}` : `${path}.${i}`;
|
|
111
|
+
if (NESTED.has(c.type) && c.id !== self?.id)
|
|
112
|
+
this.declareNested(c, enclosing, p);
|
|
113
|
+
else
|
|
114
|
+
this.nested(c, enclosing, exclude, p, self);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
declareNested(node, enclosing, path) {
|
|
118
|
+
const own = node.childForFieldName('name');
|
|
119
|
+
const name = own?.text ?? '<lambda>';
|
|
120
|
+
const kind = node.type === 'class_definition' ? 'type' : 'function';
|
|
121
|
+
let signature = '';
|
|
122
|
+
if (node.type === 'function_definition')
|
|
123
|
+
signature = pythonSignature(node);
|
|
124
|
+
else if (node.type === 'lambda') {
|
|
125
|
+
const params = node.childForFieldName('parameters');
|
|
126
|
+
signature = '(' + (params ? namedChildren(params).map(() => '_').join(',') : '') + ')';
|
|
127
|
+
}
|
|
128
|
+
const holder = node.parent?.type === 'decorated_definition' ? node.parent : node;
|
|
129
|
+
const decl = this.b.add(kind, name, `${enclosing.qualified_name}/${name}@${path}`, signature, holder, enclosing.id, ['unstable:anonymous']);
|
|
130
|
+
const skip = new Set(own ? [own.id] : []);
|
|
131
|
+
const doc = docstring(node.childForFieldName('body'));
|
|
132
|
+
if (doc)
|
|
133
|
+
skip.add(doc.id);
|
|
134
|
+
this.b.setBody(decl, this.tokens([holder], skip));
|
|
135
|
+
this.nested(holder, decl, skip, '', node);
|
|
136
|
+
}
|
|
137
|
+
/** One statement of a module or class body. */
|
|
138
|
+
statement(stmt, prefix, parent, inClass, replace) {
|
|
139
|
+
const d = definitionOf(stmt);
|
|
140
|
+
if (d) {
|
|
141
|
+
const nameNode = d.def.childForFieldName('name');
|
|
142
|
+
const name = nameNode?.text ?? '<unnamed>';
|
|
143
|
+
if (d.def.type === 'class_definition') {
|
|
144
|
+
this.type(d.def, d.holder, name, nameNode, prefix, parent, replace);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const kind = inClass ? 'method' : 'function';
|
|
148
|
+
const signature = pythonSignature(d.def);
|
|
149
|
+
const decl = this.b.add(kind, name, prefix + name, signature, d.holder, parent.id);
|
|
150
|
+
replace.set(d.holder.id, placeholder(kind, name, signature));
|
|
151
|
+
const skip = new Set(nameNode ? [nameNode.id] : []);
|
|
152
|
+
const doc = docstring(d.def.childForFieldName('body'));
|
|
153
|
+
if (doc)
|
|
154
|
+
skip.add(doc.id);
|
|
155
|
+
this.b.setBody(decl, this.tokens([d.holder], skip));
|
|
156
|
+
this.nested(d.holder, decl, skip, '', d.def);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (stmt.type === 'expression_statement') {
|
|
160
|
+
const a = namedChildren(stmt)[0];
|
|
161
|
+
if (a?.type !== 'assignment')
|
|
162
|
+
return;
|
|
163
|
+
const left = a.childForFieldName('left');
|
|
164
|
+
if (left?.type !== 'identifier')
|
|
165
|
+
return;
|
|
166
|
+
const t = a.childForFieldName('type');
|
|
167
|
+
const signature = t ? compact(t.text) : '';
|
|
168
|
+
const decl = this.b.add('field', left.text, prefix + left.text, signature, stmt, parent.id);
|
|
169
|
+
replace.set(stmt.id, placeholder('field', left.text, signature));
|
|
170
|
+
const skip = new Set([left.id]);
|
|
171
|
+
this.b.setBody(decl, this.tokens([stmt], skip));
|
|
172
|
+
this.nested(stmt, decl, skip);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
type(def, holder, name, nameNode, prefix, parent, replace) {
|
|
176
|
+
const supers = def.childForFieldName('superclasses');
|
|
177
|
+
const signature = supers ? compact(supers.text) : '';
|
|
178
|
+
const decl = this.b.add('type', name, prefix + name, signature, holder, parent.id);
|
|
179
|
+
replace.set(holder.id, placeholder('type', name, signature));
|
|
180
|
+
const inner = new Map();
|
|
181
|
+
const body = def.childForFieldName('body');
|
|
182
|
+
const doc = docstring(body);
|
|
183
|
+
for (const s of body ? namedChildren(body) : []) {
|
|
184
|
+
if (s !== doc)
|
|
185
|
+
this.statement(s, decl.qualified_name + '.', decl, true, inner);
|
|
186
|
+
}
|
|
187
|
+
const skip = new Set(nameNode ? [nameNode.id] : []);
|
|
188
|
+
if (doc)
|
|
189
|
+
skip.add(doc.id);
|
|
190
|
+
this.b.setBody(decl, this.tokens([holder], skip, inner));
|
|
191
|
+
this.nested(holder, decl, new Set([...skip, ...inner.keys()]), '', def);
|
|
192
|
+
}
|
|
193
|
+
module(root, decl) {
|
|
194
|
+
const replace = new Map();
|
|
195
|
+
const doc = docstring(root);
|
|
196
|
+
for (const s of namedChildren(root))
|
|
197
|
+
if (s !== doc)
|
|
198
|
+
this.statement(s, decl.qualified_name + ':', decl, false, replace);
|
|
199
|
+
const skip = new Set(doc ? [doc.id] : []);
|
|
200
|
+
this.b.setBody(decl, this.tokens([root], skip, replace));
|
|
201
|
+
this.nested(root, decl, new Set([...skip, ...replace.keys()]));
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/** Derive `ids@0.1` ids from an already-parsed Python tree. */
|
|
205
|
+
export function derivePythonIds(tree, filePath, options = {}) {
|
|
206
|
+
const module = options.module ?? pythonModuleName(filePath);
|
|
207
|
+
const builder = new Builder('python', options.keepBodyTokens === true);
|
|
208
|
+
const moduleDecl = builder.add('module', module, module, '', tree.rootNode, null);
|
|
209
|
+
new PythonExtractor(builder).module(tree.rootNode, moduleDecl);
|
|
210
|
+
return { scheme: STABLE_ID_SCHEME, file: filePath, language: 'python', module, decls: builder.decls, ...partialOf(tree.rootNode) };
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=python.js.map
|