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.
- package/dist/index.js +7473 -6816
- 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-KMTTD3BL.js → chunk-4VT2M7WL.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-RU2BCN4G.js → chunk-WBWD7ZCM.js} +8215 -7599
- 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 +99 -30
- package/packages/safe-js/dist/interp/methods/function.d.ts +1 -1
- package/packages/safe-js/dist/interp/methods/function.js +33 -16
- package/packages/safe-js/dist/interp/object-model.js +25 -11
- 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-RU2BCN4G.js.map +0 -7
- /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") {
|
|
@@ -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>;
|