@rohal12/spindle-lsp 0.13.2 → 0.13.3
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/bin.js +849 -163
- package/dist/bin.js.map +3 -3
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -6174,7 +6174,7 @@ function isRawMacro(name) {
|
|
|
6174
6174
|
return RAW_BODY_MACROS.has(name);
|
|
6175
6175
|
}
|
|
6176
6176
|
function isBlockMacro(name) {
|
|
6177
|
-
return BLOCK_MACROS.has(name);
|
|
6177
|
+
return BLOCK_MACROS.has(name) || BLOCK_WIDGETS.has(name);
|
|
6178
6178
|
}
|
|
6179
6179
|
function buildAst(nodes) {
|
|
6180
6180
|
return nodes.map(astNode);
|
|
@@ -6445,7 +6445,7 @@ function getLineInfo(input, offset2) {
|
|
|
6445
6445
|
}
|
|
6446
6446
|
function getOptions(opts) {
|
|
6447
6447
|
var options = {};
|
|
6448
|
-
for (var opt in defaultOptions) options[opt] = opts && hasOwn(opts, opt) ? opts[opt] : defaultOptions[opt];
|
|
6448
|
+
for (var opt in defaultOptions) options[opt] = opts && hasOwn$1(opts, opt) ? opts[opt] : defaultOptions[opt];
|
|
6449
6449
|
if (options.ecmaVersion === "latest") options.ecmaVersion = 1e8;
|
|
6450
6450
|
else if (options.ecmaVersion == null) {
|
|
6451
6451
|
if (!warnedAboutEcmaVersion && typeof console === "object" && console.warn) {
|
|
@@ -6617,7 +6617,7 @@ function transientAssignment(p, end) {
|
|
|
6617
6617
|
if (t === types$1.eof) return false;
|
|
6618
6618
|
if (depth > 0) {
|
|
6619
6619
|
if (OPENERS.has(t)) depth++;
|
|
6620
|
-
else if (CLOSERS.has(t)) depth--;
|
|
6620
|
+
else if (CLOSERS$1.has(t)) depth--;
|
|
6621
6621
|
} else if (t === types$1.bracketL) depth = 1;
|
|
6622
6622
|
else if (t === types$1.dot) {
|
|
6623
6623
|
q2.nextToken();
|
|
@@ -6628,6 +6628,9 @@ function transientAssignment(p, end) {
|
|
|
6628
6628
|
return false;
|
|
6629
6629
|
}
|
|
6630
6630
|
}
|
|
6631
|
+
function isMemberDot(type) {
|
|
6632
|
+
return type === types$1.dot || type === types$1.questionDot;
|
|
6633
|
+
}
|
|
6631
6634
|
function tokenizerAt(src, start, goal, { onComment, afterOperand = false } = {}) {
|
|
6632
6635
|
const p = new SigilParser(onComment ? {
|
|
6633
6636
|
...OPTIONS,
|
|
@@ -6699,6 +6702,9 @@ function bracketsBefore(src, pos) {
|
|
|
6699
6702
|
};
|
|
6700
6703
|
}
|
|
6701
6704
|
function parseCode(src, goal = "expression") {
|
|
6705
|
+
return parseWithAst(src, goal).out;
|
|
6706
|
+
}
|
|
6707
|
+
function parseWithAst(src, goal) {
|
|
6702
6708
|
const percentAt = /* @__PURE__ */ new Map();
|
|
6703
6709
|
for (; ; ) {
|
|
6704
6710
|
const transientsRead = /* @__PURE__ */ new Set();
|
|
@@ -6710,7 +6716,10 @@ function parseCode(src, goal = "expression") {
|
|
|
6710
6716
|
};
|
|
6711
6717
|
walk(ast, src, out, false, false);
|
|
6712
6718
|
out.refs.sort((a, b) => a.start - b.start);
|
|
6713
|
-
return
|
|
6719
|
+
return {
|
|
6720
|
+
out,
|
|
6721
|
+
ast
|
|
6722
|
+
};
|
|
6714
6723
|
} catch (error48) {
|
|
6715
6724
|
const pos = error48.pos ?? -1;
|
|
6716
6725
|
if (!(error48 instanceof SyntaxError) || percentAt.has(pos)) throw error48;
|
|
@@ -7035,7 +7044,7 @@ function walkTokens(src, from, handlers, nesting, goal, oneTemplate) {
|
|
|
7035
7044
|
if (t === types$1.name) {
|
|
7036
7045
|
const sigil = sigilAt(src, tok.start, tok.value);
|
|
7037
7046
|
const property = prev === types$1.dot || prev === types$1.questionDot || (sigil === "$" || sigil === "_") && keyPosition(src, tok.end, prev);
|
|
7038
|
-
if (sigil && !property) handlers.variable?.(sigil,
|
|
7047
|
+
if (sigil && !property) handlers.variable?.(sigil, tok.value.slice(1), tok.start, nesting, tok.end);
|
|
7039
7048
|
else code(tok.start, tok.end);
|
|
7040
7049
|
} else if (t === types$1.string || t === types$1.regexp || t === types$1.template || t === types$1.invalidTemplate) literal3(tok.start, tok.end);
|
|
7041
7050
|
else if (t === types$1.backQuote) {
|
|
@@ -7416,15 +7425,15 @@ function topLevelIndices(src, isSeparator) {
|
|
|
7416
7425
|
} });
|
|
7417
7426
|
return indices;
|
|
7418
7427
|
}
|
|
7419
|
-
function
|
|
7420
|
-
const
|
|
7428
|
+
function topLevelSpans(src, isSeparator) {
|
|
7429
|
+
const spans = [];
|
|
7421
7430
|
let from = 0;
|
|
7422
7431
|
for (const i2 of topLevelIndices(src, isSeparator)) {
|
|
7423
|
-
|
|
7432
|
+
spans.push([from, i2]);
|
|
7424
7433
|
from = i2 + 1;
|
|
7425
7434
|
}
|
|
7426
|
-
|
|
7427
|
-
return
|
|
7435
|
+
spans.push([from, src.length]);
|
|
7436
|
+
return spans;
|
|
7428
7437
|
}
|
|
7429
7438
|
function isStandaloneValue(token) {
|
|
7430
7439
|
return startsLikeValue(token) && !endsWithOperator(token);
|
|
@@ -7441,21 +7450,31 @@ function startsLikeValue(token) {
|
|
|
7441
7450
|
return false;
|
|
7442
7451
|
}
|
|
7443
7452
|
function trySplitOnWhitespace(raw) {
|
|
7444
|
-
const args2 =
|
|
7453
|
+
const args2 = topLevelSpans(raw, isWhitespace).filter(([a, b]) => b > a);
|
|
7445
7454
|
if (args2.length < 2) return null;
|
|
7446
|
-
for (const
|
|
7455
|
+
for (const [a, b] of args2) if (!isStandaloneValue(raw.slice(a, b))) return null;
|
|
7447
7456
|
return args2;
|
|
7448
7457
|
}
|
|
7449
|
-
function
|
|
7450
|
-
const
|
|
7458
|
+
function trimmed$1(src, [start, end]) {
|
|
7459
|
+
const text2 = src.slice(start, end);
|
|
7460
|
+
const lead = text2.length - text2.trimStart().length;
|
|
7461
|
+
return [start + lead, Math.max(start + lead, end - (text2.length - text2.trimEnd().length))];
|
|
7462
|
+
}
|
|
7463
|
+
function splitArgSpans(raw) {
|
|
7464
|
+
const args2 = topLevelSpans(raw, (ch) => ch === ",").map((span) => trimmed$1(raw, span));
|
|
7451
7465
|
const hasComma = args2.length > 1;
|
|
7452
|
-
|
|
7466
|
+
const last2 = args2[args2.length - 1];
|
|
7467
|
+
if (last2[0] === last2[1]) args2.pop();
|
|
7453
7468
|
if (!hasComma && args2.length === 1) {
|
|
7454
|
-
const
|
|
7455
|
-
|
|
7469
|
+
const [start, end] = args2[0];
|
|
7470
|
+
const split = trySplitOnWhitespace(raw.slice(start, end));
|
|
7471
|
+
if (split) return split.map(([a, b]) => [start + a, start + b]);
|
|
7456
7472
|
}
|
|
7457
7473
|
return args2;
|
|
7458
7474
|
}
|
|
7475
|
+
function splitArgs(raw) {
|
|
7476
|
+
return splitArgSpans(raw).map(([a, b]) => raw.slice(a, b));
|
|
7477
|
+
}
|
|
7459
7478
|
function terms(src) {
|
|
7460
7479
|
const spans = [];
|
|
7461
7480
|
let start = 0;
|
|
@@ -7529,8 +7548,9 @@ function readOptions(params, src, { at: at3, spans }) {
|
|
|
7529
7548
|
}
|
|
7530
7549
|
return options;
|
|
7531
7550
|
}
|
|
7532
|
-
function takeFlag(src, word) {
|
|
7551
|
+
function takeFlag(src, word, alone) {
|
|
7533
7552
|
const spans = terms(src);
|
|
7553
|
+
if (spans.length === 1) return alone && slice(src, spans[0]) === word ? [src.length, src.length] : null;
|
|
7534
7554
|
if (spans.length < 2) return null;
|
|
7535
7555
|
if (slice(src, spans[spans.length - 1]) === word) {
|
|
7536
7556
|
const rest = [0, spans[spans.length - 2][1]];
|
|
@@ -7565,8 +7585,9 @@ function trimmed(src, at3) {
|
|
|
7565
7585
|
}
|
|
7566
7586
|
function readGroup(params, src, args2, { at: srcAt, spans }) {
|
|
7567
7587
|
let [text2, at3] = trimmed(src ?? "", srcAt);
|
|
7588
|
+
const alone = !params.some((p) => p.type !== "flag" && p.required);
|
|
7568
7589
|
for (const flag of params.filter((p) => p.type === "flag")) {
|
|
7569
|
-
const rest2 = src === null ? null : takeFlag(text2, flag.name);
|
|
7590
|
+
const rest2 = src === null ? null : takeFlag(text2, flag.name, alone);
|
|
7570
7591
|
args2[flag.name] = rest2 !== null;
|
|
7571
7592
|
if (rest2) [text2, at3] = trimmed(slice(text2, rest2), at3 + rest2[0]);
|
|
7572
7593
|
}
|
|
@@ -7637,9 +7658,40 @@ function passageTarget(arg) {
|
|
|
7637
7658
|
name
|
|
7638
7659
|
};
|
|
7639
7660
|
}
|
|
7661
|
+
function checkParameterTypes(macro, parameters) {
|
|
7662
|
+
const holdsFix = `Give a \`string\` or \`text\` parameter one of ${STRING_HOLDS.join(", ")} to hold (see docs/custom-macros.md#what-a-string-holds).`;
|
|
7663
|
+
for (const param of parameters) {
|
|
7664
|
+
const type = param.type;
|
|
7665
|
+
if (!PARAMETER_TYPES.includes(type)) throw parameterError(macro, param, type === void 0 ? "has no type" : `has the unknown type ${JSON.stringify(type)}`, `Give it one of the types ${PARAMETER_TYPES.join(", ")} (see docs/custom-macros.md#parameter-types), or declare no parameters and read props.rawArgs.`);
|
|
7666
|
+
const holds = param.holds;
|
|
7667
|
+
if (holds !== void 0 && type !== "string" && type !== "text") throw parameterError(macro, param, `is of the type ${type}, which holds what it is`, holdsFix);
|
|
7668
|
+
if (holds !== void 0 && !STRING_HOLDS.includes(holds)) throw parameterError(macro, param, `holds the unknown ${JSON.stringify(holds)}`, holdsFix);
|
|
7669
|
+
if (param.parameters) checkParameterTypes(macro, param.parameters);
|
|
7670
|
+
}
|
|
7671
|
+
}
|
|
7672
|
+
function parameterError(macro, param, problem, fix) {
|
|
7673
|
+
return /* @__PURE__ */ new Error(`spindle: The parameter "${param.name}" of the macro {${macro}} ${problem}. ${fix}`);
|
|
7674
|
+
}
|
|
7675
|
+
function getMacroRegistry() {
|
|
7676
|
+
return Array.from(metadataRegistry.values());
|
|
7677
|
+
}
|
|
7640
7678
|
function subMacroParameters(name) {
|
|
7641
7679
|
return SUB_MACRO_PARAMETERS.get(name.toLowerCase());
|
|
7642
7680
|
}
|
|
7681
|
+
function variableNameError(name, label2 = name) {
|
|
7682
|
+
return name === "__proto__" ? `"${label2}" cannot be used as a variable name (${RESERVED_NAME} is reserved)` : void 0;
|
|
7683
|
+
}
|
|
7684
|
+
function ownEntries(sources, keep = () => true) {
|
|
7685
|
+
const record2 = /* @__PURE__ */ Object.create(null);
|
|
7686
|
+
for (const source of sources) {
|
|
7687
|
+
if (!source) continue;
|
|
7688
|
+
for (const key of Object.keys(source)) {
|
|
7689
|
+
const value = source[key];
|
|
7690
|
+
if (keep(value)) record2[key] = value;
|
|
7691
|
+
}
|
|
7692
|
+
}
|
|
7693
|
+
return record2;
|
|
7694
|
+
}
|
|
7643
7695
|
function withParseCache(fn) {
|
|
7644
7696
|
const outer = parses;
|
|
7645
7697
|
parses = /* @__PURE__ */ new Map();
|
|
@@ -7668,6 +7720,13 @@ function pieceOffset(piece, index) {
|
|
|
7668
7720
|
function extentOf(piece) {
|
|
7669
7721
|
return piece.kind === "code" ? piece.code.length : piece.kind === "text" ? piece.text.length : piece.length;
|
|
7670
7722
|
}
|
|
7723
|
+
function widgetParameters(params, holds = {}) {
|
|
7724
|
+
if (!params.some((param) => hasOwn(holds, param))) return void 0;
|
|
7725
|
+
return params.map((name) => ({
|
|
7726
|
+
name,
|
|
7727
|
+
...hasOwn(holds, name) ? { holds: holds[name] } : {}
|
|
7728
|
+
}));
|
|
7729
|
+
}
|
|
7671
7730
|
function withHolds(params, holds) {
|
|
7672
7731
|
return params.map((param) => {
|
|
7673
7732
|
if (param.parameters) return {
|
|
@@ -7682,8 +7741,13 @@ function withHolds(params, holds) {
|
|
|
7682
7741
|
}
|
|
7683
7742
|
function parameterLookup(macros) {
|
|
7684
7743
|
const parameters = new NameMap();
|
|
7685
|
-
|
|
7686
|
-
|
|
7744
|
+
const widgets = new NameMap();
|
|
7745
|
+
for (const { name, parameters: params, interpolate, widget } of macros) {
|
|
7746
|
+
if (params) parameters.set(name, withHolds(params, holdsByDefault(interpolate)));
|
|
7747
|
+
const declared = widget && widgetParameters(widget.params, widget.holds);
|
|
7748
|
+
if (declared) widgets.set(name, declared);
|
|
7749
|
+
}
|
|
7750
|
+
const lookup = (name) => {
|
|
7687
7751
|
let params = parameters.get(name);
|
|
7688
7752
|
if (!params) {
|
|
7689
7753
|
const sub = subMacroParameters(name);
|
|
@@ -7691,6 +7755,8 @@ function parameterLookup(macros) {
|
|
|
7691
7755
|
}
|
|
7692
7756
|
return params;
|
|
7693
7757
|
};
|
|
7758
|
+
if (widgets.size > 0) lookup.widget = (name) => widgets.get(name);
|
|
7759
|
+
return lookup;
|
|
7694
7760
|
}
|
|
7695
7761
|
function codeGoal(param) {
|
|
7696
7762
|
if (param.type === "expression" || param.type === "passage") return "expression";
|
|
@@ -7781,6 +7847,8 @@ function* codeAndText(src, tokens2, parametersOf2) {
|
|
|
7781
7847
|
}
|
|
7782
7848
|
const params = parametersOf2(name);
|
|
7783
7849
|
if (params) yield* argPieces(args2, argsAt, params, token.name, label2);
|
|
7850
|
+
const widget = parametersOf2.widget?.(name);
|
|
7851
|
+
if (widget) yield* widgetPieces(args2, argsAt, widget, token.name, label2);
|
|
7784
7852
|
}
|
|
7785
7853
|
}
|
|
7786
7854
|
}
|
|
@@ -7836,23 +7904,42 @@ function nestedPiece(piece, toRoot, where2) {
|
|
|
7836
7904
|
...nested
|
|
7837
7905
|
};
|
|
7838
7906
|
}
|
|
7839
|
-
function
|
|
7907
|
+
function escapeAt(raw, i2, escapes) {
|
|
7908
|
+
if (escapes === "quotes") {
|
|
7909
|
+
const next = raw.charAt(i2 + 1);
|
|
7910
|
+
return /["'\\]/.test(next) ? {
|
|
7911
|
+
length: 2,
|
|
7912
|
+
text: next
|
|
7913
|
+
} : void 0;
|
|
7914
|
+
}
|
|
7915
|
+
JS_ESCAPE_RE.lastIndex = i2;
|
|
7916
|
+
const written2 = JS_ESCAPE_RE.exec(raw)?.[0];
|
|
7917
|
+
const text2 = written2 && stringLiteralValue(`"${written2}"`);
|
|
7918
|
+
return typeof text2 === "string" ? {
|
|
7919
|
+
length: written2.length,
|
|
7920
|
+
text: text2
|
|
7921
|
+
} : void 0;
|
|
7922
|
+
}
|
|
7923
|
+
function escapeOffsets(raw, at3, value, escapes) {
|
|
7840
7924
|
const offsets = [];
|
|
7841
7925
|
let escaped = false;
|
|
7842
7926
|
let i2 = 0;
|
|
7843
7927
|
while (offsets.length < value.length) {
|
|
7844
7928
|
if (i2 >= raw.length) return void 0;
|
|
7845
|
-
|
|
7846
|
-
if (
|
|
7847
|
-
|
|
7848
|
-
|
|
7849
|
-
}
|
|
7929
|
+
const escape2 = raw[i2] === "\\" ? escapeAt(raw, i2, escapes) : void 0;
|
|
7930
|
+
if (!escape2) {
|
|
7931
|
+
offsets.push(at3 + i2++);
|
|
7932
|
+
continue;
|
|
7933
|
+
}
|
|
7934
|
+
if (!value.startsWith(escape2.text, offsets.length)) return void 0;
|
|
7935
|
+
for (let k2 = 0; k2 < escape2.text.length; k2++) offsets.push(at3 + i2);
|
|
7936
|
+
escaped = true;
|
|
7937
|
+
i2 += escape2.length;
|
|
7850
7938
|
}
|
|
7851
7939
|
offsets.push(at3 + i2);
|
|
7852
7940
|
return escaped ? offsets : void 0;
|
|
7853
7941
|
}
|
|
7854
7942
|
function* argPieces(args2, offset2, params, macro, label2) {
|
|
7855
|
-
const name = macro.toLowerCase();
|
|
7856
7943
|
let values;
|
|
7857
7944
|
const spans = /* @__PURE__ */ new Map();
|
|
7858
7945
|
try {
|
|
@@ -7865,10 +7952,34 @@ function* argPieces(args2, offset2, params, macro, label2) {
|
|
|
7865
7952
|
offset: offset2,
|
|
7866
7953
|
length: args2.length,
|
|
7867
7954
|
label: label2,
|
|
7868
|
-
macro:
|
|
7955
|
+
macro: macro.toLowerCase()
|
|
7869
7956
|
};
|
|
7870
7957
|
return;
|
|
7871
7958
|
}
|
|
7959
|
+
yield* valuePieces(args2, offset2, params, values, spans, macro, label2, "quotes");
|
|
7960
|
+
}
|
|
7961
|
+
function* widgetPieces(args2, offset2, params, macro, label2) {
|
|
7962
|
+
const written2 = splitArgSpans(args2);
|
|
7963
|
+
const declared = [];
|
|
7964
|
+
const values = {};
|
|
7965
|
+
const spans = /* @__PURE__ */ new Map();
|
|
7966
|
+
params.forEach(({ name, holds }, i2) => {
|
|
7967
|
+
const span = written2[i2];
|
|
7968
|
+
const value = span && stringLiteralValue(args2.slice(...span));
|
|
7969
|
+
if (!holds || value == null) return;
|
|
7970
|
+
const param = {
|
|
7971
|
+
name,
|
|
7972
|
+
type: "string",
|
|
7973
|
+
holds
|
|
7974
|
+
};
|
|
7975
|
+
declared.push(param);
|
|
7976
|
+
values[name] = value;
|
|
7977
|
+
spans.set(param, span);
|
|
7978
|
+
});
|
|
7979
|
+
yield* valuePieces(args2, offset2, declared, values, spans, macro, label2, "javascript");
|
|
7980
|
+
}
|
|
7981
|
+
function* valuePieces(args2, offset2, params, values, spans, macro, label2, escapes) {
|
|
7982
|
+
const name = macro.toLowerCase();
|
|
7872
7983
|
function* visit(list3, from) {
|
|
7873
7984
|
for (const param of list3) {
|
|
7874
7985
|
const value = from[param.name];
|
|
@@ -7913,7 +8024,7 @@ function* argPieces(args2, offset2, params, macro, label2) {
|
|
|
7913
8024
|
}
|
|
7914
8025
|
const at3 = offset2 + start + (value !== written2 && /^["']/.test(written2) ? 1 : 0);
|
|
7915
8026
|
const holds = stringHolds(param);
|
|
7916
|
-
const sourceOffsets = escapeOffsets(args2.slice(at3 - offset2), at3, value);
|
|
8027
|
+
const sourceOffsets = escapeOffsets(args2.slice(at3 - offset2), at3, value, escapes);
|
|
7917
8028
|
if (holds === "expression" || holds === "statements") {
|
|
7918
8029
|
const piece = {
|
|
7919
8030
|
kind: "code",
|
|
@@ -7966,15 +8077,13 @@ function attributeValues(src, token) {
|
|
|
7966
8077
|
function sigilExpressions(value) {
|
|
7967
8078
|
const found = [];
|
|
7968
8079
|
let from = 0;
|
|
7969
|
-
for (const part of splitSigilTemplate(value)) {
|
|
7970
|
-
if (!("expr" in part)) continue;
|
|
7971
|
-
const at3 = locate(value, part.expr, from);
|
|
7972
|
-
from = at3 + part.expr.length;
|
|
8080
|
+
for (const part of splitSigilTemplate(value)) if ("expr" in part) {
|
|
7973
8081
|
found.push({
|
|
7974
8082
|
expr: part.expr,
|
|
7975
|
-
at:
|
|
8083
|
+
at: from + 1
|
|
7976
8084
|
});
|
|
7977
|
-
|
|
8085
|
+
from += part.expr.length + 2;
|
|
8086
|
+
} else from += ("text" in part ? part.text : part.verbatim).length;
|
|
7978
8087
|
return found;
|
|
7979
8088
|
}
|
|
7980
8089
|
function locate(text2, part, from) {
|
|
@@ -7983,23 +8092,6 @@ function locate(text2, part, from) {
|
|
|
7983
8092
|
const anywhere = text2.indexOf(part);
|
|
7984
8093
|
return anywhere >= 0 ? anywhere : from;
|
|
7985
8094
|
}
|
|
7986
|
-
function checkParameterTypes(macro, parameters) {
|
|
7987
|
-
const holdsFix = `Give a \`string\` or \`text\` parameter one of ${STRING_HOLDS.join(", ")} to hold (see docs/custom-macros.md#what-a-string-holds).`;
|
|
7988
|
-
for (const param of parameters) {
|
|
7989
|
-
const type = param.type;
|
|
7990
|
-
if (!PARAMETER_TYPES.includes(type)) throw parameterError(macro, param, type === void 0 ? "has no type" : `has the unknown type ${JSON.stringify(type)}`, `Give it one of the types ${PARAMETER_TYPES.join(", ")} (see docs/custom-macros.md#parameter-types), or declare no parameters and read props.rawArgs.`);
|
|
7991
|
-
const holds = param.holds;
|
|
7992
|
-
if (holds !== void 0 && type !== "string" && type !== "text") throw parameterError(macro, param, `is of the type ${type}, which holds what it is`, holdsFix);
|
|
7993
|
-
if (holds !== void 0 && !STRING_HOLDS.includes(holds)) throw parameterError(macro, param, `holds the unknown ${JSON.stringify(holds)}`, holdsFix);
|
|
7994
|
-
if (param.parameters) checkParameterTypes(macro, param.parameters);
|
|
7995
|
-
}
|
|
7996
|
-
}
|
|
7997
|
-
function parameterError(macro, param, problem, fix) {
|
|
7998
|
-
return /* @__PURE__ */ new Error(`spindle: The parameter "${param.name}" of the macro {${macro}} ${problem}. ${fix}`);
|
|
7999
|
-
}
|
|
8000
|
-
function getMacroRegistry() {
|
|
8001
|
-
return Array.from(metadataRegistry.values());
|
|
8002
|
-
}
|
|
8003
8095
|
function textContainsChildren(text2, parametersOf2) {
|
|
8004
8096
|
if (!text2.includes("{")) return false;
|
|
8005
8097
|
let nodes;
|
|
@@ -8030,6 +8122,7 @@ function astContainsChildren(nodes, parametersOf2 = registeredParameters) {
|
|
|
8030
8122
|
}, parametersOf2) || astContainsChildren(node.children, parametersOf2)) return true;
|
|
8031
8123
|
}
|
|
8032
8124
|
if (node.type === "macro") {
|
|
8125
|
+
if (node.name.toLowerCase() === "widget") continue;
|
|
8033
8126
|
if (tokenTextContainsChildren({
|
|
8034
8127
|
isClose: false,
|
|
8035
8128
|
nameStart: 0,
|
|
@@ -8048,9 +8141,25 @@ function astContainsChildren(nodes, parametersOf2 = registeredParameters) {
|
|
|
8048
8141
|
return false;
|
|
8049
8142
|
}
|
|
8050
8143
|
function widgetDef({ name = "", parameters = "" }) {
|
|
8144
|
+
const params = [];
|
|
8145
|
+
const holds = {};
|
|
8146
|
+
const badHolds = [];
|
|
8147
|
+
for (const word of parameters.split(/[\s,]+/)) {
|
|
8148
|
+
if (!word.startsWith("@")) continue;
|
|
8149
|
+
const [param = word, written2] = word.split(/:(.*)/s);
|
|
8150
|
+
params.push(param);
|
|
8151
|
+
if (written2 === void 0) continue;
|
|
8152
|
+
if (STRING_HOLDS.includes(written2)) holds[param] = written2;
|
|
8153
|
+
else badHolds.push({
|
|
8154
|
+
param,
|
|
8155
|
+
written: written2
|
|
8156
|
+
});
|
|
8157
|
+
}
|
|
8051
8158
|
return {
|
|
8052
8159
|
name,
|
|
8053
|
-
params
|
|
8160
|
+
params,
|
|
8161
|
+
...Object.keys(holds).length > 0 ? { holds } : {},
|
|
8162
|
+
...badHolds.length > 0 ? { badHolds } : {}
|
|
8054
8163
|
};
|
|
8055
8164
|
}
|
|
8056
8165
|
function parseWidgetDef(rawArgs) {
|
|
@@ -8102,8 +8211,11 @@ function widgetDefinitions$1(passages, parametersOf2 = registeredParameters) {
|
|
|
8102
8211
|
}
|
|
8103
8212
|
return found;
|
|
8104
8213
|
}
|
|
8105
|
-
function
|
|
8106
|
-
|
|
8214
|
+
function effectiveWidgetDefinitions(definitions) {
|
|
8215
|
+
const inInit = (def) => def.passage === "StoryInit";
|
|
8216
|
+
const effective = new NameMap();
|
|
8217
|
+
for (const def of [...definitions.filter((def2) => !inInit(def2)), ...definitions.filter(inInit)]) if (def.closeStart !== void 0) effective.set(def.name, def);
|
|
8218
|
+
return [...effective.values()];
|
|
8107
8219
|
}
|
|
8108
8220
|
function distance(a, b) {
|
|
8109
8221
|
let prev = Array.from({ length: b.length + 1 }, (_2, j2) => j2);
|
|
@@ -8257,20 +8369,6 @@ function validateMarkup(passages, options) {
|
|
|
8257
8369
|
for (const [passage, tokens2] of parsed) withParseCache(() => checkPassage(passage, tokens2));
|
|
8258
8370
|
return diagnostics;
|
|
8259
8371
|
}
|
|
8260
|
-
function variableNameError(name, label2 = name) {
|
|
8261
|
-
return name === "__proto__" ? `"${label2}" cannot be used as a variable name (${RESERVED_NAME} is reserved)` : void 0;
|
|
8262
|
-
}
|
|
8263
|
-
function ownEntries(sources, keep = () => true) {
|
|
8264
|
-
const record2 = /* @__PURE__ */ Object.create(null);
|
|
8265
|
-
for (const source of sources) {
|
|
8266
|
-
if (!source) continue;
|
|
8267
|
-
for (const key of Object.keys(source)) {
|
|
8268
|
-
const value = source[key];
|
|
8269
|
-
if (keep(value)) record2[key] = value;
|
|
8270
|
-
}
|
|
8271
|
-
}
|
|
8272
|
-
return record2;
|
|
8273
|
-
}
|
|
8274
8372
|
function staticLiteral(src) {
|
|
8275
8373
|
const reader = new Reader(src);
|
|
8276
8374
|
const value = reader.value();
|
|
@@ -8281,6 +8379,17 @@ function entryOrder(keys) {
|
|
|
8281
8379
|
const all = [...keys];
|
|
8282
8380
|
return [...all.filter((key) => ARRAY_INDEX_RE.test(key)).sort((a, b) => Number(a) - Number(b)), ...all.filter((key) => !ARRAY_INDEX_RE.test(key))];
|
|
8283
8381
|
}
|
|
8382
|
+
function regexLiterals(src, goal = "expression", handlers = {}) {
|
|
8383
|
+
const ends = /* @__PURE__ */ new Map();
|
|
8384
|
+
lexJs(src, {
|
|
8385
|
+
...handlers,
|
|
8386
|
+
literal(text2, index, nesting) {
|
|
8387
|
+
if (text2.charAt(0) === "/" && !/^\/[/*]/.test(text2)) ends.set(index, index + text2.length);
|
|
8388
|
+
handlers.literal?.(text2, index, nesting);
|
|
8389
|
+
}
|
|
8390
|
+
}, goal);
|
|
8391
|
+
return ends;
|
|
8392
|
+
}
|
|
8284
8393
|
function bigintValue(digits) {
|
|
8285
8394
|
try {
|
|
8286
8395
|
return BigInt(digits.replace(/_/g, "")).toString();
|
|
@@ -8406,6 +8515,7 @@ function checkReference(ref2, declared) {
|
|
|
8406
8515
|
const part = ref2.path[i2];
|
|
8407
8516
|
if (current2.type === "array") return null;
|
|
8408
8517
|
if (current2.type === "null") return null;
|
|
8518
|
+
if (current2.type === "string" && isArrayIndex(part)) continue;
|
|
8409
8519
|
const sample = PRIMITIVE_SAMPLES[current2.type];
|
|
8410
8520
|
if (sample && part in sample) {
|
|
8411
8521
|
const memberType = typeof sample[part];
|
|
@@ -8421,9 +8531,20 @@ function checkReference(ref2, declared) {
|
|
|
8421
8531
|
}
|
|
8422
8532
|
return null;
|
|
8423
8533
|
}
|
|
8424
|
-
function referenceAt(code,
|
|
8534
|
+
function referenceAt(code, sigil, name, start, end, at3) {
|
|
8535
|
+
FIELD_PATH_RE.lastIndex = end;
|
|
8536
|
+
const fields = FIELD_PATH_RE.exec(code)[0];
|
|
8537
|
+
return {
|
|
8538
|
+
sigil,
|
|
8539
|
+
name,
|
|
8540
|
+
path: fields ? fields.slice(1).split(".") : [],
|
|
8541
|
+
start: at3(start),
|
|
8542
|
+
end: at3(end + fields.length)
|
|
8543
|
+
};
|
|
8544
|
+
}
|
|
8545
|
+
function termReferenceAt(term, index, at3) {
|
|
8425
8546
|
VAR_PATH_RE.lastIndex = index;
|
|
8426
|
-
const match = VAR_PATH_RE.exec(
|
|
8547
|
+
const match = VAR_PATH_RE.exec(term);
|
|
8427
8548
|
if (!match) return void 0;
|
|
8428
8549
|
const [name, ...path] = match[2].split(".");
|
|
8429
8550
|
return {
|
|
@@ -8449,39 +8570,42 @@ function scanCode(code, at3, emit, goal = "expression") {
|
|
|
8449
8570
|
}
|
|
8450
8571
|
for (const ref2 of parsed.refs) {
|
|
8451
8572
|
if (ref2.sigil !== "$" && ref2.sigil !== "%") continue;
|
|
8452
|
-
|
|
8453
|
-
if (found) emit(found);
|
|
8573
|
+
emit(referenceAt(code, ref2.sigil, ref2.name, ref2.start, ref2.end, at3));
|
|
8454
8574
|
}
|
|
8455
8575
|
}
|
|
8456
8576
|
function scanCodeLeniently(code, at3, emit, goal) {
|
|
8457
8577
|
lexJs(code, {
|
|
8458
|
-
variable(sigil,
|
|
8578
|
+
variable(sigil, name, index, _nesting, end) {
|
|
8459
8579
|
if (sigil !== "$" && sigil !== "%") return;
|
|
8460
|
-
|
|
8461
|
-
if (found) emit(found);
|
|
8580
|
+
emit(referenceAt(code, sigil, name, index, end, at3));
|
|
8462
8581
|
},
|
|
8463
8582
|
literal() {
|
|
8464
8583
|
}
|
|
8465
8584
|
}, goal);
|
|
8466
8585
|
}
|
|
8467
|
-
function
|
|
8586
|
+
function scanPieces(pieces, at3, emit, options) {
|
|
8587
|
+
for (const piece of pieces) {
|
|
8588
|
+
const pieceAt = (i2) => at3(pieceOffset(piece, i2));
|
|
8589
|
+
if (piece.kind === "code") scanCode(piece.code, pieceAt, emit, piece.goal);
|
|
8590
|
+
else if (piece.kind === "text") scanInterpolations(piece.text, pieceAt, emit, {
|
|
8591
|
+
...options,
|
|
8592
|
+
storeVarMacros: NO_STORE_VAR_MACROS
|
|
8593
|
+
});
|
|
8594
|
+
}
|
|
8595
|
+
}
|
|
8596
|
+
function scanArgs(token, parametersOf2, at3, emit, options) {
|
|
8468
8597
|
if (!token.rawArgs) return;
|
|
8598
|
+
const params = parametersOf2(token.name);
|
|
8599
|
+
let byParameters = false;
|
|
8469
8600
|
if (params) {
|
|
8470
8601
|
if (options.all && !options.storeVarMacros.has(token.name.toLowerCase())) scanVariableParameters(token, params, at3, emit);
|
|
8471
8602
|
const pieces = [...argPieces(token.rawArgs, token.argsStart, params, token.name, "")];
|
|
8472
|
-
|
|
8473
|
-
|
|
8474
|
-
const pieceAt = (i2) => at3(pieceOffset(piece, i2));
|
|
8475
|
-
if (piece.kind === "code") scanCode(piece.code, pieceAt, emit, piece.goal);
|
|
8476
|
-
else if (piece.kind === "text") scanInterpolations(piece.text, pieceAt, emit, {
|
|
8477
|
-
...options,
|
|
8478
|
-
storeVarMacros: NO_STORE_VAR_MACROS
|
|
8479
|
-
});
|
|
8480
|
-
}
|
|
8481
|
-
return;
|
|
8482
|
-
}
|
|
8603
|
+
byParameters = !pieces.some((piece) => piece.kind === "argument-error");
|
|
8604
|
+
if (byParameters) scanPieces(pieces, at3, emit, options);
|
|
8483
8605
|
}
|
|
8484
|
-
scanCode(token.rawArgs, (i2) => at3(token.argsStart + i2), emit);
|
|
8606
|
+
if (!byParameters) scanCode(token.rawArgs, (i2) => at3(token.argsStart + i2), emit);
|
|
8607
|
+
const widget = parametersOf2.widget?.(token.name);
|
|
8608
|
+
if (widget) scanPieces(widgetPieces(token.rawArgs, token.argsStart, widget, token.name, ""), at3, emit, options);
|
|
8485
8609
|
}
|
|
8486
8610
|
function scanVariableParameters(token, params, at3, emit) {
|
|
8487
8611
|
const spans = /* @__PURE__ */ new Map();
|
|
@@ -8494,7 +8618,7 @@ function scanVariableParameters(token, params, at3, emit) {
|
|
|
8494
8618
|
for (const param of params) {
|
|
8495
8619
|
const span = spans.get(param);
|
|
8496
8620
|
if (param.type !== "variable" || !span) continue;
|
|
8497
|
-
const ref2 =
|
|
8621
|
+
const ref2 = termReferenceAt(token.rawArgs.slice(span[0], span[1]), 0, (i2) => at3(token.argsStart + span[0] + i2));
|
|
8498
8622
|
if (ref2) emit(ref2);
|
|
8499
8623
|
}
|
|
8500
8624
|
}
|
|
@@ -8533,7 +8657,7 @@ function collectTokenRefs(content, tokens2, at3, emit, options) {
|
|
|
8533
8657
|
else scanInterpolations(value, valueIn, emit, options);
|
|
8534
8658
|
}
|
|
8535
8659
|
else if (token.type === "macro" && !token.isClose) {
|
|
8536
|
-
scanArgs(token, parametersOf2
|
|
8660
|
+
scanArgs(token, parametersOf2, at3, emit, options);
|
|
8537
8661
|
scanSelectors(content, token, at3, emit, options);
|
|
8538
8662
|
if (storeVarMacros.has(token.name.toLowerCase())) {
|
|
8539
8663
|
const lead = token.rawArgs.length - token.rawArgs.trimStart().length;
|
|
@@ -8569,7 +8693,7 @@ function collectTokenRefs(content, tokens2, at3, emit, options) {
|
|
|
8569
8693
|
function collectVariableReferences(content, options) {
|
|
8570
8694
|
const found = [];
|
|
8571
8695
|
withParseCache(() => collectTokenRefs(content, tokensOf(content, false, options), (i2) => i2, (ref2) => found.push(ref2), options));
|
|
8572
|
-
return found;
|
|
8696
|
+
return found.sort((a, b) => a.start - b.start);
|
|
8573
8697
|
}
|
|
8574
8698
|
function checkVariableReferences(passages, declared, options) {
|
|
8575
8699
|
const diagnostics = [];
|
|
@@ -8593,10 +8717,13 @@ function checkVariableReferences(passages, declared, options) {
|
|
|
8593
8717
|
}
|
|
8594
8718
|
function codeOnly(source) {
|
|
8595
8719
|
const chars = Array.from({ length: source.length }, () => " ");
|
|
8596
|
-
|
|
8720
|
+
const regexes = regexLiterals(source, "statements", { code(ch, index) {
|
|
8597
8721
|
for (let k2 = 0; k2 < ch.length; k2++) chars[index + k2] = ch[k2];
|
|
8598
|
-
} }
|
|
8599
|
-
return
|
|
8722
|
+
} });
|
|
8723
|
+
return {
|
|
8724
|
+
code: chars.join(""),
|
|
8725
|
+
regexes
|
|
8726
|
+
};
|
|
8600
8727
|
}
|
|
8601
8728
|
function written(props, key, read) {
|
|
8602
8729
|
const value = read(props.get(key));
|
|
@@ -8659,18 +8786,23 @@ function macroOf(config2) {
|
|
|
8659
8786
|
return macro;
|
|
8660
8787
|
}
|
|
8661
8788
|
function discoverMacros(source) {
|
|
8662
|
-
const code = codeOnly(source);
|
|
8789
|
+
const { code, regexes } = codeOnly(source);
|
|
8663
8790
|
const found = [];
|
|
8791
|
+
let bindings;
|
|
8664
8792
|
for (const call of code.matchAll(CALL_RE)) {
|
|
8665
8793
|
let at3 = call.index + call[0].length;
|
|
8666
8794
|
if (code.charAt(at3) !== "{") {
|
|
8667
8795
|
const variable = IDENTIFIER_ARGUMENT_RE.exec(code.slice(at3))?.[1];
|
|
8668
8796
|
if (!variable) continue;
|
|
8669
|
-
|
|
8670
|
-
|
|
8671
|
-
|
|
8672
|
-
|
|
8673
|
-
|
|
8797
|
+
bindings ?? (bindings = new Bindings(code));
|
|
8798
|
+
const object3 = bindings.objectOf(variable, call.index, CONFIG_KEYS);
|
|
8799
|
+
if (object3 === void 0) continue;
|
|
8800
|
+
at3 = object3;
|
|
8801
|
+
}
|
|
8802
|
+
const reader = new ConfigReader(source, {
|
|
8803
|
+
goal: "statements",
|
|
8804
|
+
regexes
|
|
8805
|
+
});
|
|
8674
8806
|
reader.i = at3;
|
|
8675
8807
|
const config2 = reader.datum();
|
|
8676
8808
|
const macro = config2 && macroOf(config2);
|
|
@@ -8682,8 +8814,9 @@ function validateStoryMarkup(passages, macros, options = {}) {
|
|
|
8682
8814
|
const list3 = [...passages];
|
|
8683
8815
|
const all = [...macros];
|
|
8684
8816
|
const known = /* @__PURE__ */ new Set();
|
|
8685
|
-
const
|
|
8686
|
-
const blocks = new Set(
|
|
8817
|
+
const widgets = widgetDefinitions$1(list3, parameterLookup(all));
|
|
8818
|
+
const blocks = new Set(effectiveWidgetDefinitions(widgets).filter((def) => def.block).map((def) => def.name.toLowerCase()));
|
|
8819
|
+
const parametersOf2 = parameterLookup([...all, ...definedWidgetMacros(widgets)]);
|
|
8687
8820
|
for (const macro of all) {
|
|
8688
8821
|
const name = macro.name.toLowerCase();
|
|
8689
8822
|
known.add(name);
|
|
@@ -8699,6 +8832,12 @@ function validateStoryMarkup(passages, macros, options = {}) {
|
|
|
8699
8832
|
tolerant: options.tolerant
|
|
8700
8833
|
});
|
|
8701
8834
|
}
|
|
8835
|
+
function definedWidgetMacros(widgets) {
|
|
8836
|
+
return widgets.map((widget) => ({
|
|
8837
|
+
name: widget.name,
|
|
8838
|
+
widget
|
|
8839
|
+
}));
|
|
8840
|
+
}
|
|
8702
8841
|
function blockLookup(macros) {
|
|
8703
8842
|
const blocks = new Set(macros.filter((m) => m.block).map((m) => m.name.toLowerCase()));
|
|
8704
8843
|
return (name) => blocks.has(name.toLowerCase()) || isBlockMacro(name);
|
|
@@ -8711,12 +8850,13 @@ function passagePieces(source, macros = []) {
|
|
|
8711
8850
|
function widgetDefinitions(passages, macros = []) {
|
|
8712
8851
|
return widgetDefinitions$1(passages, parameterLookup([...macros]));
|
|
8713
8852
|
}
|
|
8714
|
-
function referenceOptions(macros, all = false) {
|
|
8853
|
+
function referenceOptions(macros, all = false, passages = []) {
|
|
8715
8854
|
const list3 = [...macros];
|
|
8855
|
+
const widgets = widgetDefinitions$1(passages, parameterLookup(list3));
|
|
8716
8856
|
return {
|
|
8717
8857
|
all,
|
|
8718
8858
|
storeVarMacros: new Set(list3.filter((m) => m.storeVar).map((m) => m.name.toLowerCase())),
|
|
8719
|
-
parametersOf: parameterLookup(list3),
|
|
8859
|
+
parametersOf: parameterLookup([...list3, ...definedWidgetMacros(widgets)]),
|
|
8720
8860
|
tolerant: true
|
|
8721
8861
|
};
|
|
8722
8862
|
}
|
|
@@ -8724,9 +8864,10 @@ function variableReferences(source, macros = [], options = {}) {
|
|
|
8724
8864
|
return collectVariableReferences(source, referenceOptions(macros, options.all));
|
|
8725
8865
|
}
|
|
8726
8866
|
function validateVariableReferences(passages, declarations, macros = []) {
|
|
8727
|
-
|
|
8867
|
+
const list3 = [...passages];
|
|
8868
|
+
return checkVariableReferences(list3.filter((p) => !p.tags?.some((t) => NOT_MARKUP_TAGS.includes(t))), declarations, referenceOptions(macros, false, list3));
|
|
8728
8869
|
}
|
|
8729
|
-
var SIGIL_SCOPES, SIGIL_CHARS, grammar_shared_default, LB, RB, SIGIL_SCOPES$1, withSelectors, VOID_TAGS, BRANCH_PARENT$1, LINK_SEPARATORS, NO_SELECTORS, EMAIL_AUTOLINK, peg$SyntaxError, NameMap, NameSet, BLOCK_MACROS, RAW_BODY_MACROS, BRANCHING, quoteArg, last$1, BRANCH_PARENT, isBranchTag, lowerName, nameOf, closerOf, closes, astralIdentifierCodes, astralIdentifierStartCodes, nonASCIIidentifierChars, nonASCIIidentifierStartChars, reservedWords, ecma5AndLessKeywords, keywords$1, keywordRelationalOperator, nonASCIIidentifierStart, nonASCIIidentifier, TokenType, beforeExpr, startsExpr, keywords, types$1, lineBreak, lineBreakG, nonASCIIwhitespace, skipWhiteSpace, ref, hasOwnProperty, toString, hasOwn, isArray, regexpCache, loneSurrogate, Position, SourceLocation, defaultOptions, warnedAboutEcmaVersion, SCOPE_TOP, SCOPE_FUNCTION, SCOPE_ASYNC, SCOPE_GENERATOR, SCOPE_ARROW, SCOPE_SIMPLE_CATCH, SCOPE_SUPER, SCOPE_DIRECT_SUPER, SCOPE_CLASS_STATIC_BLOCK, SCOPE_CLASS_FIELD_INIT, SCOPE_SWITCH, SCOPE_VAR, BIND_NONE, BIND_VAR, BIND_LEXICAL, BIND_FUNCTION, BIND_SIMPLE_CATCH, BIND_OUTSIDE, Parser, prototypeAccessors, pp$9, literal, DestructuringErrors, pp$8, loopLabel, switchLabel, empty$1, FUNC_STATEMENT, FUNC_HANGING_STATEMENT, FUNC_NULLABLE_ID, pp$7, TokContext, types, pp$6, pp$5, empty, pp$4, pp$3, Scope, Node, pp$2, scriptValuesAddedInUnicode, ecma9BinaryProperties, ecma10BinaryProperties, ecma11BinaryProperties, ecma12BinaryProperties, ecma13BinaryProperties, unicodeBinaryProperties, unicodeBinaryPropertiesOfStrings, unicodeGeneralCategoryValues, ecma9ScriptValues, ecma10ScriptValues, ecma11ScriptValues, ecma12ScriptValues, ecma13ScriptValues, unicodeScriptValues, data, ecmaVersion, i, list, pp$1, BranchID, RegExpValidationState, CharSetNone, CharSetOk, CharSetString, Token, pp, INVALID_TEMPLATE_ESCAPE_ERROR, OPTIONS, AT_NAME_RE, TRANS_NAME_RE, SIGIL_IDENT_RE, LINE_BREAK_RE, NOT_A_BODY_RE, OPERAND_ENDS, SigilParser, OPENERS, CLOSERS, CodeSyntaxError, last, CLOSER, isNode, NAMESPACE_NAME, WORD_RE$2, FLAGS_RE, WORDS_BEFORE_STRING, NON_STRING_QUOTE_PREFIX, memoInput, memo, defaultCodeEnd, defaultHooks, MarkupError, OFFSET_FIELD, listeners, TRAILING_OPERATOR_RE, slice, MacroArgumentError, WORD_RE$1, NUMBER_RE$1, WORD_OR_PUNCT_RE, LEADING_OPERATOR_RE, takesRest, SUB_MACRO_PARAMETERS, parses, CONDITION_MACROS, PASSAGE_BODIES, holdsByDefault,
|
|
8870
|
+
var SIGIL_SCOPES, SIGIL_CHARS, grammar_shared_default, LB, RB, SIGIL_SCOPES$1, withSelectors, VOID_TAGS, BRANCH_PARENT$1, LINK_SEPARATORS, NO_SELECTORS, EMAIL_AUTOLINK, peg$SyntaxError, NameMap, NameSet, BLOCK_MACROS, BLOCK_WIDGETS, RAW_BODY_MACROS, BRANCHING, quoteArg, last$1, BRANCH_PARENT, isBranchTag, lowerName, nameOf, closerOf, closes, astralIdentifierCodes, astralIdentifierStartCodes, nonASCIIidentifierChars, nonASCIIidentifierStartChars, reservedWords, ecma5AndLessKeywords, keywords$1, keywordRelationalOperator, nonASCIIidentifierStart, nonASCIIidentifier, TokenType, beforeExpr, startsExpr, keywords, types$1, lineBreak, lineBreakG, nonASCIIwhitespace, skipWhiteSpace, ref, hasOwnProperty, toString, hasOwn$1, isArray, regexpCache, loneSurrogate, Position, SourceLocation, defaultOptions, warnedAboutEcmaVersion, SCOPE_TOP, SCOPE_FUNCTION, SCOPE_ASYNC, SCOPE_GENERATOR, SCOPE_ARROW, SCOPE_SIMPLE_CATCH, SCOPE_SUPER, SCOPE_DIRECT_SUPER, SCOPE_CLASS_STATIC_BLOCK, SCOPE_CLASS_FIELD_INIT, SCOPE_SWITCH, SCOPE_VAR, BIND_NONE, BIND_VAR, BIND_LEXICAL, BIND_FUNCTION, BIND_SIMPLE_CATCH, BIND_OUTSIDE, Parser, prototypeAccessors, pp$9, literal, DestructuringErrors, pp$8, loopLabel, switchLabel, empty$1, FUNC_STATEMENT, FUNC_HANGING_STATEMENT, FUNC_NULLABLE_ID, pp$7, TokContext, types, pp$6, pp$5, empty, pp$4, pp$3, Scope, Node, pp$2, scriptValuesAddedInUnicode, ecma9BinaryProperties, ecma10BinaryProperties, ecma11BinaryProperties, ecma12BinaryProperties, ecma13BinaryProperties, unicodeBinaryProperties, unicodeBinaryPropertiesOfStrings, unicodeGeneralCategoryValues, ecma9ScriptValues, ecma10ScriptValues, ecma11ScriptValues, ecma12ScriptValues, ecma13ScriptValues, unicodeScriptValues, data, ecmaVersion, i, list, pp$1, BranchID, RegExpValidationState, CharSetNone, CharSetOk, CharSetString, Token, pp, INVALID_TEMPLATE_ESCAPE_ERROR, OPTIONS, AT_NAME_RE, TRANS_NAME_RE, SIGIL_IDENT_RE, LINE_BREAK_RE, NOT_A_BODY_RE, OPERAND_ENDS, SigilParser, OPENERS, CLOSERS$1, CodeSyntaxError, last, CLOSER, isNode, NAMESPACE_NAME, WORD_RE$2, FLAGS_RE, WORDS_BEFORE_STRING, NON_STRING_QUOTE_PREFIX, memoInput, memo, defaultCodeEnd, defaultHooks, MarkupError, OFFSET_FIELD, listeners, TRAILING_OPERATOR_RE, slice, MacroArgumentError, WORD_RE$1, NUMBER_RE$1, WORD_OR_PUNCT_RE, LEADING_OPERATOR_RE, takesRest, PARAMETER_TYPES, STRING_HOLDS, metadataRegistry, SUB_MACRO_PARAMETERS, RESERVED_NAME, isArrayIndex, hasOwn, createNamespace, parses, CONDITION_MACROS, PASSAGE_BODIES, holdsByDefault, JS_ESCAPE_RE, textPiece, registeredParameters, WIDGET_PARAMETERS, NOT_MARKUP, NOT_MARKUP_TAGS$1, BRANCH_MACROS, didYouMean, PASSAGE_ARGUMENT_HINT, BARE_WORD_RE, NUMBER_RE, IDENT_RE, KEY_RE, ARROW_RE, LINE_END_RE, ARRAY_INDEX_RE, UNSUPPORTED_UNDEFINED, Reader, VAR_PATH_RE, QUOTED_VAR_ARG_RE, VALID_VAR_TYPES, PRIMITIVE_SAMPLES, UNSUPPORTED_TYPE, NO_STORE_VAR_MACROS, FIELD_PATH_RE, CLOSERS, BLOCK_WORDS, NOT_PARAMETERS, DECLARATIONS, WRITE_RE, MUTATORS, MUTATING_CALL_RE, BEFORE_BINDING, isWordChar, Bindings, CALL_RE, IDENTIFIER_ARGUMENT_RE, WORD_RE, MODIFIER_RE, KEY_START_RE, CONFIG_KEYS, ConfigReader, stringOf, booleanOf, textOf, stringsOf, NOT_MARKUP_TAGS;
|
|
8730
8871
|
var init_story_variables = __esm({
|
|
8731
8872
|
"node_modules/@rohal12/spindle/dist/pkg/story-variables.js"() {
|
|
8732
8873
|
SIGIL_SCOPES = {
|
|
@@ -8891,6 +9032,9 @@ var init_story_variables = __esm({
|
|
|
8891
9032
|
delete(name) {
|
|
8892
9033
|
this.names.delete(name);
|
|
8893
9034
|
}
|
|
9035
|
+
clear() {
|
|
9036
|
+
this.names.clear();
|
|
9037
|
+
}
|
|
8894
9038
|
};
|
|
8895
9039
|
BLOCK_MACROS = new NameSet([
|
|
8896
9040
|
"if",
|
|
@@ -8908,6 +9052,7 @@ var init_story_variables = __esm({
|
|
|
8908
9052
|
"span",
|
|
8909
9053
|
"nobr"
|
|
8910
9054
|
]);
|
|
9055
|
+
BLOCK_WIDGETS = new NameSet();
|
|
8911
9056
|
RAW_BODY_MACROS = /* @__PURE__ */ new Set(["do"]);
|
|
8912
9057
|
BRANCHING = /* @__PURE__ */ new Set([
|
|
8913
9058
|
"if",
|
|
@@ -10085,7 +10230,7 @@ var init_story_variables = __esm({
|
|
|
10085
10230
|
ref = Object.prototype;
|
|
10086
10231
|
hasOwnProperty = ref.hasOwnProperty;
|
|
10087
10232
|
toString = ref.toString;
|
|
10088
|
-
hasOwn = Object.hasOwn || (function(obj, propName) {
|
|
10233
|
+
hasOwn$1 = Object.hasOwn || (function(obj, propName) {
|
|
10089
10234
|
return hasOwnProperty.call(obj, propName);
|
|
10090
10235
|
});
|
|
10091
10236
|
isArray = Array.isArray || (function(obj) {
|
|
@@ -11015,7 +11160,7 @@ var init_story_variables = __esm({
|
|
|
11015
11160
|
var parent = len === 0 ? null : this.privateNameStack[len - 1];
|
|
11016
11161
|
for (var i2 = 0; i2 < used.length; ++i2) {
|
|
11017
11162
|
var id = used[i2];
|
|
11018
|
-
if (!hasOwn(declared, id.name)) {
|
|
11163
|
+
if (!hasOwn$1(declared, id.name)) {
|
|
11019
11164
|
if (parent) parent.used.push(id);
|
|
11020
11165
|
else this.raiseRecoverable(id.start, "Private field '#" + id.name + "' must be declared in an enclosing class");
|
|
11021
11166
|
}
|
|
@@ -11093,7 +11238,7 @@ var init_story_variables = __esm({
|
|
|
11093
11238
|
pp$8.checkExport = function(exports$1, name, pos) {
|
|
11094
11239
|
if (!exports$1) return;
|
|
11095
11240
|
if (typeof name !== "string") name = name.type === "Identifier" ? name.name : name.value;
|
|
11096
|
-
if (hasOwn(exports$1, name)) this.raiseRecoverable(pos, "Duplicate export '" + name + "'");
|
|
11241
|
+
if (hasOwn$1(exports$1, name)) this.raiseRecoverable(pos, "Duplicate export '" + name + "'");
|
|
11097
11242
|
exports$1[name] = true;
|
|
11098
11243
|
};
|
|
11099
11244
|
pp$8.checkPatternExport = function(exports$1, pat) {
|
|
@@ -11212,7 +11357,7 @@ var init_story_variables = __esm({
|
|
|
11212
11357
|
} else first = false;
|
|
11213
11358
|
var attr = this.parseImportAttribute();
|
|
11214
11359
|
var keyName = attr.key.type === "Identifier" ? attr.key.name : attr.key.value;
|
|
11215
|
-
if (hasOwn(attributeKeys, keyName)) this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'");
|
|
11360
|
+
if (hasOwn$1(attributeKeys, keyName)) this.raiseRecoverable(attr.key.start, "Duplicate attribute key '" + keyName + "'");
|
|
11216
11361
|
attributeKeys[keyName] = true;
|
|
11217
11362
|
nodes.push(attr);
|
|
11218
11363
|
}
|
|
@@ -11374,7 +11519,7 @@ var init_story_variables = __esm({
|
|
|
11374
11519
|
if (isBind) {
|
|
11375
11520
|
if (bindingType === BIND_LEXICAL && expr.name === "let") this.raiseRecoverable(expr.start, "let is disallowed as a lexically bound name");
|
|
11376
11521
|
if (checkClashes) {
|
|
11377
|
-
if (hasOwn(checkClashes, expr.name)) this.raiseRecoverable(expr.start, "Argument name clash");
|
|
11522
|
+
if (hasOwn$1(checkClashes, expr.name)) this.raiseRecoverable(expr.start, "Argument name clash");
|
|
11378
11523
|
checkClashes[expr.name] = true;
|
|
11379
11524
|
}
|
|
11380
11525
|
if (bindingType !== BIND_OUTSIDE) this.declareName(expr.name, bindingType, expr.start);
|
|
@@ -13034,7 +13179,7 @@ var init_story_variables = __esm({
|
|
|
13034
13179
|
return CharSetNone;
|
|
13035
13180
|
};
|
|
13036
13181
|
pp$1.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
|
|
13037
|
-
if (!hasOwn(state.unicodeProperties.nonBinary, name)) state.raise("Invalid property name");
|
|
13182
|
+
if (!hasOwn$1(state.unicodeProperties.nonBinary, name)) state.raise("Invalid property name");
|
|
13038
13183
|
if (!state.unicodeProperties.nonBinary[name].test(value)) state.raise("Invalid property value");
|
|
13039
13184
|
};
|
|
13040
13185
|
pp$1.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
|
|
@@ -14026,15 +14171,15 @@ var init_story_variables = __esm({
|
|
|
14026
14171
|
}
|
|
14027
14172
|
const self = this;
|
|
14028
14173
|
const prevType = self.type;
|
|
14029
|
-
this.prevValue = self.value;
|
|
14030
|
-
const property = type.keyword !== void 0 && (prevType
|
|
14174
|
+
this.prevValue = isMemberDot(this.typeBeforeLast) ? void 0 : self.value;
|
|
14175
|
+
const property = type.keyword !== void 0 && isMemberDot(prevType) || (type === types$1._function || type === types$1._class) && notABody(self.input, self.pos);
|
|
14031
14176
|
if (!property && (type === types$1._function || type === types$1._class)) {
|
|
14032
14177
|
const before = type === types$1._function && prevType === types$1.name && this.prevValue === "async" && !this.breakHere ? this.typeBeforeLast : prevType;
|
|
14033
14178
|
self.type = before === types$1.colon && this.colonEndsTernary ? types$1.parenL : before;
|
|
14034
14179
|
}
|
|
14035
14180
|
this.typeBeforeLast = prevType;
|
|
14036
14181
|
super.finishToken(property ? types$1.name : type, value);
|
|
14037
|
-
if (type === types$1.name && value === "of" && (prevType === types$1._const || prevType === types$1._var || this.prevValue === "let")) self.exprAllowed = false;
|
|
14182
|
+
if (type === types$1.name && (isMemberDot(prevType) || value === "of" && (prevType === types$1._const || prevType === types$1._var || this.prevValue === "let"))) self.exprAllowed = false;
|
|
14038
14183
|
}
|
|
14039
14184
|
braceIsBlock(prevType) {
|
|
14040
14185
|
if (prevType === types$1.colon && this.colonEndsTernary) return false;
|
|
@@ -14054,7 +14199,7 @@ var init_story_variables = __esm({
|
|
|
14054
14199
|
types$1.braceL,
|
|
14055
14200
|
types$1.dollarBraceL
|
|
14056
14201
|
]);
|
|
14057
|
-
CLOSERS = /* @__PURE__ */ new Set([
|
|
14202
|
+
CLOSERS$1 = /* @__PURE__ */ new Set([
|
|
14058
14203
|
types$1.parenR,
|
|
14059
14204
|
types$1.bracketR,
|
|
14060
14205
|
types$1.braceR
|
|
@@ -14163,28 +14308,6 @@ var init_story_variables = __esm({
|
|
|
14163
14308
|
WORD_OR_PUNCT_RE = /\S+/y;
|
|
14164
14309
|
LEADING_OPERATOR_RE = /^(?:[-+*/&|^=<>?:,.]|%(?![A-Za-z_]))/;
|
|
14165
14310
|
takesRest = (param) => param.type === "expression" || param.type === "statements" || param.type === "passage" || param.type === "text";
|
|
14166
|
-
SUB_MACRO_PARAMETERS = /* @__PURE__ */ new Map([["option", [{
|
|
14167
|
-
name: "value",
|
|
14168
|
-
type: "string",
|
|
14169
|
-
holds: "text",
|
|
14170
|
-
required: true
|
|
14171
|
-
}]]]);
|
|
14172
|
-
parses = null;
|
|
14173
|
-
CONDITION_MACROS = /* @__PURE__ */ new Set([
|
|
14174
|
-
"if",
|
|
14175
|
-
"elseif",
|
|
14176
|
-
"case"
|
|
14177
|
-
]);
|
|
14178
|
-
PASSAGE_BODIES = /* @__PURE__ */ new Set(["dialog"]);
|
|
14179
|
-
holdsByDefault = (interpolate) => interpolate ? "markup" : "text";
|
|
14180
|
-
textPiece = (text2, offset2, where2) => ({
|
|
14181
|
-
kind: "text",
|
|
14182
|
-
text: text2,
|
|
14183
|
-
offset: offset2,
|
|
14184
|
-
where: where2,
|
|
14185
|
-
tokens: [],
|
|
14186
|
-
errors: []
|
|
14187
|
-
});
|
|
14188
14311
|
new NameMap();
|
|
14189
14312
|
new NameMap();
|
|
14190
14313
|
new NameSet();
|
|
@@ -14210,6 +14333,34 @@ var init_story_variables = __esm({
|
|
|
14210
14333
|
"statements"
|
|
14211
14334
|
];
|
|
14212
14335
|
metadataRegistry = new NameMap();
|
|
14336
|
+
SUB_MACRO_PARAMETERS = /* @__PURE__ */ new Map([["option", [{
|
|
14337
|
+
name: "value",
|
|
14338
|
+
type: "string",
|
|
14339
|
+
holds: "text",
|
|
14340
|
+
required: true
|
|
14341
|
+
}]]]);
|
|
14342
|
+
RESERVED_NAME = "__proto__";
|
|
14343
|
+
isArrayIndex = (key) => /^(?:0|[1-9]\d*)$/.test(key);
|
|
14344
|
+
hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
|
|
14345
|
+
createNamespace = (...sources) => ownEntries(sources);
|
|
14346
|
+
Object.freeze(createNamespace());
|
|
14347
|
+
parses = null;
|
|
14348
|
+
CONDITION_MACROS = /* @__PURE__ */ new Set([
|
|
14349
|
+
"if",
|
|
14350
|
+
"elseif",
|
|
14351
|
+
"case"
|
|
14352
|
+
]);
|
|
14353
|
+
PASSAGE_BODIES = /* @__PURE__ */ new Set(["dialog"]);
|
|
14354
|
+
holdsByDefault = (interpolate) => interpolate ? "markup" : "text";
|
|
14355
|
+
JS_ESCAPE_RE = /\\(?:u\{[0-9a-fA-F]+\}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{2}|[0-3][0-7]{0,2}|[4-7][0-7]?|\r\n|[^])/y;
|
|
14356
|
+
textPiece = (text2, offset2, where2) => ({
|
|
14357
|
+
kind: "text",
|
|
14358
|
+
text: text2,
|
|
14359
|
+
offset: offset2,
|
|
14360
|
+
where: where2,
|
|
14361
|
+
tokens: [],
|
|
14362
|
+
errors: []
|
|
14363
|
+
});
|
|
14213
14364
|
registeredParameters = (name) => parameterLookup(getMacroRegistry())(name);
|
|
14214
14365
|
WIDGET_PARAMETERS = [{
|
|
14215
14366
|
name: "name",
|
|
@@ -14237,22 +14388,26 @@ var init_story_variables = __esm({
|
|
|
14237
14388
|
didYouMean = (best, quote) => best ? ` Did you mean ${quote(best)}?` : "";
|
|
14238
14389
|
PASSAGE_ARGUMENT_HINT = " (a passage name is a quoted string or an expression)";
|
|
14239
14390
|
BARE_WORD_RE = /^[A-Za-z][\w$]*$/;
|
|
14240
|
-
|
|
14241
|
-
createNamespace = (...sources) => ownEntries(sources);
|
|
14242
|
-
Object.freeze(createNamespace());
|
|
14243
|
-
NUMBER_RE = /(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|(?:\d[\d_]*\.?[\d_]*|\.\d[\d_]*)(?:[eE][+-]?\d+)?)(n?)/y;
|
|
14391
|
+
NUMBER_RE = /(?:0[xX][\da-fA-F_]+|0[bB][01_]+|0[oO][0-7_]+|(?:\d[\d_]*\.?[\d_]*|\.\d[\d_]*)(?:[eE][+-]?\d[\d_]*)?)(n?)/y;
|
|
14244
14392
|
IDENT_RE = /[A-Za-z_$][\w$]*/y;
|
|
14245
14393
|
KEY_RE = /[\w$]+/y;
|
|
14246
14394
|
ARROW_RE = /(?:async\s+)?(?:\((?:[^()]|\([^()]*\))*\)|[A-Za-z_$][\w$]*)\s*=>/y;
|
|
14395
|
+
LINE_END_RE = /[\n\r\u2028\u2029]/g;
|
|
14247
14396
|
ARRAY_INDEX_RE = /^(?:0|[1-9]\d{0,8})$/;
|
|
14248
14397
|
UNSUPPORTED_UNDEFINED = {
|
|
14249
14398
|
unsupported: "undefined",
|
|
14250
14399
|
value: "undefined"
|
|
14251
14400
|
};
|
|
14252
14401
|
Reader = class {
|
|
14253
|
-
|
|
14402
|
+
/**
|
|
14403
|
+
* `regexes` (see regexLiterals) are read from `src` when they are first
|
|
14404
|
+
* needed, unless the caller has them already.
|
|
14405
|
+
*/
|
|
14406
|
+
constructor(src, options = {}) {
|
|
14254
14407
|
this.src = src;
|
|
14255
14408
|
this.i = 0;
|
|
14409
|
+
this.goal = options.goal ?? "expression";
|
|
14410
|
+
this.regexes = options.regexes;
|
|
14256
14411
|
}
|
|
14257
14412
|
/** Skip whitespace and comments. */
|
|
14258
14413
|
space() {
|
|
@@ -14260,8 +14415,8 @@ var init_story_variables = __esm({
|
|
|
14260
14415
|
for (; ; ) {
|
|
14261
14416
|
while (/\s/.test(src.charAt(this.i))) this.i++;
|
|
14262
14417
|
if (src.startsWith("//", this.i)) {
|
|
14263
|
-
|
|
14264
|
-
this.i =
|
|
14418
|
+
LINE_END_RE.lastIndex = this.i;
|
|
14419
|
+
this.i = LINE_END_RE.test(src) ? LINE_END_RE.lastIndex - 1 : src.length;
|
|
14265
14420
|
} else if (src.startsWith("/*", this.i)) {
|
|
14266
14421
|
const end = src.indexOf("*/", this.i + 2);
|
|
14267
14422
|
this.i = end < 0 ? src.length : end + 2;
|
|
@@ -14320,10 +14475,9 @@ var init_story_variables = __esm({
|
|
|
14320
14475
|
i2++;
|
|
14321
14476
|
while (/\s/.test(src.charAt(i2))) i2++;
|
|
14322
14477
|
}
|
|
14323
|
-
|
|
14324
|
-
const match = NUMBER_RE.exec(src);
|
|
14478
|
+
const match = this.numberAt(i2);
|
|
14325
14479
|
if (match) {
|
|
14326
|
-
this.i =
|
|
14480
|
+
this.i = i2 + match[0].length;
|
|
14327
14481
|
if (!match[1]) return { shape: { type: "number" } };
|
|
14328
14482
|
if (sign === "+") return { throws: "Cannot convert a BigInt value to a number" };
|
|
14329
14483
|
const digits = bigintValue(match[0].slice(0, -1));
|
|
@@ -14333,11 +14487,17 @@ var init_story_variables = __esm({
|
|
|
14333
14487
|
};
|
|
14334
14488
|
}
|
|
14335
14489
|
IDENT_RE.lastIndex = i2;
|
|
14336
|
-
|
|
14490
|
+
const word = IDENT_RE.exec(src)?.[0];
|
|
14491
|
+
if (word === "Infinity" || word === "NaN") {
|
|
14337
14492
|
this.i = IDENT_RE.lastIndex;
|
|
14338
14493
|
return { shape: { type: "number" } };
|
|
14339
14494
|
}
|
|
14340
14495
|
}
|
|
14496
|
+
/** The numeric literal (a BigInt's `n` is `match[1]`) at `at`, if there is one. */
|
|
14497
|
+
numberAt(at3) {
|
|
14498
|
+
NUMBER_RE.lastIndex = at3;
|
|
14499
|
+
return NUMBER_RE.exec(this.src);
|
|
14500
|
+
}
|
|
14341
14501
|
/** A keyword, a function, or a name (which is not static). */
|
|
14342
14502
|
word() {
|
|
14343
14503
|
const { src } = this;
|
|
@@ -14357,6 +14517,7 @@ var init_story_variables = __esm({
|
|
|
14357
14517
|
this.i = end;
|
|
14358
14518
|
return { shape: { type: "null" } };
|
|
14359
14519
|
case "NaN":
|
|
14520
|
+
case "Infinity":
|
|
14360
14521
|
this.i = end;
|
|
14361
14522
|
return { shape: { type: "number" } };
|
|
14362
14523
|
case "undefined":
|
|
@@ -14498,14 +14659,22 @@ var init_story_variables = __esm({
|
|
|
14498
14659
|
const { src } = this;
|
|
14499
14660
|
const c = src.charAt(this.i);
|
|
14500
14661
|
if (c === '"' || c === "'") return this.stringValue();
|
|
14662
|
+
if (/[\d.]/.test(c)) return this.numberKey();
|
|
14501
14663
|
KEY_RE.lastIndex = this.i;
|
|
14502
14664
|
const found = KEY_RE.exec(src)?.[0];
|
|
14503
14665
|
if (found === void 0) return void 0;
|
|
14504
14666
|
this.i = KEY_RE.lastIndex;
|
|
14505
|
-
|
|
14506
|
-
|
|
14667
|
+
return found;
|
|
14668
|
+
}
|
|
14669
|
+
/** A number as a key: the whole literal, named as the runtime names it. */
|
|
14670
|
+
numberKey() {
|
|
14671
|
+
const match = this.numberAt(this.i);
|
|
14672
|
+
if (!match) return void 0;
|
|
14673
|
+
this.i += match[0].length;
|
|
14674
|
+
if (/[\w$]/.test(this.src.charAt(this.i))) return void 0;
|
|
14675
|
+
const digits = match[0].replace(/_/g, "");
|
|
14507
14676
|
if (/^0\d/.test(digits)) return void 0;
|
|
14508
|
-
if (
|
|
14677
|
+
if (match[1]) return bigintValue(digits.slice(0, -1));
|
|
14509
14678
|
const value = Number(digits);
|
|
14510
14679
|
return Number.isNaN(value) ? void 0 : String(value);
|
|
14511
14680
|
}
|
|
@@ -14548,6 +14717,14 @@ var init_story_variables = __esm({
|
|
|
14548
14717
|
this.space();
|
|
14549
14718
|
return true;
|
|
14550
14719
|
}
|
|
14720
|
+
if (c === "/") {
|
|
14721
|
+
this.regexes ?? (this.regexes = regexLiterals(src, this.goal));
|
|
14722
|
+
const end = this.regexes.get(this.i);
|
|
14723
|
+
if (end !== void 0) {
|
|
14724
|
+
this.i = end;
|
|
14725
|
+
return true;
|
|
14726
|
+
}
|
|
14727
|
+
}
|
|
14551
14728
|
if (c === "[" || c === "{" || c === "(") return this.skipBalanced();
|
|
14552
14729
|
if (c === "]" || c === "}" || c === ")") return false;
|
|
14553
14730
|
this.i++;
|
|
@@ -14585,9 +14762,470 @@ var init_story_variables = __esm({
|
|
|
14585
14762
|
};
|
|
14586
14763
|
UNSUPPORTED_TYPE = "Expected number, string, boolean, array, or object.";
|
|
14587
14764
|
NO_STORE_VAR_MACROS = /* @__PURE__ */ new Set();
|
|
14765
|
+
FIELD_PATH_RE = /(?:\.\w+)*/y;
|
|
14766
|
+
CLOSERS = {
|
|
14767
|
+
"}": "{",
|
|
14768
|
+
")": "(",
|
|
14769
|
+
"]": "["
|
|
14770
|
+
};
|
|
14771
|
+
BLOCK_WORDS = /* @__PURE__ */ new Set([
|
|
14772
|
+
"if",
|
|
14773
|
+
"for",
|
|
14774
|
+
"while",
|
|
14775
|
+
"switch",
|
|
14776
|
+
"with",
|
|
14777
|
+
"catch"
|
|
14778
|
+
]);
|
|
14779
|
+
NOT_PARAMETERS = /* @__PURE__ */ new Set([
|
|
14780
|
+
"if",
|
|
14781
|
+
"for",
|
|
14782
|
+
"while",
|
|
14783
|
+
"switch",
|
|
14784
|
+
"with"
|
|
14785
|
+
]);
|
|
14786
|
+
DECLARATIONS = /* @__PURE__ */ new Set([
|
|
14787
|
+
"const",
|
|
14788
|
+
"let",
|
|
14789
|
+
"var"
|
|
14790
|
+
]);
|
|
14791
|
+
WRITE_RE = /(?:(?:\*\*|<<|>>>?|&&|\|\||\?\?|[-+*/%&|^])=(?!=)|=(?![=>])|\+\+|--)/y;
|
|
14792
|
+
MUTATORS = /* @__PURE__ */ new Set([
|
|
14793
|
+
"push",
|
|
14794
|
+
"pop",
|
|
14795
|
+
"shift",
|
|
14796
|
+
"unshift",
|
|
14797
|
+
"splice",
|
|
14798
|
+
"sort",
|
|
14799
|
+
"reverse",
|
|
14800
|
+
"fill",
|
|
14801
|
+
"copyWithin"
|
|
14802
|
+
]);
|
|
14803
|
+
MUTATING_CALL_RE = /(?:Object|Reflect)\s*\.\s*(?:assign|defineProperty|defineProperties|setPrototypeOf|set|deleteProperty)\s*$/;
|
|
14804
|
+
BEFORE_BINDING = {
|
|
14805
|
+
"{": "{,:",
|
|
14806
|
+
"[": "[,",
|
|
14807
|
+
"(": "(,"
|
|
14808
|
+
};
|
|
14809
|
+
isWordChar = (c) => !!c && /[\w$]/.test(c);
|
|
14810
|
+
Bindings = class {
|
|
14811
|
+
constructor(code) {
|
|
14812
|
+
this.code = code;
|
|
14813
|
+
this.groups = [];
|
|
14814
|
+
this.byOpen = /* @__PURE__ */ new Map();
|
|
14815
|
+
this.byClose = /* @__PURE__ */ new Map();
|
|
14816
|
+
this.functions = /* @__PURE__ */ new Map();
|
|
14817
|
+
this.top = {
|
|
14818
|
+
start: -1,
|
|
14819
|
+
end: Infinity
|
|
14820
|
+
};
|
|
14821
|
+
this.readGroups();
|
|
14822
|
+
}
|
|
14823
|
+
/**
|
|
14824
|
+
* The `{` of the object literal that `name`, used at `at`, is declared as
|
|
14825
|
+
* (`const`, `let` or `var`), when that is the declaration it names: the
|
|
14826
|
+
* innermost one in the scope of the use, that comes before it unless the
|
|
14827
|
+
* use is in a function of its own. `undefined` if it names another value,
|
|
14828
|
+
* more than one declaration is the innermost, or the value is written to
|
|
14829
|
+
* (given another, or one of its `properties` set) where the use can follow.
|
|
14830
|
+
*/
|
|
14831
|
+
objectOf(name, at3, properties) {
|
|
14832
|
+
const { code } = this;
|
|
14833
|
+
const escaped = name.replace(/\$/g, "\\$");
|
|
14834
|
+
const bindings = [];
|
|
14835
|
+
for (const m of code.matchAll(new RegExp(`(?<![\\w$])${escaped}(?![\\w$])`, "g"))) {
|
|
14836
|
+
const binding = this.bindingAt(m.index, name.length, properties);
|
|
14837
|
+
if (binding) bindings.push(binding);
|
|
14838
|
+
}
|
|
14839
|
+
const declarations = bindings.filter((b) => !b.write);
|
|
14840
|
+
for (const b of bindings) if (b.write) b.scope = this.innermostVisible(declarations, b.at)[0]?.scope ?? this.top;
|
|
14841
|
+
const found = this.innermostVisible(bindings, at3);
|
|
14842
|
+
return found.length === 1 ? found[0].object : void 0;
|
|
14843
|
+
}
|
|
14844
|
+
/**
|
|
14845
|
+
* Of the `bindings` the use at `at` can see, those in the innermost scope:
|
|
14846
|
+
* the scope is the use's, and a binding comes before it, unless the use is
|
|
14847
|
+
* in a function of its own.
|
|
14848
|
+
*/
|
|
14849
|
+
innermostVisible(bindings, at3) {
|
|
14850
|
+
const useFunction = this.functionStart(at3);
|
|
14851
|
+
const visible = bindings.filter((b) => b.scope.start <= at3 && at3 < b.scope.end && (!b.ordered || b.at < at3 || this.functionStart(b.at) !== useFunction));
|
|
14852
|
+
const innermost = Math.max(...visible.map((b) => b.scope.start));
|
|
14853
|
+
return visible.filter((b) => b.scope.start === innermost);
|
|
14854
|
+
}
|
|
14855
|
+
readGroups() {
|
|
14856
|
+
const { code, groups } = this;
|
|
14857
|
+
const stack = [];
|
|
14858
|
+
for (let i2 = 0; i2 < code.length; i2++) {
|
|
14859
|
+
const c = code.charAt(i2);
|
|
14860
|
+
if (c === "{" || c === "(" || c === "[") {
|
|
14861
|
+
const group = {
|
|
14862
|
+
kind: c,
|
|
14863
|
+
open: i2,
|
|
14864
|
+
close: code.length,
|
|
14865
|
+
parent: stack[stack.length - 1]
|
|
14866
|
+
};
|
|
14867
|
+
groups.push(group);
|
|
14868
|
+
stack.push(group);
|
|
14869
|
+
this.byOpen.set(i2, group);
|
|
14870
|
+
} else if (CLOSERS[c]) {
|
|
14871
|
+
let k2 = stack.length - 1;
|
|
14872
|
+
while (k2 >= 0 && stack[k2].kind !== CLOSERS[c]) k2--;
|
|
14873
|
+
if (k2 >= 0) {
|
|
14874
|
+
stack[k2].close = i2;
|
|
14875
|
+
this.byClose.set(i2, stack[k2]);
|
|
14876
|
+
stack.length = k2;
|
|
14877
|
+
}
|
|
14878
|
+
}
|
|
14879
|
+
}
|
|
14880
|
+
}
|
|
14881
|
+
/** The innermost group that has `index` inside it, of this kind if given. */
|
|
14882
|
+
innermost(index, kind) {
|
|
14883
|
+
const { groups } = this;
|
|
14884
|
+
for (let k2 = groups.length - 1; k2 >= 0; k2--) {
|
|
14885
|
+
const g = groups[k2];
|
|
14886
|
+
if (g.open < index && index < g.close && (!kind || g.kind === kind)) return g;
|
|
14887
|
+
}
|
|
14888
|
+
}
|
|
14889
|
+
/**
|
|
14890
|
+
* The word before a `(` group (`if`, `for`, `catch`, a function's name…);
|
|
14891
|
+
* `for await` is `for`.
|
|
14892
|
+
*/
|
|
14893
|
+
ownerWord(paren) {
|
|
14894
|
+
const word = this.wordBefore(this.backFrom(paren.open) + 1);
|
|
14895
|
+
if (word.text !== "await") return word.text;
|
|
14896
|
+
const before = this.wordBefore(this.backFrom(word.start) + 1).text;
|
|
14897
|
+
return before === "for" ? before : word.text;
|
|
14898
|
+
}
|
|
14899
|
+
/**
|
|
14900
|
+
* Whether the `{` group is the body of a function (or method), or of a
|
|
14901
|
+
* class static block, which has the scope of a `var` of its own.
|
|
14902
|
+
*/
|
|
14903
|
+
isFunctionBody(group) {
|
|
14904
|
+
if (group.kind !== "{") return false;
|
|
14905
|
+
let known = this.functions.get(group);
|
|
14906
|
+
if (known === void 0) {
|
|
14907
|
+
const before = this.backFrom(group.open);
|
|
14908
|
+
const { code } = this;
|
|
14909
|
+
if (code.charAt(before) === ")") {
|
|
14910
|
+
const params = this.byClose.get(before);
|
|
14911
|
+
known = !!params && !BLOCK_WORDS.has(this.ownerWord(params));
|
|
14912
|
+
} else known = code.slice(before - 1, before + 1) === "=>" || this.wordBefore(before + 1).text === "static";
|
|
14913
|
+
this.functions.set(group, known);
|
|
14914
|
+
}
|
|
14915
|
+
return known;
|
|
14916
|
+
}
|
|
14917
|
+
/** The start of the function that has `index` in its body, or -1. */
|
|
14918
|
+
functionStart(index) {
|
|
14919
|
+
for (let g = this.innermost(index, "{"); g; g = g.parent) if (g.kind === "{" && this.isFunctionBody(g)) return g.open;
|
|
14920
|
+
return -1;
|
|
14921
|
+
}
|
|
14922
|
+
scopeOf(group) {
|
|
14923
|
+
return group ? {
|
|
14924
|
+
start: group.open,
|
|
14925
|
+
end: group.close
|
|
14926
|
+
} : this.top;
|
|
14927
|
+
}
|
|
14928
|
+
/** The block `index` is in: what `let` and `const` declare for. */
|
|
14929
|
+
blockAt(index) {
|
|
14930
|
+
return this.scopeOf(this.innermost(index, "{"));
|
|
14931
|
+
}
|
|
14932
|
+
/** The function (or the whole text) `index` is in: what `var` declares for. */
|
|
14933
|
+
functionAt(index) {
|
|
14934
|
+
const start = this.functionStart(index);
|
|
14935
|
+
return start < 0 ? this.top : this.scopeOf(this.byOpen.get(start));
|
|
14936
|
+
}
|
|
14937
|
+
/**
|
|
14938
|
+
* What the declaration keyword `word` (`var`, `let`, `const`) declares for:
|
|
14939
|
+
* the function for `var`, the block for the others, or the `for` statement,
|
|
14940
|
+
* header and body, when the declaration is in its header.
|
|
14941
|
+
*/
|
|
14942
|
+
declaredIn(word) {
|
|
14943
|
+
if (word.text === "var") return this.functionAt(word.start);
|
|
14944
|
+
const group = this.innermost(word.start);
|
|
14945
|
+
if (group?.kind === "(" && this.ownerWord(group) === "for") return {
|
|
14946
|
+
start: group.open,
|
|
14947
|
+
end: this.statementEnd(group.close + 1)
|
|
14948
|
+
};
|
|
14949
|
+
return this.blockAt(word.start);
|
|
14950
|
+
}
|
|
14951
|
+
/**
|
|
14952
|
+
* Where the statement that starts at `from` ends: a block, the body of an
|
|
14953
|
+
* `if`, `for`, `while` or `with` (and the `else` of an `if`), or else up to
|
|
14954
|
+
* a `;`, the closer of the group it is in, or a line break that is followed
|
|
14955
|
+
* by a statement of its own.
|
|
14956
|
+
*/
|
|
14957
|
+
statementEnd(from) {
|
|
14958
|
+
const { code } = this;
|
|
14959
|
+
const start = this.forward(from);
|
|
14960
|
+
const block = this.byOpen.get(start);
|
|
14961
|
+
if (block?.kind === "{") return Math.min(block.close + 1, code.length);
|
|
14962
|
+
const word = this.wordAt(start);
|
|
14963
|
+
if (/^(?:if|for|while|with)$/.test(word)) {
|
|
14964
|
+
let paren = this.forward(start + word.length);
|
|
14965
|
+
if (word === "for" && this.wordAt(paren) === "await") paren = this.forward(paren + 5);
|
|
14966
|
+
const header = this.byOpen.get(paren);
|
|
14967
|
+
if (header) {
|
|
14968
|
+
const end = this.statementEnd(header.close + 1);
|
|
14969
|
+
const next = this.forward(end);
|
|
14970
|
+
return word === "if" && this.wordAt(next) === "else" ? this.statementEnd(next + 4) : end;
|
|
14971
|
+
}
|
|
14972
|
+
}
|
|
14973
|
+
for (let end = start; end < code.length; end++) {
|
|
14974
|
+
const c = code.charAt(end);
|
|
14975
|
+
if (c === ";") return end + 1;
|
|
14976
|
+
if (CLOSERS[c]) return end;
|
|
14977
|
+
const group = this.byOpen.get(end);
|
|
14978
|
+
if (group) end = group.close;
|
|
14979
|
+
else if (c === "\n" && this.startsStatement(end)) return end;
|
|
14980
|
+
}
|
|
14981
|
+
return code.length;
|
|
14982
|
+
}
|
|
14983
|
+
/** Whether the line break at `index` ends a statement, and one follows. */
|
|
14984
|
+
startsStatement(index) {
|
|
14985
|
+
const next = this.forward(index);
|
|
14986
|
+
return /[\w$)\]}]/.test(this.code.charAt(this.backFrom(index))) && isWordChar(this.code.charAt(next)) && !/^(?:in|of|instanceof|else)$/.test(this.wordAt(next));
|
|
14987
|
+
}
|
|
14988
|
+
/** What a parameter list, whose `)` is `close`, is the scope of: the body. */
|
|
14989
|
+
bodyAfter(close) {
|
|
14990
|
+
const next = this.forward(close + 1);
|
|
14991
|
+
if (this.code.charAt(next) === "{") return this.scopeOf(this.byOpen.get(next));
|
|
14992
|
+
return this.code.startsWith("=>", next) ? this.arrowBody(next + 2) : void 0;
|
|
14993
|
+
}
|
|
14994
|
+
/** The body of an arrow function, whose `=>` ends before `from`. */
|
|
14995
|
+
arrowBody(from) {
|
|
14996
|
+
const { code } = this;
|
|
14997
|
+
const start = this.forward(from);
|
|
14998
|
+
if (code.charAt(start) === "{") return this.scopeOf(this.byOpen.get(start));
|
|
14999
|
+
let end = start;
|
|
15000
|
+
while (end < code.length && !",;)]}".includes(code.charAt(end))) {
|
|
15001
|
+
end = this.byOpen.get(end)?.close ?? end;
|
|
15002
|
+
end++;
|
|
15003
|
+
}
|
|
15004
|
+
return {
|
|
15005
|
+
start,
|
|
15006
|
+
end
|
|
15007
|
+
};
|
|
15008
|
+
}
|
|
15009
|
+
/** The index of the last character that is no space before `index`, or -1. */
|
|
15010
|
+
backFrom(index) {
|
|
15011
|
+
let i2 = index - 1;
|
|
15012
|
+
while (i2 >= 0 && /\s/.test(this.code.charAt(i2))) i2--;
|
|
15013
|
+
return i2;
|
|
15014
|
+
}
|
|
15015
|
+
/** The index of the first character that is no space from `index` on. */
|
|
15016
|
+
forward(index) {
|
|
15017
|
+
let i2 = index;
|
|
15018
|
+
while (i2 < this.code.length && /\s/.test(this.code.charAt(i2))) i2++;
|
|
15019
|
+
return i2;
|
|
15020
|
+
}
|
|
15021
|
+
/** The word that starts at `index` (empty if there is none). */
|
|
15022
|
+
wordAt(index) {
|
|
15023
|
+
return this.code.slice(index, this.nameEnd(index));
|
|
15024
|
+
}
|
|
15025
|
+
/** The word that ends before `end`, and where it starts. */
|
|
15026
|
+
wordBefore(end) {
|
|
15027
|
+
let start = end;
|
|
15028
|
+
while (start > 0 && isWordChar(this.code.charAt(start - 1))) start--;
|
|
15029
|
+
return {
|
|
15030
|
+
text: this.code.slice(start, end),
|
|
15031
|
+
start
|
|
15032
|
+
};
|
|
15033
|
+
}
|
|
15034
|
+
/**
|
|
15035
|
+
* What the name of `length` characters at `at` declares, or writes to, if it
|
|
15036
|
+
* does. A write to a `properties` of it counts, one to another does not.
|
|
15037
|
+
*/
|
|
15038
|
+
bindingAt(at3, length, properties) {
|
|
15039
|
+
const { code } = this;
|
|
15040
|
+
let before = this.backFrom(at3);
|
|
15041
|
+
const spread = code.slice(before - 2, before + 1) === "...";
|
|
15042
|
+
if (code.charAt(before) === "." && !spread) return void 0;
|
|
15043
|
+
if (spread) before = this.backFrom(before - 2);
|
|
15044
|
+
const after = this.forward(at3 + length);
|
|
15045
|
+
return this.declarationAt(at3, before, spread) ?? this.patternAt(at3, before, after) ?? this.arrowParameterAt(at3, after) ?? (spread ? void 0 : this.writeAt(at3, before, after, properties));
|
|
15046
|
+
}
|
|
15047
|
+
/** `const x`, `let x`, `var x`, a later `y` of `let x, y`, `function x`, `class x`. */
|
|
15048
|
+
declarationAt(at3, before, spread) {
|
|
15049
|
+
if (spread) return void 0;
|
|
15050
|
+
const word = this.code.charAt(before) === "," ? this.listKeyword(before) : this.wordBefore(before + 1);
|
|
15051
|
+
if (!word || this.code.charAt(word.start - 1) === ".") return void 0;
|
|
15052
|
+
if (DECLARATIONS.has(word.text)) {
|
|
15053
|
+
const scope = this.declaredIn(word);
|
|
15054
|
+
const init = /\s*=\s*(?=\{)/y;
|
|
15055
|
+
init.lastIndex = this.nameEnd(at3);
|
|
15056
|
+
return {
|
|
15057
|
+
scope,
|
|
15058
|
+
at: at3,
|
|
15059
|
+
ordered: true,
|
|
15060
|
+
object: init.test(this.code) ? init.lastIndex : void 0
|
|
15061
|
+
};
|
|
15062
|
+
}
|
|
15063
|
+
if (word.text === "function" || word.text === "class") return {
|
|
15064
|
+
scope: this.blockAt(word.start),
|
|
15065
|
+
at: at3,
|
|
15066
|
+
ordered: word.text === "class"
|
|
15067
|
+
};
|
|
15068
|
+
}
|
|
15069
|
+
/**
|
|
15070
|
+
* The `const`, `let` or `var` of the declaration list that the `,` at
|
|
15071
|
+
* `comma` is in (`let a = 1, b`, also in a `for` header): the nearest one
|
|
15072
|
+
* before it in the same brackets, that no `;` is between.
|
|
15073
|
+
*/
|
|
15074
|
+
listKeyword(comma) {
|
|
15075
|
+
const { code } = this;
|
|
15076
|
+
const floor = this.innermost(comma)?.open ?? -1;
|
|
15077
|
+
for (let i2 = comma - 1; i2 > floor; i2--) {
|
|
15078
|
+
const c = code.charAt(i2);
|
|
15079
|
+
if (c === ";") return void 0;
|
|
15080
|
+
const group = CLOSERS[c] ? this.byClose.get(i2) : void 0;
|
|
15081
|
+
if (group) i2 = group.open;
|
|
15082
|
+
else if (isWordChar(c)) {
|
|
15083
|
+
const word = this.wordBefore(i2 + 1);
|
|
15084
|
+
if (DECLARATIONS.has(word.text) && code.charAt(word.start - 1) !== ".") return word;
|
|
15085
|
+
i2 = word.start;
|
|
15086
|
+
}
|
|
15087
|
+
}
|
|
15088
|
+
}
|
|
15089
|
+
nameEnd(at3) {
|
|
15090
|
+
let end = at3;
|
|
15091
|
+
while (isWordChar(this.code.charAt(end))) end++;
|
|
15092
|
+
return end;
|
|
15093
|
+
}
|
|
15094
|
+
/**
|
|
15095
|
+
* A name in a pattern (`const { x } = …`) or a parameter list; or one a
|
|
15096
|
+
* pattern assigns to (`({ x } = …)`).
|
|
15097
|
+
*/
|
|
15098
|
+
patternAt(at3, before, after) {
|
|
15099
|
+
const { code } = this;
|
|
15100
|
+
const inner = this.innermost(at3);
|
|
15101
|
+
if (!inner || !BEFORE_BINDING[inner.kind].includes(code.charAt(before))) return;
|
|
15102
|
+
if (inner.kind === "{" && code.charAt(after) === ":") return void 0;
|
|
15103
|
+
let pattern;
|
|
15104
|
+
for (let group = inner; group; group = group.parent) {
|
|
15105
|
+
if (group.kind === "(") {
|
|
15106
|
+
const scope = NOT_PARAMETERS.has(this.ownerWord(group)) ? void 0 : this.bodyAfter(group.close);
|
|
15107
|
+
return scope ? {
|
|
15108
|
+
scope,
|
|
15109
|
+
at: at3,
|
|
15110
|
+
ordered: false
|
|
15111
|
+
} : this.patternWriteAt(at3, pattern);
|
|
15112
|
+
}
|
|
15113
|
+
pattern = group;
|
|
15114
|
+
const open = this.backFrom(group.open);
|
|
15115
|
+
const word = code.charAt(open) === "," ? this.listKeyword(open) : this.wordBefore(open + 1);
|
|
15116
|
+
if (word && DECLARATIONS.has(word.text)) return {
|
|
15117
|
+
scope: this.declaredIn(word),
|
|
15118
|
+
at: at3,
|
|
15119
|
+
ordered: true
|
|
15120
|
+
};
|
|
15121
|
+
if (!"({[,:".includes(code.charAt(open))) break;
|
|
15122
|
+
}
|
|
15123
|
+
return this.patternWriteAt(at3, pattern);
|
|
15124
|
+
}
|
|
15125
|
+
/** `[x] = …`, `({ x } = …)`, `for ({ x } of …)`: a name that is assigned to. */
|
|
15126
|
+
patternWriteAt(at3, pattern) {
|
|
15127
|
+
if (!pattern) return void 0;
|
|
15128
|
+
const { code } = this;
|
|
15129
|
+
const open = this.backFrom(pattern.open);
|
|
15130
|
+
if (/[\w$)\]]/.test(code.charAt(open))) return void 0;
|
|
15131
|
+
const next = this.forward(pattern.close + 1);
|
|
15132
|
+
return pattern.parent?.kind === "(" && this.ownerWord(pattern.parent) === "for" && /^(?:of|in)(?![\w$])/.test(code.slice(next)) || this.isWriteOperator(next) ? {
|
|
15133
|
+
scope: this.top,
|
|
15134
|
+
at: at3,
|
|
15135
|
+
ordered: true,
|
|
15136
|
+
write: true
|
|
15137
|
+
} : void 0;
|
|
15138
|
+
}
|
|
15139
|
+
/** `x => …`. */
|
|
15140
|
+
arrowParameterAt(at3, after) {
|
|
15141
|
+
return this.code.startsWith("=>", after) ? {
|
|
15142
|
+
scope: this.arrowBody(after + 2),
|
|
15143
|
+
at: at3,
|
|
15144
|
+
ordered: false
|
|
15145
|
+
} : void 0;
|
|
15146
|
+
}
|
|
15147
|
+
/** Whether an assignment, `++` or `--` operator is at `index`. */
|
|
15148
|
+
isWriteOperator(index) {
|
|
15149
|
+
WRITE_RE.lastIndex = index;
|
|
15150
|
+
return WRITE_RE.test(this.code);
|
|
15151
|
+
}
|
|
15152
|
+
/**
|
|
15153
|
+
* `x = …`, `x += …`, `x++`, `for (x of …)`, and the writes to what it
|
|
15154
|
+
* holds that change the config it is (`x.name = …`, `delete x.name`,
|
|
15155
|
+
* `x.parameters.push(…)`, `Object.assign(x, …)`): a value not known.
|
|
15156
|
+
*/
|
|
15157
|
+
writeAt(at3, before, after, properties) {
|
|
15158
|
+
const { code } = this;
|
|
15159
|
+
if (this.isClassBody(this.innermost(at3))) return void 0;
|
|
15160
|
+
const { keys, end } = this.memberChain(after);
|
|
15161
|
+
const written2 = ["++", "--"].includes(code.slice(before - 1, before + 1)) || this.isWriteOperator(end) || keys.length > 0 && (this.wordBefore(before + 1).text === "delete" || keys.length > 1 && code.charAt(end) === "(" && MUTATORS.has(keys[keys.length - 1])) || keys.length === 0 && this.isForTarget(before, end) || keys.length === 0 && this.isMutatedArgument(before, end);
|
|
15162
|
+
const first = keys[0];
|
|
15163
|
+
if (!written2 || first && !properties.has(first)) return void 0;
|
|
15164
|
+
return {
|
|
15165
|
+
scope: this.top,
|
|
15166
|
+
at: at3,
|
|
15167
|
+
ordered: true,
|
|
15168
|
+
write: true
|
|
15169
|
+
};
|
|
15170
|
+
}
|
|
15171
|
+
/** Whether the group is the body of a class: its members are its own. */
|
|
15172
|
+
isClassBody(group) {
|
|
15173
|
+
if (group?.kind !== "{") return false;
|
|
15174
|
+
let start = group.open;
|
|
15175
|
+
while (start > 0 && !"{};".includes(this.code.charAt(start - 1))) start--;
|
|
15176
|
+
return /(?<![\w$.])class(?![\w$])/.test(this.code.slice(start, group.open));
|
|
15177
|
+
}
|
|
15178
|
+
/**
|
|
15179
|
+
* The properties read from a name at `from` (`.a.b[c]`, a key is null if
|
|
15180
|
+
* computed), and where the chain ends.
|
|
15181
|
+
*/
|
|
15182
|
+
memberChain(from) {
|
|
15183
|
+
const { code } = this;
|
|
15184
|
+
const keys = [];
|
|
15185
|
+
let end = from;
|
|
15186
|
+
for (; ; ) {
|
|
15187
|
+
let i2 = end;
|
|
15188
|
+
if (code.startsWith("?.", i2)) i2 += 2;
|
|
15189
|
+
else if (code.charAt(i2) === "." && code.charAt(i2 + 1) !== ".") i2++;
|
|
15190
|
+
else if (code.charAt(i2) !== "[") break;
|
|
15191
|
+
i2 = this.forward(i2);
|
|
15192
|
+
const bracket = code.charAt(i2) === "[" ? this.byOpen.get(i2) : void 0;
|
|
15193
|
+
const key = bracket ? "" : this.wordAt(i2);
|
|
15194
|
+
if (!bracket && !key) break;
|
|
15195
|
+
keys.push(bracket ? null : key);
|
|
15196
|
+
end = this.forward(bracket ? bracket.close + 1 : i2 + key.length);
|
|
15197
|
+
}
|
|
15198
|
+
return {
|
|
15199
|
+
keys,
|
|
15200
|
+
end
|
|
15201
|
+
};
|
|
15202
|
+
}
|
|
15203
|
+
/** `for (x of …)`: the name is assigned each item. */
|
|
15204
|
+
isForTarget(before, end) {
|
|
15205
|
+
const group = this.byOpen.get(before);
|
|
15206
|
+
return group?.kind === "(" && this.ownerWord(group) === "for" && /^(?:of|in)(?![\w$])/.test(this.code.slice(end));
|
|
15207
|
+
}
|
|
15208
|
+
/** `Object.assign(x, …)` and the like: the name is the first argument. */
|
|
15209
|
+
isMutatedArgument(before, end) {
|
|
15210
|
+
const group = this.byOpen.get(before);
|
|
15211
|
+
return group?.kind === "(" && ",)".includes(this.code.charAt(end)) && MUTATING_CALL_RE.test(this.code.slice(0, group.open));
|
|
15212
|
+
}
|
|
15213
|
+
};
|
|
14588
15214
|
CALL_RE = /(?<![\w$])defineMacro\s*\(\s*/g;
|
|
14589
15215
|
IDENTIFIER_ARGUMENT_RE = /^([A-Za-z_$][\w$]*)\s*[,)]/;
|
|
14590
15216
|
WORD_RE = /[A-Za-z_]+/y;
|
|
15217
|
+
MODIFIER_RE = /^(?:get|set|async)?$/;
|
|
15218
|
+
KEY_START_RE = /[\w$'"[.*]/;
|
|
15219
|
+
CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
15220
|
+
"name",
|
|
15221
|
+
"block",
|
|
15222
|
+
"subMacros",
|
|
15223
|
+
"parameters",
|
|
15224
|
+
"interpolate",
|
|
15225
|
+
"storeVar",
|
|
15226
|
+
"merged",
|
|
15227
|
+
"description"
|
|
15228
|
+
]);
|
|
14591
15229
|
ConfigReader = class extends Reader {
|
|
14592
15230
|
constructor(..._args) {
|
|
14593
15231
|
super(..._args);
|
|
@@ -14686,18 +15324,47 @@ var init_story_variables = __esm({
|
|
|
14686
15324
|
}
|
|
14687
15325
|
record() {
|
|
14688
15326
|
const props = /* @__PURE__ */ new Map();
|
|
14689
|
-
return this.elements("}", () => {
|
|
14690
|
-
const key = this.key();
|
|
14691
|
-
this.space();
|
|
14692
|
-
if (key !== void 0 && this.src.charAt(this.i) === ":") {
|
|
14693
|
-
this.i++;
|
|
14694
|
-
props.set(key, this.member());
|
|
14695
|
-
} else if (!this.skipMember()) this.fail();
|
|
14696
|
-
}) ? {
|
|
15327
|
+
return this.elements("}", () => this.property(props)) ? {
|
|
14697
15328
|
type: "object",
|
|
14698
15329
|
props
|
|
14699
15330
|
} : void 0;
|
|
14700
15331
|
}
|
|
15332
|
+
/**
|
|
15333
|
+
* A member: what it sets replaces an earlier member of the key. One that is
|
|
15334
|
+
* not a literal (a method, an accessor, a shorthand) sets its key to a
|
|
15335
|
+
* value not known; a spread of an object literal sets the members of it, a
|
|
15336
|
+
* spread of anything else or a computed key can set any key.
|
|
15337
|
+
*/
|
|
15338
|
+
property(props) {
|
|
15339
|
+
const { src } = this;
|
|
15340
|
+
if (src.startsWith("...", this.i)) {
|
|
15341
|
+
this.i += 3;
|
|
15342
|
+
this.space();
|
|
15343
|
+
const spread = src.charAt(this.i) === "{" ? this.record() : void 0;
|
|
15344
|
+
this.space();
|
|
15345
|
+
if (spread?.type === "object" && this.atElementEnd()) {
|
|
15346
|
+
for (const [key, value] of spread.props) props.set(key, value);
|
|
15347
|
+
return;
|
|
15348
|
+
}
|
|
15349
|
+
props.clear();
|
|
15350
|
+
} else {
|
|
15351
|
+
let key = this.key();
|
|
15352
|
+
this.space();
|
|
15353
|
+
if (key !== void 0 && src.charAt(this.i) === ":") {
|
|
15354
|
+
this.i++;
|
|
15355
|
+
props.set(key, this.member());
|
|
15356
|
+
return;
|
|
15357
|
+
}
|
|
15358
|
+
if (MODIFIER_RE.test(key ?? "") && KEY_START_RE.test(src.charAt(this.i))) {
|
|
15359
|
+
if (src.charAt(this.i) === "*") this.i++;
|
|
15360
|
+
this.space();
|
|
15361
|
+
key = this.key();
|
|
15362
|
+
}
|
|
15363
|
+
if (key === void 0) props.clear();
|
|
15364
|
+
else props.set(key, void 0);
|
|
15365
|
+
}
|
|
15366
|
+
if (!this.skipMember()) this.fail();
|
|
15367
|
+
}
|
|
14701
15368
|
/** Stop reading: the text cannot be skipped through. */
|
|
14702
15369
|
fail() {
|
|
14703
15370
|
this.failed = true;
|
|
@@ -14956,48 +15623,56 @@ var init_macro_registry = __esm({
|
|
|
14956
15623
|
"name": "story-title",
|
|
14957
15624
|
"block": false,
|
|
14958
15625
|
"subMacros": [],
|
|
15626
|
+
"interpolate": true,
|
|
14959
15627
|
"source": "builtin"
|
|
14960
15628
|
},
|
|
14961
15629
|
{
|
|
14962
15630
|
"name": "back",
|
|
14963
15631
|
"block": false,
|
|
14964
15632
|
"subMacros": [],
|
|
15633
|
+
"interpolate": true,
|
|
14965
15634
|
"source": "builtin"
|
|
14966
15635
|
},
|
|
14967
15636
|
{
|
|
14968
15637
|
"name": "forward",
|
|
14969
15638
|
"block": false,
|
|
14970
15639
|
"subMacros": [],
|
|
15640
|
+
"interpolate": true,
|
|
14971
15641
|
"source": "builtin"
|
|
14972
15642
|
},
|
|
14973
15643
|
{
|
|
14974
15644
|
"name": "quicksave",
|
|
14975
15645
|
"block": false,
|
|
14976
15646
|
"subMacros": [],
|
|
15647
|
+
"interpolate": true,
|
|
14977
15648
|
"source": "builtin"
|
|
14978
15649
|
},
|
|
14979
15650
|
{
|
|
14980
15651
|
"name": "quickload",
|
|
14981
15652
|
"block": false,
|
|
14982
15653
|
"subMacros": [],
|
|
15654
|
+
"interpolate": true,
|
|
14983
15655
|
"source": "builtin"
|
|
14984
15656
|
},
|
|
14985
15657
|
{
|
|
14986
15658
|
"name": "restart",
|
|
14987
15659
|
"block": false,
|
|
14988
15660
|
"subMacros": [],
|
|
15661
|
+
"interpolate": true,
|
|
14989
15662
|
"source": "builtin"
|
|
14990
15663
|
},
|
|
14991
15664
|
{
|
|
14992
15665
|
"name": "saves",
|
|
14993
15666
|
"block": false,
|
|
14994
15667
|
"subMacros": [],
|
|
15668
|
+
"interpolate": true,
|
|
14995
15669
|
"source": "builtin"
|
|
14996
15670
|
},
|
|
14997
15671
|
{
|
|
14998
15672
|
"name": "settings",
|
|
14999
15673
|
"block": false,
|
|
15000
15674
|
"subMacros": [],
|
|
15675
|
+
"interpolate": true,
|
|
15001
15676
|
"source": "builtin"
|
|
15002
15677
|
},
|
|
15003
15678
|
{
|
|
@@ -15023,12 +15698,14 @@ var init_macro_registry = __esm({
|
|
|
15023
15698
|
"name": "save-manager",
|
|
15024
15699
|
"block": false,
|
|
15025
15700
|
"subMacros": [],
|
|
15701
|
+
"interpolate": true,
|
|
15026
15702
|
"source": "builtin"
|
|
15027
15703
|
},
|
|
15028
15704
|
{
|
|
15029
15705
|
"name": "settings-controls",
|
|
15030
15706
|
"block": false,
|
|
15031
15707
|
"subMacros": [],
|
|
15708
|
+
"interpolate": true,
|
|
15032
15709
|
"source": "builtin"
|
|
15033
15710
|
},
|
|
15034
15711
|
{
|
|
@@ -15054,6 +15731,7 @@ var init_macro_registry = __esm({
|
|
|
15054
15731
|
"name": "nobr",
|
|
15055
15732
|
"block": true,
|
|
15056
15733
|
"subMacros": [],
|
|
15734
|
+
"interpolate": true,
|
|
15057
15735
|
"source": "builtin"
|
|
15058
15736
|
},
|
|
15059
15737
|
{
|
|
@@ -15088,6 +15766,7 @@ var init_macro_registry = __esm({
|
|
|
15088
15766
|
"block": false,
|
|
15089
15767
|
"subMacros": [],
|
|
15090
15768
|
"storeVar": true,
|
|
15769
|
+
"interpolate": true,
|
|
15091
15770
|
"parameters": [
|
|
15092
15771
|
{
|
|
15093
15772
|
"name": "variable",
|
|
@@ -15107,6 +15786,7 @@ var init_macro_registry = __esm({
|
|
|
15107
15786
|
"block": false,
|
|
15108
15787
|
"subMacros": [],
|
|
15109
15788
|
"storeVar": true,
|
|
15789
|
+
"interpolate": true,
|
|
15110
15790
|
"parameters": [
|
|
15111
15791
|
{
|
|
15112
15792
|
"name": "variable",
|
|
@@ -15126,6 +15806,7 @@ var init_macro_registry = __esm({
|
|
|
15126
15806
|
"block": false,
|
|
15127
15807
|
"subMacros": [],
|
|
15128
15808
|
"storeVar": true,
|
|
15809
|
+
"interpolate": true,
|
|
15129
15810
|
"parameters": [
|
|
15130
15811
|
{
|
|
15131
15812
|
"name": "variable",
|
|
@@ -15145,6 +15826,7 @@ var init_macro_registry = __esm({
|
|
|
15145
15826
|
"block": false,
|
|
15146
15827
|
"subMacros": [],
|
|
15147
15828
|
"storeVar": true,
|
|
15829
|
+
"interpolate": true,
|
|
15148
15830
|
"parameters": [
|
|
15149
15831
|
{
|
|
15150
15832
|
"name": "variable",
|
|
@@ -15164,6 +15846,7 @@ var init_macro_registry = __esm({
|
|
|
15164
15846
|
"block": false,
|
|
15165
15847
|
"subMacros": [],
|
|
15166
15848
|
"storeVar": true,
|
|
15849
|
+
"interpolate": true,
|
|
15167
15850
|
"parameters": [
|
|
15168
15851
|
{
|
|
15169
15852
|
"name": "variable",
|
|
@@ -15191,6 +15874,7 @@ var init_macro_registry = __esm({
|
|
|
15191
15874
|
"option"
|
|
15192
15875
|
],
|
|
15193
15876
|
"storeVar": true,
|
|
15877
|
+
"interpolate": true,
|
|
15194
15878
|
"parameters": [
|
|
15195
15879
|
{
|
|
15196
15880
|
"name": "variable",
|
|
@@ -15205,6 +15889,7 @@ var init_macro_registry = __esm({
|
|
|
15205
15889
|
"block": true,
|
|
15206
15890
|
"subMacros": [],
|
|
15207
15891
|
"storeVar": true,
|
|
15892
|
+
"interpolate": true,
|
|
15208
15893
|
"parameters": [
|
|
15209
15894
|
{
|
|
15210
15895
|
"name": "variable",
|
|
@@ -15218,6 +15903,7 @@ var init_macro_registry = __esm({
|
|
|
15218
15903
|
"name": "span",
|
|
15219
15904
|
"block": true,
|
|
15220
15905
|
"subMacros": [],
|
|
15906
|
+
"interpolate": true,
|
|
15221
15907
|
"source": "builtin"
|
|
15222
15908
|
},
|
|
15223
15909
|
{
|
|
@@ -71918,7 +72604,7 @@ var init_server4 = __esm({
|
|
|
71918
72604
|
|
|
71919
72605
|
// src/bin.ts
|
|
71920
72606
|
var args = process.argv.slice(2);
|
|
71921
|
-
var VERSION = "0.13.
|
|
72607
|
+
var VERSION = "0.13.3";
|
|
71922
72608
|
var HELP = `spindle-lsp v${VERSION}
|
|
71923
72609
|
Language Server Protocol server for Spindle story format
|
|
71924
72610
|
|