poe-code 14.0.64 → 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.
- package/dist/index.js +7442 -6809
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-js/dist/chunks/{chunk-3EXDJDQM.js → chunk-4VT2M7WL.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-XO7B4P27.js → chunk-WBWD7ZCM.js} +8189 -7596
- package/packages/safe-js/dist/chunks/chunk-WBWD7ZCM.js.map +7 -0
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/index.js.map +1 -1
- package/packages/safe-js/dist/interp/async.d.ts +13 -2
- package/packages/safe-js/dist/interp/async.js +16 -6
- package/packages/safe-js/dist/interp/classes.d.ts +4 -0
- package/packages/safe-js/dist/interp/classes.js +176 -0
- package/packages/safe-js/dist/interp/exceptions.js +4 -1
- package/packages/safe-js/dist/interp/globals/object-array.d.ts +2 -1
- package/packages/safe-js/dist/interp/globals/object-array.js +1 -1
- package/packages/safe-js/dist/interp/globals/object.js +10 -2
- package/packages/safe-js/dist/interp/globals/primitives.js +8 -3
- package/packages/safe-js/dist/interp/interpreter.d.ts +1 -1
- package/packages/safe-js/dist/interp/interpreter.js +95 -27
- package/packages/safe-js/dist/interp/methods/function.d.ts +1 -1
- package/packages/safe-js/dist/interp/methods/function.js +1 -1
- package/packages/safe-js/dist/interp/patterns.d.ts +1 -1
- package/packages/safe-js/dist/interp/patterns.js +1 -1
- package/packages/safe-js/dist/interp/values.d.ts +2 -1
- package/packages/safe-js/dist/lint/class-elements.d.ts +5 -0
- package/packages/safe-js/dist/lint/class-elements.js +20 -0
- package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +16 -0
- package/packages/safe-js/dist/lint/rules/AS-destructure-null-default.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-export-import-meta.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-floating-promise.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-frontmatter-field-unused.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-jsdoc-type.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-large-literal.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-missing-async.js +16 -0
- package/packages/safe-js/dist/lint/rules/AS-mutating-frozen.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-needless-template.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-shadow-global.js +12 -0
- package/packages/safe-js/dist/lint/rules/AS-unbounded-loop.js +11 -0
- package/packages/safe-js/dist/lint/rules/AS-unreachable.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS-unused-import.js +16 -2
- package/packages/safe-js/dist/lint/rules/AS001.js +0 -1
- package/packages/safe-js/dist/lint/rules/AS003.js +16 -2
- package/packages/safe-js/dist/lint/rules/AS006-007.js +16 -2
- package/packages/safe-js/dist/lint/rules/AS009.js +20 -1
- package/packages/safe-js/dist/lint/rules/AS010.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS011.js +9 -0
- package/packages/safe-js/dist/lint/rules/AS015.js +9 -0
- package/packages/safe-js/dist/parse/function-source.d.ts +2 -2
- package/packages/safe-js/dist/parse/parser.d.ts +42 -2
- package/packages/safe-js/dist/parse/parser.js +180 -36
- package/packages/safe-js/dist/parse/tokenizer.js +3 -0
- package/packages/safe-js/dist/parse.d.ts +1 -1
- package/packages/safe-js/dist/chunks/chunk-XO7B4P27.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-3EXDJDQM.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
|
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") {
|
|
@@ -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 =
|
|
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>;
|
|
@@ -247,6 +247,46 @@ export type FunctionExpression = BaseNode & {
|
|
|
247
247
|
method?: true;
|
|
248
248
|
params: ArrowFunctionExpression["params"];
|
|
249
249
|
};
|
|
250
|
+
export type ClassElement = (BaseNode & {
|
|
251
|
+
type: "MethodDefinition";
|
|
252
|
+
computed: boolean;
|
|
253
|
+
key: Expression;
|
|
254
|
+
kind: "constructor" | "method";
|
|
255
|
+
static: boolean;
|
|
256
|
+
value: FunctionExpression;
|
|
257
|
+
}) | (BaseNode & {
|
|
258
|
+
type: "PropertyDefinition";
|
|
259
|
+
computed: boolean;
|
|
260
|
+
key: Expression;
|
|
261
|
+
static: boolean;
|
|
262
|
+
value?: Expression;
|
|
263
|
+
}) | (BaseNode & {
|
|
264
|
+
type: "StaticBlock";
|
|
265
|
+
body: BlockStatement;
|
|
266
|
+
});
|
|
267
|
+
export type ClassBody = BaseNode & {
|
|
268
|
+
type: "ClassBody";
|
|
269
|
+
body: ClassElement[];
|
|
270
|
+
};
|
|
271
|
+
export type ClassDeclaration = BaseNode & {
|
|
272
|
+
type: "ClassDeclaration";
|
|
273
|
+
id: Identifier;
|
|
274
|
+
superClass?: Expression;
|
|
275
|
+
body: ClassBody;
|
|
276
|
+
};
|
|
277
|
+
export type ClassExpression = BaseNode & {
|
|
278
|
+
type: "ClassExpression";
|
|
279
|
+
id?: Identifier;
|
|
280
|
+
superClass?: Expression;
|
|
281
|
+
body: ClassBody;
|
|
282
|
+
};
|
|
283
|
+
export type ClassNode = ClassDeclaration | ClassExpression;
|
|
284
|
+
export type SuperExpression = BaseNode & {
|
|
285
|
+
type: "Super";
|
|
286
|
+
};
|
|
287
|
+
export type NewTargetExpression = BaseNode & {
|
|
288
|
+
type: "NewTargetExpression";
|
|
289
|
+
};
|
|
250
290
|
export type IfStatement = BaseNode & {
|
|
251
291
|
type: "IfStatement";
|
|
252
292
|
test: Expression;
|
|
@@ -339,7 +379,7 @@ export type Module = BaseNode & {
|
|
|
339
379
|
type: "Module";
|
|
340
380
|
body: Statement[];
|
|
341
381
|
};
|
|
342
|
-
export type Statement = BlockStatement | BreakStatement | DoWhileStatement | ExportDefaultDeclaration | ExportNamedDeclaration | ImportDeclaration | TryStatement | ContinueStatement | EmptyStatement | ExpressionStatement | FunctionDeclaration | ForInStatement | ForOfStatement | ForStatement | IfStatement | ReturnStatement | SwitchStatement | ThrowStatement | VariableDeclaration | WhileStatement;
|
|
382
|
+
export type Statement = BlockStatement | ClassDeclaration | BreakStatement | DoWhileStatement | ExportDefaultDeclaration | ExportNamedDeclaration | ImportDeclaration | TryStatement | ContinueStatement | EmptyStatement | ExpressionStatement | FunctionDeclaration | ForInStatement | ForOfStatement | ForStatement | IfStatement | ReturnStatement | SwitchStatement | ThrowStatement | VariableDeclaration | WhileStatement;
|
|
343
383
|
export type ArrowFunctionExpression = BaseNode & {
|
|
344
384
|
type: "ArrowFunctionExpression";
|
|
345
385
|
async: boolean;
|
|
@@ -348,7 +388,7 @@ export type ArrowFunctionExpression = BaseNode & {
|
|
|
348
388
|
params: Array<AssignmentPattern | ArrayPattern | Identifier | ObjectPattern | RestElement>;
|
|
349
389
|
};
|
|
350
390
|
export type FunctionNode = ArrowFunctionExpression | FunctionDeclaration | FunctionExpression;
|
|
351
|
-
export type Expression = ArrowFunctionExpression | AssignmentExpression | ArrayExpression | AwaitExpression | BinaryExpression | BooleanLiteral | CallExpression | ConditionalExpression | FunctionExpression | Identifier | LogicalExpression | MemberExpression | MetaProperty | NewExpression | NullLiteral | NumericLiteral | ObjectExpression | RegexLiteral | SequenceExpression | StringLiteral | TaggedTemplateExpression | TemplateLiteral | ThisExpression | UnaryExpression | UpdateExpression | UndefinedLiteral | YieldExpression;
|
|
391
|
+
export type Expression = ArrowFunctionExpression | AssignmentExpression | ArrayExpression | AwaitExpression | BinaryExpression | BooleanLiteral | CallExpression | ConditionalExpression | ClassExpression | FunctionExpression | Identifier | LogicalExpression | MemberExpression | MetaProperty | NewExpression | NewTargetExpression | NullLiteral | NumericLiteral | ObjectExpression | RegexLiteral | SequenceExpression | StringLiteral | SuperExpression | TaggedTemplateExpression | TemplateLiteral | ThisExpression | UnaryExpression | UpdateExpression | UndefinedLiteral | YieldExpression;
|
|
352
392
|
export type ParseResult = Expression | Statement;
|
|
353
393
|
export declare function parse(source: string, filename?: string, owner?: CompileOwner): ParseResult;
|
|
354
394
|
export declare function parseModule(source: string, filename?: string, owner?: CompileOwner): Module;
|