poe-code 14.0.59 → 14.0.61
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 +148 -108
- 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-YZGYOQK3.js → chunk-VAYQP2VZ.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-D4YY44EF.js → chunk-ZTGKRKQH.js} +141 -104
- package/packages/safe-js/dist/chunks/chunk-ZTGKRKQH.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/interp/interpreter.js +8 -14
- package/packages/safe-js/dist/interp/methods/string.js +18 -0
- package/packages/safe-js/dist/interp/resources.d.ts +2 -0
- package/packages/safe-js/dist/interp/resources.js +11 -0
- package/packages/safe-js/dist/interp/string-coercion.js +13 -4
- package/packages/safe-js/dist/parse/parser.js +45 -42
- package/packages/safe-js/dist/chunks/chunk-D4YY44EF.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-YZGYOQK3.js.map → chunk-VAYQP2VZ.js.map} +0 -0
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveFsConfig,
|
|
23
23
|
splitFrontmatter,
|
|
24
24
|
withBrokenPipeGuard
|
|
25
|
-
} from "./chunks/chunk-
|
|
25
|
+
} from "./chunks/chunk-VAYQP2VZ.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-ZTGKRKQH.js";
|
|
38
38
|
import "./chunks/chunk-UXMKEUH3.js";
|
|
39
39
|
import "./chunks/chunk-5DYEOCT5.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-VAYQP2VZ.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-ZTGKRKQH.js";
|
|
54
54
|
import "./chunks/chunk-UXMKEUH3.js";
|
|
55
55
|
import "./chunks/chunk-5DYEOCT5.js";
|
|
56
56
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -4,7 +4,8 @@ import { toPropertyKey } from "./property-key.js";
|
|
|
4
4
|
import { assertPromiseExecutionAllowed } from "./promise-tracker.js";
|
|
5
5
|
import { SandboxJobQueue, runAsyncPrefix, suspendJob } from "./jobs.js";
|
|
6
6
|
import { withCancellationSignal } from "./cancel.js";
|
|
7
|
-
import {
|
|
7
|
+
import { retainValues } from "./resources.js";
|
|
8
|
+
import { sandboxString } from "./string-coercion.js";
|
|
8
9
|
import { attachErrorSpan, formatErrorStack, replaceErrorStack } from "../error/shape.js";
|
|
9
10
|
import { evaluateArrowFunctionExpression, evaluateFunctionExpression, evaluateAwaitExpression, emitResumeBreakpoint, createInterpretedClosure, normalizeClosureResult } from "./async.js";
|
|
10
11
|
import { HostCallResumabilityError } from "./host-call.js";
|
|
@@ -360,14 +361,18 @@ function isObjectPrototypeSetterProperty(property, key) {
|
|
|
360
361
|
}
|
|
361
362
|
async function evaluateTemplateLiteral(node, context) {
|
|
362
363
|
let value = context.budget.allocateString(node.quasis[0]?.value.cooked ?? "");
|
|
363
|
-
|
|
364
|
+
let input = undefined;
|
|
365
|
+
const release = retainValues(context.budget, () => [value, input]);
|
|
364
366
|
try {
|
|
365
367
|
for (let index = 0; index < node.expressions.length; index += 1) {
|
|
366
368
|
const expression = await evaluateNode(node.expressions[index], context);
|
|
367
369
|
if (expression.kind !== "normal") {
|
|
368
370
|
return expression;
|
|
369
371
|
}
|
|
370
|
-
|
|
372
|
+
input = expression.value;
|
|
373
|
+
const text = sandboxString(input, context.budget, createCoercionContext(context));
|
|
374
|
+
const expressionText = typeof text === "string" ? text : await text;
|
|
375
|
+
input = undefined;
|
|
371
376
|
value = context.budget.allocateString(value + expressionText);
|
|
372
377
|
const quasiText = context.budget.allocateString(node.quasis[index + 1]?.value.cooked ?? "");
|
|
373
378
|
value = context.budget.allocateString(value + quasiText);
|
|
@@ -1831,17 +1836,6 @@ async function evaluateMemberAccess(node, context, consume) {
|
|
|
1831
1836
|
release();
|
|
1832
1837
|
}
|
|
1833
1838
|
}
|
|
1834
|
-
function retainValues(budget, values) {
|
|
1835
|
-
const retained = {};
|
|
1836
|
-
budget.setRetainedValues(retained, values);
|
|
1837
|
-
const pending = runResources.getStore()?.referenceReleases;
|
|
1838
|
-
const release = () => {
|
|
1839
|
-
budget.setRetainedValues(retained, undefined);
|
|
1840
|
-
pending?.delete(release);
|
|
1841
|
-
};
|
|
1842
|
-
pending?.add(release);
|
|
1843
|
-
return release;
|
|
1844
|
-
}
|
|
1845
1839
|
async function evaluateMemberProperty(node, context) {
|
|
1846
1840
|
const property = await evaluateNode(node, context);
|
|
1847
1841
|
if (property.kind !== "normal") {
|
|
@@ -2,6 +2,7 @@ import { invokeBuiltinClosure } from "../builtin-call.js";
|
|
|
2
2
|
import { CompileScope } from "../regex/compile-guard.js";
|
|
3
3
|
import { normalizeLastIndex } from "../regex/engine.js";
|
|
4
4
|
import { sandboxNumber, sandboxString } from "../string-coercion.js";
|
|
5
|
+
import { retainValues } from "../resources.js";
|
|
5
6
|
import { createSandboxClosure, createSandboxRegex, deepCopyFromSandbox, isSandboxClosure, isSandboxRegex } from "../values.js";
|
|
6
7
|
import { executeRegex, toMatchArray } from "./regex.js";
|
|
7
8
|
const SPLIT_STRING_MESSAGE = "String#split only supports string separator values.";
|
|
@@ -83,6 +84,9 @@ export function isStringMethodName(property) {
|
|
|
83
84
|
}
|
|
84
85
|
export function validateStringMethodArguments(_methodName, _args) { }
|
|
85
86
|
export function callStringMethod(value, methodName, args, budget, callClosure = async (closure, closureArgs) => await closure.call(closureArgs), parent, context) {
|
|
87
|
+
if (methodName === "concat" && args.some(argument => argument !== null && typeof argument === "object")) {
|
|
88
|
+
return callConcat(value, args, budget, context);
|
|
89
|
+
}
|
|
86
90
|
if (methodName === "isWellFormed") {
|
|
87
91
|
for (let index = 0; index < value.length; index++) {
|
|
88
92
|
const codeUnit = value.charCodeAt(index);
|
|
@@ -239,6 +243,20 @@ export function callStringMethod(value, methodName, args, budget, callClosure =
|
|
|
239
243
|
operation.release();
|
|
240
244
|
}
|
|
241
245
|
}
|
|
246
|
+
async function callConcat(value, args, budget, context) {
|
|
247
|
+
let result = budget.allocateString(value);
|
|
248
|
+
const release = retainValues(budget, () => [result]);
|
|
249
|
+
try {
|
|
250
|
+
for (const argument of args) {
|
|
251
|
+
const text = sandboxString(argument, budget, context);
|
|
252
|
+
result = budget.allocateString(result + (typeof text === "string" ? text : await text));
|
|
253
|
+
}
|
|
254
|
+
return result;
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
release();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
242
260
|
function callReplaceLikeMethod(value, methodName, args, budget, callClosure, context) {
|
|
243
261
|
const search = args[0];
|
|
244
262
|
const replacement = args[1];
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
import type { Budget } from "./budget.js";
|
|
2
3
|
export type RunResources = {
|
|
3
4
|
signal: AbortSignal;
|
|
4
5
|
referenceReleases: Set<() => void>;
|
|
5
6
|
add(close: () => Promise<void>): void;
|
|
6
7
|
};
|
|
7
8
|
export declare const runResources: AsyncLocalStorage<RunResources>;
|
|
9
|
+
export declare function retainValues(budget: Budget, values: () => Iterable<unknown>): () => void;
|
|
8
10
|
export declare function withRunResources<Result>(signal: AbortSignal | undefined, execute: () => Promise<Result>): Promise<Result>;
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
export const runResources = new AsyncLocalStorage();
|
|
3
|
+
export function retainValues(budget, values) {
|
|
4
|
+
const retained = {};
|
|
5
|
+
budget.setRetainedValues(retained, values);
|
|
6
|
+
const pending = runResources.getStore()?.referenceReleases;
|
|
7
|
+
const release = () => {
|
|
8
|
+
budget.setRetainedValues(retained, undefined);
|
|
9
|
+
pending?.delete(release);
|
|
10
|
+
};
|
|
11
|
+
pending?.add(release);
|
|
12
|
+
return release;
|
|
13
|
+
}
|
|
3
14
|
export async function withRunResources(signal, execute) {
|
|
4
15
|
const controller = new AbortController();
|
|
5
16
|
const cancel = () => controller.abort(signal?.reason);
|
|
@@ -7,6 +7,7 @@ import { isGuestHostObject } from "./host-capabilities.js";
|
|
|
7
7
|
import { collectionIteratorState, isSandboxCollectionIterator } from "./collection-iterator.js";
|
|
8
8
|
import { getGuestFunctionProperties, getSandboxPrototype, hasExplicitSandboxPrototype, isGuestClosure } from "./object-model.js";
|
|
9
9
|
import { getRegexMember } from "./methods/regex.js";
|
|
10
|
+
import { retainValues } from "./resources.js";
|
|
10
11
|
import { isSandboxClosure, isSandboxPromise, isSandboxMap, isSandboxSet, isSandboxRegex, isSandboxGenerator } from "./values.js";
|
|
11
12
|
const defaultStringHook = Symbol("defaultStringHook");
|
|
12
13
|
const defaultValueHook = Symbol("defaultValueHook");
|
|
@@ -118,9 +119,10 @@ async function defaultToString(value, budget, context, joining) {
|
|
|
118
119
|
if (joining.has(value))
|
|
119
120
|
return "";
|
|
120
121
|
joining.add(value);
|
|
122
|
+
let text = "";
|
|
123
|
+
const release = retainValues(budget, () => [text]);
|
|
121
124
|
try {
|
|
122
125
|
const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
|
|
123
|
-
let text = "";
|
|
124
126
|
for (let index = 0; index < length; index++) {
|
|
125
127
|
budget.visitNode();
|
|
126
128
|
const element = ownDataValue(value, String(index));
|
|
@@ -132,15 +134,22 @@ async function defaultToString(value, budget, context, joining) {
|
|
|
132
134
|
return text;
|
|
133
135
|
}
|
|
134
136
|
finally {
|
|
137
|
+
release();
|
|
135
138
|
joining.delete(value);
|
|
136
139
|
}
|
|
137
140
|
}
|
|
138
141
|
if (sandboxErrorTypes.has(value)) {
|
|
139
142
|
const nameValue = ownDataValue(value, "name");
|
|
140
143
|
const name = nameValue === undefined ? "Error" : await sandboxString(nameValue, budget, context, joining);
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
const release = retainValues(budget, () => [name]);
|
|
145
|
+
try {
|
|
146
|
+
const messageValue = ownDataValue(value, "message");
|
|
147
|
+
const message = messageValue === undefined ? "" : await sandboxString(messageValue, budget, context, joining);
|
|
148
|
+
return name === "" ? message : message === "" ? name : `${name}: ${message}`;
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
release();
|
|
152
|
+
}
|
|
144
153
|
}
|
|
145
154
|
return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
|
|
146
155
|
}
|
|
@@ -107,24 +107,22 @@ function parseTokens(tokens, compilation) {
|
|
|
107
107
|
function parseModuleTokens(tokens, compilation) {
|
|
108
108
|
return new Parser(tokens, compilation).parseModule();
|
|
109
109
|
}
|
|
110
|
-
function parseExpressionTokens(tokens, compilation) {
|
|
111
|
-
return new Parser(tokens, compilation).parseExpressionOnly();
|
|
112
|
-
}
|
|
113
110
|
class Parser {
|
|
114
111
|
tokens;
|
|
115
112
|
compilation;
|
|
113
|
+
functionContext;
|
|
116
114
|
index = 0;
|
|
117
115
|
breakableDepth = 0;
|
|
118
116
|
conditionalExpressionDepth = 0;
|
|
119
117
|
ifStatementDepth = 0;
|
|
120
118
|
loopDepth = 0;
|
|
121
|
-
generatorBody = false;
|
|
122
119
|
scopes = [new Map()];
|
|
123
120
|
functionScopes = new WeakSet();
|
|
124
121
|
varNames = new WeakMap();
|
|
125
|
-
constructor(tokens, compilation) {
|
|
122
|
+
constructor(tokens, compilation, functionContext = "normal") {
|
|
126
123
|
this.tokens = tokens;
|
|
127
124
|
this.compilation = compilation;
|
|
125
|
+
this.functionContext = functionContext;
|
|
128
126
|
this.functionScopes.add(this.scopes[0]);
|
|
129
127
|
}
|
|
130
128
|
parseTopLevel() {
|
|
@@ -312,9 +310,9 @@ class Parser {
|
|
|
312
310
|
}
|
|
313
311
|
parseArrowFunctionBody(params) {
|
|
314
312
|
if (this.currentToken().type === "punctuator" && this.currentToken().value === "{") {
|
|
315
|
-
return this.withFunctionContext(
|
|
313
|
+
return this.withFunctionContext("normal", () => this.parseBlockStatement(params));
|
|
316
314
|
}
|
|
317
|
-
return this.withFunctionContext(
|
|
315
|
+
return this.withFunctionContext("normal", () => this.parseExpression().node);
|
|
318
316
|
}
|
|
319
317
|
parseBlockStatement(params, catchParam) {
|
|
320
318
|
const start = this.expectPunctuator("{");
|
|
@@ -921,7 +919,7 @@ class Parser {
|
|
|
921
919
|
return parsedParams;
|
|
922
920
|
});
|
|
923
921
|
const generator = generatorToken !== undefined;
|
|
924
|
-
const body = this.withFunctionContext(generator, () => this.parseBlockStatement(params));
|
|
922
|
+
const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
|
|
925
923
|
return {
|
|
926
924
|
type: "FunctionDeclaration",
|
|
927
925
|
async: asyncToken !== undefined,
|
|
@@ -952,30 +950,32 @@ class Parser {
|
|
|
952
950
|
};
|
|
953
951
|
}
|
|
954
952
|
parseArrowParameters() {
|
|
955
|
-
this.
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
while (true) {
|
|
961
|
-
const param = this.parseBindingElement();
|
|
962
|
-
params.push(param);
|
|
963
|
-
const comma = this.consumePunctuator(",");
|
|
964
|
-
if (comma === undefined) {
|
|
965
|
-
break;
|
|
953
|
+
return this.withFunctionContext("parameters", () => {
|
|
954
|
+
this.expectPunctuator("(");
|
|
955
|
+
const params = [];
|
|
956
|
+
if (this.consumePunctuator(")") !== undefined) {
|
|
957
|
+
return params;
|
|
966
958
|
}
|
|
967
|
-
|
|
959
|
+
while (true) {
|
|
960
|
+
const param = this.parseBindingElement();
|
|
961
|
+
params.push(param);
|
|
962
|
+
const comma = this.consumePunctuator(",");
|
|
963
|
+
if (comma === undefined) {
|
|
964
|
+
break;
|
|
965
|
+
}
|
|
966
|
+
if (param.type === "RestElement") {
|
|
967
|
+
if (this.currentToken().type === "punctuator" && this.currentToken().value === ")") {
|
|
968
|
+
throw unexpectedTokenError(comma);
|
|
969
|
+
}
|
|
970
|
+
throw new Error(`Rest element must be the last parameter at line ${comma.start.line}, column ${comma.start.column}.`);
|
|
971
|
+
}
|
|
968
972
|
if (this.currentToken().type === "punctuator" && this.currentToken().value === ")") {
|
|
969
|
-
|
|
973
|
+
break;
|
|
970
974
|
}
|
|
971
|
-
throw new Error(`Rest element must be the last parameter at line ${comma.start.line}, column ${comma.start.column}.`);
|
|
972
|
-
}
|
|
973
|
-
if (this.currentToken().type === "punctuator" && this.currentToken().value === ")") {
|
|
974
|
-
break;
|
|
975
975
|
}
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
976
|
+
this.expectPunctuator(")");
|
|
977
|
+
return params;
|
|
978
|
+
});
|
|
979
979
|
}
|
|
980
980
|
parseBindingElement() {
|
|
981
981
|
if (this.consumePunctuator("...") !== undefined) {
|
|
@@ -1509,7 +1509,7 @@ class Parser {
|
|
|
1509
1509
|
};
|
|
1510
1510
|
}
|
|
1511
1511
|
if (token.type === "keyword" && token.value === "yield") {
|
|
1512
|
-
if (
|
|
1512
|
+
if (this.functionContext !== "generator") {
|
|
1513
1513
|
throw new Error(`yield is only valid inside a generator body at line ${token.start.line}, column ${token.start.column}.`);
|
|
1514
1514
|
}
|
|
1515
1515
|
this.index += 1;
|
|
@@ -1539,9 +1539,12 @@ class Parser {
|
|
|
1539
1539
|
};
|
|
1540
1540
|
}
|
|
1541
1541
|
if (token.type === "keyword" && token.value === "await") {
|
|
1542
|
-
if (this.
|
|
1542
|
+
if (this.functionContext === "generator") {
|
|
1543
1543
|
throw new Error(`generators cannot await; use a regular async function at line ${token.start.line}, column ${token.start.column}.`);
|
|
1544
1544
|
}
|
|
1545
|
+
if (this.functionContext === "parameters") {
|
|
1546
|
+
throw new Error(`await is not valid in function parameters at line ${token.start.line}, column ${token.start.column}.`);
|
|
1547
|
+
}
|
|
1545
1548
|
this.index += 1;
|
|
1546
1549
|
const argument = this.parseUnaryExpression();
|
|
1547
1550
|
return {
|
|
@@ -1666,7 +1669,7 @@ class Parser {
|
|
|
1666
1669
|
continue;
|
|
1667
1670
|
}
|
|
1668
1671
|
if (this.currentToken().type === "template") {
|
|
1669
|
-
const quasi = createTemplateLiteral(this.currentToken(), { allowMalformedEscapes: true }, this.compilation);
|
|
1672
|
+
const quasi = createTemplateLiteral(this.currentToken(), { allowMalformedEscapes: true, functionContext: this.functionContext }, this.compilation);
|
|
1670
1673
|
this.index += 1;
|
|
1671
1674
|
expression = {
|
|
1672
1675
|
node: {
|
|
@@ -1754,7 +1757,7 @@ class Parser {
|
|
|
1754
1757
|
if (token.type === "template") {
|
|
1755
1758
|
this.index += 1;
|
|
1756
1759
|
return {
|
|
1757
|
-
node: createTemplateLiteral(token, { allowMalformedEscapes: false }, this.compilation),
|
|
1760
|
+
node: createTemplateLiteral(token, { allowMalformedEscapes: false, functionContext: this.functionContext }, this.compilation),
|
|
1758
1761
|
parenthesized: false
|
|
1759
1762
|
};
|
|
1760
1763
|
}
|
|
@@ -1871,7 +1874,7 @@ class Parser {
|
|
|
1871
1874
|
return parsedParams;
|
|
1872
1875
|
});
|
|
1873
1876
|
const generator = generatorToken !== undefined;
|
|
1874
|
-
const body = this.withFunctionContext(generator, () => this.parseBlockStatement(params));
|
|
1877
|
+
const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
|
|
1875
1878
|
return {
|
|
1876
1879
|
type: "FunctionExpression",
|
|
1877
1880
|
async: asyncToken !== undefined,
|
|
@@ -2135,7 +2138,7 @@ class Parser {
|
|
|
2135
2138
|
}
|
|
2136
2139
|
return parsedParams;
|
|
2137
2140
|
});
|
|
2138
|
-
const body = this.withFunctionContext(
|
|
2141
|
+
const body = this.withFunctionContext("normal", () => this.parseBlockStatement(params));
|
|
2139
2142
|
return {
|
|
2140
2143
|
type: "FunctionExpression",
|
|
2141
2144
|
async: asyncToken !== undefined,
|
|
@@ -2546,20 +2549,20 @@ class Parser {
|
|
|
2546
2549
|
(nextToken.type === "punctuator" && (nextToken.value === ";" || nextToken.value === "}")) ||
|
|
2547
2550
|
nextToken.type === "eof");
|
|
2548
2551
|
}
|
|
2549
|
-
withFunctionContext(
|
|
2552
|
+
withFunctionContext(functionContext, callback) {
|
|
2550
2553
|
const previousBreakableDepth = this.breakableDepth;
|
|
2551
2554
|
const previousLoopDepth = this.loopDepth;
|
|
2552
|
-
const
|
|
2555
|
+
const previousFunctionContext = this.functionContext;
|
|
2553
2556
|
this.breakableDepth = 0;
|
|
2554
2557
|
this.loopDepth = 0;
|
|
2555
|
-
this.
|
|
2558
|
+
this.functionContext = functionContext;
|
|
2556
2559
|
try {
|
|
2557
2560
|
return callback();
|
|
2558
2561
|
}
|
|
2559
2562
|
finally {
|
|
2560
2563
|
this.breakableDepth = previousBreakableDepth;
|
|
2561
2564
|
this.loopDepth = previousLoopDepth;
|
|
2562
|
-
this.
|
|
2565
|
+
this.functionContext = previousFunctionContext;
|
|
2563
2566
|
}
|
|
2564
2567
|
}
|
|
2565
2568
|
withLoopContext(callback) {
|
|
@@ -3014,7 +3017,7 @@ function createLiteralFromToken(token) {
|
|
|
3014
3017
|
}
|
|
3015
3018
|
return createKeywordLiteral(token);
|
|
3016
3019
|
}
|
|
3017
|
-
function createTemplateLiteral(token, options
|
|
3020
|
+
function createTemplateLiteral(token, options, compilation) {
|
|
3018
3021
|
const raw = token.value;
|
|
3019
3022
|
const expressions = [];
|
|
3020
3023
|
const quasis = [];
|
|
@@ -3030,7 +3033,7 @@ function createTemplateLiteral(token, options = { allowMalformedEscapes: false }
|
|
|
3030
3033
|
quasis.push(createTemplateElement(token.start, raw, quasiStart, cursor, false, options));
|
|
3031
3034
|
const expressionStart = cursor + 2;
|
|
3032
3035
|
const expressionEnd = findTemplateExpressionEnd(raw, expressionStart);
|
|
3033
|
-
expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), compilation));
|
|
3036
|
+
expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), options.functionContext, compilation));
|
|
3034
3037
|
quasiStart = expressionEnd + 1;
|
|
3035
3038
|
cursor = expressionEnd + 1;
|
|
3036
3039
|
continue;
|
|
@@ -3391,13 +3394,13 @@ function decodeHexEscape(value, start) {
|
|
|
3391
3394
|
end: index + 2
|
|
3392
3395
|
};
|
|
3393
3396
|
}
|
|
3394
|
-
function parseEmbeddedExpression(source, base, compilation) {
|
|
3397
|
+
function parseEmbeddedExpression(source, base, functionContext, compilation) {
|
|
3395
3398
|
const tokens = tokenize(source, { allowRegexLiterals: true, compilation }).map((token) => ({
|
|
3396
3399
|
...token,
|
|
3397
3400
|
start: rebasePosition(token.start, base),
|
|
3398
3401
|
end: rebasePosition(token.end, base)
|
|
3399
3402
|
}));
|
|
3400
|
-
return
|
|
3403
|
+
return new Parser(tokens, compilation, functionContext).parseExpressionOnly();
|
|
3401
3404
|
}
|
|
3402
3405
|
export function findRegexLiteral(node) {
|
|
3403
3406
|
if (node === null || node === undefined) {
|