@typescript-eslint/typescript-estree 8.10.1-alpha.7 → 8.11.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.
Files changed (101) hide show
  1. package/dist/ast-converter.d.ts +1 -1
  2. package/dist/ast-converter.d.ts.map +1 -1
  3. package/dist/ast-converter.js +1 -1
  4. package/dist/ast-converter.js.map +1 -1
  5. package/dist/convert-comments.d.ts.map +1 -1
  6. package/dist/convert-comments.js +2 -2
  7. package/dist/convert-comments.js.map +1 -1
  8. package/dist/convert.d.ts +36 -36
  9. package/dist/convert.d.ts.map +1 -1
  10. package/dist/convert.js +667 -667
  11. package/dist/convert.js.map +1 -1
  12. package/dist/create-program/WatchCompilerHostOfConfigFile.d.ts +1 -1
  13. package/dist/create-program/WatchCompilerHostOfConfigFile.d.ts.map +1 -1
  14. package/dist/create-program/createIsolatedProgram.d.ts.map +1 -1
  15. package/dist/create-program/createIsolatedProgram.js +4 -4
  16. package/dist/create-program/createIsolatedProgram.js.map +1 -1
  17. package/dist/create-program/createProjectProgram.d.ts.map +1 -1
  18. package/dist/create-program/createProjectProgram.js.map +1 -1
  19. package/dist/create-program/createProjectProgramError.d.ts.map +1 -1
  20. package/dist/create-program/createProjectProgramError.js.map +1 -1
  21. package/dist/create-program/createProjectService.d.ts.map +1 -1
  22. package/dist/create-program/createProjectService.js +6 -7
  23. package/dist/create-program/createProjectService.js.map +1 -1
  24. package/dist/create-program/createSourceFile.d.ts +1 -1
  25. package/dist/create-program/createSourceFile.d.ts.map +1 -1
  26. package/dist/create-program/createSourceFile.js +2 -2
  27. package/dist/create-program/createSourceFile.js.map +1 -1
  28. package/dist/create-program/getParsedConfigFile.d.ts.map +1 -1
  29. package/dist/create-program/getParsedConfigFile.js +2 -2
  30. package/dist/create-program/getParsedConfigFile.js.map +1 -1
  31. package/dist/create-program/getScriptKind.d.ts +1 -1
  32. package/dist/create-program/getScriptKind.d.ts.map +1 -1
  33. package/dist/create-program/getScriptKind.js +9 -9
  34. package/dist/create-program/getScriptKind.js.map +1 -1
  35. package/dist/create-program/getWatchProgramsForProjects.d.ts.map +1 -1
  36. package/dist/create-program/getWatchProgramsForProjects.js +1 -1
  37. package/dist/create-program/getWatchProgramsForProjects.js.map +1 -1
  38. package/dist/create-program/shared.d.ts +3 -3
  39. package/dist/create-program/shared.d.ts.map +1 -1
  40. package/dist/create-program/shared.js +6 -6
  41. package/dist/create-program/shared.js.map +1 -1
  42. package/dist/create-program/useProvidedPrograms.d.ts +1 -1
  43. package/dist/create-program/useProvidedPrograms.d.ts.map +1 -1
  44. package/dist/create-program/useProvidedPrograms.js +2 -2
  45. package/dist/create-program/useProvidedPrograms.js.map +1 -1
  46. package/dist/createParserServices.js +1 -1
  47. package/dist/createParserServices.js.map +1 -1
  48. package/dist/index.d.ts +7 -7
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +10 -10
  51. package/dist/index.js.map +1 -1
  52. package/dist/jsx/xhtml-entities.js +223 -223
  53. package/dist/jsx/xhtml-entities.js.map +1 -1
  54. package/dist/node-utils.d.ts +14 -14
  55. package/dist/node-utils.d.ts.map +1 -1
  56. package/dist/node-utils.js +42 -42
  57. package/dist/node-utils.js.map +1 -1
  58. package/dist/parseSettings/ExpiringCache.d.ts +2 -2
  59. package/dist/parseSettings/ExpiringCache.d.ts.map +1 -1
  60. package/dist/parseSettings/ExpiringCache.js +11 -11
  61. package/dist/parseSettings/ExpiringCache.js.map +1 -1
  62. package/dist/parseSettings/createParseSettings.d.ts +1 -1
  63. package/dist/parseSettings/createParseSettings.d.ts.map +1 -1
  64. package/dist/parseSettings/createParseSettings.js +13 -13
  65. package/dist/parseSettings/createParseSettings.js.map +1 -1
  66. package/dist/parseSettings/getProjectConfigFiles.d.ts.map +1 -1
  67. package/dist/parseSettings/getProjectConfigFiles.js +1 -1
  68. package/dist/parseSettings/getProjectConfigFiles.js.map +1 -1
  69. package/dist/parseSettings/index.d.ts +2 -2
  70. package/dist/parseSettings/index.d.ts.map +1 -1
  71. package/dist/parseSettings/resolveProjectList.d.ts.map +1 -1
  72. package/dist/parseSettings/resolveProjectList.js.map +1 -1
  73. package/dist/parser-options.d.ts +3 -3
  74. package/dist/parser-options.d.ts.map +1 -1
  75. package/dist/parser.d.ts +4 -4
  76. package/dist/parser.d.ts.map +1 -1
  77. package/dist/parser.js +5 -5
  78. package/dist/parser.js.map +1 -1
  79. package/dist/semantic-or-syntactic-errors.d.ts.map +1 -1
  80. package/dist/semantic-or-syntactic-errors.js.map +1 -1
  81. package/dist/simple-traverse.d.ts +1 -1
  82. package/dist/simple-traverse.d.ts.map +1 -1
  83. package/dist/simple-traverse.js.map +1 -1
  84. package/dist/source-files.d.ts +1 -1
  85. package/dist/source-files.d.ts.map +1 -1
  86. package/dist/ts-estree/estree-to-ts-node-types.d.ts +14 -14
  87. package/dist/ts-estree/estree-to-ts-node-types.d.ts.map +1 -1
  88. package/dist/ts-estree/index.d.ts +2 -2
  89. package/dist/ts-estree/index.d.ts.map +1 -1
  90. package/dist/ts-estree/index.js +2 -2
  91. package/dist/ts-estree/index.js.map +1 -1
  92. package/dist/ts-estree/ts-nodes.d.ts +1 -1
  93. package/dist/ts-estree/ts-nodes.d.ts.map +1 -1
  94. package/dist/use-at-your-own-risk.d.ts +1 -1
  95. package/dist/use-at-your-own-risk.d.ts.map +1 -1
  96. package/dist/use-at-your-own-risk.js +1 -1
  97. package/dist/use-at-your-own-risk.js.map +1 -1
  98. package/dist/useProgramFromProjectService.d.ts.map +1 -1
  99. package/dist/useProgramFromProjectService.js +2 -2
  100. package/dist/useProgramFromProjectService.js.map +1 -1
  101. package/package.json +3 -3
package/dist/convert.js CHANGED
@@ -41,11 +41,11 @@ function convertError(error) {
41
41
  return (0, node_utils_1.createError)(('message' in error && error.message) || error.messageText, error.file, error.start);
42
42
  }
43
43
  class Converter {
44
+ allowPattern = false;
44
45
  ast;
45
- options;
46
46
  esTreeNodeToTSNodeMap = new WeakMap();
47
+ options;
47
48
  tsNodeToESTreeNodeMap = new WeakMap();
48
- allowPattern = false;
49
49
  /**
50
50
  * Converts a TypeScript node into an ESTree node
51
51
  * @param ast the full TypeScript AST
@@ -56,232 +56,276 @@ class Converter {
56
56
  this.ast = ast;
57
57
  this.options = { ...options };
58
58
  }
59
- getASTMaps() {
60
- return {
61
- esTreeNodeToTSNodeMap: this.esTreeNodeToTSNodeMap,
62
- tsNodeToESTreeNodeMap: this.tsNodeToESTreeNodeMap,
63
- };
64
- }
65
- convertProgram() {
66
- return this.converter(this.ast);
67
- }
68
- /**
69
- * Converts a TypeScript node into an ESTree node.
70
- * @param node the child ts.Node
71
- * @param parent parentNode
72
- * @param allowPattern flag to determine if patterns are allowed
73
- * @returns the converted ESTree node
74
- */
75
- converter(node, parent, allowPattern) {
76
- /**
77
- * Exit early for null and undefined
78
- */
79
- if (!node) {
80
- return null;
81
- }
82
- this.#checkModifiers(node);
83
- const pattern = this.allowPattern;
84
- if (allowPattern !== undefined) {
85
- this.allowPattern = allowPattern;
86
- }
87
- const result = this.convertNode(node, (parent ?? node.parent));
88
- this.registerTSNodeInNodeMap(node, result);
89
- this.allowPattern = pattern;
90
- return result;
91
- }
92
- /**
93
- * Fixes the exports of the given ts.Node
94
- * @returns the ESTreeNode with fixed exports
95
- */
96
- fixExports(node, result) {
97
- const isNamespaceNode = ts.isModuleDeclaration(node) &&
98
- Boolean(node.flags & ts.NodeFlags.Namespace);
99
- const modifiers = isNamespaceNode
100
- ? (0, node_utils_1.getNamespaceModifiers)(node)
101
- : (0, getModifiers_1.getModifiers)(node);
102
- if (modifiers?.[0].kind === SyntaxKind.ExportKeyword) {
103
- /**
104
- * Make sure that original node is registered instead of export
105
- */
106
- this.registerTSNodeInNodeMap(node, result);
107
- const exportKeyword = modifiers[0];
108
- const nextModifier = modifiers[1];
109
- const declarationIsDefault = nextModifier?.kind === SyntaxKind.DefaultKeyword;
110
- const varToken = declarationIsDefault
111
- ? (0, node_utils_1.findNextToken)(nextModifier, this.ast, this.ast)
112
- : (0, node_utils_1.findNextToken)(exportKeyword, this.ast, this.ast);
113
- result.range[0] = varToken.getStart(this.ast);
114
- result.loc = (0, node_utils_1.getLocFor)(result.range, this.ast);
115
- if (declarationIsDefault) {
116
- return this.createNode(node, {
117
- type: ts_estree_1.AST_NODE_TYPES.ExportDefaultDeclaration,
118
- declaration: result,
119
- range: [exportKeyword.getStart(this.ast), result.range[1]],
120
- exportKind: 'value',
121
- });
59
+ #checkForStatementDeclaration(initializer, kind) {
60
+ const loop = kind === ts.SyntaxKind.ForInStatement ? 'for...in' : 'for...of';
61
+ if (ts.isVariableDeclarationList(initializer)) {
62
+ if (initializer.declarations.length !== 1) {
63
+ this.#throwError(initializer, `Only a single variable declaration is allowed in a '${loop}' statement.`);
64
+ }
65
+ const declaration = initializer.declarations[0];
66
+ if (declaration.initializer) {
67
+ this.#throwError(declaration, `The variable declaration of a '${loop}' statement cannot have an initializer.`);
68
+ }
69
+ else if (declaration.type) {
70
+ this.#throwError(declaration, `The variable declaration of a '${loop}' statement cannot have a type annotation.`);
71
+ }
72
+ if (kind === ts.SyntaxKind.ForInStatement &&
73
+ initializer.flags & ts.NodeFlags.Using) {
74
+ this.#throwError(initializer, "The left-hand side of a 'for...in' statement cannot be a 'using' declaration.");
122
75
  }
123
- const isType = result.type === ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration ||
124
- result.type === ts_estree_1.AST_NODE_TYPES.TSTypeAliasDeclaration;
125
- const isDeclare = 'declare' in result && result.declare;
126
- return this.createNode(node,
127
- // @ts-expect-error - TODO, narrow the types here
128
- this.#withDeprecatedAliasGetter({
129
- type: ts_estree_1.AST_NODE_TYPES.ExportNamedDeclaration,
130
- declaration: result,
131
- specifiers: [],
132
- source: null,
133
- exportKind: isType || isDeclare ? 'type' : 'value',
134
- range: [exportKeyword.getStart(this.ast), result.range[1]],
135
- attributes: [],
136
- }, 'assertions', 'attributes', true));
137
76
  }
138
- return result;
139
- }
140
- /**
141
- * Register specific TypeScript node into map with first ESTree node provided
142
- */
143
- registerTSNodeInNodeMap(node, result) {
144
- if (result &&
145
- this.options.shouldPreserveNodeMaps &&
146
- !this.tsNodeToESTreeNodeMap.has(node)) {
147
- this.tsNodeToESTreeNodeMap.set(node, result);
77
+ else if (!(0, node_utils_1.isValidAssignmentTarget)(initializer) &&
78
+ initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression &&
79
+ initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
80
+ this.#throwError(initializer, `The left-hand side of a '${loop}' statement must be a variable or a property access.`);
148
81
  }
149
82
  }
150
- /**
151
- * Converts a TypeScript node into an ESTree node.
152
- * @param child the child ts.Node
153
- * @param parent parentNode
154
- * @returns the converted ESTree node
155
- */
156
- convertPattern(child, parent) {
157
- return this.converter(child, parent, true);
158
- }
159
- /**
160
- * Converts a TypeScript node into an ESTree node.
161
- * @param child the child ts.Node
162
- * @param parent parentNode
163
- * @returns the converted ESTree node
164
- */
165
- convertChild(child, parent) {
166
- return this.converter(child, parent, false);
167
- }
168
- createNode(
169
- // The 'parent' property will be added later if specified
170
- node, data) {
171
- const result = data;
172
- result.range ??= (0, node_utils_1.getRange)(node, this.ast);
173
- result.loc ??= (0, node_utils_1.getLocFor)(result.range, this.ast);
174
- if (result && this.options.shouldPreserveNodeMaps) {
175
- this.esTreeNodeToTSNodeMap.set(result, node);
83
+ #checkModifiers(node) {
84
+ if (this.options.allowInvalidAST) {
85
+ return;
176
86
  }
177
- return result;
178
- }
179
- convertBindingNameWithTypeAnnotation(name, tsType, parent) {
180
- const id = this.convertPattern(name);
181
- if (tsType) {
182
- id.typeAnnotation = this.convertTypeAnnotation(tsType, parent);
183
- this.fixParentLocation(id, id.typeAnnotation.range);
87
+ // typescript<5.0.0
88
+ if ((0, node_utils_1.nodeHasIllegalDecorators)(node)) {
89
+ this.#throwError(node.illegalDecorators[0], 'Decorators are not valid here.');
184
90
  }
185
- return id;
186
- }
187
- /**
188
- * Converts a child into a type annotation. This creates an intermediary
189
- * TypeAnnotation node to match what Flow does.
190
- * @param child The TypeScript AST node to convert.
191
- * @param parent parentNode
192
- * @returns The type annotation node.
193
- */
194
- convertTypeAnnotation(child, parent) {
195
- // in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon
196
- const offset = parent?.kind === SyntaxKind.FunctionType ||
197
- parent?.kind === SyntaxKind.ConstructorType
198
- ? 2
199
- : 1;
200
- const annotationStartCol = child.getFullStart() - offset;
201
- const range = [annotationStartCol, child.end];
202
- const loc = (0, node_utils_1.getLocFor)(range, this.ast);
203
- return {
204
- type: ts_estree_1.AST_NODE_TYPES.TSTypeAnnotation,
205
- loc,
206
- range,
207
- typeAnnotation: this.convertChild(child),
208
- };
209
- }
210
- /**
211
- * Coverts body Nodes and add a directive field to StringLiterals
212
- * @param nodes of ts.Node
213
- * @param parent parentNode
214
- * @returns Array of body statements
215
- */
216
- convertBodyExpressions(nodes, parent) {
217
- let allowDirectives = (0, node_utils_1.canContainDirective)(parent);
218
- return (nodes
219
- .map(statement => {
220
- const child = this.convertChild(statement);
221
- if (allowDirectives) {
222
- if (child?.expression &&
223
- ts.isExpressionStatement(statement) &&
224
- ts.isStringLiteral(statement.expression)) {
225
- const raw = child.expression.raw;
226
- child.directive = raw.slice(1, -1);
227
- return child; // child can be null, but it's filtered below
91
+ for (const decorator of (0, getModifiers_1.getDecorators)(node,
92
+ /* includeIllegalDecorators */ true) ?? []) {
93
+ // `checkGrammarModifiers` function in typescript
94
+ if (!(0, node_utils_1.nodeCanBeDecorated)(node)) {
95
+ if (ts.isMethodDeclaration(node) && !(0, node_utils_1.nodeIsPresent)(node.body)) {
96
+ this.#throwError(decorator, 'A decorator can only decorate a method implementation, not an overload.');
97
+ }
98
+ else {
99
+ this.#throwError(decorator, 'Decorators are not valid here.');
228
100
  }
229
- allowDirectives = false;
230
101
  }
231
- return child; // child can be null, but it's filtered below
232
- })
233
- // filter out unknown nodes for now
234
- .filter(statement => statement));
235
- }
236
- /**
237
- * Converts a ts.Node's typeArguments to TSTypeParameterInstantiation node
238
- * @param typeArguments ts.NodeArray typeArguments
239
- * @param node parent used to create this node
240
- * @returns TypeParameterInstantiation node
241
- */
242
- convertTypeArgumentsToTypeParameterInstantiation(typeArguments, node) {
243
- const greaterThanToken = (0, node_utils_1.findNextToken)(typeArguments, this.ast, this.ast);
244
- return this.createNode(node, {
245
- type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterInstantiation,
246
- range: [typeArguments.pos - 1, greaterThanToken.end],
247
- params: typeArguments.map(typeArgument => this.convertChild(typeArgument)),
248
- });
249
- }
250
- /**
251
- * Converts a ts.Node's typeParameters to TSTypeParameterDeclaration node
252
- * @param typeParameters ts.Node typeParameters
253
- * @returns TypeParameterDeclaration node
254
- */
255
- convertTSTypeParametersToTypeParametersDeclaration(typeParameters) {
256
- const greaterThanToken = (0, node_utils_1.findNextToken)(typeParameters, this.ast, this.ast);
257
- const range = [
258
- typeParameters.pos - 1,
259
- greaterThanToken.end,
260
- ];
261
- return {
262
- type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterDeclaration,
263
- range,
264
- loc: (0, node_utils_1.getLocFor)(range, this.ast),
265
- params: typeParameters.map(typeParameter => this.convertChild(typeParameter)),
266
- };
267
- }
268
- /**
269
- * Converts an array of ts.Node parameters into an array of ESTreeNode params
270
- * @param parameters An array of ts.Node params to be converted
271
- * @returns an array of converted ESTreeNode params
272
- */
273
- convertParameters(parameters) {
274
- if (!parameters?.length) {
275
- return [];
276
102
  }
277
- return parameters.map(param => {
278
- const convertedParam = this.convertChild(param);
279
- convertedParam.decorators =
280
- (0, getModifiers_1.getDecorators)(param)?.map(el => this.convertChild(el)) ?? [];
281
- return convertedParam;
282
- });
283
- }
284
- convertChainExpression(node, tsNode) {
103
+ for (const modifier of (0, getModifiers_1.getModifiers)(node,
104
+ /* includeIllegalModifiers */ true) ?? []) {
105
+ if (modifier.kind !== SyntaxKind.ReadonlyKeyword) {
106
+ if (node.kind === SyntaxKind.PropertySignature ||
107
+ node.kind === SyntaxKind.MethodSignature) {
108
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a type member`);
109
+ }
110
+ if (node.kind === SyntaxKind.IndexSignature &&
111
+ (modifier.kind !== SyntaxKind.StaticKeyword ||
112
+ !ts.isClassLike(node.parent))) {
113
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on an index signature`);
114
+ }
115
+ }
116
+ if (modifier.kind !== SyntaxKind.InKeyword &&
117
+ modifier.kind !== SyntaxKind.OutKeyword &&
118
+ modifier.kind !== SyntaxKind.ConstKeyword &&
119
+ node.kind === SyntaxKind.TypeParameter) {
120
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a type parameter`);
121
+ }
122
+ if ((modifier.kind === SyntaxKind.InKeyword ||
123
+ modifier.kind === SyntaxKind.OutKeyword) &&
124
+ (node.kind !== SyntaxKind.TypeParameter ||
125
+ !(ts.isInterfaceDeclaration(node.parent) ||
126
+ ts.isClassLike(node.parent) ||
127
+ ts.isTypeAliasDeclaration(node.parent)))) {
128
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier can only appear on a type parameter of a class, interface or type alias`);
129
+ }
130
+ if (modifier.kind === SyntaxKind.ReadonlyKeyword &&
131
+ node.kind !== SyntaxKind.PropertyDeclaration &&
132
+ node.kind !== SyntaxKind.PropertySignature &&
133
+ node.kind !== SyntaxKind.IndexSignature &&
134
+ node.kind !== SyntaxKind.Parameter) {
135
+ this.#throwError(modifier, "'readonly' modifier can only appear on a property declaration or index signature.");
136
+ }
137
+ if (modifier.kind === SyntaxKind.DeclareKeyword &&
138
+ ts.isClassLike(node.parent) &&
139
+ !ts.isPropertyDeclaration(node)) {
140
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on class elements of this kind.`);
141
+ }
142
+ if (modifier.kind === SyntaxKind.DeclareKeyword &&
143
+ ts.isVariableStatement(node)) {
144
+ const declarationKind = (0, node_utils_1.getDeclarationKind)(node.declarationList);
145
+ if (declarationKind === 'using' || declarationKind === 'await using') {
146
+ this.#throwError(modifier, `'declare' modifier cannot appear on a '${declarationKind}' declaration.`);
147
+ }
148
+ }
149
+ if (modifier.kind === SyntaxKind.AbstractKeyword &&
150
+ node.kind !== SyntaxKind.ClassDeclaration &&
151
+ node.kind !== SyntaxKind.ConstructorType &&
152
+ node.kind !== SyntaxKind.MethodDeclaration &&
153
+ node.kind !== SyntaxKind.PropertyDeclaration &&
154
+ node.kind !== SyntaxKind.GetAccessor &&
155
+ node.kind !== SyntaxKind.SetAccessor) {
156
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier can only appear on a class, method, or property declaration.`);
157
+ }
158
+ if ((modifier.kind === SyntaxKind.StaticKeyword ||
159
+ modifier.kind === SyntaxKind.PublicKeyword ||
160
+ modifier.kind === SyntaxKind.ProtectedKeyword ||
161
+ modifier.kind === SyntaxKind.PrivateKeyword) &&
162
+ (node.parent.kind === SyntaxKind.ModuleBlock ||
163
+ node.parent.kind === SyntaxKind.SourceFile)) {
164
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a module or namespace element.`);
165
+ }
166
+ if (modifier.kind === SyntaxKind.AccessorKeyword &&
167
+ node.kind !== SyntaxKind.PropertyDeclaration) {
168
+ this.#throwError(modifier, "'accessor' modifier can only appear on a property declaration.");
169
+ }
170
+ // `checkGrammarAsyncModifier` function in `typescript`
171
+ if (modifier.kind === SyntaxKind.AsyncKeyword &&
172
+ node.kind !== SyntaxKind.MethodDeclaration &&
173
+ node.kind !== SyntaxKind.FunctionDeclaration &&
174
+ node.kind !== SyntaxKind.FunctionExpression &&
175
+ node.kind !== SyntaxKind.ArrowFunction) {
176
+ this.#throwError(modifier, "'async' modifier cannot be used here.");
177
+ }
178
+ // `checkGrammarModifiers` function in `typescript`
179
+ if (node.kind === SyntaxKind.Parameter &&
180
+ (modifier.kind === SyntaxKind.StaticKeyword ||
181
+ modifier.kind === SyntaxKind.ExportKeyword ||
182
+ modifier.kind === SyntaxKind.DeclareKeyword ||
183
+ modifier.kind === SyntaxKind.AsyncKeyword)) {
184
+ this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a parameter.`);
185
+ }
186
+ // `checkGrammarModifiers` function in `typescript`
187
+ if (modifier.kind === SyntaxKind.PublicKeyword ||
188
+ modifier.kind === SyntaxKind.ProtectedKeyword ||
189
+ modifier.kind === SyntaxKind.PrivateKeyword) {
190
+ for (const anotherModifier of (0, getModifiers_1.getModifiers)(node) ?? []) {
191
+ if (anotherModifier !== modifier &&
192
+ (anotherModifier.kind === SyntaxKind.PublicKeyword ||
193
+ anotherModifier.kind === SyntaxKind.ProtectedKeyword ||
194
+ anotherModifier.kind === SyntaxKind.PrivateKeyword)) {
195
+ this.#throwError(anotherModifier, `Accessibility modifier already seen.`);
196
+ }
197
+ }
198
+ }
199
+ // `checkParameter` function in `typescript`
200
+ if (node.kind === SyntaxKind.Parameter &&
201
+ // In `typescript` package, it's `ts.hasSyntacticModifier(node, ts.ModifierFlags.ParameterPropertyModifier)`
202
+ // https://github.com/typescript-eslint/typescript-eslint/pull/6615#discussion_r1136489935
203
+ (modifier.kind === SyntaxKind.PublicKeyword ||
204
+ modifier.kind === SyntaxKind.PrivateKeyword ||
205
+ modifier.kind === SyntaxKind.ProtectedKeyword ||
206
+ modifier.kind === SyntaxKind.ReadonlyKeyword ||
207
+ modifier.kind === SyntaxKind.OverrideKeyword)) {
208
+ const func = (0, node_utils_1.getContainingFunction)(node);
209
+ if (!(func.kind === SyntaxKind.Constructor && (0, node_utils_1.nodeIsPresent)(func.body))) {
210
+ this.#throwError(modifier, 'A parameter property is only allowed in a constructor implementation.');
211
+ }
212
+ }
213
+ }
214
+ }
215
+ #throwError(node, message) {
216
+ let start;
217
+ let end;
218
+ if (typeof node === 'number') {
219
+ start = end = node;
220
+ }
221
+ else {
222
+ start = node.getStart(this.ast);
223
+ end = node.getEnd();
224
+ }
225
+ throw (0, node_utils_1.createError)(message, this.ast, start, end);
226
+ }
227
+ #throwUnlessAllowInvalidAST(node, message) {
228
+ if (!this.options.allowInvalidAST) {
229
+ this.#throwError(node, message);
230
+ }
231
+ }
232
+ /**
233
+ * Creates a getter for a property under aliasKey that returns the value under
234
+ * valueKey. If suppressDeprecatedPropertyWarnings is not enabled, the
235
+ * getter also console warns about the deprecation.
236
+ *
237
+ * @see https://github.com/typescript-eslint/typescript-eslint/issues/6469
238
+ */
239
+ #withDeprecatedAliasGetter(node, aliasKey, valueKey, suppressWarnings = false) {
240
+ let warned = suppressWarnings;
241
+ Object.defineProperty(node, aliasKey, {
242
+ configurable: true,
243
+ get: this.options.suppressDeprecatedPropertyWarnings
244
+ ? () => node[valueKey]
245
+ : () => {
246
+ if (!warned) {
247
+ process.emitWarning(`The '${aliasKey}' property is deprecated on ${node.type} nodes. Use '${valueKey}' instead. See https://typescript-eslint.io/troubleshooting/faqs/general#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings.`, 'DeprecationWarning');
248
+ warned = true;
249
+ }
250
+ return node[valueKey];
251
+ },
252
+ set(value) {
253
+ Object.defineProperty(node, aliasKey, {
254
+ enumerable: true,
255
+ value,
256
+ writable: true,
257
+ });
258
+ },
259
+ });
260
+ return node;
261
+ }
262
+ #withDeprecatedGetter(node, deprecatedKey, preferredKey, value) {
263
+ let warned = false;
264
+ Object.defineProperty(node, deprecatedKey, {
265
+ configurable: true,
266
+ get: this.options.suppressDeprecatedPropertyWarnings
267
+ ? () => value
268
+ : () => {
269
+ if (!warned) {
270
+ process.emitWarning(`The '${deprecatedKey}' property is deprecated on ${node.type} nodes. Use ${preferredKey} instead. See https://typescript-eslint.io/troubleshooting/faqs/general#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings.`, 'DeprecationWarning');
271
+ warned = true;
272
+ }
273
+ return value;
274
+ },
275
+ set(value) {
276
+ Object.defineProperty(node, deprecatedKey, {
277
+ enumerable: true,
278
+ value,
279
+ writable: true,
280
+ });
281
+ },
282
+ });
283
+ return node;
284
+ }
285
+ assertModuleSpecifier(node, allowNull) {
286
+ if (!allowNull && node.moduleSpecifier == null) {
287
+ this.#throwUnlessAllowInvalidAST(node, 'Module specifier must be a string literal.');
288
+ }
289
+ if (node.moduleSpecifier &&
290
+ node.moduleSpecifier?.kind !== SyntaxKind.StringLiteral) {
291
+ this.#throwUnlessAllowInvalidAST(node.moduleSpecifier, 'Module specifier must be a string literal.');
292
+ }
293
+ }
294
+ convertBindingNameWithTypeAnnotation(name, tsType, parent) {
295
+ const id = this.convertPattern(name);
296
+ if (tsType) {
297
+ id.typeAnnotation = this.convertTypeAnnotation(tsType, parent);
298
+ this.fixParentLocation(id, id.typeAnnotation.range);
299
+ }
300
+ return id;
301
+ }
302
+ /**
303
+ * Coverts body Nodes and add a directive field to StringLiterals
304
+ * @param nodes of ts.Node
305
+ * @param parent parentNode
306
+ * @returns Array of body statements
307
+ */
308
+ convertBodyExpressions(nodes, parent) {
309
+ let allowDirectives = (0, node_utils_1.canContainDirective)(parent);
310
+ return (nodes
311
+ .map(statement => {
312
+ const child = this.convertChild(statement);
313
+ if (allowDirectives) {
314
+ if (child?.expression &&
315
+ ts.isExpressionStatement(statement) &&
316
+ ts.isStringLiteral(statement.expression)) {
317
+ const raw = child.expression.raw;
318
+ child.directive = raw.slice(1, -1);
319
+ return child; // child can be null, but it's filtered below
320
+ }
321
+ allowDirectives = false;
322
+ }
323
+ return child; // child can be null, but it's filtered below
324
+ })
325
+ // filter out unknown nodes for now
326
+ .filter(statement => statement));
327
+ }
328
+ convertChainExpression(node, tsNode) {
285
329
  const { child, isOptional } = (() => {
286
330
  if (node.type === ts_estree_1.AST_NODE_TYPES.MemberExpression) {
287
331
  return { child: node.object, isOptional: node.optional };
@@ -314,87 +358,123 @@ class Converter {
314
358
  });
315
359
  }
316
360
  /**
317
- * For nodes that are copied directly from the TypeScript AST into
318
- * ESTree mostly as-is. The only difference is the addition of a type
319
- * property instead of a kind property. Recursively copies all children.
361
+ * Converts a TypeScript node into an ESTree node.
362
+ * @param child the child ts.Node
363
+ * @param parent parentNode
364
+ * @returns the converted ESTree node
320
365
  */
321
- deeplyCopy(node) {
322
- if (node.kind === ts.SyntaxKind.JSDocFunctionType) {
323
- this.#throwError(node, 'JSDoc types can only be used inside documentation comments.');
324
- }
325
- const customType = `TS${SyntaxKind[node.kind]}`;
326
- /**
327
- * If the "errorOnUnknownASTType" option is set to true, throw an error,
328
- * otherwise fallback to just including the unknown type as-is.
329
- */
330
- if (this.options.errorOnUnknownASTType && !ts_estree_1.AST_NODE_TYPES[customType]) {
331
- throw new Error(`Unknown AST_NODE_TYPE: "${customType}"`);
332
- }
333
- const result = this.createNode(node, {
334
- type: customType,
335
- });
336
- if ('type' in node) {
337
- result.typeAnnotation =
338
- node.type && 'kind' in node.type && ts.isTypeNode(node.type)
339
- ? this.convertTypeAnnotation(node.type, node)
340
- : null;
341
- }
342
- if ('typeArguments' in node) {
343
- result.typeArguments =
344
- node.typeArguments && 'pos' in node.typeArguments
345
- ? this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node)
346
- : null;
366
+ convertChild(child, parent) {
367
+ return this.converter(child, parent, false);
368
+ }
369
+ /**
370
+ * Converts a TypeScript node into an ESTree node.
371
+ * @param child the child ts.Node
372
+ * @param parent parentNode
373
+ * @returns the converted ESTree node
374
+ */
375
+ convertPattern(child, parent) {
376
+ return this.converter(child, parent, true);
377
+ }
378
+ /**
379
+ * Converts a child into a type annotation. This creates an intermediary
380
+ * TypeAnnotation node to match what Flow does.
381
+ * @param child The TypeScript AST node to convert.
382
+ * @param parent parentNode
383
+ * @returns The type annotation node.
384
+ */
385
+ convertTypeAnnotation(child, parent) {
386
+ // in FunctionType and ConstructorType typeAnnotation has 2 characters `=>` and in other places is just colon
387
+ const offset = parent?.kind === SyntaxKind.FunctionType ||
388
+ parent?.kind === SyntaxKind.ConstructorType
389
+ ? 2
390
+ : 1;
391
+ const annotationStartCol = child.getFullStart() - offset;
392
+ const range = [annotationStartCol, child.end];
393
+ const loc = (0, node_utils_1.getLocFor)(range, this.ast);
394
+ return {
395
+ type: ts_estree_1.AST_NODE_TYPES.TSTypeAnnotation,
396
+ loc,
397
+ range,
398
+ typeAnnotation: this.convertChild(child),
399
+ };
400
+ }
401
+ /**
402
+ * Converts a ts.Node's typeArguments to TSTypeParameterInstantiation node
403
+ * @param typeArguments ts.NodeArray typeArguments
404
+ * @param node parent used to create this node
405
+ * @returns TypeParameterInstantiation node
406
+ */
407
+ convertTypeArgumentsToTypeParameterInstantiation(typeArguments, node) {
408
+ const greaterThanToken = (0, node_utils_1.findNextToken)(typeArguments, this.ast, this.ast);
409
+ return this.createNode(node, {
410
+ type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterInstantiation,
411
+ range: [typeArguments.pos - 1, greaterThanToken.end],
412
+ params: typeArguments.map(typeArgument => this.convertChild(typeArgument)),
413
+ });
414
+ }
415
+ /**
416
+ * Converts a ts.Node's typeParameters to TSTypeParameterDeclaration node
417
+ * @param typeParameters ts.Node typeParameters
418
+ * @returns TypeParameterDeclaration node
419
+ */
420
+ convertTSTypeParametersToTypeParametersDeclaration(typeParameters) {
421
+ const greaterThanToken = (0, node_utils_1.findNextToken)(typeParameters, this.ast, this.ast);
422
+ const range = [
423
+ typeParameters.pos - 1,
424
+ greaterThanToken.end,
425
+ ];
426
+ return {
427
+ type: ts_estree_1.AST_NODE_TYPES.TSTypeParameterDeclaration,
428
+ loc: (0, node_utils_1.getLocFor)(range, this.ast),
429
+ range,
430
+ params: typeParameters.map(typeParameter => this.convertChild(typeParameter)),
431
+ };
432
+ }
433
+ /**
434
+ * Converts an array of ts.Node parameters into an array of ESTreeNode params
435
+ * @param parameters An array of ts.Node params to be converted
436
+ * @returns an array of converted ESTreeNode params
437
+ */
438
+ convertParameters(parameters) {
439
+ if (!parameters?.length) {
440
+ return [];
347
441
  }
348
- if ('typeParameters' in node) {
349
- result.typeParameters =
350
- node.typeParameters && 'pos' in node.typeParameters
351
- ? this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters)
352
- : null;
442
+ return parameters.map(param => {
443
+ const convertedParam = this.convertChild(param);
444
+ convertedParam.decorators =
445
+ (0, getModifiers_1.getDecorators)(param)?.map(el => this.convertChild(el)) ?? [];
446
+ return convertedParam;
447
+ });
448
+ }
449
+ /**
450
+ * Converts a TypeScript node into an ESTree node.
451
+ * @param node the child ts.Node
452
+ * @param parent parentNode
453
+ * @param allowPattern flag to determine if patterns are allowed
454
+ * @returns the converted ESTree node
455
+ */
456
+ converter(node, parent, allowPattern) {
457
+ /**
458
+ * Exit early for null and undefined
459
+ */
460
+ if (!node) {
461
+ return null;
353
462
  }
354
- const decorators = (0, getModifiers_1.getDecorators)(node);
355
- if (decorators?.length) {
356
- result.decorators = decorators.map(el => this.convertChild(el));
463
+ this.#checkModifiers(node);
464
+ const pattern = this.allowPattern;
465
+ if (allowPattern !== undefined) {
466
+ this.allowPattern = allowPattern;
357
467
  }
358
- // keys we never want to clone from the base typescript node as they
359
- // introduce garbage into our AST
360
- const KEYS_TO_NOT_COPY = new Set([
361
- '_children',
362
- 'decorators',
363
- 'end',
364
- 'flags',
365
- 'illegalDecorators',
366
- 'heritageClauses',
367
- 'locals',
368
- 'localSymbol',
369
- 'jsDoc',
370
- 'kind',
371
- 'modifierFlagsCache',
372
- 'modifiers',
373
- 'nextContainer',
374
- 'parent',
375
- 'pos',
376
- 'symbol',
377
- 'transformFlags',
378
- 'type',
379
- 'typeArguments',
380
- 'typeParameters',
381
- ]);
382
- Object.entries(node)
383
- .filter(([key]) => !KEYS_TO_NOT_COPY.has(key))
384
- .forEach(([key, value]) => {
385
- if (Array.isArray(value)) {
386
- result[key] = value.map(el => this.convertChild(el));
387
- }
388
- else if (value && typeof value === 'object' && value.kind) {
389
- // need to check node[key].kind to ensure we don't try to convert a symbol
390
- result[key] = this.convertChild(value);
391
- }
392
- else {
393
- result[key] = value;
394
- }
395
- });
468
+ const result = this.convertNode(node, (parent ?? node.parent));
469
+ this.registerTSNodeInNodeMap(node, result);
470
+ this.allowPattern = pattern;
396
471
  return result;
397
472
  }
473
+ convertImportAttributes(node) {
474
+ return node === undefined
475
+ ? []
476
+ : node.elements.map(element => this.convertChild(element));
477
+ }
398
478
  convertJSXIdentifier(node) {
399
479
  const result = this.createNode(node, {
400
480
  type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
@@ -409,14 +489,14 @@ class Converter {
409
489
  if (node.kind === ts.SyntaxKind.JsxNamespacedName) {
410
490
  const result = this.createNode(node, {
411
491
  type: ts_estree_1.AST_NODE_TYPES.JSXNamespacedName,
412
- namespace: this.createNode(node.namespace, {
413
- type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
414
- name: node.namespace.text,
415
- }),
416
492
  name: this.createNode(node.name, {
417
493
  type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
418
494
  name: node.name.text,
419
495
  }),
496
+ namespace: this.createNode(node.namespace, {
497
+ type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
498
+ name: node.namespace.text,
499
+ }),
420
500
  });
421
501
  this.registerTSNodeInNodeMap(node, result);
422
502
  return result;
@@ -430,17 +510,17 @@ class Converter {
430
510
  // @ts-expect-error -- TypeScript@<5.1 doesn't have ts.JsxNamespacedName
431
511
  const result = this.createNode(node, {
432
512
  type: ts_estree_1.AST_NODE_TYPES.JSXNamespacedName,
433
- namespace: this.createNode(node, {
434
- type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
435
- name: text.slice(0, colonIndex),
436
- range: [range[0], range[0] + colonIndex],
437
- }),
513
+ range,
438
514
  name: this.createNode(node, {
439
515
  type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
440
- name: text.slice(colonIndex + 1),
441
516
  range: [range[0] + colonIndex + 1, range[1]],
517
+ name: text.slice(colonIndex + 1),
518
+ }),
519
+ namespace: this.createNode(node, {
520
+ type: ts_estree_1.AST_NODE_TYPES.JSXIdentifier,
521
+ range: [range[0], range[0] + colonIndex],
522
+ name: text.slice(0, colonIndex),
442
523
  }),
443
- range,
444
524
  });
445
525
  this.registerTSNodeInNodeMap(node, result);
446
526
  return result;
@@ -493,18 +573,13 @@ class Converter {
493
573
  })(),
494
574
  optional: (0, node_utils_1.isOptional)(node),
495
575
  params: this.convertParameters(node.parameters),
496
- returnType: node.type && this.convertTypeAnnotation(node.type, node),
497
576
  readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node),
577
+ returnType: node.type && this.convertTypeAnnotation(node.type, node),
498
578
  static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node),
499
579
  typeParameters: node.typeParameters &&
500
580
  this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
501
581
  });
502
582
  }
503
- convertImportAttributes(node) {
504
- return node === undefined
505
- ? []
506
- : node.elements.map(element => this.convertChild(element));
507
- }
508
583
  /**
509
584
  * Uses the provided range location to adjust the location data of the given Node
510
585
  * @param result The node that will have its location data mutated
@@ -520,15 +595,6 @@ class Converter {
520
595
  result.loc.end = (0, node_utils_1.getLineAndCharacterFor)(result.range[1], this.ast);
521
596
  }
522
597
  }
523
- assertModuleSpecifier(node, allowNull) {
524
- if (!allowNull && node.moduleSpecifier == null) {
525
- this.#throwUnlessAllowInvalidAST(node, 'Module specifier must be a string literal.');
526
- }
527
- if (node.moduleSpecifier &&
528
- node.moduleSpecifier?.kind !== SyntaxKind.StringLiteral) {
529
- this.#throwUnlessAllowInvalidAST(node.moduleSpecifier, 'Module specifier must be a string literal.');
530
- }
531
- }
532
598
  /**
533
599
  * Converts a TypeScript node into an ESTree node.
534
600
  * The core of the conversion logic:
@@ -540,9 +606,9 @@ class Converter {
540
606
  case SyntaxKind.SourceFile: {
541
607
  return this.createNode(node, {
542
608
  type: ts_estree_1.AST_NODE_TYPES.Program,
609
+ range: [node.getStart(this.ast), node.endOfFileToken.end],
543
610
  body: this.convertBodyExpressions(node.statements, node),
544
611
  comments: undefined,
545
- range: [node.getStart(this.ast), node.endOfFileToken.end],
546
612
  sourceType: node.externalModuleIndicator ? 'module' : 'script',
547
613
  tokens: undefined,
548
614
  });
@@ -579,8 +645,8 @@ class Converter {
579
645
  case SyntaxKind.WithStatement:
580
646
  return this.createNode(node, {
581
647
  type: ts_estree_1.AST_NODE_TYPES.WithStatement,
582
- object: this.convertChild(node.expression),
583
648
  body: this.convertChild(node.statement),
649
+ object: this.convertChild(node.expression),
584
650
  });
585
651
  // Control Flow
586
652
  case SyntaxKind.ReturnStatement:
@@ -591,8 +657,8 @@ class Converter {
591
657
  case SyntaxKind.LabeledStatement:
592
658
  return this.createNode(node, {
593
659
  type: ts_estree_1.AST_NODE_TYPES.LabeledStatement,
594
- label: this.convertChild(node.label),
595
660
  body: this.convertChild(node.statement),
661
+ label: this.convertChild(node.label),
596
662
  });
597
663
  case SyntaxKind.ContinueStatement:
598
664
  return this.createNode(node, {
@@ -608,9 +674,9 @@ class Converter {
608
674
  case SyntaxKind.IfStatement:
609
675
  return this.createNode(node, {
610
676
  type: ts_estree_1.AST_NODE_TYPES.IfStatement,
611
- test: this.convertChild(node.expression),
612
- consequent: this.convertChild(node.thenStatement),
613
677
  alternate: this.convertChild(node.elseStatement),
678
+ consequent: this.convertChild(node.thenStatement),
679
+ test: this.convertChild(node.expression),
614
680
  });
615
681
  case SyntaxKind.SwitchStatement:
616
682
  if (node.caseBlock.clauses.filter(switchCase => switchCase.kind === SyntaxKind.DefaultClause).length > 1) {
@@ -618,18 +684,18 @@ class Converter {
618
684
  }
619
685
  return this.createNode(node, {
620
686
  type: ts_estree_1.AST_NODE_TYPES.SwitchStatement,
621
- discriminant: this.convertChild(node.expression),
622
687
  cases: node.caseBlock.clauses.map(el => this.convertChild(el)),
688
+ discriminant: this.convertChild(node.expression),
623
689
  });
624
690
  case SyntaxKind.CaseClause:
625
691
  case SyntaxKind.DefaultClause:
626
692
  return this.createNode(node, {
627
693
  type: ts_estree_1.AST_NODE_TYPES.SwitchCase,
628
694
  // expression is present in case only
695
+ consequent: node.statements.map(el => this.convertChild(el)),
629
696
  test: node.kind === SyntaxKind.CaseClause
630
697
  ? this.convertChild(node.expression)
631
698
  : null,
632
- consequent: node.statements.map(el => this.convertChild(el)),
633
699
  });
634
700
  // Exceptions
635
701
  case SyntaxKind.ThrowStatement:
@@ -644,8 +710,8 @@ class Converter {
644
710
  return this.createNode(node, {
645
711
  type: ts_estree_1.AST_NODE_TYPES.TryStatement,
646
712
  block: this.convertChild(node.tryBlock),
647
- handler: this.convertChild(node.catchClause),
648
713
  finalizer: this.convertChild(node.finallyBlock),
714
+ handler: this.convertChild(node.catchClause),
649
715
  });
650
716
  case SyntaxKind.CatchClause:
651
717
  if (node.variableDeclaration?.initializer) {
@@ -653,17 +719,17 @@ class Converter {
653
719
  }
654
720
  return this.createNode(node, {
655
721
  type: ts_estree_1.AST_NODE_TYPES.CatchClause,
722
+ body: this.convertChild(node.block),
656
723
  param: node.variableDeclaration
657
724
  ? this.convertBindingNameWithTypeAnnotation(node.variableDeclaration.name, node.variableDeclaration.type)
658
725
  : null,
659
- body: this.convertChild(node.block),
660
726
  });
661
727
  // Loops
662
728
  case SyntaxKind.WhileStatement:
663
729
  return this.createNode(node, {
664
730
  type: ts_estree_1.AST_NODE_TYPES.WhileStatement,
665
- test: this.convertChild(node.expression),
666
731
  body: this.convertChild(node.statement),
732
+ test: this.convertChild(node.expression),
667
733
  });
668
734
  /**
669
735
  * Unlike other parsers, TypeScript calls a "DoWhileStatement"
@@ -672,34 +738,34 @@ class Converter {
672
738
  case SyntaxKind.DoStatement:
673
739
  return this.createNode(node, {
674
740
  type: ts_estree_1.AST_NODE_TYPES.DoWhileStatement,
675
- test: this.convertChild(node.expression),
676
741
  body: this.convertChild(node.statement),
742
+ test: this.convertChild(node.expression),
677
743
  });
678
744
  case SyntaxKind.ForStatement:
679
745
  return this.createNode(node, {
680
746
  type: ts_estree_1.AST_NODE_TYPES.ForStatement,
747
+ body: this.convertChild(node.statement),
681
748
  init: this.convertChild(node.initializer),
682
749
  test: this.convertChild(node.condition),
683
750
  update: this.convertChild(node.incrementor),
684
- body: this.convertChild(node.statement),
685
751
  });
686
752
  case SyntaxKind.ForInStatement:
687
753
  this.#checkForStatementDeclaration(node.initializer, node.kind);
688
754
  return this.createNode(node, {
689
755
  type: ts_estree_1.AST_NODE_TYPES.ForInStatement,
756
+ body: this.convertChild(node.statement),
690
757
  left: this.convertPattern(node.initializer),
691
758
  right: this.convertChild(node.expression),
692
- body: this.convertChild(node.statement),
693
759
  });
694
760
  case SyntaxKind.ForOfStatement: {
695
761
  this.#checkForStatementDeclaration(node.initializer, node.kind);
696
762
  return this.createNode(node, {
697
763
  type: ts_estree_1.AST_NODE_TYPES.ForOfStatement,
698
- left: this.convertPattern(node.initializer),
699
- right: this.convertChild(node.expression),
700
- body: this.convertChild(node.statement),
701
764
  await: Boolean(node.awaitModifier &&
702
765
  node.awaitModifier.kind === SyntaxKind.AwaitKeyword),
766
+ body: this.convertChild(node.statement),
767
+ left: this.convertPattern(node.initializer),
768
+ right: this.convertChild(node.expression),
703
769
  });
704
770
  }
705
771
  // Declarations
@@ -781,7 +847,7 @@ class Converter {
781
847
  }
782
848
  // Definite assignment only allowed for non-declare let and var
783
849
  if (result.declare ||
784
- ['using', 'await using', 'const'].includes(result.kind)) {
850
+ ['await using', 'const', 'using'].includes(result.kind)) {
785
851
  node.declarationList.declarations.forEach((declaration, i) => {
786
852
  if (result.declarations[i].definite) {
787
853
  this.#throwError(declaration, `A definite assignment assertion '!' is not permitted in this context.`);
@@ -888,7 +954,7 @@ class Converter {
888
954
  }
889
955
  case SyntaxKind.PropertyAssignment: {
890
956
  // eslint-disable-next-line @typescript-eslint/no-deprecated
891
- const { questionToken, exclamationToken } = node;
957
+ const { exclamationToken, questionToken } = node;
892
958
  if (questionToken) {
893
959
  this.#throwError(questionToken, 'A property assignment cannot have a question token.');
894
960
  }
@@ -897,18 +963,18 @@ class Converter {
897
963
  }
898
964
  return this.createNode(node, {
899
965
  type: ts_estree_1.AST_NODE_TYPES.Property,
900
- key: this.convertChild(node.name),
901
- value: this.converter(node.initializer, node, this.allowPattern),
902
966
  computed: (0, node_utils_1.isComputedProperty)(node.name),
967
+ key: this.convertChild(node.name),
968
+ kind: 'init',
903
969
  method: false,
904
970
  optional: false,
905
971
  shorthand: false,
906
- kind: 'init',
972
+ value: this.converter(node.initializer, node, this.allowPattern),
907
973
  });
908
974
  }
909
975
  case SyntaxKind.ShorthandPropertyAssignment: {
910
976
  // eslint-disable-next-line @typescript-eslint/no-deprecated
911
- const { modifiers, questionToken, exclamationToken } = node;
977
+ const { exclamationToken, modifiers, questionToken } = node;
912
978
  if (modifiers) {
913
979
  this.#throwError(modifiers[0], 'A shorthand property assignment cannot have modifiers.');
914
980
  }
@@ -921,7 +987,12 @@ class Converter {
921
987
  if (node.objectAssignmentInitializer) {
922
988
  return this.createNode(node, {
923
989
  type: ts_estree_1.AST_NODE_TYPES.Property,
990
+ computed: false,
924
991
  key: this.convertChild(node.name),
992
+ kind: 'init',
993
+ method: false,
994
+ optional: false,
995
+ shorthand: true,
925
996
  value: this.createNode(node, {
926
997
  type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
927
998
  decorators: [],
@@ -930,11 +1001,6 @@ class Converter {
930
1001
  right: this.convertChild(node.objectAssignmentInitializer),
931
1002
  typeAnnotation: undefined,
932
1003
  }),
933
- computed: false,
934
- method: false,
935
- optional: false,
936
- shorthand: true,
937
- kind: 'init',
938
1004
  });
939
1005
  }
940
1006
  return this.createNode(node, {
@@ -971,25 +1037,25 @@ class Converter {
971
1037
  const key = this.convertChild(node.name);
972
1038
  return this.createNode(node, {
973
1039
  type,
974
- key,
975
1040
  accessibility: (0, node_utils_1.getTSNodeAccessibility)(node),
976
- value: isAbstract ? null : this.convertChild(node.initializer),
977
1041
  computed: (0, node_utils_1.isComputedProperty)(node.name),
978
- static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node),
979
- readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node),
980
- decorators: (0, getModifiers_1.getDecorators)(node)?.map(el => this.convertChild(el)) ?? [],
981
1042
  declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
982
- override: (0, node_utils_1.hasModifier)(SyntaxKind.OverrideKeyword, node),
983
- typeAnnotation: node.type && this.convertTypeAnnotation(node.type, node),
1043
+ decorators: (0, getModifiers_1.getDecorators)(node)?.map(el => this.convertChild(el)) ?? [],
1044
+ definite: !!node.exclamationToken,
1045
+ key,
984
1046
  optional: (key.type === ts_estree_1.AST_NODE_TYPES.Literal ||
985
1047
  node.name.kind === SyntaxKind.Identifier ||
986
1048
  node.name.kind === SyntaxKind.ComputedPropertyName ||
987
1049
  node.name.kind === SyntaxKind.PrivateIdentifier) &&
988
1050
  !!node.questionToken,
989
- definite: !!node.exclamationToken,
990
- });
991
- }
992
- case SyntaxKind.GetAccessor:
1051
+ override: (0, node_utils_1.hasModifier)(SyntaxKind.OverrideKeyword, node),
1052
+ readonly: (0, node_utils_1.hasModifier)(SyntaxKind.ReadonlyKeyword, node),
1053
+ static: (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node),
1054
+ typeAnnotation: node.type && this.convertTypeAnnotation(node.type, node),
1055
+ value: isAbstract ? null : this.convertChild(node.initializer),
1056
+ });
1057
+ }
1058
+ case SyntaxKind.GetAccessor:
993
1059
  case SyntaxKind.SetAccessor: {
994
1060
  if (node.parent.kind === SyntaxKind.InterfaceDeclaration ||
995
1061
  node.parent.kind === SyntaxKind.TypeLiteral) {
@@ -1002,13 +1068,13 @@ class Converter {
1002
1068
  type: !node.body
1003
1069
  ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
1004
1070
  : ts_estree_1.AST_NODE_TYPES.FunctionExpression,
1005
- id: null,
1006
- generator: !!node.asteriskToken,
1007
- expression: false, // ESTreeNode as ESTreeNode here
1071
+ range: [node.parameters.pos - 1, node.end],
1008
1072
  async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
1009
1073
  body: this.convertChild(node.body),
1010
1074
  declare: false,
1011
- range: [node.parameters.pos - 1, node.end],
1075
+ expression: false, // ESTreeNode as ESTreeNode here
1076
+ generator: !!node.asteriskToken,
1077
+ id: null,
1012
1078
  params: [],
1013
1079
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
1014
1080
  typeParameters: node.typeParameters &&
@@ -1022,13 +1088,13 @@ class Converter {
1022
1088
  method.params = node.parameters.map(el => this.convertChild(el));
1023
1089
  result = this.createNode(node, {
1024
1090
  type: ts_estree_1.AST_NODE_TYPES.Property,
1025
- key: this.convertChild(node.name),
1026
- value: method,
1027
1091
  computed: (0, node_utils_1.isComputedProperty)(node.name),
1028
- optional: !!node.questionToken,
1092
+ key: this.convertChild(node.name),
1093
+ kind: 'init',
1029
1094
  method: node.kind === SyntaxKind.MethodDeclaration,
1095
+ optional: !!node.questionToken,
1030
1096
  shorthand: false,
1031
- kind: 'init',
1097
+ value: method,
1032
1098
  });
1033
1099
  }
1034
1100
  else {
@@ -1079,6 +1145,7 @@ class Converter {
1079
1145
  type: !node.body
1080
1146
  ? ts_estree_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression
1081
1147
  : ts_estree_1.AST_NODE_TYPES.FunctionExpression,
1148
+ range: [node.parameters.pos - 1, node.end],
1082
1149
  async: false,
1083
1150
  body: this.convertChild(node.body),
1084
1151
  declare: false,
@@ -1086,7 +1153,6 @@ class Converter {
1086
1153
  generator: false,
1087
1154
  id: null,
1088
1155
  params: this.convertParameters(node.parameters),
1089
- range: [node.parameters.pos - 1, node.end],
1090
1156
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
1091
1157
  typeParameters: node.typeParameters &&
1092
1158
  this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
@@ -1096,10 +1162,10 @@ class Converter {
1096
1162
  }
1097
1163
  const constructorKey = this.createNode(node, {
1098
1164
  type: ts_estree_1.AST_NODE_TYPES.Identifier,
1165
+ range: [constructorToken.getStart(this.ast), constructorToken.end],
1099
1166
  decorators: [],
1100
1167
  name: 'constructor',
1101
1168
  optional: false,
1102
- range: [constructorToken.getStart(this.ast), constructorToken.end],
1103
1169
  typeAnnotation: undefined,
1104
1170
  });
1105
1171
  const isStatic = (0, node_utils_1.hasModifier)(SyntaxKind.StaticKeyword, node);
@@ -1110,9 +1176,9 @@ class Converter {
1110
1176
  accessibility: (0, node_utils_1.getTSNodeAccessibility)(node),
1111
1177
  computed: false,
1112
1178
  decorators: [],
1113
- optional: false,
1114
1179
  key: constructorKey,
1115
1180
  kind: isStatic ? 'method' : 'constructor',
1181
+ optional: false,
1116
1182
  override: false,
1117
1183
  static: isStatic,
1118
1184
  value: constructor,
@@ -1195,23 +1261,23 @@ class Converter {
1195
1261
  else {
1196
1262
  result = this.createNode(node, {
1197
1263
  type: ts_estree_1.AST_NODE_TYPES.Property,
1198
- key: this.convertChild(node.propertyName ?? node.name),
1199
- value: this.convertChild(node.name),
1200
1264
  computed: Boolean(node.propertyName &&
1201
1265
  node.propertyName.kind === SyntaxKind.ComputedPropertyName),
1266
+ key: this.convertChild(node.propertyName ?? node.name),
1267
+ kind: 'init',
1202
1268
  method: false,
1203
1269
  optional: false,
1204
1270
  shorthand: !node.propertyName,
1205
- kind: 'init',
1271
+ value: this.convertChild(node.name),
1206
1272
  });
1207
1273
  }
1208
1274
  if (node.initializer) {
1209
1275
  result.value = this.createNode(node, {
1210
1276
  type: ts_estree_1.AST_NODE_TYPES.AssignmentPattern,
1277
+ range: [node.name.getStart(this.ast), node.initializer.end],
1211
1278
  decorators: [],
1212
1279
  left: this.convertChild(node.name),
1213
1280
  optional: false,
1214
- range: [node.name.getStart(this.ast), node.initializer.end],
1215
1281
  right: this.convertChild(node.initializer),
1216
1282
  typeAnnotation: undefined,
1217
1283
  });
@@ -1221,12 +1287,12 @@ class Converter {
1221
1287
  case SyntaxKind.ArrowFunction: {
1222
1288
  return this.createNode(node, {
1223
1289
  type: ts_estree_1.AST_NODE_TYPES.ArrowFunctionExpression,
1290
+ async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
1291
+ body: this.convertChild(node.body),
1292
+ expression: node.body.kind !== SyntaxKind.Block,
1224
1293
  generator: false,
1225
1294
  id: null,
1226
1295
  params: this.convertParameters(node.parameters),
1227
- body: this.convertChild(node.body),
1228
- async: (0, node_utils_1.hasModifier)(SyntaxKind.AsyncKeyword, node),
1229
- expression: node.body.kind !== SyntaxKind.Block,
1230
1296
  returnType: node.type && this.convertTypeAnnotation(node.type, node),
1231
1297
  typeParameters: node.typeParameters &&
1232
1298
  this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters),
@@ -1235,8 +1301,8 @@ class Converter {
1235
1301
  case SyntaxKind.YieldExpression:
1236
1302
  return this.createNode(node, {
1237
1303
  type: ts_estree_1.AST_NODE_TYPES.YieldExpression,
1238
- delegate: !!node.asteriskToken,
1239
1304
  argument: this.convertChild(node.expression),
1305
+ delegate: !!node.asteriskToken,
1240
1306
  });
1241
1307
  case SyntaxKind.AwaitExpression:
1242
1308
  return this.createNode(node, {
@@ -1247,23 +1313,23 @@ class Converter {
1247
1313
  case SyntaxKind.NoSubstitutionTemplateLiteral:
1248
1314
  return this.createNode(node, {
1249
1315
  type: ts_estree_1.AST_NODE_TYPES.TemplateLiteral,
1316
+ expressions: [],
1250
1317
  quasis: [
1251
1318
  this.createNode(node, {
1252
1319
  type: ts_estree_1.AST_NODE_TYPES.TemplateElement,
1320
+ tail: true,
1253
1321
  value: {
1254
- raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - 1),
1255
1322
  cooked: node.text,
1323
+ raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - 1),
1256
1324
  },
1257
- tail: true,
1258
1325
  }),
1259
1326
  ],
1260
- expressions: [],
1261
1327
  });
1262
1328
  case SyntaxKind.TemplateExpression: {
1263
1329
  const result = this.createNode(node, {
1264
1330
  type: ts_estree_1.AST_NODE_TYPES.TemplateLiteral,
1265
- quasis: [this.convertChild(node.head)],
1266
1331
  expressions: [],
1332
+ quasis: [this.convertChild(node.head)],
1267
1333
  });
1268
1334
  node.templateSpans.forEach(templateSpan => {
1269
1335
  result.expressions.push(this.convertChild(templateSpan.expression));
@@ -1274,10 +1340,10 @@ class Converter {
1274
1340
  case SyntaxKind.TaggedTemplateExpression:
1275
1341
  return this.createNode(node, {
1276
1342
  type: ts_estree_1.AST_NODE_TYPES.TaggedTemplateExpression,
1343
+ quasi: this.convertChild(node.template),
1344
+ tag: this.convertChild(node.tag),
1277
1345
  typeArguments: node.typeArguments &&
1278
1346
  this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node),
1279
- tag: this.convertChild(node.tag),
1280
- quasi: this.convertChild(node.template),
1281
1347
  });
1282
1348
  case SyntaxKind.TemplateHead:
1283
1349
  case SyntaxKind.TemplateMiddle:
@@ -1285,11 +1351,11 @@ class Converter {
1285
1351
  const tail = node.kind === SyntaxKind.TemplateTail;
1286
1352
  return this.createNode(node, {
1287
1353
  type: ts_estree_1.AST_NODE_TYPES.TemplateElement,
1354
+ tail,
1288
1355
  value: {
1289
- raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - (tail ? 1 : 2)),
1290
1356
  cooked: node.text,
1357
+ raw: this.ast.text.slice(node.getStart(this.ast) + 1, node.end - (tail ? 1 : 2)),
1291
1358
  },
1292
- tail,
1293
1359
  });
1294
1360
  }
1295
1361
  // Patterns
@@ -1412,10 +1478,10 @@ class Converter {
1412
1478
  abstract: (0, node_utils_1.hasModifier)(SyntaxKind.AbstractKeyword, node),
1413
1479
  body: this.createNode(node, {
1414
1480
  type: ts_estree_1.AST_NODE_TYPES.ClassBody,
1481
+ range: [node.members.pos - 1, node.end],
1415
1482
  body: node.members
1416
1483
  .filter(node_utils_1.isESTreeClassMember)
1417
1484
  .map(el => this.convertChild(el)),
1418
- range: [node.members.pos - 1, node.end],
1419
1485
  }),
1420
1486
  declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
1421
1487
  decorators: (0, getModifiers_1.getDecorators)(node)?.map(el => this.convertChild(el)) ?? [],
@@ -1444,12 +1510,12 @@ class Converter {
1444
1510
  this.assertModuleSpecifier(node, false);
1445
1511
  const result = this.createNode(node, this.#withDeprecatedAliasGetter({
1446
1512
  type: ts_estree_1.AST_NODE_TYPES.ImportDeclaration,
1447
- source: this.convertChild(node.moduleSpecifier),
1448
- specifiers: [],
1449
- importKind: 'value',
1450
1513
  attributes: this.convertImportAttributes(
1451
1514
  // eslint-disable-next-line @typescript-eslint/no-deprecated
1452
1515
  node.attributes ?? node.assertClause),
1516
+ importKind: 'value',
1517
+ source: this.convertChild(node.moduleSpecifier),
1518
+ specifiers: [],
1453
1519
  }, 'assertions', 'attributes', true));
1454
1520
  if (node.importClause) {
1455
1521
  if (node.importClause.isTypeOnly) {
@@ -1479,16 +1545,16 @@ class Converter {
1479
1545
  case SyntaxKind.ImportSpecifier:
1480
1546
  return this.createNode(node, {
1481
1547
  type: ts_estree_1.AST_NODE_TYPES.ImportSpecifier,
1482
- local: this.convertChild(node.name),
1483
1548
  imported: this.convertChild(node.propertyName ?? node.name),
1484
1549
  importKind: node.isTypeOnly ? 'type' : 'value',
1550
+ local: this.convertChild(node.name),
1485
1551
  });
1486
1552
  case SyntaxKind.ImportClause: {
1487
1553
  const local = this.convertChild(node.name);
1488
1554
  return this.createNode(node, {
1489
1555
  type: ts_estree_1.AST_NODE_TYPES.ImportDefaultSpecifier,
1490
- local,
1491
1556
  range: local.range,
1557
+ local,
1492
1558
  });
1493
1559
  }
1494
1560
  case SyntaxKind.ExportDeclaration: {
@@ -1496,26 +1562,26 @@ class Converter {
1496
1562
  this.assertModuleSpecifier(node, true);
1497
1563
  return this.createNode(node, this.#withDeprecatedAliasGetter({
1498
1564
  type: ts_estree_1.AST_NODE_TYPES.ExportNamedDeclaration,
1499
- source: this.convertChild(node.moduleSpecifier),
1500
- specifiers: node.exportClause.elements.map(el => this.convertChild(el, node)),
1501
- exportKind: node.isTypeOnly ? 'type' : 'value',
1502
- declaration: null,
1503
1565
  attributes: this.convertImportAttributes(
1504
1566
  // eslint-disable-next-line @typescript-eslint/no-deprecated
1505
1567
  node.attributes ?? node.assertClause),
1568
+ declaration: null,
1569
+ exportKind: node.isTypeOnly ? 'type' : 'value',
1570
+ source: this.convertChild(node.moduleSpecifier),
1571
+ specifiers: node.exportClause.elements.map(el => this.convertChild(el, node)),
1506
1572
  }, 'assertions', 'attributes', true));
1507
1573
  }
1508
1574
  this.assertModuleSpecifier(node, false);
1509
1575
  return this.createNode(node, this.#withDeprecatedAliasGetter({
1510
1576
  type: ts_estree_1.AST_NODE_TYPES.ExportAllDeclaration,
1511
- source: this.convertChild(node.moduleSpecifier),
1512
- exportKind: node.isTypeOnly ? 'type' : 'value',
1513
- exported: node.exportClause?.kind === SyntaxKind.NamespaceExport
1514
- ? this.convertChild(node.exportClause.name)
1515
- : null,
1516
1577
  attributes: this.convertImportAttributes(
1517
1578
  // eslint-disable-next-line @typescript-eslint/no-deprecated
1518
1579
  node.attributes ?? node.assertClause),
1580
+ exported: node.exportClause?.kind === SyntaxKind.NamespaceExport
1581
+ ? this.convertChild(node.exportClause.name)
1582
+ : null,
1583
+ exportKind: node.isTypeOnly ? 'type' : 'value',
1584
+ source: this.convertChild(node.moduleSpecifier),
1519
1585
  }, 'assertions', 'attributes', true));
1520
1586
  }
1521
1587
  case SyntaxKind.ExportSpecifier: {
@@ -1527,9 +1593,9 @@ class Converter {
1527
1593
  }
1528
1594
  return this.createNode(node, {
1529
1595
  type: ts_estree_1.AST_NODE_TYPES.ExportSpecifier,
1530
- local: this.convertChild(local),
1531
1596
  exported: this.convertChild(node.name),
1532
1597
  exportKind: node.isTypeOnly ? 'type' : 'value',
1598
+ local: this.convertChild(local),
1533
1599
  });
1534
1600
  }
1535
1601
  case SyntaxKind.ExportAssignment:
@@ -1557,38 +1623,38 @@ class Converter {
1557
1623
  }
1558
1624
  return this.createNode(node, {
1559
1625
  type: ts_estree_1.AST_NODE_TYPES.UpdateExpression,
1626
+ argument: this.convertChild(node.operand),
1560
1627
  operator,
1561
1628
  prefix: node.kind === SyntaxKind.PrefixUnaryExpression,
1562
- argument: this.convertChild(node.operand),
1563
1629
  });
1564
1630
  }
1565
1631
  return this.createNode(node, {
1566
1632
  type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1633
+ argument: this.convertChild(node.operand),
1567
1634
  operator,
1568
1635
  prefix: node.kind === SyntaxKind.PrefixUnaryExpression,
1569
- argument: this.convertChild(node.operand),
1570
1636
  });
1571
1637
  }
1572
1638
  case SyntaxKind.DeleteExpression:
1573
1639
  return this.createNode(node, {
1574
1640
  type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1641
+ argument: this.convertChild(node.expression),
1575
1642
  operator: 'delete',
1576
1643
  prefix: true,
1577
- argument: this.convertChild(node.expression),
1578
1644
  });
1579
1645
  case SyntaxKind.VoidExpression:
1580
1646
  return this.createNode(node, {
1581
1647
  type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1648
+ argument: this.convertChild(node.expression),
1582
1649
  operator: 'void',
1583
1650
  prefix: true,
1584
- argument: this.convertChild(node.expression),
1585
1651
  });
1586
1652
  case SyntaxKind.TypeOfExpression:
1587
1653
  return this.createNode(node, {
1588
1654
  type: ts_estree_1.AST_NODE_TYPES.UnaryExpression,
1655
+ argument: this.convertChild(node.expression),
1589
1656
  operator: 'typeof',
1590
1657
  prefix: true,
1591
- argument: this.convertChild(node.expression),
1592
1658
  });
1593
1659
  case SyntaxKind.TypeOperator:
1594
1660
  return this.createNode(node, {
@@ -1639,10 +1705,10 @@ class Converter {
1639
1705
  const computed = false;
1640
1706
  const result = this.createNode(node, {
1641
1707
  type: ts_estree_1.AST_NODE_TYPES.MemberExpression,
1642
- object,
1643
- property,
1644
1708
  computed,
1709
+ object,
1645
1710
  optional: node.questionDotToken !== undefined,
1711
+ property,
1646
1712
  });
1647
1713
  return this.convertChainExpression(result, node);
1648
1714
  }
@@ -1652,10 +1718,10 @@ class Converter {
1652
1718
  const computed = true;
1653
1719
  const result = this.createNode(node, {
1654
1720
  type: ts_estree_1.AST_NODE_TYPES.MemberExpression,
1655
- object,
1656
- property,
1657
1721
  computed,
1722
+ object,
1658
1723
  optional: node.questionDotToken !== undefined,
1724
+ property,
1659
1725
  });
1660
1726
  return this.convertChainExpression(result, node);
1661
1727
  }
@@ -1666,10 +1732,10 @@ class Converter {
1666
1732
  }
1667
1733
  return this.createNode(node, {
1668
1734
  type: ts_estree_1.AST_NODE_TYPES.ImportExpression,
1669
- source: this.convertChild(node.arguments[0]),
1670
1735
  attributes: node.arguments[1]
1671
1736
  ? this.convertChild(node.arguments[1])
1672
1737
  : null,
1738
+ source: this.convertChild(node.arguments[0]),
1673
1739
  });
1674
1740
  }
1675
1741
  const callee = this.convertChild(node.expression);
@@ -1678,8 +1744,8 @@ class Converter {
1678
1744
  this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node);
1679
1745
  const result = this.createNode(node, {
1680
1746
  type: ts_estree_1.AST_NODE_TYPES.CallExpression,
1681
- callee,
1682
1747
  arguments: args,
1748
+ callee,
1683
1749
  optional: node.questionDotToken !== undefined,
1684
1750
  typeArguments,
1685
1751
  });
@@ -1701,9 +1767,9 @@ class Converter {
1701
1767
  case SyntaxKind.ConditionalExpression:
1702
1768
  return this.createNode(node, {
1703
1769
  type: ts_estree_1.AST_NODE_TYPES.ConditionalExpression,
1704
- test: this.convertChild(node.condition),
1705
- consequent: this.convertChild(node.whenTrue),
1706
1770
  alternate: this.convertChild(node.whenFalse),
1771
+ consequent: this.convertChild(node.whenTrue),
1772
+ test: this.convertChild(node.condition),
1707
1773
  });
1708
1774
  case SyntaxKind.MetaProperty: {
1709
1775
  return this.createNode(node, {
@@ -1730,17 +1796,17 @@ class Converter {
1730
1796
  case SyntaxKind.StringLiteral: {
1731
1797
  return this.createNode(node, {
1732
1798
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1799
+ raw: node.getText(),
1733
1800
  value: parent.kind === SyntaxKind.JsxAttribute
1734
1801
  ? (0, node_utils_1.unescapeStringLiteralText)(node.text)
1735
1802
  : node.text,
1736
- raw: node.getText(),
1737
1803
  });
1738
1804
  }
1739
1805
  case SyntaxKind.NumericLiteral: {
1740
1806
  return this.createNode(node, {
1741
1807
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1742
- value: Number(node.text),
1743
1808
  raw: node.getText(),
1809
+ value: Number(node.text),
1744
1810
  });
1745
1811
  }
1746
1812
  case SyntaxKind.BigIntLiteral: {
@@ -1755,10 +1821,10 @@ class Converter {
1755
1821
  const value = typeof BigInt !== 'undefined' ? BigInt(bigint) : null;
1756
1822
  return this.createNode(node, {
1757
1823
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1824
+ range,
1825
+ bigint: value == null ? bigint : String(value),
1758
1826
  raw: rawValue,
1759
1827
  value,
1760
- bigint: value == null ? bigint : String(value),
1761
- range,
1762
1828
  });
1763
1829
  }
1764
1830
  case SyntaxKind.RegularExpressionLiteral: {
@@ -1773,31 +1839,31 @@ class Converter {
1773
1839
  }
1774
1840
  return this.createNode(node, {
1775
1841
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1776
- value: regex,
1777
1842
  raw: node.text,
1778
1843
  regex: {
1779
- pattern,
1780
1844
  flags,
1845
+ pattern,
1781
1846
  },
1847
+ value: regex,
1782
1848
  });
1783
1849
  }
1784
1850
  case SyntaxKind.TrueKeyword:
1785
1851
  return this.createNode(node, {
1786
1852
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1787
- value: true,
1788
1853
  raw: 'true',
1854
+ value: true,
1789
1855
  });
1790
1856
  case SyntaxKind.FalseKeyword:
1791
1857
  return this.createNode(node, {
1792
1858
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1793
- value: false,
1794
1859
  raw: 'false',
1860
+ value: false,
1795
1861
  });
1796
1862
  case SyntaxKind.NullKeyword: {
1797
1863
  return this.createNode(node, {
1798
1864
  type: ts_estree_1.AST_NODE_TYPES.Literal,
1799
- value: null,
1800
1865
  raw: 'null',
1866
+ value: null,
1801
1867
  });
1802
1868
  }
1803
1869
  case SyntaxKind.EmptyStatement:
@@ -1812,16 +1878,16 @@ class Converter {
1812
1878
  case SyntaxKind.JsxElement:
1813
1879
  return this.createNode(node, {
1814
1880
  type: ts_estree_1.AST_NODE_TYPES.JSXElement,
1815
- openingElement: this.convertChild(node.openingElement),
1816
- closingElement: this.convertChild(node.closingElement),
1817
1881
  children: node.children.map(el => this.convertChild(el)),
1882
+ closingElement: this.convertChild(node.closingElement),
1883
+ openingElement: this.convertChild(node.openingElement),
1818
1884
  });
1819
1885
  case SyntaxKind.JsxFragment:
1820
1886
  return this.createNode(node, {
1821
1887
  type: ts_estree_1.AST_NODE_TYPES.JSXFragment,
1822
- openingFragment: this.convertChild(node.openingFragment),
1823
- closingFragment: this.convertChild(node.closingFragment),
1824
1888
  children: node.children.map(el => this.convertChild(el)),
1889
+ closingFragment: this.convertChild(node.closingFragment),
1890
+ openingFragment: this.convertChild(node.openingFragment),
1825
1891
  });
1826
1892
  case SyntaxKind.JsxSelfClosingElement: {
1827
1893
  return this.createNode(node, {
@@ -1830,28 +1896,28 @@ class Converter {
1830
1896
  * Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement,
1831
1897
  * TypeScript does not seem to have the idea of openingElement when tag is self-closing
1832
1898
  */
1899
+ children: [],
1900
+ closingElement: null,
1833
1901
  openingElement: this.createNode(node, {
1834
1902
  type: ts_estree_1.AST_NODE_TYPES.JSXOpeningElement,
1903
+ range: (0, node_utils_1.getRange)(node, this.ast),
1904
+ attributes: node.attributes.properties.map(el => this.convertChild(el)),
1905
+ name: this.convertJSXTagName(node.tagName, node),
1906
+ selfClosing: true,
1835
1907
  typeArguments: node.typeArguments
1836
1908
  ? this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node)
1837
1909
  : undefined,
1838
- selfClosing: true,
1839
- name: this.convertJSXTagName(node.tagName, node),
1840
- attributes: node.attributes.properties.map(el => this.convertChild(el)),
1841
- range: (0, node_utils_1.getRange)(node, this.ast),
1842
1910
  }),
1843
- closingElement: null,
1844
- children: [],
1845
1911
  });
1846
1912
  }
1847
1913
  case SyntaxKind.JsxOpeningElement: {
1848
1914
  return this.createNode(node, {
1849
1915
  type: ts_estree_1.AST_NODE_TYPES.JSXOpeningElement,
1916
+ attributes: node.attributes.properties.map(el => this.convertChild(el)),
1917
+ name: this.convertJSXTagName(node.tagName, node),
1918
+ selfClosing: false,
1850
1919
  typeArguments: node.typeArguments &&
1851
1920
  this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node),
1852
- selfClosing: false,
1853
- name: this.convertJSXTagName(node.tagName, node),
1854
- attributes: node.attributes.properties.map(el => this.convertChild(el)),
1855
1921
  });
1856
1922
  }
1857
1923
  case SyntaxKind.JsxClosingElement:
@@ -1898,9 +1964,9 @@ class Converter {
1898
1964
  const text = this.ast.text.slice(start, end);
1899
1965
  return this.createNode(node, {
1900
1966
  type: ts_estree_1.AST_NODE_TYPES.JSXText,
1901
- value: (0, node_utils_1.unescapeStringLiteralText)(text),
1902
- raw: text,
1903
1967
  range: [start, end],
1968
+ raw: text,
1969
+ value: (0, node_utils_1.unescapeStringLiteralText)(text),
1904
1970
  });
1905
1971
  }
1906
1972
  case SyntaxKind.JsxSpreadAttribute:
@@ -1919,19 +1985,19 @@ class Converter {
1919
1985
  case SyntaxKind.TypeReference:
1920
1986
  return this.createNode(node, {
1921
1987
  type: ts_estree_1.AST_NODE_TYPES.TSTypeReference,
1922
- typeName: this.convertChild(node.typeName),
1923
1988
  typeArguments: node.typeArguments &&
1924
1989
  this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node),
1990
+ typeName: this.convertChild(node.typeName),
1925
1991
  });
1926
1992
  case SyntaxKind.TypeParameter: {
1927
1993
  return this.createNode(node, {
1928
1994
  type: ts_estree_1.AST_NODE_TYPES.TSTypeParameter,
1929
- name: this.convertChild(node.name),
1995
+ const: (0, node_utils_1.hasModifier)(SyntaxKind.ConstKeyword, node),
1930
1996
  constraint: node.constraint && this.convertChild(node.constraint),
1931
1997
  default: node.default ? this.convertChild(node.default) : undefined,
1932
1998
  in: (0, node_utils_1.hasModifier)(SyntaxKind.InKeyword, node),
1999
+ name: this.convertChild(node.name),
1933
2000
  out: (0, node_utils_1.hasModifier)(SyntaxKind.OutKeyword, node),
1934
- const: (0, node_utils_1.hasModifier)(SyntaxKind.ConstKeyword, node),
1935
2001
  });
1936
2002
  }
1937
2003
  case SyntaxKind.ThisType:
@@ -1976,8 +2042,8 @@ class Converter {
1976
2042
  case SyntaxKind.IndexedAccessType: {
1977
2043
  return this.createNode(node, {
1978
2044
  type: ts_estree_1.AST_NODE_TYPES.TSIndexedAccessType,
1979
- objectType: this.convertChild(node.objectType),
1980
2045
  indexType: this.convertChild(node.indexType),
2046
+ objectType: this.convertChild(node.objectType),
1981
2047
  });
1982
2048
  }
1983
2049
  case SyntaxKind.ConditionalType: {
@@ -1985,8 +2051,8 @@ class Converter {
1985
2051
  type: ts_estree_1.AST_NODE_TYPES.TSConditionalType,
1986
2052
  checkType: this.convertChild(node.checkType),
1987
2053
  extendsType: this.convertChild(node.extendsType),
1988
- trueType: this.convertChild(node.trueType),
1989
2054
  falseType: this.convertChild(node.falseType),
2055
+ trueType: this.convertChild(node.trueType),
1990
2056
  });
1991
2057
  }
1992
2058
  case SyntaxKind.TypeQuery:
@@ -2121,8 +2187,8 @@ class Converter {
2121
2187
  type: ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration,
2122
2188
  body: this.createNode(node, {
2123
2189
  type: ts_estree_1.AST_NODE_TYPES.TSInterfaceBody,
2124
- body: node.members.map(member => this.convertChild(member)),
2125
2190
  range: [node.members.pos - 1, node.end],
2191
+ body: node.members.map(member => this.convertChild(member)),
2126
2192
  }),
2127
2193
  declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
2128
2194
  extends: interfaceExtends,
@@ -2158,12 +2224,12 @@ class Converter {
2158
2224
  }
2159
2225
  const result = this.createNode(node, {
2160
2226
  type: ts_estree_1.AST_NODE_TYPES.TSImportType,
2227
+ range,
2161
2228
  argument: this.convertChild(node.argument),
2162
2229
  qualifier: this.convertChild(node.qualifier),
2163
2230
  typeArguments: node.typeArguments
2164
2231
  ? this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node)
2165
2232
  : null,
2166
- range,
2167
2233
  });
2168
2234
  if (node.isTypeOf) {
2169
2235
  return this.createNode(node, {
@@ -2180,8 +2246,8 @@ class Converter {
2180
2246
  type: ts_estree_1.AST_NODE_TYPES.TSEnumDeclaration,
2181
2247
  body: this.createNode(node, {
2182
2248
  type: ts_estree_1.AST_NODE_TYPES.TSEnumBody,
2183
- members,
2184
2249
  range: [node.members.pos - 1, node.end],
2250
+ members,
2185
2251
  }),
2186
2252
  const: (0, node_utils_1.hasModifier)(SyntaxKind.ConstKeyword, node),
2187
2253
  declare: (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node),
@@ -2215,11 +2281,11 @@ class Converter {
2215
2281
  this.#throwUnlessAllowInvalidAST(node.name, 'global module augmentation must have an Identifier id');
2216
2282
  }
2217
2283
  return {
2218
- kind: 'global',
2219
2284
  body: body,
2220
2285
  declare: false,
2221
2286
  global: false,
2222
2287
  id,
2288
+ kind: 'global',
2223
2289
  };
2224
2290
  }
2225
2291
  if (!(node.flags & ts.NodeFlags.Namespace)) {
@@ -2242,11 +2308,11 @@ class Converter {
2242
2308
  this.#throwUnlessAllowInvalidAST(node.name, '`namespace`s must have an Identifier id');
2243
2309
  }
2244
2310
  let name = this.createNode(node.name, {
2311
+ type: ts_estree_1.AST_NODE_TYPES.Identifier,
2312
+ range: [node.name.getStart(this.ast), node.name.getEnd()],
2245
2313
  decorators: [],
2246
2314
  name: node.name.text,
2247
2315
  optional: false,
2248
- range: [node.name.getStart(this.ast), node.name.getEnd()],
2249
- type: ts_estree_1.AST_NODE_TYPES.Identifier,
2250
2316
  typeAnnotation: undefined,
2251
2317
  });
2252
2318
  while (node.body &&
@@ -2256,26 +2322,26 @@ class Converter {
2256
2322
  isDeclare ||= (0, node_utils_1.hasModifier)(SyntaxKind.DeclareKeyword, node);
2257
2323
  const nextName = node.name;
2258
2324
  const right = this.createNode(nextName, {
2325
+ type: ts_estree_1.AST_NODE_TYPES.Identifier,
2326
+ range: [nextName.getStart(this.ast), nextName.getEnd()],
2259
2327
  decorators: [],
2260
2328
  name: nextName.text,
2261
2329
  optional: false,
2262
- range: [nextName.getStart(this.ast), nextName.getEnd()],
2263
- type: ts_estree_1.AST_NODE_TYPES.Identifier,
2264
2330
  typeAnnotation: undefined,
2265
2331
  });
2266
2332
  name = this.createNode(nextName, {
2333
+ type: ts_estree_1.AST_NODE_TYPES.TSQualifiedName,
2334
+ range: [name.range[0], right.range[1]],
2267
2335
  left: name,
2268
2336
  right,
2269
- range: [name.range[0], right.range[1]],
2270
- type: ts_estree_1.AST_NODE_TYPES.TSQualifiedName,
2271
2337
  });
2272
2338
  }
2273
2339
  return {
2274
- kind: 'namespace',
2275
2340
  body: this.convertChild(node.body),
2276
2341
  declare: false,
2277
2342
  global: false,
2278
2343
  id: name,
2344
+ kind: 'namespace',
2279
2345
  };
2280
2346
  })(),
2281
2347
  });
@@ -2331,8 +2397,8 @@ class Converter {
2331
2397
  case SyntaxKind.TypeAssertionExpression: {
2332
2398
  return this.createNode(node, {
2333
2399
  type: ts_estree_1.AST_NODE_TYPES.TSTypeAssertion,
2334
- typeAnnotation: this.convertChild(node.type),
2335
2400
  expression: this.convertChild(node.expression),
2401
+ typeAnnotation: this.convertChild(node.type),
2336
2402
  });
2337
2403
  }
2338
2404
  case SyntaxKind.ImportEqualsDeclaration: {
@@ -2440,230 +2506,164 @@ class Converter {
2440
2506
  return this.deeplyCopy(node);
2441
2507
  }
2442
2508
  }
2443
- #checkModifiers(node) {
2444
- if (this.options.allowInvalidAST) {
2445
- return;
2509
+ createNode(
2510
+ // The 'parent' property will be added later if specified
2511
+ node, data) {
2512
+ const result = data;
2513
+ result.range ??= (0, node_utils_1.getRange)(node, this.ast);
2514
+ result.loc ??= (0, node_utils_1.getLocFor)(result.range, this.ast);
2515
+ if (result && this.options.shouldPreserveNodeMaps) {
2516
+ this.esTreeNodeToTSNodeMap.set(result, node);
2446
2517
  }
2447
- // typescript<5.0.0
2448
- if ((0, node_utils_1.nodeHasIllegalDecorators)(node)) {
2449
- this.#throwError(node.illegalDecorators[0], 'Decorators are not valid here.');
2518
+ return result;
2519
+ }
2520
+ convertProgram() {
2521
+ return this.converter(this.ast);
2522
+ }
2523
+ /**
2524
+ * For nodes that are copied directly from the TypeScript AST into
2525
+ * ESTree mostly as-is. The only difference is the addition of a type
2526
+ * property instead of a kind property. Recursively copies all children.
2527
+ */
2528
+ deeplyCopy(node) {
2529
+ if (node.kind === ts.SyntaxKind.JSDocFunctionType) {
2530
+ this.#throwError(node, 'JSDoc types can only be used inside documentation comments.');
2450
2531
  }
2451
- for (const decorator of (0, getModifiers_1.getDecorators)(node,
2452
- /* includeIllegalDecorators */ true) ?? []) {
2453
- // `checkGrammarModifiers` function in typescript
2454
- if (!(0, node_utils_1.nodeCanBeDecorated)(node)) {
2455
- if (ts.isMethodDeclaration(node) && !(0, node_utils_1.nodeIsPresent)(node.body)) {
2456
- this.#throwError(decorator, 'A decorator can only decorate a method implementation, not an overload.');
2457
- }
2458
- else {
2459
- this.#throwError(decorator, 'Decorators are not valid here.');
2460
- }
2461
- }
2532
+ const customType = `TS${SyntaxKind[node.kind]}`;
2533
+ /**
2534
+ * If the "errorOnUnknownASTType" option is set to true, throw an error,
2535
+ * otherwise fallback to just including the unknown type as-is.
2536
+ */
2537
+ if (this.options.errorOnUnknownASTType && !ts_estree_1.AST_NODE_TYPES[customType]) {
2538
+ throw new Error(`Unknown AST_NODE_TYPE: "${customType}"`);
2462
2539
  }
2463
- for (const modifier of (0, getModifiers_1.getModifiers)(node,
2464
- /* includeIllegalModifiers */ true) ?? []) {
2465
- if (modifier.kind !== SyntaxKind.ReadonlyKeyword) {
2466
- if (node.kind === SyntaxKind.PropertySignature ||
2467
- node.kind === SyntaxKind.MethodSignature) {
2468
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a type member`);
2469
- }
2470
- if (node.kind === SyntaxKind.IndexSignature &&
2471
- (modifier.kind !== SyntaxKind.StaticKeyword ||
2472
- !ts.isClassLike(node.parent))) {
2473
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on an index signature`);
2474
- }
2475
- }
2476
- if (modifier.kind !== SyntaxKind.InKeyword &&
2477
- modifier.kind !== SyntaxKind.OutKeyword &&
2478
- modifier.kind !== SyntaxKind.ConstKeyword &&
2479
- node.kind === SyntaxKind.TypeParameter) {
2480
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a type parameter`);
2481
- }
2482
- if ((modifier.kind === SyntaxKind.InKeyword ||
2483
- modifier.kind === SyntaxKind.OutKeyword) &&
2484
- (node.kind !== SyntaxKind.TypeParameter ||
2485
- !(ts.isInterfaceDeclaration(node.parent) ||
2486
- ts.isClassLike(node.parent) ||
2487
- ts.isTypeAliasDeclaration(node.parent)))) {
2488
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier can only appear on a type parameter of a class, interface or type alias`);
2489
- }
2490
- if (modifier.kind === SyntaxKind.ReadonlyKeyword &&
2491
- node.kind !== SyntaxKind.PropertyDeclaration &&
2492
- node.kind !== SyntaxKind.PropertySignature &&
2493
- node.kind !== SyntaxKind.IndexSignature &&
2494
- node.kind !== SyntaxKind.Parameter) {
2495
- this.#throwError(modifier, "'readonly' modifier can only appear on a property declaration or index signature.");
2496
- }
2497
- if (modifier.kind === SyntaxKind.DeclareKeyword &&
2498
- ts.isClassLike(node.parent) &&
2499
- !ts.isPropertyDeclaration(node)) {
2500
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on class elements of this kind.`);
2501
- }
2502
- if (modifier.kind === SyntaxKind.DeclareKeyword &&
2503
- ts.isVariableStatement(node)) {
2504
- const declarationKind = (0, node_utils_1.getDeclarationKind)(node.declarationList);
2505
- if (declarationKind === 'using' || declarationKind === 'await using') {
2506
- this.#throwError(modifier, `'declare' modifier cannot appear on a '${declarationKind}' declaration.`);
2507
- }
2508
- }
2509
- if (modifier.kind === SyntaxKind.AbstractKeyword &&
2510
- node.kind !== SyntaxKind.ClassDeclaration &&
2511
- node.kind !== SyntaxKind.ConstructorType &&
2512
- node.kind !== SyntaxKind.MethodDeclaration &&
2513
- node.kind !== SyntaxKind.PropertyDeclaration &&
2514
- node.kind !== SyntaxKind.GetAccessor &&
2515
- node.kind !== SyntaxKind.SetAccessor) {
2516
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier can only appear on a class, method, or property declaration.`);
2517
- }
2518
- if ((modifier.kind === SyntaxKind.StaticKeyword ||
2519
- modifier.kind === SyntaxKind.PublicKeyword ||
2520
- modifier.kind === SyntaxKind.ProtectedKeyword ||
2521
- modifier.kind === SyntaxKind.PrivateKeyword) &&
2522
- (node.parent.kind === SyntaxKind.ModuleBlock ||
2523
- node.parent.kind === SyntaxKind.SourceFile)) {
2524
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a module or namespace element.`);
2525
- }
2526
- if (modifier.kind === SyntaxKind.AccessorKeyword &&
2527
- node.kind !== SyntaxKind.PropertyDeclaration) {
2528
- this.#throwError(modifier, "'accessor' modifier can only appear on a property declaration.");
2529
- }
2530
- // `checkGrammarAsyncModifier` function in `typescript`
2531
- if (modifier.kind === SyntaxKind.AsyncKeyword &&
2532
- node.kind !== SyntaxKind.MethodDeclaration &&
2533
- node.kind !== SyntaxKind.FunctionDeclaration &&
2534
- node.kind !== SyntaxKind.FunctionExpression &&
2535
- node.kind !== SyntaxKind.ArrowFunction) {
2536
- this.#throwError(modifier, "'async' modifier cannot be used here.");
2537
- }
2538
- // `checkGrammarModifiers` function in `typescript`
2539
- if (node.kind === SyntaxKind.Parameter &&
2540
- (modifier.kind === SyntaxKind.StaticKeyword ||
2541
- modifier.kind === SyntaxKind.ExportKeyword ||
2542
- modifier.kind === SyntaxKind.DeclareKeyword ||
2543
- modifier.kind === SyntaxKind.AsyncKeyword)) {
2544
- this.#throwError(modifier, `'${ts.tokenToString(modifier.kind)}' modifier cannot appear on a parameter.`);
2545
- }
2546
- // `checkGrammarModifiers` function in `typescript`
2547
- if (modifier.kind === SyntaxKind.PublicKeyword ||
2548
- modifier.kind === SyntaxKind.ProtectedKeyword ||
2549
- modifier.kind === SyntaxKind.PrivateKeyword) {
2550
- for (const anotherModifier of (0, getModifiers_1.getModifiers)(node) ?? []) {
2551
- if (anotherModifier !== modifier &&
2552
- (anotherModifier.kind === SyntaxKind.PublicKeyword ||
2553
- anotherModifier.kind === SyntaxKind.ProtectedKeyword ||
2554
- anotherModifier.kind === SyntaxKind.PrivateKeyword)) {
2555
- this.#throwError(anotherModifier, `Accessibility modifier already seen.`);
2556
- }
2557
- }
2558
- }
2559
- // `checkParameter` function in `typescript`
2560
- if (node.kind === SyntaxKind.Parameter &&
2561
- // In `typescript` package, it's `ts.hasSyntacticModifier(node, ts.ModifierFlags.ParameterPropertyModifier)`
2562
- // https://github.com/typescript-eslint/typescript-eslint/pull/6615#discussion_r1136489935
2563
- (modifier.kind === SyntaxKind.PublicKeyword ||
2564
- modifier.kind === SyntaxKind.PrivateKeyword ||
2565
- modifier.kind === SyntaxKind.ProtectedKeyword ||
2566
- modifier.kind === SyntaxKind.ReadonlyKeyword ||
2567
- modifier.kind === SyntaxKind.OverrideKeyword)) {
2568
- const func = (0, node_utils_1.getContainingFunction)(node);
2569
- if (!(func.kind === SyntaxKind.Constructor && (0, node_utils_1.nodeIsPresent)(func.body))) {
2570
- this.#throwError(modifier, 'A parameter property is only allowed in a constructor implementation.');
2571
- }
2572
- }
2540
+ const result = this.createNode(node, {
2541
+ type: customType,
2542
+ });
2543
+ if ('type' in node) {
2544
+ result.typeAnnotation =
2545
+ node.type && 'kind' in node.type && ts.isTypeNode(node.type)
2546
+ ? this.convertTypeAnnotation(node.type, node)
2547
+ : null;
2573
2548
  }
2574
- }
2575
- #throwUnlessAllowInvalidAST(node, message) {
2576
- if (!this.options.allowInvalidAST) {
2577
- this.#throwError(node, message);
2549
+ if ('typeArguments' in node) {
2550
+ result.typeArguments =
2551
+ node.typeArguments && 'pos' in node.typeArguments
2552
+ ? this.convertTypeArgumentsToTypeParameterInstantiation(node.typeArguments, node)
2553
+ : null;
2578
2554
  }
2579
- }
2580
- /**
2581
- * Creates a getter for a property under aliasKey that returns the value under
2582
- * valueKey. If suppressDeprecatedPropertyWarnings is not enabled, the
2583
- * getter also console warns about the deprecation.
2584
- *
2585
- * @see https://github.com/typescript-eslint/typescript-eslint/issues/6469
2586
- */
2587
- #withDeprecatedAliasGetter(node, aliasKey, valueKey, suppressWarnings = false) {
2588
- let warned = suppressWarnings;
2589
- Object.defineProperty(node, aliasKey, {
2590
- configurable: true,
2591
- get: this.options.suppressDeprecatedPropertyWarnings
2592
- ? () => node[valueKey]
2593
- : () => {
2594
- if (!warned) {
2595
- process.emitWarning(`The '${aliasKey}' property is deprecated on ${node.type} nodes. Use '${valueKey}' instead. See https://typescript-eslint.io/troubleshooting/faqs/general#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings.`, 'DeprecationWarning');
2596
- warned = true;
2597
- }
2598
- return node[valueKey];
2599
- },
2600
- set(value) {
2601
- Object.defineProperty(node, aliasKey, {
2602
- enumerable: true,
2603
- writable: true,
2604
- value,
2605
- });
2606
- },
2607
- });
2608
- return node;
2609
- }
2610
- #withDeprecatedGetter(node, deprecatedKey, preferredKey, value) {
2611
- let warned = false;
2612
- Object.defineProperty(node, deprecatedKey, {
2613
- configurable: true,
2614
- get: this.options.suppressDeprecatedPropertyWarnings
2615
- ? () => value
2616
- : () => {
2617
- if (!warned) {
2618
- process.emitWarning(`The '${deprecatedKey}' property is deprecated on ${node.type} nodes. Use ${preferredKey} instead. See https://typescript-eslint.io/troubleshooting/faqs/general#the-key-property-is-deprecated-on-type-nodes-use-key-instead-warnings.`, 'DeprecationWarning');
2619
- warned = true;
2620
- }
2621
- return value;
2622
- },
2623
- set(value) {
2624
- Object.defineProperty(node, deprecatedKey, {
2625
- enumerable: true,
2626
- writable: true,
2627
- value,
2628
- });
2629
- },
2630
- });
2631
- return node;
2632
- }
2633
- #throwError(node, message) {
2634
- let start;
2635
- let end;
2636
- if (typeof node === 'number') {
2637
- start = end = node;
2555
+ if ('typeParameters' in node) {
2556
+ result.typeParameters =
2557
+ node.typeParameters && 'pos' in node.typeParameters
2558
+ ? this.convertTSTypeParametersToTypeParametersDeclaration(node.typeParameters)
2559
+ : null;
2638
2560
  }
2639
- else {
2640
- start = node.getStart(this.ast);
2641
- end = node.getEnd();
2561
+ const decorators = (0, getModifiers_1.getDecorators)(node);
2562
+ if (decorators?.length) {
2563
+ result.decorators = decorators.map(el => this.convertChild(el));
2642
2564
  }
2643
- throw (0, node_utils_1.createError)(message, this.ast, start, end);
2644
- }
2645
- #checkForStatementDeclaration(initializer, kind) {
2646
- const loop = kind === ts.SyntaxKind.ForInStatement ? 'for...in' : 'for...of';
2647
- if (ts.isVariableDeclarationList(initializer)) {
2648
- if (initializer.declarations.length !== 1) {
2649
- this.#throwError(initializer, `Only a single variable declaration is allowed in a '${loop}' statement.`);
2565
+ // keys we never want to clone from the base typescript node as they
2566
+ // introduce garbage into our AST
2567
+ const KEYS_TO_NOT_COPY = new Set([
2568
+ '_children',
2569
+ 'decorators',
2570
+ 'end',
2571
+ 'flags',
2572
+ 'heritageClauses',
2573
+ 'illegalDecorators',
2574
+ 'jsDoc',
2575
+ 'kind',
2576
+ 'locals',
2577
+ 'localSymbol',
2578
+ 'modifierFlagsCache',
2579
+ 'modifiers',
2580
+ 'nextContainer',
2581
+ 'parent',
2582
+ 'pos',
2583
+ 'symbol',
2584
+ 'transformFlags',
2585
+ 'type',
2586
+ 'typeArguments',
2587
+ 'typeParameters',
2588
+ ]);
2589
+ Object.entries(node)
2590
+ .filter(([key]) => !KEYS_TO_NOT_COPY.has(key))
2591
+ .forEach(([key, value]) => {
2592
+ if (Array.isArray(value)) {
2593
+ result[key] = value.map(el => this.convertChild(el));
2650
2594
  }
2651
- const declaration = initializer.declarations[0];
2652
- if (declaration.initializer) {
2653
- this.#throwError(declaration, `The variable declaration of a '${loop}' statement cannot have an initializer.`);
2595
+ else if (value && typeof value === 'object' && value.kind) {
2596
+ // need to check node[key].kind to ensure we don't try to convert a symbol
2597
+ result[key] = this.convertChild(value);
2654
2598
  }
2655
- else if (declaration.type) {
2656
- this.#throwError(declaration, `The variable declaration of a '${loop}' statement cannot have a type annotation.`);
2599
+ else {
2600
+ result[key] = value;
2657
2601
  }
2658
- if (kind === ts.SyntaxKind.ForInStatement &&
2659
- initializer.flags & ts.NodeFlags.Using) {
2660
- this.#throwError(initializer, "The left-hand side of a 'for...in' statement cannot be a 'using' declaration.");
2602
+ });
2603
+ return result;
2604
+ }
2605
+ /**
2606
+ * Fixes the exports of the given ts.Node
2607
+ * @returns the ESTreeNode with fixed exports
2608
+ */
2609
+ fixExports(node, result) {
2610
+ const isNamespaceNode = ts.isModuleDeclaration(node) &&
2611
+ Boolean(node.flags & ts.NodeFlags.Namespace);
2612
+ const modifiers = isNamespaceNode
2613
+ ? (0, node_utils_1.getNamespaceModifiers)(node)
2614
+ : (0, getModifiers_1.getModifiers)(node);
2615
+ if (modifiers?.[0].kind === SyntaxKind.ExportKeyword) {
2616
+ /**
2617
+ * Make sure that original node is registered instead of export
2618
+ */
2619
+ this.registerTSNodeInNodeMap(node, result);
2620
+ const exportKeyword = modifiers[0];
2621
+ const nextModifier = modifiers[1];
2622
+ const declarationIsDefault = nextModifier?.kind === SyntaxKind.DefaultKeyword;
2623
+ const varToken = declarationIsDefault
2624
+ ? (0, node_utils_1.findNextToken)(nextModifier, this.ast, this.ast)
2625
+ : (0, node_utils_1.findNextToken)(exportKeyword, this.ast, this.ast);
2626
+ result.range[0] = varToken.getStart(this.ast);
2627
+ result.loc = (0, node_utils_1.getLocFor)(result.range, this.ast);
2628
+ if (declarationIsDefault) {
2629
+ return this.createNode(node, {
2630
+ type: ts_estree_1.AST_NODE_TYPES.ExportDefaultDeclaration,
2631
+ range: [exportKeyword.getStart(this.ast), result.range[1]],
2632
+ declaration: result,
2633
+ exportKind: 'value',
2634
+ });
2661
2635
  }
2636
+ const isType = result.type === ts_estree_1.AST_NODE_TYPES.TSInterfaceDeclaration ||
2637
+ result.type === ts_estree_1.AST_NODE_TYPES.TSTypeAliasDeclaration;
2638
+ const isDeclare = 'declare' in result && result.declare;
2639
+ return this.createNode(node,
2640
+ // @ts-expect-error - TODO, narrow the types here
2641
+ this.#withDeprecatedAliasGetter({
2642
+ type: ts_estree_1.AST_NODE_TYPES.ExportNamedDeclaration,
2643
+ range: [exportKeyword.getStart(this.ast), result.range[1]],
2644
+ attributes: [],
2645
+ declaration: result,
2646
+ exportKind: isType || isDeclare ? 'type' : 'value',
2647
+ source: null,
2648
+ specifiers: [],
2649
+ }, 'assertions', 'attributes', true));
2662
2650
  }
2663
- else if (!(0, node_utils_1.isValidAssignmentTarget)(initializer) &&
2664
- initializer.kind !== ts.SyntaxKind.ObjectLiteralExpression &&
2665
- initializer.kind !== ts.SyntaxKind.ArrayLiteralExpression) {
2666
- this.#throwError(initializer, `The left-hand side of a '${loop}' statement must be a variable or a property access.`);
2651
+ return result;
2652
+ }
2653
+ getASTMaps() {
2654
+ return {
2655
+ esTreeNodeToTSNodeMap: this.esTreeNodeToTSNodeMap,
2656
+ tsNodeToESTreeNodeMap: this.tsNodeToESTreeNodeMap,
2657
+ };
2658
+ }
2659
+ /**
2660
+ * Register specific TypeScript node into map with first ESTree node provided
2661
+ */
2662
+ registerTSNodeInNodeMap(node, result) {
2663
+ if (result &&
2664
+ this.options.shouldPreserveNodeMaps &&
2665
+ !this.tsNodeToESTreeNodeMap.has(node)) {
2666
+ this.tsNodeToESTreeNodeMap.set(node, result);
2667
2667
  }
2668
2668
  }
2669
2669
  }