poe-code 14.0.63 → 14.0.65

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 (58) hide show
  1. package/dist/index.js +7473 -6816
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-js/dist/chunks/{chunk-KMTTD3BL.js → chunk-4VT2M7WL.js} +2 -2
  6. package/packages/safe-js/dist/chunks/{chunk-RU2BCN4G.js → chunk-WBWD7ZCM.js} +8215 -7599
  7. package/packages/safe-js/dist/chunks/chunk-WBWD7ZCM.js.map +7 -0
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.js +1 -1
  10. package/packages/safe-js/dist/index.js +2 -2
  11. package/packages/safe-js/dist/index.js.map +1 -1
  12. package/packages/safe-js/dist/interp/async.d.ts +13 -2
  13. package/packages/safe-js/dist/interp/async.js +16 -6
  14. package/packages/safe-js/dist/interp/classes.d.ts +4 -0
  15. package/packages/safe-js/dist/interp/classes.js +176 -0
  16. package/packages/safe-js/dist/interp/exceptions.js +4 -1
  17. package/packages/safe-js/dist/interp/globals/object-array.d.ts +2 -1
  18. package/packages/safe-js/dist/interp/globals/object-array.js +1 -1
  19. package/packages/safe-js/dist/interp/globals/object.js +10 -2
  20. package/packages/safe-js/dist/interp/globals/primitives.js +8 -3
  21. package/packages/safe-js/dist/interp/interpreter.d.ts +1 -1
  22. package/packages/safe-js/dist/interp/interpreter.js +99 -30
  23. package/packages/safe-js/dist/interp/methods/function.d.ts +1 -1
  24. package/packages/safe-js/dist/interp/methods/function.js +33 -16
  25. package/packages/safe-js/dist/interp/object-model.js +25 -11
  26. package/packages/safe-js/dist/interp/patterns.d.ts +1 -1
  27. package/packages/safe-js/dist/interp/patterns.js +1 -1
  28. package/packages/safe-js/dist/interp/values.d.ts +2 -1
  29. package/packages/safe-js/dist/lint/class-elements.d.ts +5 -0
  30. package/packages/safe-js/dist/lint/class-elements.js +20 -0
  31. package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +16 -0
  32. package/packages/safe-js/dist/lint/rules/AS-destructure-null-default.js +9 -0
  33. package/packages/safe-js/dist/lint/rules/AS-export-import-meta.js +9 -0
  34. package/packages/safe-js/dist/lint/rules/AS-floating-promise.js +9 -0
  35. package/packages/safe-js/dist/lint/rules/AS-frontmatter-field-unused.js +9 -0
  36. package/packages/safe-js/dist/lint/rules/AS-jsdoc-type.js +9 -0
  37. package/packages/safe-js/dist/lint/rules/AS-large-literal.js +9 -0
  38. package/packages/safe-js/dist/lint/rules/AS-missing-async.js +16 -0
  39. package/packages/safe-js/dist/lint/rules/AS-mutating-frozen.js +9 -0
  40. package/packages/safe-js/dist/lint/rules/AS-needless-template.js +9 -0
  41. package/packages/safe-js/dist/lint/rules/AS-shadow-global.js +12 -0
  42. package/packages/safe-js/dist/lint/rules/AS-unbounded-loop.js +11 -0
  43. package/packages/safe-js/dist/lint/rules/AS-unreachable.js +9 -0
  44. package/packages/safe-js/dist/lint/rules/AS-unused-import.js +16 -2
  45. package/packages/safe-js/dist/lint/rules/AS001.js +0 -1
  46. package/packages/safe-js/dist/lint/rules/AS003.js +16 -2
  47. package/packages/safe-js/dist/lint/rules/AS006-007.js +16 -2
  48. package/packages/safe-js/dist/lint/rules/AS009.js +20 -1
  49. package/packages/safe-js/dist/lint/rules/AS010.js +9 -0
  50. package/packages/safe-js/dist/lint/rules/AS011.js +9 -0
  51. package/packages/safe-js/dist/lint/rules/AS015.js +9 -0
  52. package/packages/safe-js/dist/parse/function-source.d.ts +2 -2
  53. package/packages/safe-js/dist/parse/parser.d.ts +42 -2
  54. package/packages/safe-js/dist/parse/parser.js +180 -36
  55. package/packages/safe-js/dist/parse/tokenizer.js +3 -0
  56. package/packages/safe-js/dist/parse.d.ts +1 -1
  57. package/packages/safe-js/dist/chunks/chunk-RU2BCN4G.js.map +0 -7
  58. /package/packages/safe-js/dist/chunks/{chunk-KMTTD3BL.js.map → chunk-4VT2M7WL.js.map} +0 -0
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  import { normalizeModuleRegistrations } from "./module-registry.js";
3
4
  const AS_FLOATING_PROMISE_MESSAGE = "Promise-returning call is not awaited, returned, stored, or chained.";
@@ -28,6 +29,10 @@ class ASFloatingPromiseScanner {
28
29
  });
29
30
  }
30
31
  visitStatement(node) {
32
+ if (node.type === "ClassDeclaration") {
33
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
34
+ return;
35
+ }
31
36
  switch (node.type) {
32
37
  case "FunctionDeclaration":
33
38
  this.visitArrowFunction(node);
@@ -163,6 +168,10 @@ class ASFloatingPromiseScanner {
163
168
  this.visitExpression(node.argument);
164
169
  }
165
170
  visitExpression(node) {
171
+ if (node.type === "ClassExpression") {
172
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
173
+ return;
174
+ }
166
175
  switch (node.type) {
167
176
  case "YieldExpression":
168
177
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export function AS_FRONTMATTER_FIELD_UNUSED(source, options = {}) {
3
4
  if (options.frontmatterFields === undefined) {
@@ -34,6 +35,10 @@ class ASFrontmatterFieldUnusedScanner {
34
35
  }
35
36
  }
36
37
  visitStatement(node) {
38
+ if (node.type === "ClassDeclaration") {
39
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
40
+ return;
41
+ }
37
42
  switch (node.type) {
38
43
  case "FunctionDeclaration":
39
44
  this.visitArrowFunction(node);
@@ -162,6 +167,10 @@ class ASFrontmatterFieldUnusedScanner {
162
167
  this.visitExpression(node.argument);
163
168
  }
164
169
  visitExpression(node) {
170
+ if (node.type === "ClassExpression") {
171
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
172
+ return;
173
+ }
165
174
  switch (node.type) {
166
175
  case "YieldExpression":
167
176
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  import { hasTypedModuleRegistrations } from "./module-registry.js";
3
4
  export function AS_JSDOC_TYPE(source, options = {}) {
@@ -27,6 +28,10 @@ class ASJsdocTypeScanner {
27
28
  }
28
29
  }
29
30
  visitStatement(node) {
31
+ if (node.type === "ClassDeclaration") {
32
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
33
+ return;
34
+ }
30
35
  switch (node.type) {
31
36
  case "FunctionDeclaration":
32
37
  this.visitArrowFunction(node);
@@ -166,6 +171,10 @@ class ASJsdocTypeScanner {
166
171
  }
167
172
  }
168
173
  visitExpression(node) {
174
+ if (node.type === "ClassExpression") {
175
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
176
+ return;
177
+ }
169
178
  switch (node.type) {
170
179
  case "YieldExpression":
171
180
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  const DEFAULT_LARGE_LITERAL_THRESHOLD = 1000;
3
4
  export function AS_LARGE_LITERAL(source, options = {}) {
@@ -21,6 +22,10 @@ class ASLargeLiteralScanner {
21
22
  }
22
23
  }
23
24
  visitStatement(node) {
25
+ if (node.type === "ClassDeclaration") {
26
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
27
+ return;
28
+ }
24
29
  switch (node.type) {
25
30
  case "FunctionDeclaration":
26
31
  this.visitArrowFunction(node);
@@ -144,6 +149,10 @@ class ASLargeLiteralScanner {
144
149
  this.visitExpression(node.argument);
145
150
  }
146
151
  visitExpression(node) {
152
+ if (node.type === "ClassExpression") {
153
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
154
+ return;
155
+ }
147
156
  switch (node.type) {
148
157
  case "YieldExpression":
149
158
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { classDefinitionContains, visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export const AS_MISSING_ASYNC_MESSAGE = "Functions that contain await must be marked async.";
3
4
  export function AS_MISSING_ASYNC(source, options = {}) {
@@ -27,6 +28,10 @@ class ASMissingAsyncScanner {
27
28
  }
28
29
  }
29
30
  visitStatement(node) {
31
+ if (node.type === "ClassDeclaration") {
32
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
33
+ return;
34
+ }
30
35
  switch (node.type) {
31
36
  case "FunctionDeclaration":
32
37
  this.visitFunctionExpression(node);
@@ -150,6 +155,10 @@ class ASMissingAsyncScanner {
150
155
  this.visitExpression(node.argument);
151
156
  }
152
157
  visitExpression(node) {
158
+ if (node.type === "ClassExpression") {
159
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
160
+ return;
161
+ }
153
162
  switch (node.type) {
154
163
  case "YieldExpression":
155
164
  if (node.argument !== undefined) {
@@ -377,6 +386,8 @@ function statementListContainsAwait(statements) {
377
386
  }
378
387
  function statementContainsAwait(node) {
379
388
  switch (node.type) {
389
+ case "ClassDeclaration":
390
+ return classDefinitionContains(node, expressionContainsAwait);
380
391
  case "BlockStatement":
381
392
  return statementListContainsAwait(node.body);
382
393
  case "ExpressionStatement":
@@ -439,6 +450,11 @@ function variableDeclarationContainsAwait(node) {
439
450
  }
440
451
  function expressionContainsAwait(node) {
441
452
  switch (node.type) {
453
+ case "ClassExpression":
454
+ return classDefinitionContains(node, expressionContainsAwait);
455
+ case "NewTargetExpression":
456
+ case "Super":
457
+ return false;
442
458
  case "AwaitExpression":
443
459
  return true;
444
460
  case "YieldExpression":
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  const MUTATING_ARRAY_METHODS = new Set([
3
4
  "copyWithin",
@@ -32,6 +33,10 @@ class ASMutatingFrozenScanner {
32
33
  });
33
34
  }
34
35
  visitStatement(node) {
36
+ if (node.type === "ClassDeclaration") {
37
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
38
+ return;
39
+ }
35
40
  switch (node.type) {
36
41
  case "FunctionDeclaration":
37
42
  this.visitArrowFunction(node);
@@ -172,6 +177,10 @@ class ASMutatingFrozenScanner {
172
177
  this.visitExpression(node.argument);
173
178
  }
174
179
  visitExpression(node) {
180
+ if (node.type === "ClassExpression") {
181
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
182
+ return;
183
+ }
175
184
  switch (node.type) {
176
185
  case "YieldExpression":
177
186
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export const AS_NEEDLESS_TEMPLATE_MESSAGE = "Template literals with only one interpolation should use the value or String(value).";
3
4
  export function AS_NEEDLESS_TEMPLATE(source, options = {}) {
@@ -44,6 +45,10 @@ class ASNeedlessTemplateScanner {
44
45
  }
45
46
  }
46
47
  visitStatement(node) {
48
+ if (node.type === "ClassDeclaration") {
49
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
50
+ return;
51
+ }
47
52
  switch (node.type) {
48
53
  case "FunctionDeclaration":
49
54
  this.visitArrowFunction(node);
@@ -170,6 +175,10 @@ class ASNeedlessTemplateScanner {
170
175
  this.visitExpression(node.argument);
171
176
  }
172
177
  visitExpression(node) {
178
+ if (node.type === "ClassExpression") {
179
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
180
+ return;
181
+ }
173
182
  switch (node.type) {
174
183
  case "YieldExpression":
175
184
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  import { KNOWN_RUNTIME_GLOBALS } from "./known-globals.js";
3
4
  export function AS_SHADOW_GLOBAL(source, options = {}) {
@@ -21,6 +22,11 @@ class ASShadowGlobalScanner {
21
22
  }
22
23
  }
23
24
  visitStatement(node) {
25
+ if (node.type === "ClassDeclaration") {
26
+ this.reportIfGlobalShadow(node.id);
27
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
28
+ return;
29
+ }
24
30
  switch (node.type) {
25
31
  case "FunctionDeclaration":
26
32
  this.visitArrowFunctionExpression(node);
@@ -147,6 +153,12 @@ class ASShadowGlobalScanner {
147
153
  }
148
154
  }
149
155
  visitExpression(node) {
156
+ if (node.type === "ClassExpression") {
157
+ if (node.id !== undefined)
158
+ this.reportIfGlobalShadow(node.id);
159
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
160
+ return;
161
+ }
150
162
  switch (node.type) {
151
163
  case "YieldExpression":
152
164
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  const MESSAGE = "Unbounded loop or generator source has no static exit with break, return, or throw.";
3
4
  export function AS_UNBOUNDED_LOOP(source, options = {}) {
@@ -20,6 +21,10 @@ class ASUnboundedLoopScanner {
20
21
  }
21
22
  }
22
23
  visitStatement(node) {
24
+ if (node.type === "ClassDeclaration") {
25
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
26
+ return;
27
+ }
23
28
  switch (node.type) {
24
29
  case "FunctionDeclaration":
25
30
  this.visitArrowFunction(node);
@@ -159,6 +164,10 @@ class ASUnboundedLoopScanner {
159
164
  this.visitExpression(node.argument);
160
165
  }
161
166
  visitExpression(node) {
167
+ if (node.type === "ClassExpression") {
168
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
169
+ return;
170
+ }
162
171
  switch (node.type) {
163
172
  case "YieldExpression":
164
173
  if (node.argument !== undefined) {
@@ -330,6 +339,8 @@ function isTrueLiteral(node) {
330
339
  }
331
340
  function bodyHasExit(node, exitingLabels, allowUnlabeledBreak) {
332
341
  switch (node.type) {
342
+ case "ClassDeclaration":
343
+ return false;
333
344
  case "BlockStatement":
334
345
  return node.body.some((statement) => bodyHasExit(statement, exitingLabels, allowUnlabeledBreak));
335
346
  case "IfStatement":
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export function AS_UNREACHABLE(source, options = {}) {
3
4
  return new ASUnreachableScanner(options.filename ?? "<input>").scan(source);
@@ -30,6 +31,10 @@ class ASUnreachableScanner {
30
31
  return terminated;
31
32
  }
32
33
  visitStatement(node) {
34
+ if (node.type === "ClassDeclaration") {
35
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
36
+ return false;
37
+ }
33
38
  switch (node.type) {
34
39
  case "FunctionDeclaration":
35
40
  this.visitArrowFunction(node);
@@ -157,6 +162,10 @@ class ASUnreachableScanner {
157
162
  this.visitExpression(node.argument);
158
163
  }
159
164
  visitExpression(node) {
165
+ if (node.type === "ClassExpression") {
166
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
167
+ return;
168
+ }
160
169
  switch (node.type) {
161
170
  case "YieldExpression":
162
171
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export function AS_UNUSED_IMPORT(source, options = {}) {
3
4
  const filename = options.filename ?? "<input>";
@@ -54,6 +55,10 @@ class ASUnusedImportScanner {
54
55
  });
55
56
  }
56
57
  visitStatement(node) {
58
+ if (node.type === "ClassDeclaration") {
59
+ this.visitClass(node);
60
+ return;
61
+ }
57
62
  switch (node.type) {
58
63
  case "FunctionDeclaration":
59
64
  this.visitArrowFunction(node);
@@ -183,7 +188,16 @@ class ASUnusedImportScanner {
183
188
  this.visitExpression(node.init);
184
189
  }
185
190
  }
191
+ visitClass(node) {
192
+ this.withScope(node.id === undefined ? [] : [{ kind: "const", name: node.id.name }], () => {
193
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
194
+ });
195
+ }
186
196
  visitExpression(node) {
197
+ if (node.type === "ClassExpression") {
198
+ this.visitClass(node);
199
+ return;
200
+ }
187
201
  switch (node.type) {
188
202
  case "YieldExpression":
189
203
  if (node.argument !== undefined) {
@@ -426,7 +440,7 @@ class ASUnusedImportScanner {
426
440
  bindings.push(...this.collectImportBindings(statement));
427
441
  continue;
428
442
  }
429
- if (statement.type === "FunctionDeclaration") {
443
+ if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration") {
430
444
  bindings.push({ kind: "let", name: statement.id.name });
431
445
  continue;
432
446
  }
@@ -443,7 +457,7 @@ class ASUnusedImportScanner {
443
457
  collectBlockBindings(body) {
444
458
  const bindings = [];
445
459
  for (const statement of body) {
446
- if (statement.type === "FunctionDeclaration") {
460
+ if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration") {
447
461
  bindings.push({ kind: "let", name: statement.id.name });
448
462
  }
449
463
  if (statement.type === "VariableDeclaration") {
@@ -214,7 +214,6 @@ class AS001Scanner {
214
214
  }
215
215
  reportForbiddenIdentifier(token) {
216
216
  switch (token.value) {
217
- case "class":
218
217
  case "eval":
219
218
  case "Function":
220
219
  case "with":
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  import { KNOWN_RUNTIME_GLOBALS } from "./known-globals.js";
3
4
  import { hoistedVarDeclarations } from "../../parse/bindings.js";
@@ -26,6 +27,10 @@ class AS003Scanner {
26
27
  });
27
28
  }
28
29
  visitStatement(node) {
30
+ if (node.type === "ClassDeclaration") {
31
+ this.visitClass(node);
32
+ return;
33
+ }
29
34
  switch (node.type) {
30
35
  case "FunctionDeclaration":
31
36
  this.visitArrowFunction(node);
@@ -185,7 +190,16 @@ class AS003Scanner {
185
190
  this.visitExpression(node.init);
186
191
  }
187
192
  }
193
+ visitClass(node) {
194
+ this.withScope(node.id === undefined ? [] : [{ kind: "const", name: node.id.name }], () => {
195
+ visitClassElements(node, expression => this.visitExpression(expression), block => this.visitBlock(block, true));
196
+ });
197
+ }
188
198
  visitExpression(node) {
199
+ if (node.type === "ClassExpression") {
200
+ this.visitClass(node);
201
+ return;
202
+ }
189
203
  switch (node.type) {
190
204
  case "YieldExpression":
191
205
  if (node.argument !== undefined) {
@@ -487,7 +501,7 @@ class AS003Scanner {
487
501
  bindings.push(...this.collectImportBindings(statement));
488
502
  continue;
489
503
  }
490
- if (statement.type === "FunctionDeclaration") {
504
+ if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration") {
491
505
  bindings.push({ kind: "let", name: statement.id.name });
492
506
  continue;
493
507
  }
@@ -504,7 +518,7 @@ class AS003Scanner {
504
518
  collectBlockBindings(body) {
505
519
  const bindings = [];
506
520
  for (const statement of body) {
507
- if (statement.type === "FunctionDeclaration") {
521
+ if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration") {
508
522
  bindings.push({ kind: "let", name: statement.id.name });
509
523
  }
510
524
  if (statement.type === "VariableDeclaration" && statement.kind !== "var") {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  import { hoistedVarDeclarations } from "../../parse/bindings.js";
3
4
  export function AS006_007(source, options = {}) {
@@ -26,6 +27,10 @@ class AS006007Scanner {
26
27
  });
27
28
  }
28
29
  visitStatement(node) {
30
+ if (node.type === "ClassDeclaration") {
31
+ this.visitClass(node);
32
+ return;
33
+ }
29
34
  switch (node.type) {
30
35
  case "FunctionDeclaration":
31
36
  this.visitArrowFunction(node);
@@ -186,7 +191,16 @@ class AS006007Scanner {
186
191
  });
187
192
  }
188
193
  }
194
+ visitClass(node) {
195
+ this.withScope(node.id === undefined ? [] : [this.createBinding(node.id, "param")], () => {
196
+ visitClassElements(node, expression => this.visitExpression(expression), block => this.visitBlock(block, true));
197
+ });
198
+ }
189
199
  visitExpression(node) {
200
+ if (node.type === "ClassExpression") {
201
+ this.visitClass(node);
202
+ return;
203
+ }
190
204
  switch (node.type) {
191
205
  case "YieldExpression":
192
206
  if (node.argument !== undefined) {
@@ -482,7 +496,7 @@ class AS006007Scanner {
482
496
  bindings.push(...this.collectImportBindings(statement));
483
497
  continue;
484
498
  }
485
- if (statement.type === "FunctionDeclaration") {
499
+ if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration") {
486
500
  bindings.push(this.createBinding(statement.id, "let"));
487
501
  continue;
488
502
  }
@@ -499,7 +513,7 @@ class AS006007Scanner {
499
513
  collectBlockBindings(body) {
500
514
  const bindings = [];
501
515
  for (const statement of body) {
502
- if (statement.type === "FunctionDeclaration") {
516
+ if (statement.type === "FunctionDeclaration" || statement.type === "ClassDeclaration") {
503
517
  bindings.push(this.createBinding(statement.id, "let"));
504
518
  }
505
519
  if (statement.type === "VariableDeclaration" && statement.kind !== "var") {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  const MESSAGE = "Async arrow returns a host call without awaiting it. Add 'await' or document that this function intentionally returns a Promise.";
3
4
  export function AS009(source, options = {}) {
@@ -27,6 +28,10 @@ class AS009Scanner {
27
28
  }
28
29
  }
29
30
  visitStatement(node) {
31
+ if (node.type === "ClassDeclaration") {
32
+ this.visitClass(node);
33
+ return;
34
+ }
30
35
  switch (node.type) {
31
36
  case "FunctionDeclaration":
32
37
  this.visitArrowFunction(node);
@@ -158,7 +163,19 @@ class AS009Scanner {
158
163
  this.visitExpression(node.init);
159
164
  }
160
165
  }
166
+ visitClass(node) {
167
+ const scope = new Map();
168
+ if (node.id !== undefined)
169
+ scope.set(node.id.name, "local");
170
+ this.withScope(scope, () => {
171
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
172
+ });
173
+ }
161
174
  visitExpression(node) {
175
+ if (node.type === "ClassExpression") {
176
+ this.visitClass(node);
177
+ return;
178
+ }
162
179
  switch (node.type) {
163
180
  case "YieldExpression":
164
181
  if (node.argument !== undefined) {
@@ -395,7 +412,7 @@ class AS009Scanner {
395
412
  return undefined;
396
413
  }
397
414
  collectModuleBindings(node) {
398
- const scope = new Map();
415
+ const scope = this.collectBlockBindings(node.body);
399
416
  for (const statement of node.body) {
400
417
  if (statement.type === "ImportDeclaration") {
401
418
  this.mergeScope(scope, this.collectImportBindings(statement));
@@ -406,6 +423,8 @@ class AS009Scanner {
406
423
  collectBlockBindings(body) {
407
424
  const scope = new Map();
408
425
  for (const statement of body) {
426
+ if (statement.type === "ClassDeclaration")
427
+ scope.set(statement.id.name, "local");
409
428
  if (statement.type === "VariableDeclaration") {
410
429
  for (const declarator of statement.declarations) {
411
430
  this.collectBindingNamesFromPattern(declarator.id, scope);
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export function AS010(source, options = {}) {
3
4
  return new AS010Scanner(options.filename ?? "<input>").scan(source);
@@ -37,6 +38,10 @@ class AS010Scanner {
37
38
  }
38
39
  }
39
40
  visitStatement(node) {
41
+ if (node.type === "ClassDeclaration") {
42
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
43
+ return;
44
+ }
40
45
  switch (node.type) {
41
46
  case "FunctionDeclaration":
42
47
  this.visitArrowFunction(node);
@@ -178,6 +183,10 @@ class AS010Scanner {
178
183
  });
179
184
  }
180
185
  visitExpression(node) {
186
+ if (node.type === "ClassExpression") {
187
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
188
+ return;
189
+ }
181
190
  switch (node.type) {
182
191
  case "YieldExpression":
183
192
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  const FORBIDDEN_PROPERTY_NAMES = new Set(["__proto__", "prototype", "constructor"]);
3
4
  const MESSAGE = "Property access to '__proto__', 'prototype', and 'constructor' is not allowed.";
@@ -20,6 +21,10 @@ class AS011Scanner {
20
21
  }
21
22
  }
22
23
  visitStatement(node) {
24
+ if (node.type === "ClassDeclaration") {
25
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
26
+ return;
27
+ }
23
28
  switch (node.type) {
24
29
  case "FunctionDeclaration":
25
30
  this.visitArrowFunction(node);
@@ -140,6 +145,10 @@ class AS011Scanner {
140
145
  this.visitExpression(node.argument);
141
146
  }
142
147
  visitExpression(node) {
148
+ if (node.type === "ClassExpression") {
149
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
150
+ return;
151
+ }
143
152
  switch (node.type) {
144
153
  case "YieldExpression":
145
154
  if (node.argument !== undefined) {
@@ -1,3 +1,4 @@
1
+ import { visitClassElements } from "../class-elements.js";
1
2
  import { parseModule } from "../../parse/parser.js";
2
3
  export function AS015(source, options = {}) {
3
4
  return new AS015Scanner(options.filename ?? "<input>").scan(source);
@@ -18,6 +19,10 @@ class AS015Scanner {
18
19
  }
19
20
  }
20
21
  visitStatement(node) {
22
+ if (node.type === "ClassDeclaration") {
23
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
24
+ return;
25
+ }
21
26
  switch (node.type) {
22
27
  case "FunctionDeclaration":
23
28
  this.visitArrowFunction(node);
@@ -138,6 +143,10 @@ class AS015Scanner {
138
143
  this.visitExpression(node.argument);
139
144
  }
140
145
  visitExpression(node) {
146
+ if (node.type === "ClassExpression") {
147
+ visitClassElements(node, expression => this.visitExpression(expression), statement => this.visitStatement(statement));
148
+ return;
149
+ }
141
150
  switch (node.type) {
142
151
  case "YieldExpression":
143
152
  if (node.argument !== undefined) {
@@ -1,7 +1,7 @@
1
- import type { FunctionNode } from "./parser.js";
1
+ import type { ClassNode, FunctionNode } from "./parser.js";
2
2
  export type FunctionSource = {
3
3
  readonly text: string;
4
4
  readonly start: number;
5
5
  readonly end: number;
6
6
  };
7
- export declare const functionSources: WeakMap<FunctionNode, FunctionSource>;
7
+ export declare const functionSources: WeakMap<FunctionNode | ClassNode, FunctionSource>;