poe-code 14.0.69 → 14.0.70
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 +229 -139
- 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-KHKBLB42.js → chunk-BTIHHHII.js} +222 -134
- package/packages/safe-js/dist/chunks/chunk-BTIHHHII.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-KLAZUIHL.js → chunk-DUCQNFXN.js} +2 -2
- 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/interp/cancel.d.ts +1 -0
- package/packages/safe-js/dist/interp/cancel.js +1 -1
- package/packages/safe-js/dist/interp/interpreter.js +27 -42
- package/packages/safe-js/dist/interp/iteration.d.ts +3 -0
- package/packages/safe-js/dist/interp/iteration.js +103 -2
- package/packages/safe-js/dist/lint/rules/AS-async-not-needed.js +2 -1
- package/packages/safe-js/dist/parse/parser.d.ts +1 -0
- package/packages/safe-js/dist/parse/parser.js +15 -6
- package/packages/safe-js/dist/chunks/chunk-KHKBLB42.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-KLAZUIHL.js.map → chunk-DUCQNFXN.js.map} +0 -0
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
validateMigrationSemantics,
|
|
28
28
|
validateSnapshotData,
|
|
29
29
|
validateSnapshotMigration
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-BTIHHHII.js";
|
|
31
31
|
import {
|
|
32
32
|
createFileSystem,
|
|
33
33
|
createNodeFileSystemAdapterRegistry,
|
|
@@ -8249,4 +8249,4 @@ export {
|
|
|
8249
8249
|
parseMcpConfig,
|
|
8250
8250
|
makeMcpModule
|
|
8251
8251
|
};
|
|
8252
|
-
//# sourceMappingURL=chunk-
|
|
8252
|
+
//# sourceMappingURL=chunk-DUCQNFXN.js.map
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveFsConfig,
|
|
23
23
|
splitFrontmatter,
|
|
24
24
|
withBrokenPipeGuard
|
|
25
|
-
} from "./chunks/chunk-
|
|
25
|
+
} from "./chunks/chunk-DUCQNFXN.js";
|
|
26
26
|
import {
|
|
27
27
|
Budget,
|
|
28
28
|
SandboxError,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
replaceErrorStack,
|
|
35
35
|
restore,
|
|
36
36
|
run
|
|
37
|
-
} from "./chunks/chunk-
|
|
37
|
+
} from "./chunks/chunk-BTIHHHII.js";
|
|
38
38
|
import "./chunks/chunk-ZWJ5BJUI.js";
|
|
39
39
|
import "./chunks/chunk-3YTQEPZI.js";
|
|
40
40
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
runWithSpawnUsageAccumulator,
|
|
27
27
|
splitFrontmatter,
|
|
28
28
|
supportsSpawnMode
|
|
29
|
-
} from "./chunks/chunk-
|
|
29
|
+
} from "./chunks/chunk-DUCQNFXN.js";
|
|
30
30
|
import {
|
|
31
31
|
Budget,
|
|
32
32
|
FileSnapshotBackend,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
registerPendingHostCallPolicy,
|
|
51
51
|
restore,
|
|
52
52
|
run
|
|
53
|
-
} from "./chunks/chunk-
|
|
53
|
+
} from "./chunks/chunk-BTIHHHII.js";
|
|
54
54
|
import "./chunks/chunk-ZWJ5BJUI.js";
|
|
55
55
|
import "./chunks/chunk-3YTQEPZI.js";
|
|
56
56
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -6,3 +6,4 @@ export declare function wrapCancelableBindings(bindings: Record<string, SandboxV
|
|
|
6
6
|
export declare function registerPromiseCancellation(promise: SandboxPromise): void;
|
|
7
7
|
export declare function readPromiseCancellation(promise: SandboxPromise, original: Promise<SandboxValue>): Promise<SandboxValue>;
|
|
8
8
|
export declare function awaitSandboxValue(value: SandboxValue, signal?: AbortSignal, budget?: Budget): Promise<SandboxValue>;
|
|
9
|
+
export declare function awaitWithSignal<T>(promise: PromiseLike<T>, signal?: AbortSignal): Promise<T>;
|
|
@@ -142,7 +142,7 @@ export function awaitSandboxValue(value, signal, budget) {
|
|
|
142
142
|
: awaitWithSignal(resolved, signal);
|
|
143
143
|
return isSandboxPromise(value) ? pending : interruptOnFatalPromiseRejection(pending);
|
|
144
144
|
}
|
|
145
|
-
function awaitWithSignal(promise, signal) {
|
|
145
|
+
export function awaitWithSignal(promise, signal) {
|
|
146
146
|
if (signal === undefined)
|
|
147
147
|
return Promise.resolve(promise);
|
|
148
148
|
if (signal.aborted) {
|
|
@@ -23,7 +23,7 @@ import { assertSandboxDataDepth } from "../graph-depth.js";
|
|
|
23
23
|
import { callMapMethod, getMapMember, isMapMethodName } from "./methods/map.js";
|
|
24
24
|
import { callNumberMethod, getNumberMember, isNumberMethodName } from "./methods/number.js";
|
|
25
25
|
import { getPromiseMember, isSandboxPromiseConstructor } from "./promise.js";
|
|
26
|
-
import {
|
|
26
|
+
import { closeIterator, getSandboxAsyncIterator, getSandboxIterator } from "./iteration.js";
|
|
27
27
|
import { assertCollectionMutable } from "./running-state.js";
|
|
28
28
|
import { getGeneratorMember } from "./methods/generator.js";
|
|
29
29
|
import { getRegexMember, isRegexMethodName, setRegexMember } from "./methods/regex.js";
|
|
@@ -1116,7 +1116,7 @@ async function evaluateForOfStatement(node, context) {
|
|
|
1116
1116
|
const restored = context.scope.consumeRestoredBinding(restoredIteration.values[0]);
|
|
1117
1117
|
if (restored.found && Array.isArray(restored.value)) {
|
|
1118
1118
|
restoredEntry = { done: false, value: restored.value[1] };
|
|
1119
|
-
if (isSandboxMap(restored.value[0]) || isSandboxSet(restored.value[0]) || isSandboxCollectionIterator(restored.value[0])) {
|
|
1119
|
+
if (Array.isArray(restored.value[0]) || isSandboxMap(restored.value[0]) || isSandboxSet(restored.value[0]) || isSandboxCollectionIterator(restored.value[0])) {
|
|
1120
1120
|
return evaluateForOfIterator(node, restored.value[0], context, restoredEntry);
|
|
1121
1121
|
}
|
|
1122
1122
|
}
|
|
@@ -1125,7 +1125,7 @@ async function evaluateForOfStatement(node, context) {
|
|
|
1125
1125
|
if (iterable.kind !== "normal") {
|
|
1126
1126
|
return iterable;
|
|
1127
1127
|
}
|
|
1128
|
-
const values = snapshotableIterationValues(iterable.value);
|
|
1128
|
+
const values = node.await ? undefined : snapshotableIterationValues(iterable.value);
|
|
1129
1129
|
if (values === undefined) {
|
|
1130
1130
|
return evaluateForOfIterator(node, iterable.value, context, restoredEntry);
|
|
1131
1131
|
}
|
|
@@ -1164,16 +1164,31 @@ async function evaluateForOfStatement(node, context) {
|
|
|
1164
1164
|
};
|
|
1165
1165
|
}
|
|
1166
1166
|
async function evaluateForOfIterator(node, value, context, restoredEntry) {
|
|
1167
|
-
const iterator =
|
|
1167
|
+
const iterator = node.await
|
|
1168
|
+
? getSandboxAsyncIterator(value, context.budget, createCoercionContext(context), context.signal)
|
|
1169
|
+
: getSandboxIterator(value, context.budget, createCoercionContext(context));
|
|
1168
1170
|
if (iterator === undefined) {
|
|
1169
1171
|
throw new TypeError(`${String(value)} is not a supported iterable`);
|
|
1170
1172
|
}
|
|
1173
|
+
const nextIteration = async () => {
|
|
1174
|
+
const pending = Promise.resolve(iterator.next());
|
|
1175
|
+
if (!node.await)
|
|
1176
|
+
return pending;
|
|
1177
|
+
context.onSuspend?.();
|
|
1178
|
+
const leaveAwait = context.budget.enterAwait();
|
|
1179
|
+
try {
|
|
1180
|
+
return await suspendJob(pending);
|
|
1181
|
+
}
|
|
1182
|
+
finally {
|
|
1183
|
+
leaveAwait();
|
|
1184
|
+
}
|
|
1185
|
+
};
|
|
1171
1186
|
const releaseIterator = retainValues(context.budget, () => [value, iterator.retainedValue]);
|
|
1172
1187
|
try {
|
|
1173
1188
|
const nodeId = node.nodeId ?? -1;
|
|
1174
1189
|
let index = consumeRestoredLoopIterationIndex(node, context);
|
|
1175
1190
|
for (let skipped = 0; skipped < index; skipped += 1) {
|
|
1176
|
-
const skippedIteration = await
|
|
1191
|
+
const skippedIteration = await nextIteration();
|
|
1177
1192
|
if (typeof skippedIteration !== "object" || skippedIteration === null) {
|
|
1178
1193
|
throw new TypeError("Iterator result must be an object.");
|
|
1179
1194
|
}
|
|
@@ -1182,7 +1197,7 @@ async function evaluateForOfIterator(node, value, context, restoredEntry) {
|
|
|
1182
1197
|
}
|
|
1183
1198
|
}
|
|
1184
1199
|
while (true) {
|
|
1185
|
-
const iteration = restoredEntry ?? (await
|
|
1200
|
+
const iteration = restoredEntry ?? (await nextIteration());
|
|
1186
1201
|
restoredEntry = undefined;
|
|
1187
1202
|
if (typeof iteration !== "object" || iteration === null) {
|
|
1188
1203
|
throw new TypeError("Iterator result must be an object.");
|
|
@@ -1497,7 +1512,7 @@ function createLoopIterationContext(context, scope) {
|
|
|
1497
1512
|
snapshot.loopIterations = {};
|
|
1498
1513
|
for (const [nodeId, iteration] of context.activeLoopIterations) {
|
|
1499
1514
|
if (typeof iteration !== "number" &&
|
|
1500
|
-
(isSandboxMap(iteration.values[0]) || isSandboxSet(iteration.values[0]) || isSandboxCollectionIterator(iteration.values[0]))) {
|
|
1515
|
+
(Array.isArray(iteration.values[0]) || isSandboxMap(iteration.values[0]) || isSandboxSet(iteration.values[0]) || isSandboxCollectionIterator(iteration.values[0]))) {
|
|
1501
1516
|
const bindingName = `#for-of:${nodeId}`;
|
|
1502
1517
|
snapshot.bindings[bindingName] = iteration.values;
|
|
1503
1518
|
snapshot.loopIterations[nodeId] = { index: iteration.index, values: [bindingName] };
|
|
@@ -1614,7 +1629,7 @@ async function evaluateYieldExpression(node, context) {
|
|
|
1614
1629
|
return generatorCompletionResult(completion);
|
|
1615
1630
|
}
|
|
1616
1631
|
async function yieldGeneratorValue(value, node, context) {
|
|
1617
|
-
if (context.asyncGenerator)
|
|
1632
|
+
if (context.asyncGenerator && !node.delegate)
|
|
1618
1633
|
value = await suspendJob(awaitSandboxValue(value, context.signal, context.budget));
|
|
1619
1634
|
const completionPromise = context.generatorYield(allocateProducedSandboxValue(value, context.budget), node.nodeId);
|
|
1620
1635
|
emitResumeBreakpoint(context, {
|
|
@@ -1638,10 +1653,9 @@ async function evaluateYieldDelegate(node, context) {
|
|
|
1638
1653
|
if (argument.kind !== "normal") {
|
|
1639
1654
|
return argument;
|
|
1640
1655
|
}
|
|
1641
|
-
const
|
|
1642
|
-
? argument.value
|
|
1643
|
-
|
|
1644
|
-
? generatorIterator(asyncDelegate, context.budget) : getSandboxIterator(argument.value, context.budget, createCoercionContext(context));
|
|
1656
|
+
const iterator = context.asyncGenerator
|
|
1657
|
+
? getSandboxAsyncIterator(argument.value, context.budget, createCoercionContext(context), context.signal)
|
|
1658
|
+
: getSandboxIterator(argument.value, context.budget, createCoercionContext(context));
|
|
1645
1659
|
if (iterator === undefined) {
|
|
1646
1660
|
throw new TypeError(`${String(argument.value)} is not a supported iterable`);
|
|
1647
1661
|
}
|
|
@@ -1672,19 +1686,7 @@ async function evaluateYieldDelegate(node, context) {
|
|
|
1672
1686
|
throw new TypeError("Iterator result must be an object.");
|
|
1673
1687
|
}
|
|
1674
1688
|
const done = result.done;
|
|
1675
|
-
|
|
1676
|
-
if (context.asyncGenerator) {
|
|
1677
|
-
try {
|
|
1678
|
-
value = await suspendJob(awaitSandboxValue(value, context.signal, context.budget));
|
|
1679
|
-
}
|
|
1680
|
-
catch (error) {
|
|
1681
|
-
if (isFatalSandboxError(error) || error instanceof HostCallResumabilityError)
|
|
1682
|
-
throw error;
|
|
1683
|
-
if (!asyncDelegate && !done && method !== "return")
|
|
1684
|
-
await closeIterator(iterator, true);
|
|
1685
|
-
throw error;
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1689
|
+
const value = result.value;
|
|
1688
1690
|
if (done) {
|
|
1689
1691
|
if (completion.type === "return") {
|
|
1690
1692
|
return generatorCompletionResult({ type: "return", value });
|
|
@@ -2937,23 +2939,6 @@ function describeObjectSpreadValue(value) {
|
|
|
2937
2939
|
}
|
|
2938
2940
|
return typeof value;
|
|
2939
2941
|
}
|
|
2940
|
-
async function closeIterator(iterator, preserveThrow = false) {
|
|
2941
|
-
try {
|
|
2942
|
-
const close = iterator.return;
|
|
2943
|
-
if (close === undefined)
|
|
2944
|
-
return;
|
|
2945
|
-
const returned = close();
|
|
2946
|
-
const result = iterator.generator || iterator.asynchronous ? await returned : returned;
|
|
2947
|
-
if ((typeof result !== "object" && typeof result !== "function") || result === null) {
|
|
2948
|
-
throw new TypeError("Iterator return result must be an object.");
|
|
2949
|
-
}
|
|
2950
|
-
}
|
|
2951
|
-
catch (error) {
|
|
2952
|
-
if (!preserveThrow || isFatalSandboxError(error) || error instanceof HostCallResumabilityError) {
|
|
2953
|
-
throw error;
|
|
2954
|
-
}
|
|
2955
|
-
}
|
|
2956
|
-
}
|
|
2957
2942
|
function defineSandboxProperty(target, key, value) {
|
|
2958
2943
|
Object.defineProperty(target, key, {
|
|
2959
2944
|
configurable: true,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type SandboxGenerator, type SandboxCallContext, type SandboxValue } from "./values.js";
|
|
2
2
|
import { Budget } from "./budget.js";
|
|
3
3
|
export type SandboxIterator = {
|
|
4
|
+
readonly asyncProtocol?: true;
|
|
4
5
|
readonly generator?: true;
|
|
5
6
|
readonly asynchronous?: true;
|
|
6
7
|
readonly retainedValue?: SandboxValue;
|
|
@@ -9,5 +10,7 @@ export type SandboxIterator = {
|
|
|
9
10
|
return?(value?: SandboxValue): IteratorResult<SandboxValue> | Promise<IteratorResult<SandboxValue>>;
|
|
10
11
|
throw?(error?: SandboxValue): IteratorResult<SandboxValue> | Promise<IteratorResult<SandboxValue>>;
|
|
11
12
|
};
|
|
13
|
+
export declare function getSandboxAsyncIterator(value: SandboxValue, budget: Budget, context?: SandboxCallContext, signal?: AbortSignal): SandboxIterator | undefined;
|
|
14
|
+
export declare function closeIterator(iterator: SandboxIterator, preserveThrow?: boolean): Promise<void>;
|
|
12
15
|
export declare function getSandboxIterator(value: SandboxValue, budget?: Budget, context?: SandboxCallContext): SandboxIterator | undefined;
|
|
13
16
|
export declare function generatorIterator(generator: SandboxGenerator, budget?: Budget): SandboxIterator;
|
|
@@ -4,9 +4,110 @@ import { isFloat32Array } from "./float32.js";
|
|
|
4
4
|
import { boxedValue, isSandboxBox } from "./boxed.js";
|
|
5
5
|
import { getHostObjectIterator, isGuestHostObject } from "./host-capabilities.js";
|
|
6
6
|
import { isSandboxCollectionIterator, nextCollectionIterator } from "./collection-iterator.js";
|
|
7
|
-
import { Budget } from "./budget.js";
|
|
7
|
+
import { Budget, isFatalSandboxError } from "./budget.js";
|
|
8
8
|
import { sandboxString } from "./string-coercion.js";
|
|
9
|
-
import { awaitSandboxValue } from "./cancel.js";
|
|
9
|
+
import { awaitSandboxValue, awaitWithSignal } from "./cancel.js";
|
|
10
|
+
import { HostCallResumabilityError } from "./host-call.js";
|
|
11
|
+
import { suspendJob } from "./jobs.js";
|
|
12
|
+
export function getSandboxAsyncIterator(value, budget, context, signal) {
|
|
13
|
+
if (isSandboxGenerator(value) && value.async) {
|
|
14
|
+
return { ...generatorIterator(value, budget), asyncProtocol: true };
|
|
15
|
+
}
|
|
16
|
+
if (value !== null && (typeof value === "object" || typeof value === "function") && !isGuestHostObject(value)) {
|
|
17
|
+
const method = value[Symbol.asyncIterator];
|
|
18
|
+
if (method !== undefined && method !== null) {
|
|
19
|
+
if (typeof method !== "function")
|
|
20
|
+
throw new TypeError("Async iterator method must be callable.");
|
|
21
|
+
const iterator = Reflect.apply(method, value, []);
|
|
22
|
+
if ((typeof iterator !== "object" && typeof iterator !== "function") || iterator === null) {
|
|
23
|
+
throw new TypeError("Async iterator must be an object.");
|
|
24
|
+
}
|
|
25
|
+
const next = iterator.next;
|
|
26
|
+
const invoke = async (operation, args) => {
|
|
27
|
+
if (typeof operation !== "function")
|
|
28
|
+
throw new TypeError("Async iterator operation must be callable.");
|
|
29
|
+
const pending = Promise.resolve(Reflect.apply(operation, iterator, args)).then(result => ({ result }));
|
|
30
|
+
const { result } = await awaitWithSignal(pending, signal);
|
|
31
|
+
if ((typeof result !== "object" && typeof result !== "function") || result === null) {
|
|
32
|
+
throw new TypeError("Iterator result must be an object.");
|
|
33
|
+
}
|
|
34
|
+
// Keep protocol reads lazy without re-assimilating the result's `then` property.
|
|
35
|
+
return {
|
|
36
|
+
get done() { return result.done; },
|
|
37
|
+
get value() { return result.value; }
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
asyncProtocol: true,
|
|
42
|
+
retainedValue: value,
|
|
43
|
+
next: (...args) => invoke(next, args),
|
|
44
|
+
get return() {
|
|
45
|
+
const operation = iterator.return;
|
|
46
|
+
return operation === undefined || operation === null ? undefined : (...args) => invoke(operation, args);
|
|
47
|
+
},
|
|
48
|
+
get throw() {
|
|
49
|
+
const operation = iterator.throw;
|
|
50
|
+
return operation === undefined || operation === null ? undefined : (...args) => invoke(operation, args);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const iterator = getSandboxIterator(value, budget, context);
|
|
56
|
+
if (iterator === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
const invoke = async (method, args) => {
|
|
59
|
+
const operation = iterator[method];
|
|
60
|
+
if (operation === undefined) {
|
|
61
|
+
if (method === "throw") {
|
|
62
|
+
await closeIterator(iterator);
|
|
63
|
+
throw new TypeError("Delegated iterator does not provide a throw method.");
|
|
64
|
+
}
|
|
65
|
+
return { done: true, value: args[0] };
|
|
66
|
+
}
|
|
67
|
+
const returned = operation(...args);
|
|
68
|
+
const result = iterator.generator || iterator.asynchronous ? await returned : returned;
|
|
69
|
+
if ((typeof result !== "object" && typeof result !== "function") || result === null) {
|
|
70
|
+
throw new TypeError("Iterator result must be an object.");
|
|
71
|
+
}
|
|
72
|
+
const done = Boolean(result.done);
|
|
73
|
+
const resultValue = result.value;
|
|
74
|
+
try {
|
|
75
|
+
return { done, value: await awaitSandboxValue(resultValue, signal, budget) };
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
if (isFatalSandboxError(error) || error instanceof HostCallResumabilityError)
|
|
79
|
+
throw error;
|
|
80
|
+
if (!done && method !== "return")
|
|
81
|
+
await closeIterator(iterator, true);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
asyncProtocol: true,
|
|
87
|
+
snapshotIndex: iterator.snapshotIndex,
|
|
88
|
+
get retainedValue() { return iterator.retainedValue; },
|
|
89
|
+
next: (...args) => invoke("next", args),
|
|
90
|
+
return: (...args) => invoke("return", args),
|
|
91
|
+
throw: (...args) => invoke("throw", args)
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export async function closeIterator(iterator, preserveThrow = false) {
|
|
95
|
+
try {
|
|
96
|
+
const close = iterator.return;
|
|
97
|
+
if (close === undefined)
|
|
98
|
+
return;
|
|
99
|
+
const returned = close();
|
|
100
|
+
const result = iterator.asyncProtocol ? await suspendJob(Promise.resolve(returned))
|
|
101
|
+
: iterator.generator || iterator.asynchronous ? await returned : returned;
|
|
102
|
+
if ((typeof result !== "object" && typeof result !== "function") || result === null) {
|
|
103
|
+
throw new TypeError("Iterator return result must be an object.");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (!preserveThrow || isFatalSandboxError(error) || error instanceof HostCallResumabilityError)
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
10
111
|
export function getSandboxIterator(value, budget, context) {
|
|
11
112
|
if (isSandboxBox(value) && typeof boxedValue(value) === "string") {
|
|
12
113
|
const primitive = boxedValue(value);
|
|
@@ -437,7 +437,8 @@ function statementContainsAwait(node) {
|
|
|
437
437
|
statementContainsAwait(node.body));
|
|
438
438
|
case "ForInStatement":
|
|
439
439
|
case "ForOfStatement":
|
|
440
|
-
return ((node.
|
|
440
|
+
return ((node.type === "ForOfStatement" && node.await === true) ||
|
|
441
|
+
(node.left.type === "VariableDeclaration" && variableDeclarationContainsAwait(node.left)) ||
|
|
441
442
|
(node.left.type !== "VariableDeclaration" && assignmentTargetContainsAwait(node.left)) ||
|
|
442
443
|
expressionContainsAwait(node.right) ||
|
|
443
444
|
statementContainsAwait(node.body));
|
|
@@ -121,7 +121,7 @@ class Parser {
|
|
|
121
121
|
scopes = [new Map()];
|
|
122
122
|
functionScopes = new WeakSet();
|
|
123
123
|
varNames = new WeakMap();
|
|
124
|
-
constructor(tokens, source, compilation, functionContext = "
|
|
124
|
+
constructor(tokens, source, compilation, functionContext = "top-level", lexicalContext = { ...ordinaryFunctionContext, newTarget: false }) {
|
|
125
125
|
this.tokens = tokens;
|
|
126
126
|
this.source = source;
|
|
127
127
|
this.compilation = compilation;
|
|
@@ -283,7 +283,7 @@ class Parser {
|
|
|
283
283
|
this.expectPunctuator("=>");
|
|
284
284
|
const body = this.withLexicalContext({
|
|
285
285
|
...this.lexicalContext, return: true, await: isAsync || this.lexicalContext.strictAwait !== true
|
|
286
|
-
}, () => this.parseArrowFunctionBody(params));
|
|
286
|
+
}, () => this.parseArrowFunctionBody(params, isAsync));
|
|
287
287
|
return this.withFunctionSource({
|
|
288
288
|
type: "ArrowFunctionExpression",
|
|
289
289
|
async: isAsync,
|
|
@@ -322,11 +322,11 @@ class Parser {
|
|
|
322
322
|
this.conditionalExpressionDepth -= 1;
|
|
323
323
|
}
|
|
324
324
|
}
|
|
325
|
-
parseArrowFunctionBody(params) {
|
|
325
|
+
parseArrowFunctionBody(params, async) {
|
|
326
326
|
if (this.currentToken().type === "punctuator" && this.currentToken().value === "{") {
|
|
327
|
-
return this.withFunctionContext("normal", () => this.parseBlockStatement(params));
|
|
327
|
+
return this.withFunctionContext(async ? "async" : "normal", () => this.parseBlockStatement(params));
|
|
328
328
|
}
|
|
329
|
-
return this.withFunctionContext("normal", () => this.parseExpression().node);
|
|
329
|
+
return this.withFunctionContext(async ? "async" : "normal", () => this.parseExpression().node);
|
|
330
330
|
}
|
|
331
331
|
parseBlockStatement(params, catchParam) {
|
|
332
332
|
const start = this.expectPunctuator("{");
|
|
@@ -600,9 +600,17 @@ class Parser {
|
|
|
600
600
|
}
|
|
601
601
|
parseForStatement(labels) {
|
|
602
602
|
const forToken = this.expectKeyword("for");
|
|
603
|
+
const awaitToken = this.consumeKeyword("await");
|
|
604
|
+
if (awaitToken !== undefined && this.functionContext !== "top-level" &&
|
|
605
|
+
this.functionContext !== "async" && this.functionContext !== "async-generator") {
|
|
606
|
+
throw new Error("for await is only valid at top level or inside an async function.");
|
|
607
|
+
}
|
|
603
608
|
return this.withScope(() => {
|
|
604
609
|
this.expectPunctuator("(");
|
|
605
610
|
const iterationOperator = this.findTopLevelForIterationOperator(this.index);
|
|
611
|
+
if (awaitToken !== undefined && iterationOperator?.value !== "of") {
|
|
612
|
+
throw new Error("for await requires an of loop.");
|
|
613
|
+
}
|
|
606
614
|
if (iterationOperator?.value === "in") {
|
|
607
615
|
const left = this.parseForInLeft();
|
|
608
616
|
this.expectKeyword("in");
|
|
@@ -626,6 +634,7 @@ class Parser {
|
|
|
626
634
|
const body = this.withLoopContext(() => this.parseStatement());
|
|
627
635
|
return {
|
|
628
636
|
type: "ForOfStatement",
|
|
637
|
+
...(awaitToken === undefined ? {} : { await: true }),
|
|
629
638
|
left,
|
|
630
639
|
right,
|
|
631
640
|
body,
|
|
@@ -999,7 +1008,7 @@ class Parser {
|
|
|
999
1008
|
if (accessor === "set" && (params.length !== 1 || params[0]?.type === "RestElement"))
|
|
1000
1009
|
throw new Error("A setter must have exactly one non-rest parameter.");
|
|
1001
1010
|
const bodyTokenIndex = this.index;
|
|
1002
|
-
const body = this.withFunctionContext(generator ? async ? "async-generator" : "generator" : "normal", () => this.parseBlockStatement(params));
|
|
1011
|
+
const body = this.withFunctionContext(generator ? async ? "async-generator" : "generator" : async ? "async" : "normal", () => this.parseBlockStatement(params));
|
|
1003
1012
|
if (accessor === "set" && params[0]?.type !== "Identifier") {
|
|
1004
1013
|
let directiveTokenIndex = bodyTokenIndex + 1;
|
|
1005
1014
|
for (const statement of body.body) {
|