@marko/language-tools 2.5.57 → 2.5.58
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/extractors/script/util/attach-scopes.d.ts +2 -6
- package/dist/extractors/script/util/script-parser.d.ts +20 -3
- package/dist/index.js +275 -172
- package/dist/index.mjs +275 -172
- package/marko.internal.d.ts +28 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -863,7 +863,10 @@ function sortBySourceThenGenerated(a, b) {
|
|
|
863
863
|
}
|
|
864
864
|
|
|
865
865
|
// src/extractors/html/keywords.ts
|
|
866
|
-
var builtinTagsRegex =
|
|
866
|
+
var builtinTagsRegex = (
|
|
867
|
+
/* cspell:disable-next-line */
|
|
868
|
+
/^(?:a(?:(?:bbr|cronym|ddress|pplet|r(?:ea|ticle)|side|udio))?|b(?:(?:ase(?:font)?|d[io]|gsound|ig|l(?:ink|ockquote)|ody|r|utton))?|c(?:a(?:nvas|ption)|enter|ite|o(?:de|l(?:group)?|mmand|ntent))|d(?:ata(?:list)?|d|e(?:l|tails)|fn|i(?:alog|r|v)|l|t)|e(?:lement|m(?:bed)?)|f(?:i(?:eldset|g(?:caption|ure))|o(?:nt|oter|rm)|rame(?:set)?)|h(?:1|2|3|4|5|6|ead(?:er)?|group|r|tml)|i(?:(?:frame|m(?:age|g)|n(?:put|s)|sindex))?|k(?:bd|eygen)|l(?:abel|egend|i(?:(?:nk|sting))?)|m(?:a(?:in|p|r(?:k|quee)|th)|e(?:nu(?:item)?|t(?:a|er))|ulticol)|n(?:av|extid|o(?:br|embed|frames|script))|o(?:bject|l|pt(?:group|ion)|utput)|p(?:(?:aram|icture|laintext|r(?:e|ogress)))?|q|r(?:bc?|p|tc?|uby)|s(?:(?:amp|cript|e(?:ction|lect)|hadow|lot|mall|ource|pa(?:cer|n)|t(?:r(?:ike|ong)|yle)|u(?:b|mmary|p)|vg))?|t(?:able|body|d|e(?:mplate|xtarea)|foot|h(?:ead)?|i(?:me|tle)|r(?:ack)?|t)|ul?|v(?:ar|ideo)|wbr|xmp)$/
|
|
869
|
+
);
|
|
867
870
|
function isHTMLTag(tag) {
|
|
868
871
|
return builtinTagsRegex.test(tag);
|
|
869
872
|
}
|
|
@@ -1062,31 +1065,16 @@ var import_relative_import_path = require("relative-import-path");
|
|
|
1062
1065
|
|
|
1063
1066
|
// src/extractors/script/util/attach-scopes.ts
|
|
1064
1067
|
var import_compiler = require("@marko/compiler");
|
|
1065
|
-
|
|
1066
|
-
// src/extractors/script/util/is-text-only-script.ts
|
|
1067
|
-
function isTextOnlyScript(tag) {
|
|
1068
|
-
if (tag.nameText !== "script" || tag.args || tag.attrs || !tag.body) {
|
|
1069
|
-
return false;
|
|
1070
|
-
}
|
|
1071
|
-
for (const child of tag.body) {
|
|
1072
|
-
if (child.type !== 17 /* Text */) {
|
|
1073
|
-
return false;
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
return true;
|
|
1077
|
-
}
|
|
1078
|
-
|
|
1079
|
-
// src/extractors/script/util/attach-scopes.ts
|
|
1080
1068
|
var VISITOR_KEYS = import_compiler.types.VISITOR_KEYS;
|
|
1081
|
-
var
|
|
1069
|
+
var ATTR_UNNAMED = "value";
|
|
1082
1070
|
var Scopes = /* @__PURE__ */ new WeakMap();
|
|
1083
1071
|
var BoundAttrValueRange = /* @__PURE__ */ new WeakMap();
|
|
1084
|
-
function crawlProgramScope(parsed,
|
|
1072
|
+
function crawlProgramScope(parsed, ast) {
|
|
1085
1073
|
var _a;
|
|
1086
|
-
const { program
|
|
1074
|
+
const { program } = parsed;
|
|
1087
1075
|
const mutations = [];
|
|
1088
1076
|
const potentialHoists = [];
|
|
1089
|
-
const
|
|
1077
|
+
const potentialMutations = /* @__PURE__ */ new Map();
|
|
1090
1078
|
const programScope = {
|
|
1091
1079
|
parent: void 0,
|
|
1092
1080
|
hoists: false,
|
|
@@ -1134,10 +1122,13 @@ function crawlProgramScope(parsed, scriptParser) {
|
|
|
1134
1122
|
}
|
|
1135
1123
|
}
|
|
1136
1124
|
}
|
|
1137
|
-
for (const [scope, nodes] of
|
|
1125
|
+
for (const [scope, nodes] of potentialMutations) {
|
|
1126
|
+
const shadows = /* @__PURE__ */ new Set();
|
|
1127
|
+
const blockMutations = [];
|
|
1138
1128
|
for (const node of nodes) {
|
|
1139
|
-
|
|
1129
|
+
trackMutations(node, scope, mutations, shadows, blockMutations);
|
|
1140
1130
|
}
|
|
1131
|
+
flushMutations(scope, mutations, shadows, blockMutations);
|
|
1141
1132
|
}
|
|
1142
1133
|
if (mutations.length) {
|
|
1143
1134
|
return mutations.sort(byStart);
|
|
@@ -1150,18 +1141,14 @@ function crawlProgramScope(parsed, scriptParser) {
|
|
|
1150
1141
|
case 16 /* AttrTag */: {
|
|
1151
1142
|
if (child.var) {
|
|
1152
1143
|
parentScope.bindings ??= {};
|
|
1153
|
-
const
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
);
|
|
1157
|
-
if (parsedFn) {
|
|
1158
|
-
const lVal = parsedFn.params[0];
|
|
1159
|
-
checkForMutations(parentScope, lVal);
|
|
1144
|
+
const tagVar = ast.tagVar(child.var);
|
|
1145
|
+
if (tagVar) {
|
|
1146
|
+
checkForMutations(parentScope, tagVar);
|
|
1160
1147
|
for (const id of getVarIdentifiers(
|
|
1161
1148
|
parsed,
|
|
1162
|
-
|
|
1149
|
+
tagVar,
|
|
1163
1150
|
"",
|
|
1164
|
-
|
|
1151
|
+
ATTR_UNNAMED
|
|
1165
1152
|
)) {
|
|
1166
1153
|
const { name, objectPath, sourceName } = id;
|
|
1167
1154
|
const binding = parentScope.bindings[name] = {
|
|
@@ -1186,12 +1173,9 @@ function crawlProgramScope(parsed, scriptParser) {
|
|
|
1186
1173
|
};
|
|
1187
1174
|
if (child.params) {
|
|
1188
1175
|
bodyScope.bindings ??= {};
|
|
1189
|
-
const
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
);
|
|
1193
|
-
if (parsedFn) {
|
|
1194
|
-
for (const param of parsedFn.params) {
|
|
1176
|
+
const parsedParams = ast.tagParams(child.params);
|
|
1177
|
+
if (parsedParams) {
|
|
1178
|
+
for (const param of parsedParams) {
|
|
1195
1179
|
checkForMutations(bodyScope, param);
|
|
1196
1180
|
for (const name of getIdentifiers(param)) {
|
|
1197
1181
|
bodyScope.bindings[name] = {
|
|
@@ -1205,19 +1189,16 @@ function crawlProgramScope(parsed, scriptParser) {
|
|
|
1205
1189
|
}
|
|
1206
1190
|
}
|
|
1207
1191
|
}
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
}`
|
|
1219
|
-
)
|
|
1220
|
-
);
|
|
1192
|
+
const scriptBody = ast.scriptBody(child);
|
|
1193
|
+
if (scriptBody) {
|
|
1194
|
+
const nodes = potentialMutations.get(parentScope);
|
|
1195
|
+
if (nodes) {
|
|
1196
|
+
nodes.push(...scriptBody);
|
|
1197
|
+
} else {
|
|
1198
|
+
potentialMutations.set(parentScope, [
|
|
1199
|
+
...scriptBody
|
|
1200
|
+
]);
|
|
1201
|
+
}
|
|
1221
1202
|
} else {
|
|
1222
1203
|
visit(child.body, bodyScope);
|
|
1223
1204
|
}
|
|
@@ -1227,22 +1208,13 @@ ${read({
|
|
|
1227
1208
|
for (const attr of child.attrs) {
|
|
1228
1209
|
switch (attr.type) {
|
|
1229
1210
|
case 15 /* AttrSpread */: {
|
|
1230
|
-
checkForMutations(
|
|
1231
|
-
parentScope,
|
|
1232
|
-
scriptParser.expressionAt(
|
|
1233
|
-
attr.value.start,
|
|
1234
|
-
read(attr.value)
|
|
1235
|
-
)
|
|
1236
|
-
);
|
|
1211
|
+
checkForMutations(parentScope, ast.attrSpread(attr));
|
|
1237
1212
|
break;
|
|
1238
1213
|
}
|
|
1239
1214
|
case 10 /* AttrNamed */: {
|
|
1240
1215
|
switch ((_a2 = attr.value) == null ? void 0 : _a2.type) {
|
|
1241
1216
|
case 13 /* AttrValue */: {
|
|
1242
|
-
let parsedValue =
|
|
1243
|
-
attr.value.value.start,
|
|
1244
|
-
read(attr.value.value)
|
|
1245
|
-
);
|
|
1217
|
+
let parsedValue = ast.attrValue(attr.value);
|
|
1246
1218
|
if (parsedValue) {
|
|
1247
1219
|
if (!attr.value.bound) {
|
|
1248
1220
|
checkForMutations(parentScope, parsedValue);
|
|
@@ -1292,13 +1264,7 @@ ${read({
|
|
|
1292
1264
|
case 14 /* AttrMethod */: {
|
|
1293
1265
|
checkForMutations(
|
|
1294
1266
|
parentScope,
|
|
1295
|
-
|
|
1296
|
-
attr.value.params.start - 2,
|
|
1297
|
-
`{_${read({
|
|
1298
|
-
start: attr.value.params.start,
|
|
1299
|
-
end: attr.value.body.end
|
|
1300
|
-
})}}`
|
|
1301
|
-
)
|
|
1267
|
+
ast.attrMethod(attr.value)
|
|
1302
1268
|
);
|
|
1303
1269
|
break;
|
|
1304
1270
|
}
|
|
@@ -1315,12 +1281,24 @@ ${read({
|
|
|
1315
1281
|
}
|
|
1316
1282
|
function checkForMutations(scope, node) {
|
|
1317
1283
|
if (node) {
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1284
|
+
traverse(node, (child) => {
|
|
1285
|
+
switch (child.type) {
|
|
1286
|
+
case "FunctionDeclaration":
|
|
1287
|
+
case "FunctionExpression":
|
|
1288
|
+
case "ObjectMethod":
|
|
1289
|
+
case "ArrowFunctionExpression":
|
|
1290
|
+
case "ClassMethod":
|
|
1291
|
+
case "ClassPrivateMethod": {
|
|
1292
|
+
const nodes = potentialMutations.get(scope);
|
|
1293
|
+
if (nodes) {
|
|
1294
|
+
nodes.push(child);
|
|
1295
|
+
} else {
|
|
1296
|
+
potentialMutations.set(scope, [child]);
|
|
1297
|
+
}
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1324
1302
|
}
|
|
1325
1303
|
}
|
|
1326
1304
|
}
|
|
@@ -1499,32 +1477,13 @@ function* getVarIdentifiers(parsed, lVal, objectPath, sourceName) {
|
|
|
1499
1477
|
break;
|
|
1500
1478
|
}
|
|
1501
1479
|
}
|
|
1502
|
-
function
|
|
1503
|
-
traverse(root, (node) => {
|
|
1504
|
-
switch (node.type) {
|
|
1505
|
-
// Since the root will always be an expression it's impossible
|
|
1506
|
-
// to hit a "FunctionDeclaration" without first going through
|
|
1507
|
-
// a a different function context. So we don't need to track it.
|
|
1508
|
-
// case "FunctionDeclaration":
|
|
1509
|
-
case "FunctionExpression":
|
|
1510
|
-
case "ObjectMethod":
|
|
1511
|
-
case "ArrowFunctionExpression":
|
|
1512
|
-
case "ClassMethod":
|
|
1513
|
-
case "ClassPrivateMethod":
|
|
1514
|
-
trackMutations(node, scope, mutations, node, /* @__PURE__ */ new Set(), []);
|
|
1515
|
-
return true;
|
|
1516
|
-
}
|
|
1517
|
-
});
|
|
1518
|
-
}
|
|
1519
|
-
function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows, parentBlockMutations) {
|
|
1480
|
+
function trackMutations(node, scope, mutations, parentBlockShadows, parentBlockMutations) {
|
|
1520
1481
|
if (!node) return;
|
|
1521
|
-
let block = parentBlock;
|
|
1522
1482
|
let blockShadows = parentBlockShadows;
|
|
1523
1483
|
let blockMutations = parentBlockMutations;
|
|
1524
1484
|
switch (node.type) {
|
|
1525
1485
|
case "BlockStatement":
|
|
1526
|
-
if (
|
|
1527
|
-
block = node;
|
|
1486
|
+
if (blockMutations === parentBlockMutations) {
|
|
1528
1487
|
blockShadows = new Set(blockShadows);
|
|
1529
1488
|
blockMutations = [];
|
|
1530
1489
|
}
|
|
@@ -1532,12 +1491,10 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1532
1491
|
case "ForStatement":
|
|
1533
1492
|
case "ForInStatement":
|
|
1534
1493
|
case "ForOfStatement":
|
|
1535
|
-
block = node.body;
|
|
1536
1494
|
blockShadows = new Set(blockShadows);
|
|
1537
1495
|
blockMutations = [];
|
|
1538
1496
|
break;
|
|
1539
1497
|
case "ArrowFunctionExpression":
|
|
1540
|
-
block = node.body;
|
|
1541
1498
|
blockShadows = new Set(blockShadows);
|
|
1542
1499
|
blockMutations = [];
|
|
1543
1500
|
for (const param of node.params) {
|
|
@@ -1547,7 +1504,6 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1547
1504
|
case "ObjectMethod":
|
|
1548
1505
|
case "ClassMethod":
|
|
1549
1506
|
case "ClassPrivateMethod":
|
|
1550
|
-
block = node.body;
|
|
1551
1507
|
blockShadows = new Set(blockShadows);
|
|
1552
1508
|
blockMutations = [];
|
|
1553
1509
|
for (const param of node.params) {
|
|
@@ -1555,7 +1511,6 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1555
1511
|
}
|
|
1556
1512
|
break;
|
|
1557
1513
|
case "FunctionExpression":
|
|
1558
|
-
block = node.body;
|
|
1559
1514
|
blockShadows = new Set(blockShadows);
|
|
1560
1515
|
blockMutations = [];
|
|
1561
1516
|
if (node.id) {
|
|
@@ -1567,7 +1522,6 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1567
1522
|
break;
|
|
1568
1523
|
case "FunctionDeclaration":
|
|
1569
1524
|
trackShadows(node.id, scope, parentBlockShadows);
|
|
1570
|
-
block = node.body;
|
|
1571
1525
|
blockShadows = new Set(blockShadows);
|
|
1572
1526
|
blockMutations = [];
|
|
1573
1527
|
for (const param of node.params) {
|
|
@@ -1575,7 +1529,6 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1575
1529
|
}
|
|
1576
1530
|
break;
|
|
1577
1531
|
case "ClassExpression":
|
|
1578
|
-
block = node.body;
|
|
1579
1532
|
blockShadows = new Set(blockShadows);
|
|
1580
1533
|
blockMutations = [];
|
|
1581
1534
|
if (node.id) {
|
|
@@ -1586,12 +1539,10 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1586
1539
|
if (node.id) {
|
|
1587
1540
|
trackShadows(node.id, scope, parentBlockShadows);
|
|
1588
1541
|
}
|
|
1589
|
-
block = node.body;
|
|
1590
1542
|
blockShadows = new Set(blockShadows);
|
|
1591
1543
|
blockMutations = [];
|
|
1592
1544
|
break;
|
|
1593
1545
|
case "CatchClause":
|
|
1594
|
-
block = node.body;
|
|
1595
1546
|
blockShadows = new Set(blockShadows);
|
|
1596
1547
|
blockMutations = [];
|
|
1597
1548
|
if (node.param) {
|
|
@@ -1618,34 +1569,23 @@ function trackMutations(node, scope, mutations, parentBlock, parentBlockShadows,
|
|
|
1618
1569
|
const child = node[key];
|
|
1619
1570
|
if (Array.isArray(child)) {
|
|
1620
1571
|
for (const item of child) {
|
|
1621
|
-
trackMutations(
|
|
1622
|
-
item,
|
|
1623
|
-
scope,
|
|
1624
|
-
mutations,
|
|
1625
|
-
block,
|
|
1626
|
-
blockShadows,
|
|
1627
|
-
blockMutations
|
|
1628
|
-
);
|
|
1572
|
+
trackMutations(item, scope, mutations, blockShadows, blockMutations);
|
|
1629
1573
|
}
|
|
1630
1574
|
} else {
|
|
1631
|
-
trackMutations(
|
|
1632
|
-
child,
|
|
1633
|
-
scope,
|
|
1634
|
-
mutations,
|
|
1635
|
-
block,
|
|
1636
|
-
blockShadows,
|
|
1637
|
-
blockMutations
|
|
1638
|
-
);
|
|
1575
|
+
trackMutations(child, scope, mutations, blockShadows, blockMutations);
|
|
1639
1576
|
}
|
|
1640
1577
|
}
|
|
1641
|
-
if (
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1578
|
+
if (blockMutations !== parentBlockMutations && blockMutations.length) {
|
|
1579
|
+
flushMutations(scope, mutations, blockShadows, blockMutations);
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
function flushMutations(scope, mutations, blockShadows, blockMutations) {
|
|
1583
|
+
for (const { name, start } of blockMutations) {
|
|
1584
|
+
if (start == null || blockShadows.has(name)) continue;
|
|
1585
|
+
const binding = resolveWritableVar(scope, name);
|
|
1586
|
+
if (binding) {
|
|
1587
|
+
binding.mutated = true;
|
|
1588
|
+
mutations.push({ start, binding });
|
|
1649
1589
|
}
|
|
1650
1590
|
}
|
|
1651
1591
|
}
|
|
@@ -1832,6 +1772,19 @@ function detectAPIFromTag(parsed, tag) {
|
|
|
1832
1772
|
return detectAPIFromBody(parsed, tag.body);
|
|
1833
1773
|
}
|
|
1834
1774
|
|
|
1775
|
+
// src/extractors/script/util/is-text-only-script.ts
|
|
1776
|
+
function isTextOnlyScript(tag) {
|
|
1777
|
+
if (tag.nameText !== "script" || tag.args || tag.attrs || !tag.body) {
|
|
1778
|
+
return false;
|
|
1779
|
+
}
|
|
1780
|
+
for (const child of tag.body) {
|
|
1781
|
+
if (child.type !== 17 /* Text */) {
|
|
1782
|
+
return false;
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
return true;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1835
1788
|
// src/extractors/script/util/jsdoc-input-type.ts
|
|
1836
1789
|
var MaybeInputTypedefReg = /@typedef\b[\s\S]*\bInput\b/;
|
|
1837
1790
|
function getJSDocInputType(comment, ts) {
|
|
@@ -1946,13 +1899,137 @@ var import_babel = require("@marko/compiler/internal/babel");
|
|
|
1946
1899
|
var plugins = ["exportDefaultFrom", "importAssertions", "typescript"];
|
|
1947
1900
|
var ScriptParser = class {
|
|
1948
1901
|
#parsed;
|
|
1902
|
+
#cache = /* @__PURE__ */ new Map();
|
|
1949
1903
|
constructor(parsed) {
|
|
1950
1904
|
this.#parsed = parsed;
|
|
1951
1905
|
}
|
|
1952
|
-
|
|
1953
|
-
|
|
1906
|
+
tagName(name) {
|
|
1907
|
+
return this.#templateExpressions(name);
|
|
1908
|
+
}
|
|
1909
|
+
tagShorthandId(shorthandId) {
|
|
1910
|
+
return this.#templateExpressions(shorthandId);
|
|
1911
|
+
}
|
|
1912
|
+
tagShorthandClassName(node) {
|
|
1913
|
+
return this.#templateExpressions(node);
|
|
1914
|
+
}
|
|
1915
|
+
tagVar(node) {
|
|
1916
|
+
const start = node.value.start - 1;
|
|
1917
|
+
const expr = this.#cache.get(start) ?? this.#expressionAt(start, `(${this.#parsed.read(node.value)})=>0`);
|
|
1918
|
+
if (expr) {
|
|
1919
|
+
return expr.params[0];
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
tagParams(node) {
|
|
1923
|
+
const start = node.start;
|
|
1924
|
+
const expr = this.#cache.get(start) ?? this.#expressionAt(start, `(${this.#parsed.read(node.value)})=>0`);
|
|
1925
|
+
if (expr) {
|
|
1926
|
+
return expr.params;
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
tagTypeParams(node) {
|
|
1930
|
+
const start = node.value.start - 1;
|
|
1931
|
+
const expr = this.#cache.get(start) ?? this.#expressionAt(start, `<${this.#parsed.read(node.value)}>()=>0`);
|
|
1932
|
+
if (expr) {
|
|
1933
|
+
return expr.typeParameters;
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
tagArgs(node) {
|
|
1937
|
+
const start = node.value.start - 2;
|
|
1938
|
+
const expr = this.#cache.get(start) ?? this.#expressionAt(start, `_(${this.#parsed.read(node.value)})`);
|
|
1939
|
+
if (expr) {
|
|
1940
|
+
return expr.arguments;
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
tagTypeArgs(node) {
|
|
1944
|
+
const start = node.value.start - 2;
|
|
1945
|
+
const expr = this.#cache.get(start) ?? this.#expressionAt(start, `_<${this.#parsed.read(node.value)}>()`);
|
|
1946
|
+
if (expr) {
|
|
1947
|
+
return expr.typeParameters;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
attrValue(node) {
|
|
1951
|
+
const start = node.value.start;
|
|
1952
|
+
return (this.#cache.get(start) ?? this.#expressionAt(start, this.#parsed.read(node.value))) || void 0;
|
|
1953
|
+
}
|
|
1954
|
+
attrSpread(node) {
|
|
1955
|
+
const start = node.value.start;
|
|
1956
|
+
return (this.#cache.get(start) ?? this.#expressionAt(start, this.#parsed.read(node.value))) || void 0;
|
|
1957
|
+
}
|
|
1958
|
+
attrMethod(node) {
|
|
1959
|
+
const start = node.params.start - 2;
|
|
1960
|
+
const expr = this.#cache.get(start) ?? this.#expressionAt(
|
|
1961
|
+
start,
|
|
1962
|
+
`{_${this.#parsed.read({ start: node.params.start, end: node.body.end })}}`
|
|
1963
|
+
);
|
|
1964
|
+
if (expr) {
|
|
1965
|
+
return expr.properties[0];
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
attrArgs(node) {
|
|
1969
|
+
const start = node.value.start;
|
|
1970
|
+
return (this.#cache.get(start) ?? this.#expressionAt(start, this.#parsed.read(node.value))) || void 0;
|
|
1971
|
+
}
|
|
1972
|
+
placeholder(node) {
|
|
1973
|
+
const start = node.value.start;
|
|
1974
|
+
return (this.#cache.get(start) ?? this.#expressionAt(start, this.#parsed.read(node.value))) || void 0;
|
|
1975
|
+
}
|
|
1976
|
+
scriptBody(node) {
|
|
1977
|
+
if (!isTextOnlyScript(node)) return;
|
|
1978
|
+
const start = node.body[0].start;
|
|
1979
|
+
const statements = this.#cache.get(start) ?? this.#statementsAt(
|
|
1980
|
+
start,
|
|
1981
|
+
this.#parsed.read({ start, end: node.body[node.body.length - 1].end })
|
|
1982
|
+
);
|
|
1983
|
+
if (statements) {
|
|
1984
|
+
return statements;
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
scriptlet(node) {
|
|
1988
|
+
const start = node.value.start;
|
|
1989
|
+
const statements = this.#cache.get(start) ?? this.#statementsAt(start, this.#parsed.read(node.value));
|
|
1990
|
+
if (statements) {
|
|
1991
|
+
return statements;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
import(node) {
|
|
1995
|
+
const statements = this.#cache.get(node.start) ?? this.#statementsAt(node.start, this.#parsed.read(node));
|
|
1996
|
+
if (statements) {
|
|
1997
|
+
return statements[0];
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
export(node) {
|
|
2001
|
+
const statements = this.#cache.get(node.start) ?? this.#statementsAt(node.start, this.#parsed.read(node));
|
|
2002
|
+
if (statements) {
|
|
2003
|
+
return statements[0];
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
class(node) {
|
|
2007
|
+
const expr = this.#cache.get(node.start) ?? this.#expressionAt(node.start, this.#parsed.read(node));
|
|
2008
|
+
return expr || void 0;
|
|
2009
|
+
}
|
|
2010
|
+
static(node) {
|
|
2011
|
+
const start = node.start + "static ".length;
|
|
2012
|
+
const statements = this.#cache.get(start) ?? this.#statementsAt(start, this.#parsed.read({ start, end: node.end }));
|
|
2013
|
+
if (statements) {
|
|
2014
|
+
return statements;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
#templateExpressions(template) {
|
|
2018
|
+
const { expressions } = template;
|
|
2019
|
+
if (!expressions.length) return;
|
|
2020
|
+
const result = [];
|
|
2021
|
+
for (const expr of expressions) {
|
|
2022
|
+
const start = expr.value.start;
|
|
2023
|
+
const parsed = this.#cache.get(start) ?? this.#expressionAt(start, this.#parsed.read(expr.value));
|
|
2024
|
+
if (!parsed) return;
|
|
2025
|
+
result.push(parsed);
|
|
2026
|
+
}
|
|
2027
|
+
if (result.length) return result;
|
|
2028
|
+
}
|
|
2029
|
+
#statementsAt(startIndex, src) {
|
|
1954
2030
|
try {
|
|
1955
|
-
|
|
2031
|
+
const pos = this.#parsed.positionAt(startIndex);
|
|
2032
|
+
const result = (0, import_babel.parse)(src, {
|
|
1956
2033
|
plugins,
|
|
1957
2034
|
startIndex,
|
|
1958
2035
|
startLine: pos.line + 1,
|
|
@@ -1966,14 +2043,18 @@ var ScriptParser = class {
|
|
|
1966
2043
|
allowReturnOutsideFunction: true,
|
|
1967
2044
|
sourceFilename: this.#parsed.filename
|
|
1968
2045
|
}).program.body;
|
|
2046
|
+
if (result.length) {
|
|
2047
|
+
this.#cache.set(startIndex, result);
|
|
2048
|
+
return result;
|
|
2049
|
+
}
|
|
1969
2050
|
} catch {
|
|
1970
|
-
return [];
|
|
1971
2051
|
}
|
|
2052
|
+
this.#cache.set(startIndex, false);
|
|
1972
2053
|
}
|
|
1973
|
-
expressionAt(startIndex, src) {
|
|
1974
|
-
const pos = this.#parsed.positionAt(startIndex);
|
|
2054
|
+
#expressionAt(startIndex, src) {
|
|
1975
2055
|
try {
|
|
1976
|
-
|
|
2056
|
+
const pos = this.#parsed.positionAt(startIndex);
|
|
2057
|
+
const result = (0, import_babel.parseExpression)(src, {
|
|
1977
2058
|
plugins,
|
|
1978
2059
|
startIndex,
|
|
1979
2060
|
startLine: pos.line + 1,
|
|
@@ -1987,8 +2068,10 @@ var ScriptParser = class {
|
|
|
1987
2068
|
allowReturnOutsideFunction: true,
|
|
1988
2069
|
sourceFilename: this.#parsed.filename
|
|
1989
2070
|
});
|
|
2071
|
+
this.#cache.set(startIndex, result);
|
|
2072
|
+
return result;
|
|
1990
2073
|
} catch {
|
|
1991
|
-
|
|
2074
|
+
this.#cache.set(startIndex, false);
|
|
1992
2075
|
}
|
|
1993
2076
|
}
|
|
1994
2077
|
};
|
|
@@ -2000,7 +2083,7 @@ var SEP_COMMA_SPACE = ", ";
|
|
|
2000
2083
|
var SEP_COMMA_NEW_LINE = ",\n";
|
|
2001
2084
|
var VAR_LOCAL_PREFIX = "__marko_internal_";
|
|
2002
2085
|
var VAR_SHARED_PREFIX = `Marko._.`;
|
|
2003
|
-
var
|
|
2086
|
+
var ATTR_UNNAMED2 = "value";
|
|
2004
2087
|
var REG_EXT = /(?<=[/\\][^/\\]+)\.[^.]+$/;
|
|
2005
2088
|
var REG_BLOCK = /\s*{/y;
|
|
2006
2089
|
var REG_NEW_LINE = /^|(\r?\n)/g;
|
|
@@ -2031,7 +2114,7 @@ var ScriptExtractor = class {
|
|
|
2031
2114
|
#interop;
|
|
2032
2115
|
#parsed;
|
|
2033
2116
|
#extractor;
|
|
2034
|
-
#
|
|
2117
|
+
#ast;
|
|
2035
2118
|
#read;
|
|
2036
2119
|
#lookup;
|
|
2037
2120
|
#scriptLang;
|
|
@@ -2057,9 +2140,9 @@ var ScriptExtractor = class {
|
|
|
2057
2140
|
this.#ts = opts.ts;
|
|
2058
2141
|
this.#runtimeTypes = opts.runtimeTypesCode;
|
|
2059
2142
|
this.#extractor = new Extractor(parsed);
|
|
2060
|
-
this.#
|
|
2143
|
+
this.#ast = new ScriptParser(parsed);
|
|
2061
2144
|
this.#read = parsed.read.bind(parsed);
|
|
2062
|
-
this.#mutations = crawlProgramScope(this.#parsed, this.#
|
|
2145
|
+
this.#mutations = crawlProgramScope(this.#parsed, this.#ast);
|
|
2063
2146
|
this.#writeProgram(parsed.program);
|
|
2064
2147
|
}
|
|
2065
2148
|
end() {
|
|
@@ -2359,8 +2442,10 @@ function ${templateName}() {
|
|
|
2359
2442
|
this.#extractor.write(`return new (class MarkoReturn<Return = void> {
|
|
2360
2443
|
`);
|
|
2361
2444
|
if (scopeExpr) {
|
|
2362
|
-
this.#extractor.write(
|
|
2363
|
-
`);
|
|
2445
|
+
this.#extractor.write(
|
|
2446
|
+
`readonly [${varShared("scope")}] = ${scopeExpr};
|
|
2447
|
+
`
|
|
2448
|
+
);
|
|
2364
2449
|
}
|
|
2365
2450
|
this.#extractor.write(`declare return: Return;
|
|
2366
2451
|
constructor(_?: Return) {}
|
|
@@ -2404,7 +2489,7 @@ constructor(_?: Return) {}
|
|
|
2404
2489
|
}
|
|
2405
2490
|
this.#writeComments(child);
|
|
2406
2491
|
this.#extractor.write("if (").copy(
|
|
2407
|
-
this.#getRangeWithoutTrailingComma((_a = child.args) == null ? void 0 : _a.value) || this.#getAttrValue(child,
|
|
2492
|
+
this.#getRangeWithoutTrailingComma((_a = child.args) == null ? void 0 : _a.value) || this.#getAttrValue(child, ATTR_UNNAMED2) || "undefined"
|
|
2408
2493
|
).write(") {\n");
|
|
2409
2494
|
const ifBody = this.#processBody(child);
|
|
2410
2495
|
if (ifBody == null ? void 0 : ifBody.content) {
|
|
@@ -2684,7 +2769,7 @@ scope: ${scopeExpr}
|
|
|
2684
2769
|
const value = attr.value;
|
|
2685
2770
|
const modifier = !value || value.type === 13 /* AttrValue */ ? this.#getNamedAttrModifier(attr) : void 0;
|
|
2686
2771
|
const defaultMapPosition = isDefault ? attr.name : void 0;
|
|
2687
|
-
let name = isDefault ?
|
|
2772
|
+
let name = isDefault ? ATTR_UNNAMED2 : attr.name;
|
|
2688
2773
|
if (modifier) {
|
|
2689
2774
|
name = { start: attr.name.start, end: modifier.start - 1 };
|
|
2690
2775
|
}
|
|
@@ -2761,10 +2846,10 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2761
2846
|
stringLiteralFirstArgMatch[2]
|
|
2762
2847
|
);
|
|
2763
2848
|
if (isValidProperty) {
|
|
2764
|
-
const
|
|
2849
|
+
const propertyNameStart = stringLiteralStart + 1;
|
|
2765
2850
|
this.#extractor.write("component.").copy({
|
|
2766
|
-
start:
|
|
2767
|
-
end:
|
|
2851
|
+
start: propertyNameStart,
|
|
2852
|
+
end: propertyNameStart + stringLiteralValue.length
|
|
2768
2853
|
});
|
|
2769
2854
|
} else {
|
|
2770
2855
|
this.#extractor.write(`component[`).copy({
|
|
@@ -2800,7 +2885,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2800
2885
|
);
|
|
2801
2886
|
return hasAttrs;
|
|
2802
2887
|
}
|
|
2803
|
-
#writeAttrTags({ staticAttrTags, dynamicAttrTagParents }) {
|
|
2888
|
+
#writeAttrTags({ staticAttrTags, dynamicAttrTagParents }, constraintExpr) {
|
|
2804
2889
|
let wasMerge = false;
|
|
2805
2890
|
if (dynamicAttrTagParents) {
|
|
2806
2891
|
if (staticAttrTags) {
|
|
@@ -2821,7 +2906,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2821
2906
|
this.#extractor.write(`}${SEP_COMMA_NEW_LINE}`);
|
|
2822
2907
|
}
|
|
2823
2908
|
if (dynamicAttrTagParents) {
|
|
2824
|
-
this.#writeDynamicAttrTagParents(dynamicAttrTagParents);
|
|
2909
|
+
this.#writeDynamicAttrTagParents(dynamicAttrTagParents, constraintExpr);
|
|
2825
2910
|
if (wasMerge) this.#extractor.write(`)${SEP_COMMA_NEW_LINE}`);
|
|
2826
2911
|
}
|
|
2827
2912
|
}
|
|
@@ -2837,18 +2922,8 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2837
2922
|
if (isRepeated) {
|
|
2838
2923
|
const templateVar = this.#getTemplateVar(firstAttrTag.owner);
|
|
2839
2924
|
if (templateVar) {
|
|
2840
|
-
let accessor = `"${name}"`;
|
|
2841
|
-
let curTag = firstAttrTag.parent;
|
|
2842
|
-
while (curTag) {
|
|
2843
|
-
if (curTag.type === 16 /* AttrTag */) {
|
|
2844
|
-
accessor = `"${this.#getAttrTagName(curTag)}",${accessor}`;
|
|
2845
|
-
} else if (!isControlFlowTag(curTag)) {
|
|
2846
|
-
break;
|
|
2847
|
-
}
|
|
2848
|
-
curTag = curTag.parent;
|
|
2849
|
-
}
|
|
2850
2925
|
this.#extractor.write(
|
|
2851
|
-
`${varShared("attrTagFor")}(${templateVar},${
|
|
2926
|
+
`${varShared("attrTagFor")}(${templateVar},${this.#getAttrTagPath(firstAttrTag)})(`
|
|
2852
2927
|
);
|
|
2853
2928
|
} else {
|
|
2854
2929
|
this.#extractor.write(`${varShared("attrTag")}(`);
|
|
@@ -2870,7 +2945,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2870
2945
|
}
|
|
2871
2946
|
}
|
|
2872
2947
|
}
|
|
2873
|
-
#writeDynamicAttrTagParents(dynamicAttrTagParents) {
|
|
2948
|
+
#writeDynamicAttrTagParents(dynamicAttrTagParents, constraintExpr) {
|
|
2874
2949
|
var _a, _b, _c;
|
|
2875
2950
|
for (const tag of dynamicAttrTagParents) {
|
|
2876
2951
|
switch (tag.nameText) {
|
|
@@ -2878,7 +2953,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2878
2953
|
const alternates = IF_TAG_ALTERNATES.get(tag);
|
|
2879
2954
|
this.#writeComments(tag);
|
|
2880
2955
|
this.#extractor.write("((\n").copy(
|
|
2881
|
-
this.#getRangeWithoutTrailingComma((_a = tag.args) == null ? void 0 : _a.value) || this.#getAttrValue(tag,
|
|
2956
|
+
this.#getRangeWithoutTrailingComma((_a = tag.args) == null ? void 0 : _a.value) || this.#getAttrValue(tag, ATTR_UNNAMED2) || "undefined"
|
|
2882
2957
|
).write("\n) ? ");
|
|
2883
2958
|
this.#writeDynamicAttrTagBody(tag);
|
|
2884
2959
|
let needsAlternate = true;
|
|
@@ -2912,8 +2987,12 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2912
2987
|
this.#extractor.write("\n}, \n");
|
|
2913
2988
|
this.#writeComments(tag);
|
|
2914
2989
|
this.#extractor.copy(tag.typeParams).write("(\n").copy((_b = tag.params) == null ? void 0 : _b.value).write("\n) => (");
|
|
2915
|
-
this.#writeDynamicAttrTagBody(tag);
|
|
2916
|
-
this.#extractor.write(")
|
|
2990
|
+
this.#writeDynamicAttrTagBody(tag, constraintExpr);
|
|
2991
|
+
this.#extractor.write(")");
|
|
2992
|
+
if (constraintExpr) {
|
|
2993
|
+
this.#extractor.write(`,${constraintExpr}`);
|
|
2994
|
+
}
|
|
2995
|
+
this.#extractor.write(")");
|
|
2917
2996
|
break;
|
|
2918
2997
|
}
|
|
2919
2998
|
case "while": {
|
|
@@ -2971,7 +3050,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
2971
3050
|
this.#extractor.write(`}${SEP_COMMA_NEW_LINE}`);
|
|
2972
3051
|
} else if (body) {
|
|
2973
3052
|
hasInput = true;
|
|
2974
|
-
this.#writeAttrTags(body);
|
|
3053
|
+
this.#writeAttrTags(body, this.#getTagInputType(tag));
|
|
2975
3054
|
hasBodyContent = body.content !== void 0;
|
|
2976
3055
|
} else if (tag.close) {
|
|
2977
3056
|
hasBodyContent = true;
|
|
@@ -3134,7 +3213,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
3134
3213
|
const alternate = {
|
|
3135
3214
|
condition: this.#getRangeWithoutTrailingComma(
|
|
3136
3215
|
(_a = nextChild.args) == null ? void 0 : _a.value
|
|
3137
|
-
) || this.#getAttrValue(nextChild,
|
|
3216
|
+
) || this.#getAttrValue(nextChild, ATTR_UNNAMED2),
|
|
3138
3217
|
node: nextChild
|
|
3139
3218
|
};
|
|
3140
3219
|
hasDynamicAttrTags ||= nextChild.hasAttrTags;
|
|
@@ -3207,7 +3286,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
3207
3286
|
return { content, staticAttrTags, dynamicAttrTagParents };
|
|
3208
3287
|
}
|
|
3209
3288
|
}
|
|
3210
|
-
#writeDynamicAttrTagBody(tag) {
|
|
3289
|
+
#writeDynamicAttrTagBody(tag, constraintExpr) {
|
|
3211
3290
|
const body = this.#processBody(tag);
|
|
3212
3291
|
if (body) {
|
|
3213
3292
|
if (body.content) {
|
|
@@ -3216,7 +3295,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
3216
3295
|
this.#extractor.write("return ");
|
|
3217
3296
|
}
|
|
3218
3297
|
this.#extractor.write("{\n");
|
|
3219
|
-
this.#writeAttrTags(body);
|
|
3298
|
+
this.#writeAttrTags(body, constraintExpr);
|
|
3220
3299
|
this.#extractor.write("}");
|
|
3221
3300
|
if (body.content) {
|
|
3222
3301
|
this.#endChildren();
|
|
@@ -3229,7 +3308,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
3229
3308
|
#getAttrValue(tag, name) {
|
|
3230
3309
|
if (tag.attrs) {
|
|
3231
3310
|
for (const attr of tag.attrs) {
|
|
3232
|
-
if (isValueAttribute(attr) && (this.#read(attr.name) ||
|
|
3311
|
+
if (isValueAttribute(attr) && (this.#read(attr.name) || ATTR_UNNAMED2) === name) {
|
|
3233
3312
|
return attr.value.value;
|
|
3234
3313
|
}
|
|
3235
3314
|
}
|
|
@@ -3267,9 +3346,9 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
3267
3346
|
var _a;
|
|
3268
3347
|
for (const node of program.static) {
|
|
3269
3348
|
if (node.type === 25 /* Export */) {
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
const
|
|
3349
|
+
if (this.#testAtIndex(REG_INPUT_TYPE, node.start + "export ".length)) {
|
|
3350
|
+
const exported = this.#ast.export(node);
|
|
3351
|
+
const inputType = exported == null ? void 0 : exported.declaration;
|
|
3273
3352
|
return {
|
|
3274
3353
|
typeParameters: (_a = inputType == null ? void 0 : inputType.typeParameters) == null ? void 0 : _a.params.map((param) => {
|
|
3275
3354
|
return {
|
|
@@ -3376,6 +3455,30 @@ ${isMutatedVar(tag.parent, valueLiteral) ? varLocal(`change__${valueLiteral}.`)
|
|
|
3376
3455
|
const { nameText } = tag;
|
|
3377
3456
|
return ((_a = this.#lookup.getTag(nameText)) == null ? void 0 : _a.targetProperty) || nameText.slice(nameText.lastIndexOf(":") + 1);
|
|
3378
3457
|
}
|
|
3458
|
+
#getAttrTagPath(tag) {
|
|
3459
|
+
let path4 = `"${this.#getAttrTagName(tag)}"`;
|
|
3460
|
+
let curTag = tag.parent;
|
|
3461
|
+
while (curTag) {
|
|
3462
|
+
if (curTag.type === 16 /* AttrTag */) {
|
|
3463
|
+
path4 = `"${this.#getAttrTagName(curTag)}",${path4}`;
|
|
3464
|
+
} else if (!isControlFlowTag(curTag)) {
|
|
3465
|
+
break;
|
|
3466
|
+
}
|
|
3467
|
+
curTag = curTag.parent;
|
|
3468
|
+
}
|
|
3469
|
+
return path4;
|
|
3470
|
+
}
|
|
3471
|
+
#getTagInputType(tag) {
|
|
3472
|
+
if (tag.type === 16 /* AttrTag */) {
|
|
3473
|
+
if (!tag.owner) return;
|
|
3474
|
+
const templateVar2 = this.#getTemplateVar(tag.owner);
|
|
3475
|
+
if (!templateVar2) return;
|
|
3476
|
+
return `${varShared("inputForAttr")}(${templateVar2},${this.#getAttrTagPath(tag)})`;
|
|
3477
|
+
}
|
|
3478
|
+
const templateVar = this.#getTemplateVar(tag);
|
|
3479
|
+
if (!templateVar) return;
|
|
3480
|
+
return `${varShared("input")}(${templateVar})`;
|
|
3481
|
+
}
|
|
3379
3482
|
#writeAttrTagTree(tree, valueExpression, nested) {
|
|
3380
3483
|
this.#extractor.write(
|
|
3381
3484
|
`${varShared(nested ? "nestedAttrTagNames" : "attrTagNames")}(${valueExpression},input=>{
|
|
@@ -3965,7 +4068,7 @@ var marko_default = {
|
|
|
3965
4068
|
isExportComponentType(statement) || // skips the generated `export { type Component }`.
|
|
3966
4069
|
isImportComponentType(statement) || // skips the generated `import type Component from "..."`.
|
|
3967
4070
|
isExportEmptyInputType(statement) || // skips empty exported Input, eg `export type Input = {}` or `export interface Input {}`.
|
|
3968
|
-
isExportInputTypeAsComponentInput(statement) || // skips
|
|
4071
|
+
isExportInputTypeAsComponentInput(statement) || // skips outputting `export type Input = Component["input"]` since it's inferred.
|
|
3969
4072
|
defaultExportId && // If the `export default` was an identifier, we also remove the variable that declared the identifier.
|
|
3970
4073
|
isVariableStatementForName(statement, defaultExportId)) {
|
|
3971
4074
|
continue;
|