ember-estree 0.6.0 → 0.6.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/package.json +2 -1
- package/src/parse.js +49 -19
- package/src/transforms.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ember-estree",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "ESTree generator for gjs and gts file used by ember",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"AST",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@tsconfig/node-lts": "^22.0.2",
|
|
41
|
+
"@typescript-eslint/parser": "^8.59.0",
|
|
41
42
|
"mitata": "^1.0.34",
|
|
42
43
|
"oxfmt": "^0.40.0",
|
|
43
44
|
"oxlint": "^1.55.0",
|
package/src/parse.js
CHANGED
|
@@ -13,7 +13,29 @@ import { parseSync } from "oxc-parser";
|
|
|
13
13
|
import { Preprocessor } from "content-tag";
|
|
14
14
|
import { walk } from "zimmerframe";
|
|
15
15
|
|
|
16
|
-
import { processTemplate, DocumentLines, glimmerVisitorKeys } from "./transforms.js";
|
|
16
|
+
import { processTemplate, DocumentLines, glimmerVisitorKeys, setParent } from "./transforms.js";
|
|
17
|
+
|
|
18
|
+
// Swap `oldNode` for `newNode` in whichever slot of `parent` currently holds it.
|
|
19
|
+
// Used to splice a GlimmerTemplate directly into the outer AST without
|
|
20
|
+
// allocating new ancestor objects — keeps WeakMap-keyed data (scope manager,
|
|
21
|
+
// esTreeNodeToTSNodeMap) attached to the existing nodes.
|
|
22
|
+
function replaceInParent(parent, oldNode, newNode) {
|
|
23
|
+
for (const key of Object.keys(parent)) {
|
|
24
|
+
const v = parent[key];
|
|
25
|
+
if (v === oldNode) {
|
|
26
|
+
parent[key] = newNode;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (Array.isArray(v)) {
|
|
30
|
+
const idx = v.indexOf(oldNode);
|
|
31
|
+
if (idx !== -1) {
|
|
32
|
+
v[idx] = newNode;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
17
39
|
|
|
18
40
|
const preprocessor = new Preprocessor();
|
|
19
41
|
|
|
@@ -112,8 +134,11 @@ export function toTree(source, options = {}) {
|
|
|
112
134
|
? new Map(parseResults.map((r) => [r.range.startUtf16Codepoint, r]))
|
|
113
135
|
: null;
|
|
114
136
|
|
|
115
|
-
// Process a matched placeholder node: create Glimmer AST and tokens
|
|
116
|
-
|
|
137
|
+
// Process a matched placeholder node: create Glimmer AST and tokens.
|
|
138
|
+
// `placeholderNode` is the original JS/TS node being swapped out; we stash
|
|
139
|
+
// it on templateInfos so consumers can forward its parser-services mapping
|
|
140
|
+
// (e.g. esTreeNodeToTSNodeMap) onto the GlimmerTemplate that replaces it.
|
|
141
|
+
function processPlaceholder(parseResult, placeholderNode) {
|
|
117
142
|
let templateContent = parseResult.contents;
|
|
118
143
|
let contentRange = [
|
|
119
144
|
parseResult.contentRange.startUtf16Codepoint,
|
|
@@ -159,7 +184,7 @@ export function toTree(source, options = {}) {
|
|
|
159
184
|
];
|
|
160
185
|
}
|
|
161
186
|
|
|
162
|
-
templateInfos.push({ utf16Range: fullRange, ast });
|
|
187
|
+
templateInfos.push({ utf16Range: fullRange, ast, placeholder: placeholderNode });
|
|
163
188
|
return ast;
|
|
164
189
|
}
|
|
165
190
|
|
|
@@ -186,21 +211,23 @@ export function toTree(source, options = {}) {
|
|
|
186
211
|
if (hasTemplates && PLACEHOLDER_TYPES.has(node.type)) {
|
|
187
212
|
const parseResult = matchPlaceholder(node);
|
|
188
213
|
if (parseResult) {
|
|
189
|
-
const ast = processPlaceholder(parseResult);
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
//
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
214
|
+
const ast = processPlaceholder(parseResult, node);
|
|
215
|
+
// Splice in place: write the GlimmerTemplate directly into the
|
|
216
|
+
// parent's slot instead of returning it from the visitor. Returning
|
|
217
|
+
// would trigger zimmerframe's apply_mutations, which shallow-clones
|
|
218
|
+
// every ancestor up to the root — orphaning any WeakMap-keyed data
|
|
219
|
+
// held by custom parsers (scope manager, esTreeNodeToTSNodeMap).
|
|
220
|
+
// In-place mutation preserves node identity for all ancestors.
|
|
221
|
+
const parent = state?.parentPath?.node ?? null;
|
|
222
|
+
if (parent) replaceInParent(parent, node, ast);
|
|
223
|
+
setParent(ast, parent);
|
|
224
|
+
// Dispatch visitors on the Glimmer subtree. We pass `state` so the
|
|
225
|
+
// Glimmer root's parentPath reflects its true JS parent — the
|
|
199
226
|
// placeholder (TemplateLiteral / StaticBlock) is an internal
|
|
200
|
-
// artifact
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
return
|
|
227
|
+
// artifact. Not returning anything keeps apply_mutations from
|
|
228
|
+
// firing up the ancestor chain.
|
|
229
|
+
if (hasVisitors) visit(ast, state);
|
|
230
|
+
return;
|
|
204
231
|
}
|
|
205
232
|
}
|
|
206
233
|
|
|
@@ -240,8 +267,11 @@ export function toTree(source, options = {}) {
|
|
|
240
267
|
// original source byte-for-byte across JS and Glimmer regions.
|
|
241
268
|
//
|
|
242
269
|
// Tokens are sorted by range, so use binary search for O(log n) lookup.
|
|
270
|
+
// Only splice if the caller asked for tokens — otherwise `ti.ast.tokens`
|
|
271
|
+
// wasn't populated by processPlaceholder, and a custom parser may still
|
|
272
|
+
// have returned its own token stream we shouldn't touch.
|
|
243
273
|
const astRoot = result.ast.program || result.ast;
|
|
244
|
-
if (astRoot.tokens) {
|
|
274
|
+
if (generateTokens && astRoot.tokens) {
|
|
245
275
|
for (const ti of templateInfos) {
|
|
246
276
|
const [tStart, tEnd] = ti.utf16Range;
|
|
247
277
|
const tokens = astRoot.tokens;
|
package/src/transforms.js
CHANGED
|
@@ -64,7 +64,7 @@ export const glimmerVisitorKeys = (() => {
|
|
|
64
64
|
// Block: blockParams
|
|
65
65
|
const _desc = { value: undefined, configurable: true, enumerable: true, writable: true };
|
|
66
66
|
const _parentDesc = { value: null, configurable: true, enumerable: false, writable: true };
|
|
67
|
-
function setParent(node, parent) {
|
|
67
|
+
export function setParent(node, parent) {
|
|
68
68
|
_parentDesc.value = parent;
|
|
69
69
|
Object.defineProperty(node, "parent", _parentDesc);
|
|
70
70
|
}
|