@ohos-ports/ember-estree 0.6.11-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/README.md +420 -0
- package/package.json +63 -0
- package/src/index.d.ts +68 -0
- package/src/index.js +3 -0
- package/src/parse.js +388 -0
- package/src/print.js +1095 -0
- package/src/tokens.js +177 -0
- package/src/transforms.js +279 -0
package/README.md
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# ember-estree
|
|
2
|
+
|
|
3
|
+
ESTree-compatible AST parser for Ember's `.gjs` and `.gts` files.
|
|
4
|
+
|
|
5
|
+
Parses `<template>` tags into [Glimmer](https://github.com/emberjs/ember.js/) AST nodes that are embedded directly in the ESTree, so tools like linters and codemods can work with both the JavaScript/TypeScript _and_ template portions of a single file.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add ember-estree
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Parsing
|
|
16
|
+
|
|
17
|
+
`toTree` returns a `File` node whose `.program` is a standard ESTree `Program`, with any `<template>` regions represented as `Glimmer*` AST nodes.
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
import { toTree } from "ember-estree";
|
|
21
|
+
|
|
22
|
+
let ast = toTree(`
|
|
23
|
+
import Component from "@glimmer/component";
|
|
24
|
+
|
|
25
|
+
export default class Demo extends Component {
|
|
26
|
+
<template>Hello, {{this.name}}!</template>
|
|
27
|
+
}
|
|
28
|
+
`);
|
|
29
|
+
|
|
30
|
+
console.log(ast.type); // "File"
|
|
31
|
+
console.log(ast.program.body.length); // 2 — ImportDeclaration + ClassDeclaration
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`parse` is a lower-level alternative that returns the `Program` node directly.
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
import { parse } from "ember-estree";
|
|
38
|
+
|
|
39
|
+
let program = parse(`const x = <template>hi</template>;`);
|
|
40
|
+
console.log(program.type); // "Program"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Printing
|
|
44
|
+
|
|
45
|
+
`print` converts an AST node (ESTree _or_ Glimmer) back to source code.
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { print } from "ember-estree";
|
|
49
|
+
|
|
50
|
+
print({ type: "Identifier", name: "foo" });
|
|
51
|
+
// => "foo"
|
|
52
|
+
|
|
53
|
+
print({
|
|
54
|
+
type: "GlimmerTemplate",
|
|
55
|
+
body: [{ type: "GlimmerTextNode", chars: "Hello" }],
|
|
56
|
+
});
|
|
57
|
+
// => "<template>Hello</template>"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`print` also accepts the `File` node returned by `toTree`, printing the whole program with `file.comments` woven back into the output (each comment is emitted before the nearest node that follows it in the original source). Placement is approximate — a trailing same-line comment becomes a leading comment of the next node — so pair the output with a formatter (e.g. prettier) when exact layout matters.
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { toTree, print } from "ember-estree";
|
|
64
|
+
|
|
65
|
+
let tree = toTree(`// greet the user\nlet greeting = "hello";`);
|
|
66
|
+
|
|
67
|
+
print(tree);
|
|
68
|
+
// => '// greet the user\nlet greeting = "hello";'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Options
|
|
72
|
+
|
|
73
|
+
Both `toTree` and `parse` accept an options object as their second argument.
|
|
74
|
+
|
|
75
|
+
All options are optional.
|
|
76
|
+
|
|
77
|
+
| Option | Type | Description |
|
|
78
|
+
| -------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `filePath` | `string` | Used for language detection. |
|
|
80
|
+
| `tokens` | `boolean` | Generate a flat `ast.tokens` array. Required by ESLint; skipped by default so codemods and type-checkers pay nothing. |
|
|
81
|
+
| `templateOnly` | `boolean` | Parse the source as a raw Glimmer template. Use for `.hbs` files. |
|
|
82
|
+
| `parser` | `(placeholderJS: string) => { ast, ... }` | Use a custom JS/TS parser instead of the default oxc-parser. See [Custom parser](#custom-parser). |
|
|
83
|
+
| `visitors` | `VisitorMap` <br /> or `(outerAst) => VisitorMap` | Callbacks fired on every node during traversal — JS/TS and Glimmer — in a single pass. See [Visitors](#visitors). |
|
|
84
|
+
|
|
85
|
+
Handler signature is `(node, path) => void`, where `path = { node, parent, parentPath }` — a linked list that walks all the way back through the JS/TS root, so visitors can locate the enclosing scope or class from within a Glimmer subtree.
|
|
86
|
+
|
|
87
|
+
### Token stream
|
|
88
|
+
|
|
89
|
+
Pass `tokens: true` to populate `ast.tokens` with a flat, position-sorted array of lexemes spanning the full file — including Glimmer tokens spliced in place of each `<template>` region. This is what ESLint's `SourceCode` needs; omit it for codemods or type-checkers that don't use the token stream.
|
|
90
|
+
|
|
91
|
+
```js
|
|
92
|
+
import { toTree } from "ember-estree";
|
|
93
|
+
|
|
94
|
+
const result = toTree(source, {
|
|
95
|
+
tokens: true,
|
|
96
|
+
parser: myTsParser,
|
|
97
|
+
});
|
|
98
|
+
// result.ast.program.tokens now contains JS + Glimmer tokens in source order
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For `.hbs` files via `templateOnly`, pass both flags:
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
toTree(hbsSource, { templateOnly: true, tokens: true });
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Custom parser
|
|
108
|
+
|
|
109
|
+
Pass any JS/TS parser that returns an ESTree-compatible AST. ember-estree handles template splicing and Glimmer traversal on top of it.
|
|
110
|
+
|
|
111
|
+
```js
|
|
112
|
+
import { parseSync } from "oxc-parser";
|
|
113
|
+
import { toTree } from "ember-estree";
|
|
114
|
+
|
|
115
|
+
const result = toTree(source, {
|
|
116
|
+
parser: (js) => ({
|
|
117
|
+
ast: parseSync("input.ts", js).program,
|
|
118
|
+
visitorKeys: {
|
|
119
|
+
/* ...parser's visitor keys... */
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
The parser receives a placeholder-JS string (templates replaced with backtick expressions of equal length) and must return at least `{ ast }`. Additional fields like `scopeManager`, `visitorKeys`, or `services` are preserved on the returned result.
|
|
126
|
+
|
|
127
|
+
### Visitors
|
|
128
|
+
|
|
129
|
+
Pass `visitors` to observe or rewrite the tree in a single traversal. Handlers fire on both outer JS/TS nodes and spliced Glimmer subtrees, and a single node is never dispatched twice — safe to relocate nodes mid-walk.
|
|
130
|
+
|
|
131
|
+
The pseudo-type `GlimmerBlockParams` fires on any node that carries a `blockParams` array.
|
|
132
|
+
|
|
133
|
+
**Plain-object form** — use when you only need the type → handler map:
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
import { toTree } from "ember-estree";
|
|
137
|
+
|
|
138
|
+
const identifiers = [];
|
|
139
|
+
toTree(source, {
|
|
140
|
+
visitors: {
|
|
141
|
+
Identifier: (node) => identifiers.push(node.name),
|
|
142
|
+
GlimmerPathExpression: (node) => identifiers.push(node.original),
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Factory form** — use when you need the outer JS/TS AST up front (for example, to attach state to it before the walk):
|
|
148
|
+
|
|
149
|
+
```js
|
|
150
|
+
import { toTree, print } from "ember-estree";
|
|
151
|
+
|
|
152
|
+
const ast = toTree(`const world = "🌍"; const X = <template>{{world}}</template>;`, {
|
|
153
|
+
visitors: () => ({
|
|
154
|
+
Identifier: (node) => (node.name = node.name.toUpperCase()),
|
|
155
|
+
GlimmerPathExpression(node) {
|
|
156
|
+
node.original = node.original.toUpperCase();
|
|
157
|
+
if (node.head) node.head.name = node.original;
|
|
158
|
+
},
|
|
159
|
+
}),
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
print(ast.program);
|
|
163
|
+
// => 'const WORLD = "🌍";\nconst X = <template>{{WORLD}}</template>;'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Collecting Glimmer comments into `program.comments`** — useful when adapting the AST for ESLint, which reads comments from the Program node:
|
|
167
|
+
|
|
168
|
+
```js
|
|
169
|
+
const ast = toTree(source, {
|
|
170
|
+
visitors: (outerAst) => {
|
|
171
|
+
outerAst.program.comments = [...(outerAst.comments ?? [])];
|
|
172
|
+
const push = (node) => outerAst.program.comments.push(node);
|
|
173
|
+
return {
|
|
174
|
+
GlimmerCommentStatement: push,
|
|
175
|
+
GlimmerMustacheCommentStatement: push,
|
|
176
|
+
};
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Removing nodes mid-traversal** — siblings are splice-safe:
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
toTree(source, {
|
|
185
|
+
visitors: () => ({
|
|
186
|
+
GlimmerMustacheCommentStatement(node, path) {
|
|
187
|
+
const siblings = path.parent?.body ?? path.parent?.children;
|
|
188
|
+
const idx = siblings?.indexOf(node) ?? -1;
|
|
189
|
+
if (idx >= 0) siblings.splice(idx, 1);
|
|
190
|
+
},
|
|
191
|
+
}),
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Examples
|
|
196
|
+
|
|
197
|
+
The [`examples/`](./examples) directory contains ready-to-run integrations:
|
|
198
|
+
|
|
199
|
+
| Example | Description |
|
|
200
|
+
| ------------------------------------------- | -------------------------------------------------------------------- |
|
|
201
|
+
| [`eslint-parser`](./examples/eslint-parser) | Custom ESLint parser that understands `<template>` |
|
|
202
|
+
| [`zmod`](./examples/zmod) | Codemod toolkit using [zmod](https://github.com/nicolo-ribaudo/zmod) |
|
|
203
|
+
|
|
204
|
+
<!-- ast-nodes:start -->
|
|
205
|
+
<!-- Generated by scripts/generate-ast-node-reference.mjs — do not edit by hand. -->
|
|
206
|
+
|
|
207
|
+
## AST node reference
|
|
208
|
+
|
|
209
|
+
<details>
|
|
210
|
+
<summary><strong>Every AST node</strong> ember-estree may emit (171 total) — grouped by which files they appear in</summary>
|
|
211
|
+
|
|
212
|
+
Generated from `oxc-parser`'s and `@glimmer/syntax`'s visitor-key maps. Re-run `node scripts/generate-ast-node-reference.mjs` after bumping either dependency to keep this in sync.
|
|
213
|
+
|
|
214
|
+
<details>
|
|
215
|
+
<summary><strong>Core ESTree</strong> — in <code>.gjs</code> and <code>.gts</code> (76 nodes)</summary>
|
|
216
|
+
|
|
217
|
+
Standard JavaScript node types. Present in both `.gjs` and `.gts` — TypeScript is a superset of JavaScript, so `.gts` files may contain all of these too.
|
|
218
|
+
|
|
219
|
+
| Node | Child keys |
|
|
220
|
+
| -------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
221
|
+
| `AccessorProperty` | `decorators`, `key`, `typeAnnotation`, `value` |
|
|
222
|
+
| `ArrayExpression` | `elements` |
|
|
223
|
+
| `ArrayPattern` | `decorators`, `elements`, `typeAnnotation` |
|
|
224
|
+
| `ArrowFunctionExpression` | `typeParameters`, `params`, `returnType`, `body` |
|
|
225
|
+
| `AssignmentExpression` | `left`, `right` |
|
|
226
|
+
| `AssignmentPattern` | `decorators`, `left`, `right`, `typeAnnotation` |
|
|
227
|
+
| `AwaitExpression` | `argument` |
|
|
228
|
+
| `BinaryExpression` | `left`, `right` |
|
|
229
|
+
| `BlockStatement` | `body` |
|
|
230
|
+
| `BreakStatement` | `label` |
|
|
231
|
+
| `CallExpression` | `callee`, `typeArguments`, `arguments` |
|
|
232
|
+
| `CatchClause` | `param`, `body` |
|
|
233
|
+
| `ChainExpression` | `expression` |
|
|
234
|
+
| `ClassBody` | `body` |
|
|
235
|
+
| `ClassDeclaration` | `decorators`, `id`, `typeParameters`, `superClass`, `superTypeArguments`, `implements`, `body` |
|
|
236
|
+
| `ClassExpression` | `decorators`, `id`, `typeParameters`, `superClass`, `superTypeArguments`, `implements`, `body` |
|
|
237
|
+
| `ConditionalExpression` | `test`, `consequent`, `alternate` |
|
|
238
|
+
| `ContinueStatement` | `label` |
|
|
239
|
+
| `DebuggerStatement` | _(leaf)_ |
|
|
240
|
+
| `Decorator` | `expression` |
|
|
241
|
+
| `DoWhileStatement` | `body`, `test` |
|
|
242
|
+
| `EmptyStatement` | _(leaf)_ |
|
|
243
|
+
| `ExportAllDeclaration` | `exported`, `source`, `attributes` |
|
|
244
|
+
| `ExportDefaultDeclaration` | `declaration` |
|
|
245
|
+
| `ExportNamedDeclaration` | `declaration`, `specifiers`, `source`, `attributes` |
|
|
246
|
+
| `ExportSpecifier` | `local`, `exported` |
|
|
247
|
+
| `ExpressionStatement` | `expression` |
|
|
248
|
+
| `ForInStatement` | `left`, `right`, `body` |
|
|
249
|
+
| `ForOfStatement` | `left`, `right`, `body` |
|
|
250
|
+
| `ForStatement` | `init`, `test`, `update`, `body` |
|
|
251
|
+
| `FunctionDeclaration` | `id`, `typeParameters`, `params`, `returnType`, `body` |
|
|
252
|
+
| `FunctionExpression` | `id`, `typeParameters`, `params`, `returnType`, `body` |
|
|
253
|
+
| `Identifier` | `decorators`, `typeAnnotation` |
|
|
254
|
+
| `IfStatement` | `test`, `consequent`, `alternate` |
|
|
255
|
+
| `ImportAttribute` | `key`, `value` |
|
|
256
|
+
| `ImportDeclaration` | `specifiers`, `source`, `attributes` |
|
|
257
|
+
| `ImportDefaultSpecifier` | `local` |
|
|
258
|
+
| `ImportExpression` | `source`, `options` |
|
|
259
|
+
| `ImportNamespaceSpecifier` | `local` |
|
|
260
|
+
| `ImportSpecifier` | `imported`, `local` |
|
|
261
|
+
| `LabeledStatement` | `label`, `body` |
|
|
262
|
+
| `Literal` | _(leaf)_ |
|
|
263
|
+
| `LogicalExpression` | `left`, `right` |
|
|
264
|
+
| `MemberExpression` | `object`, `property` |
|
|
265
|
+
| `MetaProperty` | `meta`, `property` |
|
|
266
|
+
| `MethodDefinition` | `decorators`, `key`, `value` |
|
|
267
|
+
| `NewExpression` | `callee`, `typeArguments`, `arguments` |
|
|
268
|
+
| `ObjectExpression` | `properties` |
|
|
269
|
+
| `ObjectPattern` | `decorators`, `properties`, `typeAnnotation` |
|
|
270
|
+
| `ParenthesizedExpression` | `expression` |
|
|
271
|
+
| `PrivateIdentifier` | _(leaf)_ |
|
|
272
|
+
| `Program` | `body` |
|
|
273
|
+
| `Property` | `key`, `value` |
|
|
274
|
+
| `PropertyDefinition` | `decorators`, `key`, `typeAnnotation`, `value` |
|
|
275
|
+
| `RestElement` | `decorators`, `argument`, `typeAnnotation` |
|
|
276
|
+
| `ReturnStatement` | `argument` |
|
|
277
|
+
| `SequenceExpression` | `expressions` |
|
|
278
|
+
| `SpreadElement` | `argument` |
|
|
279
|
+
| `StaticBlock` | `body` |
|
|
280
|
+
| `Super` | _(leaf)_ |
|
|
281
|
+
| `SwitchCase` | `test`, `consequent` |
|
|
282
|
+
| `SwitchStatement` | `discriminant`, `cases` |
|
|
283
|
+
| `TaggedTemplateExpression` | `tag`, `typeArguments`, `quasi` |
|
|
284
|
+
| `TemplateElement` | _(leaf)_ |
|
|
285
|
+
| `TemplateLiteral` | `quasis`, `expressions` |
|
|
286
|
+
| `ThisExpression` | _(leaf)_ |
|
|
287
|
+
| `ThrowStatement` | `argument` |
|
|
288
|
+
| `TryStatement` | `block`, `handler`, `finalizer` |
|
|
289
|
+
| `UnaryExpression` | `argument` |
|
|
290
|
+
| `UpdateExpression` | `argument` |
|
|
291
|
+
| `V8IntrinsicExpression` | `name`, `arguments` |
|
|
292
|
+
| `VariableDeclaration` | `declarations` |
|
|
293
|
+
| `VariableDeclarator` | `id`, `init` |
|
|
294
|
+
| `WhileStatement` | `test`, `body` |
|
|
295
|
+
| `WithStatement` | `object`, `body` |
|
|
296
|
+
| `YieldExpression` | `argument` |
|
|
297
|
+
|
|
298
|
+
</details>
|
|
299
|
+
|
|
300
|
+
<details>
|
|
301
|
+
<summary><strong>TypeScript</strong> — <code>.gts</code> only (74 nodes)</summary>
|
|
302
|
+
|
|
303
|
+
TypeScript-specific nodes. Can only appear in `.gts` files.
|
|
304
|
+
|
|
305
|
+
| Node | Child keys |
|
|
306
|
+
| --------------------------------- | ------------------------------------------------------ |
|
|
307
|
+
| `TSAbstractAccessorProperty` | `decorators`, `key`, `typeAnnotation` |
|
|
308
|
+
| `TSAbstractMethodDefinition` | `key`, `value` |
|
|
309
|
+
| `TSAbstractPropertyDefinition` | `decorators`, `key`, `typeAnnotation` |
|
|
310
|
+
| `TSAnyKeyword` | _(leaf)_ |
|
|
311
|
+
| `TSArrayType` | `elementType` |
|
|
312
|
+
| `TSAsExpression` | `expression`, `typeAnnotation` |
|
|
313
|
+
| `TSBigIntKeyword` | _(leaf)_ |
|
|
314
|
+
| `TSBooleanKeyword` | _(leaf)_ |
|
|
315
|
+
| `TSCallSignatureDeclaration` | `typeParameters`, `params`, `returnType` |
|
|
316
|
+
| `TSClassImplements` | `expression`, `typeArguments` |
|
|
317
|
+
| `TSConditionalType` | `checkType`, `extendsType`, `trueType`, `falseType` |
|
|
318
|
+
| `TSConstructorType` | `typeParameters`, `params`, `returnType` |
|
|
319
|
+
| `TSConstructSignatureDeclaration` | `typeParameters`, `params`, `returnType` |
|
|
320
|
+
| `TSDeclareFunction` | `id`, `typeParameters`, `params`, `returnType`, `body` |
|
|
321
|
+
| `TSEmptyBodyFunctionExpression` | `id`, `typeParameters`, `params`, `returnType` |
|
|
322
|
+
| `TSEnumBody` | `members` |
|
|
323
|
+
| `TSEnumDeclaration` | `id`, `body` |
|
|
324
|
+
| `TSEnumMember` | `id`, `initializer` |
|
|
325
|
+
| `TSExportAssignment` | `expression` |
|
|
326
|
+
| `TSExternalModuleReference` | `expression` |
|
|
327
|
+
| `TSFunctionType` | `typeParameters`, `params`, `returnType` |
|
|
328
|
+
| `TSImportEqualsDeclaration` | `id`, `moduleReference` |
|
|
329
|
+
| `TSImportType` | `source`, `options`, `qualifier`, `typeArguments` |
|
|
330
|
+
| `TSIndexedAccessType` | `objectType`, `indexType` |
|
|
331
|
+
| `TSIndexSignature` | `parameters`, `typeAnnotation` |
|
|
332
|
+
| `TSInferType` | `typeParameter` |
|
|
333
|
+
| `TSInstantiationExpression` | `expression`, `typeArguments` |
|
|
334
|
+
| `TSInterfaceBody` | `body` |
|
|
335
|
+
| `TSInterfaceDeclaration` | `id`, `typeParameters`, `extends`, `body` |
|
|
336
|
+
| `TSInterfaceHeritage` | `expression`, `typeArguments` |
|
|
337
|
+
| `TSIntersectionType` | `types` |
|
|
338
|
+
| `TSIntrinsicKeyword` | _(leaf)_ |
|
|
339
|
+
| `TSJSDocNonNullableType` | `typeAnnotation` |
|
|
340
|
+
| `TSJSDocNullableType` | `typeAnnotation` |
|
|
341
|
+
| `TSJSDocUnknownType` | _(leaf)_ |
|
|
342
|
+
| `TSLiteralType` | `literal` |
|
|
343
|
+
| `TSMappedType` | `key`, `constraint`, `nameType`, `typeAnnotation` |
|
|
344
|
+
| `TSMethodSignature` | `key`, `typeParameters`, `params`, `returnType` |
|
|
345
|
+
| `TSModuleBlock` | `body` |
|
|
346
|
+
| `TSModuleDeclaration` | `id`, `body` |
|
|
347
|
+
| `TSNamedTupleMember` | `label`, `elementType` |
|
|
348
|
+
| `TSNamespaceExportDeclaration` | `id` |
|
|
349
|
+
| `TSNeverKeyword` | _(leaf)_ |
|
|
350
|
+
| `TSNonNullExpression` | `expression` |
|
|
351
|
+
| `TSNullKeyword` | _(leaf)_ |
|
|
352
|
+
| `TSNumberKeyword` | _(leaf)_ |
|
|
353
|
+
| `TSObjectKeyword` | _(leaf)_ |
|
|
354
|
+
| `TSOptionalType` | `typeAnnotation` |
|
|
355
|
+
| `TSParameterProperty` | `decorators`, `parameter` |
|
|
356
|
+
| `TSParenthesizedType` | `typeAnnotation` |
|
|
357
|
+
| `TSPropertySignature` | `key`, `typeAnnotation` |
|
|
358
|
+
| `TSQualifiedName` | `left`, `right` |
|
|
359
|
+
| `TSRestType` | `typeAnnotation` |
|
|
360
|
+
| `TSSatisfiesExpression` | `expression`, `typeAnnotation` |
|
|
361
|
+
| `TSStringKeyword` | _(leaf)_ |
|
|
362
|
+
| `TSSymbolKeyword` | _(leaf)_ |
|
|
363
|
+
| `TSTemplateLiteralType` | `quasis`, `types` |
|
|
364
|
+
| `TSThisType` | _(leaf)_ |
|
|
365
|
+
| `TSTupleType` | `elementTypes` |
|
|
366
|
+
| `TSTypeAliasDeclaration` | `id`, `typeParameters`, `typeAnnotation` |
|
|
367
|
+
| `TSTypeAnnotation` | `typeAnnotation` |
|
|
368
|
+
| `TSTypeAssertion` | `typeAnnotation`, `expression` |
|
|
369
|
+
| `TSTypeLiteral` | `members` |
|
|
370
|
+
| `TSTypeOperator` | `typeAnnotation` |
|
|
371
|
+
| `TSTypeParameter` | `name`, `constraint`, `default` |
|
|
372
|
+
| `TSTypeParameterDeclaration` | `params` |
|
|
373
|
+
| `TSTypeParameterInstantiation` | `params` |
|
|
374
|
+
| `TSTypePredicate` | `parameterName`, `typeAnnotation` |
|
|
375
|
+
| `TSTypeQuery` | `exprName`, `typeArguments` |
|
|
376
|
+
| `TSTypeReference` | `typeName`, `typeArguments` |
|
|
377
|
+
| `TSUndefinedKeyword` | _(leaf)_ |
|
|
378
|
+
| `TSUnionType` | `types` |
|
|
379
|
+
| `TSUnknownKeyword` | _(leaf)_ |
|
|
380
|
+
| `TSVoidKeyword` | _(leaf)_ |
|
|
381
|
+
|
|
382
|
+
</details>
|
|
383
|
+
|
|
384
|
+
<details>
|
|
385
|
+
<summary><strong>Glimmer template</strong> — in <code>.gjs</code> and <code>.gts</code> (21 nodes)</summary>
|
|
386
|
+
|
|
387
|
+
Nodes produced inside `<template>...</template>` regions by `@glimmer/syntax`, prefixed with `Glimmer` when spliced into the ESTree.
|
|
388
|
+
|
|
389
|
+
| Node | Child keys |
|
|
390
|
+
| --------------------------------- | ----------------------------------------------------------------------------- |
|
|
391
|
+
| `GlimmerAttrNode` | `value` |
|
|
392
|
+
| `GlimmerBlock` | `body` |
|
|
393
|
+
| `GlimmerBlockStatement` | `path`, `params`, `hash`, `program`, `inverse` |
|
|
394
|
+
| `GlimmerBooleanLiteral` | _(leaf)_ |
|
|
395
|
+
| `GlimmerCommentStatement` | _(leaf)_ |
|
|
396
|
+
| `GlimmerConcatStatement` | `parts` |
|
|
397
|
+
| `GlimmerElementModifierStatement` | `path`, `params`, `hash` |
|
|
398
|
+
| `GlimmerElementNode` | `attributes`, `modifiers`, `children`, `comments`, `blockParamNodes`, `parts` |
|
|
399
|
+
| `GlimmerHash` | `pairs` |
|
|
400
|
+
| `GlimmerHashPair` | `value` |
|
|
401
|
+
| `GlimmerMustacheCommentStatement` | _(leaf)_ |
|
|
402
|
+
| `GlimmerMustacheStatement` | `path`, `params`, `hash` |
|
|
403
|
+
| `GlimmerNullLiteral` | _(leaf)_ |
|
|
404
|
+
| `GlimmerNumberLiteral` | _(leaf)_ |
|
|
405
|
+
| `GlimmerPathExpression` | _(leaf)_ |
|
|
406
|
+
| `GlimmerProgram` | `body`, `blockParamNodes` |
|
|
407
|
+
| `GlimmerStringLiteral` | _(leaf)_ |
|
|
408
|
+
| `GlimmerSubExpression` | `path`, `params`, `hash` |
|
|
409
|
+
| `GlimmerTemplate` | `body` |
|
|
410
|
+
| `GlimmerTextNode` | _(leaf)_ |
|
|
411
|
+
| `GlimmerUndefinedLiteral` | _(leaf)_ |
|
|
412
|
+
|
|
413
|
+
</details>
|
|
414
|
+
|
|
415
|
+
</details>
|
|
416
|
+
<!-- ast-nodes:end -->
|
|
417
|
+
|
|
418
|
+
## License
|
|
419
|
+
|
|
420
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ohos-ports/ember-estree",
|
|
3
|
+
"version": "0.6.11-beta.0",
|
|
4
|
+
"description": "ESTree generator for gjs and gts file used by ember",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"AST",
|
|
7
|
+
"codemod",
|
|
8
|
+
"ember",
|
|
9
|
+
"estree",
|
|
10
|
+
"glimmer",
|
|
11
|
+
"traversal",
|
|
12
|
+
"walker"
|
|
13
|
+
],
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"author": "NullVoxPopuli",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/ohos-ports/ohos-ports.git",
|
|
19
|
+
"directory": "ports/ember-estree/0.6.11"
|
|
20
|
+
},
|
|
21
|
+
"files": [
|
|
22
|
+
"src"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "src/index.js",
|
|
26
|
+
"types": "src/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./src/index.d.ts",
|
|
30
|
+
"default": "./src/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@glimmer/env": "^0.1.7",
|
|
35
|
+
"@glimmer/syntax": "^0.95.0",
|
|
36
|
+
"content-tag": "^4.2.0",
|
|
37
|
+
"@ohos-ports/oxc-parser": "0.130.0-beta.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@tsconfig/node-lts": "^24.0.0",
|
|
41
|
+
"@typescript-eslint/parser": "^8.59.3",
|
|
42
|
+
"mitata": "^1.0.34",
|
|
43
|
+
"oxfmt": "^0.49.0",
|
|
44
|
+
"oxlint": "^1.64.0",
|
|
45
|
+
"publint": "^0.3.20",
|
|
46
|
+
"release-plan": "^0.18.0",
|
|
47
|
+
"typescript": "^6.0.3",
|
|
48
|
+
"vitest": "^4.1.6",
|
|
49
|
+
"zimmerframe": "^1.1.4"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"bench": "node --expose-gc tests/parser.bench.mjs",
|
|
53
|
+
"bench:compare": "node scripts/bench-compare.mjs",
|
|
54
|
+
"bench:summary": "./scripts/local-bench-summary.sh",
|
|
55
|
+
"docs:nodes": "node scripts/generate-ast-node-reference.mjs",
|
|
56
|
+
"format": "oxfmt",
|
|
57
|
+
"format:check": "oxfmt --check",
|
|
58
|
+
"lint": "oxlint && pnpm format:check && publint",
|
|
59
|
+
"lint:fix": "oxlint --fix && oxfmt",
|
|
60
|
+
"test": "vitest run"
|
|
61
|
+
},
|
|
62
|
+
"bugs": "https://github.com/ohos-ports/ohos-ports/issues"
|
|
63
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export interface Position {
|
|
2
|
+
line: number;
|
|
3
|
+
column: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface ASTNode {
|
|
7
|
+
type: string;
|
|
8
|
+
start?: number;
|
|
9
|
+
end?: number;
|
|
10
|
+
[key: string]: unknown;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface FileNode extends ASTNode {
|
|
14
|
+
type: "File";
|
|
15
|
+
program: ASTNode;
|
|
16
|
+
comments: ASTNode[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface TemplateResult {
|
|
20
|
+
ast: ASTNode;
|
|
21
|
+
comments: ASTNode[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface VisitorPath {
|
|
25
|
+
node: ASTNode;
|
|
26
|
+
parent: ASTNode | null;
|
|
27
|
+
parentPath: VisitorPath | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface ParseOptions {
|
|
31
|
+
filePath?: string;
|
|
32
|
+
templateOnly?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Custom JS/TS parser. Called with the placeholder JS string
|
|
35
|
+
* (templates replaced with backtick expressions of equal length).
|
|
36
|
+
* Must return at least `{ ast }`.
|
|
37
|
+
*/
|
|
38
|
+
parser?: (placeholderJS: string) => { ast: ASTNode; [key: string]: unknown };
|
|
39
|
+
/**
|
|
40
|
+
* Callbacks fired on each node during traversal — outer JS/TS nodes AND
|
|
41
|
+
* spliced Glimmer subtrees — so callers can gather information or mutate
|
|
42
|
+
* the tree in a single pass.
|
|
43
|
+
*
|
|
44
|
+
* Pass either a plain handler map, or a factory `(outerAst) => handlers`
|
|
45
|
+
* that's called once after parsing (before template splicing) when you
|
|
46
|
+
* need a view of the raw JS/TS tree up front.
|
|
47
|
+
*
|
|
48
|
+
* The pseudo-type `GlimmerBlockParams` fires on any node that carries
|
|
49
|
+
* a `blockParams` array.
|
|
50
|
+
*/
|
|
51
|
+
visitors?: VisitorMap | ((outerAst: ASTNode) => VisitorMap | null | undefined);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type VisitorMap = {
|
|
55
|
+
[nodeType: string]: (node: ASTNode, path: VisitorPath) => void;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export class DocumentLines {
|
|
59
|
+
constructor(source: string);
|
|
60
|
+
positionToOffset(pos: Position): number;
|
|
61
|
+
offsetToPosition(offset: number): Position;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function toTree(source: string, options?: ParseOptions): FileNode | TemplateResult;
|
|
65
|
+
export function parse(source: string, options?: ParseOptions): FileNode | TemplateResult;
|
|
66
|
+
export function print(node: ASTNode): string;
|
|
67
|
+
|
|
68
|
+
export const glimmerVisitorKeys: Record<string, string[]>;
|
package/src/index.js
ADDED