poe-code 4.0.57 → 4.0.59

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 (51) hide show
  1. package/dist/cli/program.js +2 -1
  2. package/dist/cli/program.js.map +1 -1
  3. package/dist/index.js +1755 -2241
  4. package/dist/index.js.map +4 -4
  5. package/dist/metafile.json +1 -1
  6. package/package.json +1 -1
  7. package/packages/safejs/dist/graph-depth.js +4 -0
  8. package/packages/safejs/dist/interp/arguments.d.ts +10 -0
  9. package/packages/safejs/dist/interp/arguments.js +44 -0
  10. package/packages/safejs/dist/interp/async.js +3 -1
  11. package/packages/safejs/dist/interp/values.d.ts +1 -1
  12. package/packages/safejs/dist/interp/values.js +27 -2
  13. package/packages/safejs/dist/lint/index.js +0 -4
  14. package/packages/safejs/dist/lint/rules/AS-async-not-needed.d.ts +1 -1
  15. package/packages/safejs/dist/lint/rules/AS-async-not-needed.js +15 -3
  16. package/packages/safejs/dist/lint/rules/AS-await-non-promise.js +10 -0
  17. package/packages/safejs/dist/lint/rules/AS-destructure-null-default.js +9 -0
  18. package/packages/safejs/dist/lint/rules/AS-export-import-meta.js +17 -0
  19. package/packages/safejs/dist/lint/rules/AS-floating-promise.js +23 -2
  20. package/packages/safejs/dist/lint/rules/AS-frontmatter-field-unused.js +9 -0
  21. package/packages/safejs/dist/lint/rules/AS-jsdoc-type.js +10 -0
  22. package/packages/safejs/dist/lint/rules/AS-large-literal.js +9 -0
  23. package/packages/safejs/dist/lint/rules/AS-missing-async.d.ts +1 -1
  24. package/packages/safejs/dist/lint/rules/AS-missing-async.js +9 -1
  25. package/packages/safejs/dist/lint/rules/AS-mutating-frozen.js +9 -0
  26. package/packages/safejs/dist/lint/rules/AS-needless-template.js +9 -0
  27. package/packages/safejs/dist/lint/rules/AS-shadow-global.js +12 -0
  28. package/packages/safejs/dist/lint/rules/AS-unbounded-loop.js +9 -0
  29. package/packages/safejs/dist/lint/rules/AS-unreachable.js +9 -1
  30. package/packages/safejs/dist/lint/rules/AS-unused-import.js +22 -0
  31. package/packages/safejs/dist/lint/rules/AS001.js +0 -6
  32. package/packages/safejs/dist/lint/rules/AS003.js +22 -0
  33. package/packages/safejs/dist/lint/rules/AS006-007.js +19 -0
  34. package/packages/safejs/dist/lint/rules/AS008.js +9 -0
  35. package/packages/safejs/dist/lint/rules/AS009.js +9 -0
  36. package/packages/safejs/dist/lint/rules/AS010.js +9 -0
  37. package/packages/safejs/dist/lint/rules/AS011.js +9 -0
  38. package/packages/safejs/dist/lint/rules/AS015.js +9 -0
  39. package/packages/safejs/dist/parse/parser.d.ts +1 -0
  40. package/packages/safejs/dist/parse/parser.js +4 -7
  41. package/packages/safejs/dist/snapshot/arguments.d.ts +17 -0
  42. package/packages/safejs/dist/snapshot/arguments.js +34 -0
  43. package/packages/safejs/dist/snapshot/dump-format.js +15 -3
  44. package/packages/safejs/dist/snapshot/restore.js +27 -1
  45. package/packages/safejs/dist/snapshot/serialize.d.ts +2 -1
  46. package/packages/safejs/dist/snapshot/serialize.js +20 -10
  47. package/packages/safejs/dist/snapshot/validation.js +50 -1
  48. package/packages/safejs/dist/lint/rules/AS002.d.ts +0 -13
  49. package/packages/safejs/dist/lint/rules/AS002.js +0 -525
  50. package/packages/safejs/dist/lint/rules/AS012.d.ts +0 -13
  51. package/packages/safejs/dist/lint/rules/AS012.js +0 -384
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-code",
3
- "version": "4.0.57",
3
+ "version": "4.0.59",
4
4
  "description": "CLI tool to configure Poe API for developer workflows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,5 +1,6 @@
1
1
  import { replaceErrorStack } from "./error/shape.js";
2
2
  import { SandboxError } from "./interp/budget.js";
3
+ import { getSandboxArgumentEntries, isSandboxArguments } from "./interp/arguments.js";
3
4
  export const MAX_DATA_DEPTH = 1_024;
4
5
  export class SnapshotBudgetError extends Error {
5
6
  code = "budgetExceeded";
@@ -60,6 +61,9 @@ function walkGraphDepth(root, rootPath, assertDepth) {
60
61
  }
61
62
  }
62
63
  function graphEntries(value) {
64
+ if (isSandboxArguments(value)) {
65
+ return getSandboxArgumentEntries(value).map(([key, entry]) => [`.${key}`, entry]);
66
+ }
63
67
  if (Array.isArray(value))
64
68
  return value.map((entry, index) => [`[${index}]`, entry]);
65
69
  if (value instanceof Map) {
@@ -0,0 +1,10 @@
1
+ import type { SandboxObject, SandboxValue } from "./values.js";
2
+ declare const sandboxArgumentsBrand: unique symbol;
3
+ export type SandboxArguments = SandboxObject & {
4
+ readonly [sandboxArgumentsBrand]: true;
5
+ };
6
+ export declare function createSandboxArguments(values: readonly SandboxValue[]): SandboxArguments;
7
+ export declare function isSandboxArguments(value: unknown): value is SandboxArguments;
8
+ export declare function getSandboxArgumentEntries(value: SandboxObject): Array<[string, SandboxValue]>;
9
+ export declare function copySandboxArgumentProperties(source: SandboxObject, target: object, copyValue: (value: SandboxValue, key: string) => unknown): void;
10
+ export {};
@@ -0,0 +1,44 @@
1
+ const sandboxArgumentsBrand = Symbol("SandboxArguments");
2
+ export function createSandboxArguments(values) {
3
+ const result = (function () {
4
+ return arguments;
5
+ })();
6
+ for (let index = 0; index < values.length; index += 1) {
7
+ result[index] = values[index];
8
+ }
9
+ result.length = values.length;
10
+ Object.defineProperty(result, sandboxArgumentsBrand, { value: true });
11
+ return result;
12
+ }
13
+ export function isSandboxArguments(value) {
14
+ return typeof value === "object" && value !== null && Object.hasOwn(value, sandboxArgumentsBrand);
15
+ }
16
+ export function getSandboxArgumentEntries(value) {
17
+ return Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key, descriptor]) => "value" in descriptor ? [[key, descriptor.value]] : []);
18
+ }
19
+ export function copySandboxArgumentProperties(source, target, copyValue) {
20
+ const names = Object.getOwnPropertyNames(source);
21
+ if (!names.includes("length") || names.indexOf("length") > names.indexOf("callee")) {
22
+ Reflect.deleteProperty(target, "length");
23
+ }
24
+ for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(source))) {
25
+ if (!("value" in descriptor)) {
26
+ if (key !== "callee")
27
+ throw new TypeError(`Cannot copy arguments accessor '${key}'.`);
28
+ continue;
29
+ }
30
+ Object.defineProperty(target, key, { ...descriptor, value: copyValue(descriptor.value, key) });
31
+ }
32
+ const iterator = Object.getOwnPropertyDescriptor(source, Symbol.iterator);
33
+ if (iterator === undefined) {
34
+ Reflect.deleteProperty(target, Symbol.iterator);
35
+ }
36
+ else {
37
+ if (iterator.value !== Array.prototype.values) {
38
+ throw new TypeError("Cannot copy a replaced arguments iterator.");
39
+ }
40
+ Object.defineProperty(target, Symbol.iterator, iterator);
41
+ }
42
+ if (!Object.isExtensible(source))
43
+ Object.preventExtensions(target);
44
+ }
@@ -3,7 +3,7 @@ import { getBoundOtelSpan } from "../observability/otel.js";
3
3
  import { bindPattern } from "./patterns.js";
4
4
  import { resolveSandboxValue } from "./promise.js";
5
5
  import { hoistVarDeclarations } from "./var-hoist.js";
6
- import { createSandboxClosure, createSandboxGenerator, createSandboxPromise, isSandboxPromise } from "./values.js";
6
+ import { createSandboxArguments, createSandboxClosure, createSandboxGenerator, createSandboxPromise, isSandboxPromise } from "./values.js";
7
7
  export function emitResumeBreakpoint(context, breakpoint) {
8
8
  context.onYield?.({
9
9
  ...breakpoint,
@@ -154,6 +154,8 @@ async function createClosureScope(node, args, thisValue, context, evaluateNode)
154
154
  const scope = context.scope.child({}, { functionBoundary: true });
155
155
  if (node.type !== "ArrowFunctionExpression") {
156
156
  scope.declare("this", "const", thisValue);
157
+ context.budget.allocateArrayLength(args.length);
158
+ scope.declare("arguments", "let", createSandboxArguments(args));
157
159
  }
158
160
  await bindParameters(node.params, args, scope, context, evaluateNode);
159
161
  hoistVarDeclarations(node.body, scope);
@@ -1,6 +1,7 @@
1
1
  import type { Budget } from "./budget.js";
2
2
  import type { GeneratorChannel } from "./generator.js";
3
3
  import { type RegexPattern } from "./regex/parse.js";
4
+ export { createSandboxArguments, isSandboxArguments } from "./arguments.js";
4
5
  declare const sandboxClosureBrand: unique symbol;
5
6
  declare const sandboxGeneratorBrand: unique symbol;
6
7
  declare const sandboxMapBrand: unique symbol;
@@ -111,4 +112,3 @@ export declare function allocateProducedSandboxValue(value: SandboxValue, budget
111
112
  export declare function measureSandboxData(values: Iterable<unknown>): number;
112
113
  export declare function deepCopyFromSandbox(value: SandboxPromise, options?: CopyFromSandboxOptions): Promise<unknown>;
113
114
  export declare function deepCopyFromSandbox(value: SandboxValue, options?: CopyFromSandboxOptions): unknown;
114
- export {};
@@ -3,6 +3,8 @@ import { SandboxError } from "./budget.js";
3
3
  import { trackSandboxPromise } from "./promise-tracker.js";
4
4
  import { parseRegex } from "./regex/parse.js";
5
5
  import { assertSandboxDataDepth } from "../graph-depth.js";
6
+ import { copySandboxArgumentProperties, createSandboxArguments, getSandboxArgumentEntries, isSandboxArguments } from "./arguments.js";
7
+ export { createSandboxArguments, isSandboxArguments } from "./arguments.js";
6
8
  const sandboxClosureBrand = Symbol("SandboxClosure");
7
9
  const sandboxGeneratorBrand = Symbol("SandboxGenerator");
8
10
  const sandboxMapBrand = Symbol("SandboxMap");
@@ -203,7 +205,9 @@ export function measureSandboxData(values) {
203
205
  usage += value.source.length + value.flags.length;
204
206
  return;
205
207
  }
206
- const entries = Object.entries(value);
208
+ const entries = isSandboxArguments(value)
209
+ ? getSandboxArgumentEntries(value)
210
+ : Object.entries(value);
207
211
  usage += entries.length;
208
212
  for (const [key, entry] of entries) {
209
213
  usage += key.length;
@@ -302,6 +306,15 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
302
306
  }
303
307
  return copy;
304
308
  }
309
+ if (isSandboxArguments(value)) {
310
+ const existing = state.seen.get(value);
311
+ if (existing !== undefined)
312
+ return existing;
313
+ const copy = createSandboxArguments([]);
314
+ state.seen.set(value, copy);
315
+ copySandboxArgumentProperties(value, copy, (entry, key) => copyToSandbox(entry, state, joinPath(path, key), cloneSandboxCollections, depth + 1));
316
+ return copy;
317
+ }
305
318
  if (isPlainObject(value)) {
306
319
  const existing = state.seen.get(value);
307
320
  if (existing !== undefined) {
@@ -382,6 +395,15 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
382
395
  }
383
396
  return copy;
384
397
  }
398
+ if (isSandboxArguments(value)) {
399
+ const existing = state.seen.get(value);
400
+ if (existing !== undefined)
401
+ return existing;
402
+ const copy = createSandboxArguments([]);
403
+ state.seen.set(value, copy);
404
+ copySandboxArgumentProperties(value, copy, (entry, key) => copyFromSandbox(entry, state, joinPath(path, key), options, depth + 1));
405
+ return copy;
406
+ }
385
407
  if (isPlainObject(value)) {
386
408
  const existing = state.seen.get(value);
387
409
  if (existing !== undefined) {
@@ -457,7 +479,10 @@ function allocateSandboxValue(value, budget, seen) {
457
479
  return;
458
480
  }
459
481
  seen.add(value);
460
- for (const entry of Object.values(value)) {
482
+ const entries = isSandboxArguments(value)
483
+ ? getSandboxArgumentEntries(value).map(([, entry]) => entry)
484
+ : Object.values(value);
485
+ for (const entry of entries) {
461
486
  allocateSandboxValue(entry, budget, seen);
462
487
  }
463
488
  }
@@ -1,5 +1,4 @@
1
1
  import { AS001 } from "./rules/AS001.js";
2
- import { AS002 } from "./rules/AS002.js";
3
2
  import { AS003 } from "./rules/AS003.js";
4
3
  import { AS004 } from "./rules/AS004.js";
5
4
  import { AS005 } from "./rules/AS005.js";
@@ -8,7 +7,6 @@ import { AS008 } from "./rules/AS008.js";
8
7
  import { AS009 } from "./rules/AS009.js";
9
8
  import { AS010 } from "./rules/AS010.js";
10
9
  import { AS011 } from "./rules/AS011.js";
11
- import { AS012 } from "./rules/AS012.js";
12
10
  import { AS013 } from "./rules/AS013.js";
13
11
  import { AS015 } from "./rules/AS015.js";
14
12
  import { AS_ASYNC_NOT_NEEDED } from "./rules/AS-async-not-needed.js";
@@ -30,7 +28,6 @@ import { AS_UNUSED_IMPORT } from "./rules/AS-unused-import.js";
30
28
  import { collectComments, tokenize } from "../parse/tokenizer.js";
31
29
  import { parseModule } from "../parse/parser.js";
32
30
  const RULES = [
33
- AS002,
34
31
  AS003,
35
32
  AS004,
36
33
  AS005,
@@ -42,7 +39,6 @@ const RULES = [
42
39
  AS009,
43
40
  AS010,
44
41
  AS011,
45
- AS012,
46
42
  AS013,
47
43
  AS015,
48
44
  AS_IMPORT_CYCLE,
@@ -12,7 +12,7 @@ export type Diagnostic = {
12
12
  replacement: string;
13
13
  };
14
14
  };
15
- export declare const AS_ASYNC_NOT_NEEDED_MESSAGE = "Async arrow functions without await should remove the async keyword.";
15
+ export declare const AS_ASYNC_NOT_NEEDED_MESSAGE = "Async functions without await should remove the async keyword.";
16
16
  export declare function AS_ASYNC_NOT_NEEDED(source: string, options?: {
17
17
  filename?: string;
18
18
  }): Diagnostic[];
@@ -1,5 +1,5 @@
1
1
  import { parseModule } from "../../parse/parser.js";
2
- export const AS_ASYNC_NOT_NEEDED_MESSAGE = "Async arrow functions without await should remove the async keyword.";
2
+ export const AS_ASYNC_NOT_NEEDED_MESSAGE = "Async functions without await should remove the async keyword.";
3
3
  export function AS_ASYNC_NOT_NEEDED(source, options = {}) {
4
4
  return new ASAsyncNotNeededScanner(source, options.filename ?? "<input>").scan();
5
5
  }
@@ -33,6 +33,9 @@ class ASAsyncNotNeededScanner {
33
33
  }
34
34
  visitStatement(node) {
35
35
  switch (node.type) {
36
+ case "FunctionDeclaration":
37
+ this.visitFunctionExpression(node);
38
+ return;
36
39
  case "BlockStatement":
37
40
  this.visitBlockStatement(node);
38
41
  return;
@@ -73,6 +76,10 @@ class ASAsyncNotNeededScanner {
73
76
  this.visitArrowFunction(node.declaration, true);
74
77
  return;
75
78
  }
79
+ if (node.declaration.type === "FunctionExpression") {
80
+ this.visitFunctionExpression(node.declaration, true);
81
+ return;
82
+ }
76
83
  this.visitExpression(node.declaration);
77
84
  return;
78
85
  case "ImportDeclaration":
@@ -160,6 +167,11 @@ class ASAsyncNotNeededScanner {
160
167
  }
161
168
  visitExpression(node) {
162
169
  switch (node.type) {
170
+ case "YieldExpression":
171
+ if (node.argument !== undefined) {
172
+ this.visitExpression(node.argument);
173
+ }
174
+ return;
163
175
  case "ArrowFunctionExpression":
164
176
  this.visitArrowFunction(node, false);
165
177
  return;
@@ -224,8 +236,8 @@ class ASAsyncNotNeededScanner {
224
236
  }
225
237
  this.visitExpression(node.body);
226
238
  }
227
- visitFunctionExpression(node) {
228
- if (node.async && !bodyContainsAwait(node.body)) {
239
+ visitFunctionExpression(node, isDefaultExport = false) {
240
+ if (node.async && !isDefaultExport && !bodyContainsAwait(node.body)) {
229
241
  this.report(createAsyncKeywordSpan(node.span));
230
242
  }
231
243
  for (const param of node.params) {
@@ -19,6 +19,9 @@ class ASAwaitNonPromiseScanner {
19
19
  }
20
20
  visitStatement(node) {
21
21
  switch (node.type) {
22
+ case "FunctionDeclaration":
23
+ this.visitArrowFunction(node);
24
+ return;
22
25
  case "BlockStatement":
23
26
  this.visitBlockStatement(node);
24
27
  return;
@@ -135,6 +138,12 @@ class ASAwaitNonPromiseScanner {
135
138
  }
136
139
  visitExpression(node) {
137
140
  switch (node.type) {
141
+ case "YieldExpression":
142
+ if (node.argument !== undefined) {
143
+ this.visitExpression(node.argument);
144
+ }
145
+ return;
146
+ case "FunctionExpression":
138
147
  case "ArrowFunctionExpression":
139
148
  this.visitArrowFunction(node);
140
149
  return;
@@ -274,6 +283,7 @@ class ASAwaitNonPromiseScanner {
274
283
  }
275
284
  function isKnownNonPromiseExpression(node) {
276
285
  switch (node.type) {
286
+ case "FunctionExpression":
277
287
  case "ArrowFunctionExpression":
278
288
  case "ArrayExpression":
279
289
  case "BinaryExpression":
@@ -21,6 +21,9 @@ class ASDestructureNullDefaultScanner {
21
21
  }
22
22
  visitStatement(node) {
23
23
  switch (node.type) {
24
+ case "FunctionDeclaration":
25
+ this.visitArrowFunction(node);
26
+ return;
24
27
  case "BlockStatement":
25
28
  this.visitBlockStatement(node);
26
29
  return;
@@ -145,6 +148,12 @@ class ASDestructureNullDefaultScanner {
145
148
  }
146
149
  visitExpression(node) {
147
150
  switch (node.type) {
151
+ case "YieldExpression":
152
+ if (node.argument !== undefined) {
153
+ this.visitExpression(node.argument);
154
+ }
155
+ return;
156
+ case "FunctionExpression":
148
157
  case "ArrowFunctionExpression":
149
158
  this.visitArrowFunction(node);
150
159
  return;
@@ -36,6 +36,12 @@ class Scanner {
36
36
  }
37
37
  visitStatement(node) {
38
38
  switch (node.type) {
39
+ case "FunctionDeclaration":
40
+ for (const param of node.params) {
41
+ this.visitAssignmentTarget(param);
42
+ }
43
+ this.visitStatement(node.body);
44
+ return;
39
45
  case "ExportNamedDeclaration":
40
46
  this.visitExportNamedDeclaration(node.declaration);
41
47
  return;
@@ -171,7 +177,15 @@ class Scanner {
171
177
  }
172
178
  visitExpression(node) {
173
179
  switch (node.type) {
180
+ case "YieldExpression":
181
+ if (node.argument !== undefined) {
182
+ this.visitExpression(node.argument);
183
+ }
184
+ return;
174
185
  case "ArrowFunctionExpression":
186
+ for (const param of node.params) {
187
+ this.visitAssignmentTarget(param);
188
+ }
175
189
  if (node.body.type === "BlockStatement") {
176
190
  this.visitStatement(node.body);
177
191
  }
@@ -180,6 +194,9 @@ class Scanner {
180
194
  }
181
195
  return;
182
196
  case "FunctionExpression":
197
+ for (const param of node.params) {
198
+ this.visitAssignmentTarget(param);
199
+ }
183
200
  this.visitStatement(node.body);
184
201
  return;
185
202
  case "AwaitExpression":
@@ -29,6 +29,9 @@ class ASFloatingPromiseScanner {
29
29
  }
30
30
  visitStatement(node) {
31
31
  switch (node.type) {
32
+ case "FunctionDeclaration":
33
+ this.visitArrowFunction(node);
34
+ return;
32
35
  case "BlockStatement":
33
36
  this.visitBlockStatement(node);
34
37
  return;
@@ -161,6 +164,12 @@ class ASFloatingPromiseScanner {
161
164
  }
162
165
  visitExpression(node) {
163
166
  switch (node.type) {
167
+ case "YieldExpression":
168
+ if (node.argument !== undefined) {
169
+ this.visitExpression(node.argument);
170
+ }
171
+ return;
172
+ case "FunctionExpression":
164
173
  case "ArrowFunctionExpression":
165
174
  this.visitArrowFunction(node);
166
175
  return;
@@ -369,6 +378,7 @@ class ASFloatingPromiseScanner {
369
378
  this.reportUnhandledLikelyPromiseStatementExpression(node.alternate);
370
379
  return;
371
380
  case "CallExpression":
381
+ case "FunctionExpression":
372
382
  case "ArrowFunctionExpression":
373
383
  case "AwaitExpression":
374
384
  case "ArrayExpression":
@@ -481,6 +491,11 @@ class ASFloatingPromiseScanner {
481
491
  }
482
492
  collectBlockBindings(statements) {
483
493
  return statements.flatMap((statement) => {
494
+ if (statement.type === "FunctionDeclaration") {
495
+ return [
496
+ { async: statement.async && !statement.generator, kind: "local", name: statement.id.name }
497
+ ];
498
+ }
484
499
  if (statement.type === "VariableDeclaration") {
485
500
  return this.collectDeclarationBindings(statement);
486
501
  }
@@ -492,7 +507,9 @@ class ASFloatingPromiseScanner {
492
507
  }
493
508
  collectDeclarationBindings(node) {
494
509
  return node.declarations.flatMap((declarator) => this.collectDeclaratorBindings(declarator).map((name) => ({
495
- async: declarator.init?.type === "ArrowFunctionExpression" && declarator.init.async,
510
+ async: (declarator.init?.type === "ArrowFunctionExpression" ||
511
+ (declarator.init?.type === "FunctionExpression" && !declarator.init.generator)) &&
512
+ declarator.init.async,
496
513
  kind: "local",
497
514
  name
498
515
  })));
@@ -501,11 +518,15 @@ class ASFloatingPromiseScanner {
501
518
  return this.collectPatternBindingNames(node.id);
502
519
  }
503
520
  collectArrowFunctionBindings(node) {
504
- return node.params.flatMap((param) => this.collectParameterBindingNames(param).map((name) => ({
521
+ const bindings = node.params.flatMap((param) => this.collectParameterBindingNames(param).map((name) => ({
505
522
  async: false,
506
523
  kind: "local",
507
524
  name
508
525
  })));
526
+ if (node.type === "FunctionExpression" && node.id !== undefined) {
527
+ bindings.unshift({ async: node.async && !node.generator, kind: "local", name: node.id.name });
528
+ }
529
+ return bindings;
509
530
  }
510
531
  collectPatternBindings(node) {
511
532
  return this.collectPatternBindingNames(node).map((name) => ({
@@ -35,6 +35,9 @@ class ASFrontmatterFieldUnusedScanner {
35
35
  }
36
36
  visitStatement(node) {
37
37
  switch (node.type) {
38
+ case "FunctionDeclaration":
39
+ this.visitArrowFunction(node);
40
+ return;
38
41
  case "BlockStatement":
39
42
  this.visitBlockStatement(node);
40
43
  return;
@@ -160,6 +163,12 @@ class ASFrontmatterFieldUnusedScanner {
160
163
  }
161
164
  visitExpression(node) {
162
165
  switch (node.type) {
166
+ case "YieldExpression":
167
+ if (node.argument !== undefined) {
168
+ this.visitExpression(node.argument);
169
+ }
170
+ return;
171
+ case "FunctionExpression":
163
172
  case "ArrowFunctionExpression":
164
173
  this.visitArrowFunction(node);
165
174
  return;
@@ -28,6 +28,9 @@ class ASJsdocTypeScanner {
28
28
  }
29
29
  visitStatement(node) {
30
30
  switch (node.type) {
31
+ case "FunctionDeclaration":
32
+ this.visitArrowFunction(node);
33
+ return;
31
34
  case "BlockStatement":
32
35
  this.visitBlockStatement(node);
33
36
  return;
@@ -164,6 +167,12 @@ class ASJsdocTypeScanner {
164
167
  }
165
168
  visitExpression(node) {
166
169
  switch (node.type) {
170
+ case "YieldExpression":
171
+ if (node.argument !== undefined) {
172
+ this.visitExpression(node.argument);
173
+ }
174
+ return;
175
+ case "FunctionExpression":
167
176
  case "ArrowFunctionExpression":
168
177
  this.visitArrowFunction(node);
169
178
  return;
@@ -632,6 +641,7 @@ function inferExpressionKind(expression) {
632
641
  return "boolean";
633
642
  }
634
643
  return undefined;
644
+ case "FunctionExpression":
635
645
  case "ArrowFunctionExpression":
636
646
  case "AssignmentExpression":
637
647
  case "AwaitExpression":
@@ -22,6 +22,9 @@ class ASLargeLiteralScanner {
22
22
  }
23
23
  visitStatement(node) {
24
24
  switch (node.type) {
25
+ case "FunctionDeclaration":
26
+ this.visitArrowFunction(node);
27
+ return;
25
28
  case "BlockStatement":
26
29
  this.visitBlockStatement(node);
27
30
  return;
@@ -142,6 +145,12 @@ class ASLargeLiteralScanner {
142
145
  }
143
146
  visitExpression(node) {
144
147
  switch (node.type) {
148
+ case "YieldExpression":
149
+ if (node.argument !== undefined) {
150
+ this.visitExpression(node.argument);
151
+ }
152
+ return;
153
+ case "FunctionExpression":
145
154
  case "ArrowFunctionExpression":
146
155
  this.visitArrowFunction(node);
147
156
  return;
@@ -12,7 +12,7 @@ export type Diagnostic = {
12
12
  replacement: string;
13
13
  };
14
14
  };
15
- export declare const AS_MISSING_ASYNC_MESSAGE = "Arrow functions that contain await must be marked async.";
15
+ export declare const AS_MISSING_ASYNC_MESSAGE = "Functions that contain await must be marked async.";
16
16
  export declare function AS_MISSING_ASYNC(source: string, options?: {
17
17
  filename?: string;
18
18
  }): Diagnostic[];
@@ -1,5 +1,5 @@
1
1
  import { parseModule } from "../../parse/parser.js";
2
- export const AS_MISSING_ASYNC_MESSAGE = "Arrow functions that contain await must be marked async.";
2
+ export const AS_MISSING_ASYNC_MESSAGE = "Functions that contain await must be marked async.";
3
3
  export function AS_MISSING_ASYNC(source, options = {}) {
4
4
  return new ASMissingAsyncScanner(options.filename ?? "<input>").scan(source);
5
5
  }
@@ -28,6 +28,9 @@ class ASMissingAsyncScanner {
28
28
  }
29
29
  visitStatement(node) {
30
30
  switch (node.type) {
31
+ case "FunctionDeclaration":
32
+ this.visitFunctionExpression(node);
33
+ return;
31
34
  case "BlockStatement":
32
35
  this.visitBlockStatement(node);
33
36
  return;
@@ -148,6 +151,11 @@ class ASMissingAsyncScanner {
148
151
  }
149
152
  visitExpression(node) {
150
153
  switch (node.type) {
154
+ case "YieldExpression":
155
+ if (node.argument !== undefined) {
156
+ this.visitExpression(node.argument);
157
+ }
158
+ return;
151
159
  case "ArrowFunctionExpression":
152
160
  this.visitArrowFunction(node);
153
161
  return;
@@ -33,6 +33,9 @@ class ASMutatingFrozenScanner {
33
33
  }
34
34
  visitStatement(node) {
35
35
  switch (node.type) {
36
+ case "FunctionDeclaration":
37
+ this.visitArrowFunction(node);
38
+ return;
36
39
  case "BlockStatement":
37
40
  this.visitBlockStatement(node);
38
41
  return;
@@ -170,6 +173,12 @@ class ASMutatingFrozenScanner {
170
173
  }
171
174
  visitExpression(node) {
172
175
  switch (node.type) {
176
+ case "YieldExpression":
177
+ if (node.argument !== undefined) {
178
+ this.visitExpression(node.argument);
179
+ }
180
+ return;
181
+ case "FunctionExpression":
173
182
  case "ArrowFunctionExpression":
174
183
  this.visitArrowFunction(node);
175
184
  return;
@@ -45,6 +45,9 @@ class ASNeedlessTemplateScanner {
45
45
  }
46
46
  visitStatement(node) {
47
47
  switch (node.type) {
48
+ case "FunctionDeclaration":
49
+ this.visitArrowFunction(node);
50
+ return;
48
51
  case "BlockStatement":
49
52
  this.visitBlockStatement(node);
50
53
  return;
@@ -168,6 +171,12 @@ class ASNeedlessTemplateScanner {
168
171
  }
169
172
  visitExpression(node) {
170
173
  switch (node.type) {
174
+ case "YieldExpression":
175
+ if (node.argument !== undefined) {
176
+ this.visitExpression(node.argument);
177
+ }
178
+ return;
179
+ case "FunctionExpression":
171
180
  case "ArrowFunctionExpression":
172
181
  this.visitArrowFunction(node);
173
182
  return;
@@ -22,6 +22,9 @@ class ASShadowGlobalScanner {
22
22
  }
23
23
  visitStatement(node) {
24
24
  switch (node.type) {
25
+ case "FunctionDeclaration":
26
+ this.visitArrowFunctionExpression(node);
27
+ return;
25
28
  case "BlockStatement":
26
29
  this.visitBlockStatement(node);
27
30
  return;
@@ -145,6 +148,12 @@ class ASShadowGlobalScanner {
145
148
  }
146
149
  visitExpression(node) {
147
150
  switch (node.type) {
151
+ case "YieldExpression":
152
+ if (node.argument !== undefined) {
153
+ this.visitExpression(node.argument);
154
+ }
155
+ return;
156
+ case "FunctionExpression":
148
157
  case "ArrowFunctionExpression":
149
158
  this.visitArrowFunctionExpression(node);
150
159
  return;
@@ -196,6 +205,9 @@ class ASShadowGlobalScanner {
196
205
  }
197
206
  }
198
207
  visitArrowFunctionExpression(node) {
208
+ if (node.type !== "ArrowFunctionExpression" && node.id !== undefined) {
209
+ this.reportIfGlobalShadow(node.id);
210
+ }
199
211
  for (const parameter of node.params) {
200
212
  this.visitBindingElement(parameter);
201
213
  }
@@ -21,6 +21,9 @@ class ASUnboundedLoopScanner {
21
21
  }
22
22
  visitStatement(node) {
23
23
  switch (node.type) {
24
+ case "FunctionDeclaration":
25
+ this.visitArrowFunction(node);
26
+ return;
24
27
  case "BlockStatement":
25
28
  this.visitBlockStatement(node);
26
29
  return;
@@ -157,6 +160,12 @@ class ASUnboundedLoopScanner {
157
160
  }
158
161
  visitExpression(node) {
159
162
  switch (node.type) {
163
+ case "YieldExpression":
164
+ if (node.argument !== undefined) {
165
+ this.visitExpression(node.argument);
166
+ }
167
+ return;
168
+ case "FunctionExpression":
160
169
  case "ArrowFunctionExpression":
161
170
  this.visitArrowFunction(node);
162
171
  return;