tutuca 0.9.32 → 0.9.34
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/tutuca-cli.js +361 -134
- package/dist/tutuca-dev.js +336 -146
- package/dist/tutuca-dev.min.js +2 -2
- package/dist/tutuca-extra.js +120 -72
- package/dist/tutuca-extra.min.js +2 -2
- package/dist/tutuca.js +119 -71
- package/dist/tutuca.min.js +1 -1
- package/package.json +1 -1
package/dist/tutuca-dev.js
CHANGED
|
@@ -293,9 +293,11 @@ class ValParser {
|
|
|
293
293
|
const charCode = s.charCodeAt(0);
|
|
294
294
|
switch (charCode) {
|
|
295
295
|
case 94: {
|
|
296
|
-
const
|
|
296
|
+
const name = s.slice(1);
|
|
297
|
+
const newS = px.frame.macroVars?.[name];
|
|
297
298
|
if (newS !== undefined)
|
|
298
299
|
return this.parse(newS, px);
|
|
300
|
+
px.onParseIssue("bad-value", { role: "macro-var", name, value: s });
|
|
299
301
|
return null;
|
|
300
302
|
}
|
|
301
303
|
case 39:
|
|
@@ -632,6 +634,8 @@ class AttrParser {
|
|
|
632
634
|
this.attrs ??= [];
|
|
633
635
|
this.attrs.push(new Attr(name, val));
|
|
634
636
|
this.hasDynamic ||= !(val instanceof ConstVal);
|
|
637
|
+
} else {
|
|
638
|
+
this.px.onParseIssue("bad-value", { role: "attr", attr: name, value });
|
|
635
639
|
}
|
|
636
640
|
}
|
|
637
641
|
pushWrapper(name, raw, val) {
|
|
@@ -647,6 +651,9 @@ class AttrParser {
|
|
|
647
651
|
this.attrs ??= [];
|
|
648
652
|
this.attrs.push(this.ifAttr);
|
|
649
653
|
this.hasDynamic = true;
|
|
654
|
+
} else {
|
|
655
|
+
const info = { role: "if", attr: directiveName.slice(3), value };
|
|
656
|
+
this.px.onParseIssue("bad-value", info);
|
|
650
657
|
}
|
|
651
658
|
}
|
|
652
659
|
parseThen(s) {
|
|
@@ -669,36 +676,44 @@ class AttrParser {
|
|
|
669
676
|
this.events.add(eventName, handler, modifiers);
|
|
670
677
|
}
|
|
671
678
|
}
|
|
679
|
+
_parseDirectiveValue(directiveName, s, parserFn) {
|
|
680
|
+
const val = parserFn.call(vp, s, this.px);
|
|
681
|
+
if (val === null) {
|
|
682
|
+
const info = { role: "directive", directive: directiveName, value: s };
|
|
683
|
+
this.px.onParseIssue("bad-value", info);
|
|
684
|
+
}
|
|
685
|
+
return val;
|
|
686
|
+
}
|
|
672
687
|
parseDirective(s, directiveName) {
|
|
673
688
|
switch (directiveName) {
|
|
674
689
|
case "dangerouslysetinnerhtml":
|
|
675
690
|
this.attrs ??= [];
|
|
676
|
-
this.attrs.push(new RawHtmlAttr(
|
|
691
|
+
this.attrs.push(new RawHtmlAttr(this._parseDirectiveValue(directiveName, s, vp.parseText)));
|
|
677
692
|
this.hasDynamic = true;
|
|
678
693
|
return;
|
|
679
694
|
case "slot":
|
|
680
695
|
this.pushWrapper("slot", s, vp.const(s));
|
|
681
696
|
return;
|
|
682
697
|
case "push-view":
|
|
683
|
-
this.pushWrapper("push-view", s,
|
|
698
|
+
this.pushWrapper("push-view", s, this._parseDirectiveValue(directiveName, s, vp.parseText));
|
|
684
699
|
return;
|
|
685
700
|
case "text":
|
|
686
|
-
this.textChild =
|
|
701
|
+
this.textChild = this._parseDirectiveValue(directiveName, s, vp.parseText);
|
|
687
702
|
return;
|
|
688
703
|
case "show":
|
|
689
|
-
this.pushWrapper("show", s,
|
|
704
|
+
this.pushWrapper("show", s, this._parseDirectiveValue(directiveName, s, vp.parseCondValue));
|
|
690
705
|
return;
|
|
691
706
|
case "hide":
|
|
692
|
-
this.pushWrapper("hide", s,
|
|
707
|
+
this.pushWrapper("hide", s, this._parseDirectiveValue(directiveName, s, vp.parseCondValue));
|
|
693
708
|
return;
|
|
694
709
|
case "each":
|
|
695
|
-
this.eachAttr = this.pushWrapper("each", s,
|
|
710
|
+
this.eachAttr = this.pushWrapper("each", s, this._parseDirectiveValue(directiveName, s, vp.parseEach));
|
|
696
711
|
return;
|
|
697
712
|
case "enrich-with":
|
|
698
713
|
if (this.eachAttr !== null) {
|
|
699
|
-
this.eachAttr.enrichWithVal =
|
|
714
|
+
this.eachAttr.enrichWithVal = this._parseDirectiveValue(directiveName, s, vp.parseAlter);
|
|
700
715
|
} else {
|
|
701
|
-
this.pushWrapper("scope", s,
|
|
716
|
+
this.pushWrapper("scope", s, this._parseDirectiveValue(directiveName, s, vp.parseAlter));
|
|
702
717
|
}
|
|
703
718
|
return;
|
|
704
719
|
case "when":
|
|
@@ -722,16 +737,18 @@ class AttrParser {
|
|
|
722
737
|
this.parseThen(s);
|
|
723
738
|
else if (directiveName.startsWith("else."))
|
|
724
739
|
this.parseElse(s);
|
|
725
|
-
else
|
|
726
|
-
|
|
740
|
+
else {
|
|
741
|
+
const info = { name: directiveName, value: s };
|
|
742
|
+
this.px.onParseIssue("unknown-directive", info);
|
|
743
|
+
}
|
|
727
744
|
}
|
|
728
745
|
_parseWhen(s) {
|
|
729
746
|
if (this.eachAttr !== null)
|
|
730
|
-
this.eachAttr.whenVal =
|
|
747
|
+
this.eachAttr.whenVal = this._parseDirectiveValue("when", s, vp.parseAlter);
|
|
731
748
|
}
|
|
732
749
|
_parseLoopWith(s) {
|
|
733
750
|
if (this.eachAttr !== null)
|
|
734
|
-
this.eachAttr.loopWithVal =
|
|
751
|
+
this.eachAttr.loopWithVal = this._parseDirectiveValue("loop-with", s, vp.parseAlter);
|
|
735
752
|
}
|
|
736
753
|
parse(attributes, parseAll = false) {
|
|
737
754
|
for (const { name, value } of attributes) {
|
|
@@ -859,13 +876,22 @@ class EventHandler {
|
|
|
859
876
|
static parse(s, px) {
|
|
860
877
|
const [handlerName, ...rawArgs] = s.trim().split(/\s+/);
|
|
861
878
|
const handlerVal = vp.parseHandlerName(handlerName, px);
|
|
862
|
-
if (handlerVal === null)
|
|
879
|
+
if (handlerVal === null) {
|
|
880
|
+
const info = { role: "handler-name", value: handlerName };
|
|
881
|
+
px.onParseIssue("bad-value", info);
|
|
863
882
|
return null;
|
|
883
|
+
}
|
|
864
884
|
const args = new Array(rawArgs.length);
|
|
865
885
|
vp.allowHandlerArg();
|
|
866
886
|
for (let i = 0;i < rawArgs.length; i++) {
|
|
867
887
|
const val = vp.parse(rawArgs[i], px);
|
|
868
|
-
|
|
888
|
+
if (val !== null) {
|
|
889
|
+
args[i] = val;
|
|
890
|
+
} else {
|
|
891
|
+
const info = { role: "handler-arg", value: rawArgs[i] };
|
|
892
|
+
px.onParseIssue("bad-value", info);
|
|
893
|
+
args[i] = vp.nullConstVal;
|
|
894
|
+
}
|
|
869
895
|
}
|
|
870
896
|
return new EventHandler(handlerVal, args);
|
|
871
897
|
}
|
|
@@ -1029,63 +1055,84 @@ class ANode extends BaseNode {
|
|
|
1029
1055
|
else if (node instanceof px.Comment)
|
|
1030
1056
|
return new CommentNode(node.textContent);
|
|
1031
1057
|
const { childNodes, attributes: attrs, tagName: tag } = node;
|
|
1032
|
-
const childs =
|
|
1033
|
-
for (let i = 0;i < childNodes.length; i++)
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
const
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
node2 = px.addNodeIf(ShowNode, vp.parseCondValue(value, px), maybeFragment(childs));
|
|
1061
|
-
break;
|
|
1062
|
-
case "hide":
|
|
1063
|
-
node2 = px.addNodeIf(HideNode, vp.parseCondValue(value, px), maybeFragment(childs));
|
|
1064
|
-
break;
|
|
1065
|
-
default:
|
|
1066
|
-
px.onParseIssue("unknown-x-op", { name, value });
|
|
1067
|
-
return new CommentNode(`Error: InvalidSpecialTagOp ${name}=${value}`);
|
|
1068
|
-
}
|
|
1069
|
-
return processXExtras(node2, attrs, name, (isPseudoX ? 1 : 0) + 1, px);
|
|
1070
|
-
} else if (tag.charCodeAt(1) === 58 && tag.charCodeAt(0) === 88) {
|
|
1071
|
-
const macroName = tag.slice(2).toLowerCase();
|
|
1072
|
-
if (macroName === "slot") {
|
|
1073
|
-
const slotName = attrs.getNamedItem("name")?.value ?? "_";
|
|
1074
|
-
return px.frame.macroSlots[slotName] ?? maybeFragment(childs);
|
|
1058
|
+
const childs = [];
|
|
1059
|
+
for (let i = 0;i < childNodes.length; i++) {
|
|
1060
|
+
const child = ANode.fromDOM(childNodes[i], px);
|
|
1061
|
+
if (child !== null)
|
|
1062
|
+
childs.push(child);
|
|
1063
|
+
}
|
|
1064
|
+
const prevTag = px.currentTag;
|
|
1065
|
+
px.currentTag = tag;
|
|
1066
|
+
try {
|
|
1067
|
+
const isPseudoX = attrs[0]?.name === "@x";
|
|
1068
|
+
if (tag === "X" || isPseudoX) {
|
|
1069
|
+
return parseXOp(attrs, childs, isPseudoX ? 1 : 0, px);
|
|
1070
|
+
} else if (tag.charCodeAt(1) === 58 && tag.charCodeAt(0) === 88) {
|
|
1071
|
+
const macroName = tag.slice(2).toLowerCase();
|
|
1072
|
+
if (macroName === "slot") {
|
|
1073
|
+
const slotName = attrs.getNamedItem("name")?.value ?? "_";
|
|
1074
|
+
return px.frame.macroSlots[slotName] ?? maybeFragment(childs);
|
|
1075
|
+
}
|
|
1076
|
+
const [nAttrs, wrappers] = Attributes.parse(attrs, px, true);
|
|
1077
|
+
px.onAttributes(nAttrs, wrappers, null, true, tag);
|
|
1078
|
+
return wrap(px.newMacroNode(macroName, nAttrs.toMacroVars(), childs), px, wrappers);
|
|
1079
|
+
} else if (VALID_NODE_RE.test(tag)) {
|
|
1080
|
+
const [nAttrs, wrappers, textChild] = Attributes.parse(attrs, px);
|
|
1081
|
+
px.onAttributes(nAttrs, wrappers, textChild, false, tag);
|
|
1082
|
+
if (textChild)
|
|
1083
|
+
childs.unshift(new RenderTextNode(null, textChild));
|
|
1084
|
+
const domChilds = tag !== "PRE" ? condenseChildsWhites(childs) : childs;
|
|
1085
|
+
return wrap(new DomNode(tag, nAttrs, domChilds), px, wrappers);
|
|
1075
1086
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1087
|
+
return new CommentNode(`Error: InvalidTagName ${tag}`);
|
|
1088
|
+
} finally {
|
|
1089
|
+
px.currentTag = prevTag;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
function parseXOp(attrs, childs, opIdx, px) {
|
|
1094
|
+
if (attrs.length === 0)
|
|
1095
|
+
return maybeFragment(childs);
|
|
1096
|
+
const { name, value } = attrs[opIdx];
|
|
1097
|
+
const as = attrs.getNamedItem("as")?.value ?? null;
|
|
1098
|
+
let node;
|
|
1099
|
+
switch (name) {
|
|
1100
|
+
case "slot":
|
|
1101
|
+
node = new SlotNode(null, vp.const(value), maybeFragment(childs));
|
|
1102
|
+
break;
|
|
1103
|
+
case "text":
|
|
1104
|
+
node = px.addNodeIf(RenderTextNode, parseXOpVal(name, value, px, vp.parseText));
|
|
1105
|
+
break;
|
|
1106
|
+
case "render":
|
|
1107
|
+
node = px.addNodeIf(RenderNode, parseXOpVal(name, value, px, vp.parseRender), as);
|
|
1108
|
+
break;
|
|
1109
|
+
case "render-it":
|
|
1110
|
+
node = px.addNodeIf(RenderItNode, vp.bindValIt, as);
|
|
1111
|
+
break;
|
|
1112
|
+
case "render-each":
|
|
1113
|
+
node = RenderEachNode.parse(px, vp, value, as, attrs);
|
|
1114
|
+
break;
|
|
1115
|
+
case "show": {
|
|
1116
|
+
const val = parseXOpVal(name, value, px, vp.parseCondValue);
|
|
1117
|
+
node = px.addNodeIf(ShowNode, val, maybeFragment(childs));
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
case "hide": {
|
|
1121
|
+
const val = parseXOpVal(name, value, px, vp.parseCondValue);
|
|
1122
|
+
node = px.addNodeIf(HideNode, val, maybeFragment(childs));
|
|
1123
|
+
break;
|
|
1086
1124
|
}
|
|
1087
|
-
|
|
1125
|
+
default:
|
|
1126
|
+
px.onParseIssue("unknown-x-op", { name, value });
|
|
1127
|
+
return new CommentNode(`Error: InvalidSpecialTagOp ${name}=${value}`);
|
|
1088
1128
|
}
|
|
1129
|
+
return processXExtras(node, attrs, name, opIdx + 1, px);
|
|
1130
|
+
}
|
|
1131
|
+
function parseXOpVal(opName, value, px, parserFn) {
|
|
1132
|
+
const val = parserFn.call(vp, value, px);
|
|
1133
|
+
if (val === null)
|
|
1134
|
+
px.onParseIssue("bad-value", { role: "x-op", op: opName, value });
|
|
1135
|
+
return val;
|
|
1089
1136
|
}
|
|
1090
1137
|
function processXExtras(node, attrs, opName, startIdx, px) {
|
|
1091
1138
|
const consumed = X_OP_CONSUMED[opName];
|
|
@@ -1213,7 +1260,7 @@ class RenderEachNode extends RenderViewId {
|
|
|
1213
1260
|
return rx.renderEach(stack, this.iterInfo, this.nodeId, this.viewId);
|
|
1214
1261
|
}
|
|
1215
1262
|
static parse(px, vp2, s, as, attrs) {
|
|
1216
|
-
const node = px.addNodeIf(RenderEachNode,
|
|
1263
|
+
const node = px.addNodeIf(RenderEachNode, parseXOpVal("render-each", s, px, vp2.parseEach), as);
|
|
1217
1264
|
if (node !== null) {
|
|
1218
1265
|
const attrParser = getAttrParser(px);
|
|
1219
1266
|
attrParser.eachAttr = attrParser.pushWrapper("each", s, node.val);
|
|
@@ -1369,6 +1416,7 @@ class ParseContext {
|
|
|
1369
1416
|
this.Text = Text ?? globalThis.Text;
|
|
1370
1417
|
this.Comment = Comment ?? globalThis.Comment;
|
|
1371
1418
|
this.cacheConstNodes = true;
|
|
1419
|
+
this.currentTag = null;
|
|
1372
1420
|
}
|
|
1373
1421
|
isInsideMacro(name) {
|
|
1374
1422
|
return this.frame.macroName === name || this.parent?.isInsideMacro(name);
|
|
@@ -1424,7 +1472,7 @@ class ParseContext {
|
|
|
1424
1472
|
getNodeForId(id) {
|
|
1425
1473
|
return this.nodes[id] ?? null;
|
|
1426
1474
|
}
|
|
1427
|
-
onAttributes(_attrs, _wrapperAttrs, _textChild, _isMacroCall) {}
|
|
1475
|
+
onAttributes(_attrs, _wrapperAttrs, _textChild, _isMacroCall, _tag) {}
|
|
1428
1476
|
onParseIssue(kind, info) {
|
|
1429
1477
|
console.warn(`tutuca parse issue [${kind}]`, info);
|
|
1430
1478
|
}
|
|
@@ -1570,7 +1618,7 @@ class ParseCtxClassSetCollector extends ParseContext {
|
|
|
1570
1618
|
v.classes = this.classes;
|
|
1571
1619
|
return v;
|
|
1572
1620
|
}
|
|
1573
|
-
onAttributes(attrs, _wrapperAttrs, _textChild) {
|
|
1621
|
+
onAttributes(attrs, _wrapperAttrs, _textChild, _isMacroCall, _tag) {
|
|
1574
1622
|
if (Array.isArray(attrs.items)) {
|
|
1575
1623
|
for (const attr of attrs.items) {
|
|
1576
1624
|
if (attr.name !== "class") {
|
|
@@ -1624,6 +1672,7 @@ var FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED";
|
|
|
1624
1672
|
var COMPUTED_VAL_NOT_DEFINED = "COMPUTED_VAL_NOT_DEFINED";
|
|
1625
1673
|
var COMPUTED_NOT_REFERENCED = "COMPUTED_NOT_REFERENCED";
|
|
1626
1674
|
var DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION";
|
|
1675
|
+
var IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET";
|
|
1627
1676
|
var UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME";
|
|
1628
1677
|
var UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME";
|
|
1629
1678
|
var UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG";
|
|
@@ -1631,10 +1680,12 @@ var UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE";
|
|
|
1631
1680
|
var UNKNOWN_X_OP = "UNKNOWN_X_OP";
|
|
1632
1681
|
var UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR";
|
|
1633
1682
|
var MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX";
|
|
1683
|
+
var BAD_VALUE = "BAD_VALUE";
|
|
1634
1684
|
var PARSE_ISSUE_KIND_TO_LINT_ID = {
|
|
1635
1685
|
"unknown-directive": UNKNOWN_DIRECTIVE,
|
|
1636
1686
|
"unknown-x-op": UNKNOWN_X_OP,
|
|
1637
|
-
"unknown-x-attr": UNKNOWN_X_ATTR
|
|
1687
|
+
"unknown-x-attr": UNKNOWN_X_ATTR,
|
|
1688
|
+
"bad-value": BAD_VALUE
|
|
1638
1689
|
};
|
|
1639
1690
|
var X_KNOWN_OP_NAMES = new Set([
|
|
1640
1691
|
"slot",
|
|
@@ -1704,7 +1755,8 @@ function checkMacroCallArgs(lx, view, Comp) {
|
|
|
1704
1755
|
if (!(argName in defaults)) {
|
|
1705
1756
|
lx.error(UNKNOWN_MACRO_ARG, {
|
|
1706
1757
|
name: argName,
|
|
1707
|
-
macroName: macroNode.name
|
|
1758
|
+
macroName: macroNode.name,
|
|
1759
|
+
tag: `x:${macroNode.name}`
|
|
1708
1760
|
});
|
|
1709
1761
|
}
|
|
1710
1762
|
}
|
|
@@ -1759,7 +1811,13 @@ function checkEventModifiers(lx, view) {
|
|
|
1759
1811
|
const modWrappers = MOD_WRAPPERS_BY_EVENT[name] ?? NO_WRAPPERS;
|
|
1760
1812
|
for (const modifier of modifiers) {
|
|
1761
1813
|
if (modWrappers[modifier] === undefined) {
|
|
1762
|
-
lx.error(UNKNOWN_EVENT_MODIFIER, {
|
|
1814
|
+
lx.error(UNKNOWN_EVENT_MODIFIER, {
|
|
1815
|
+
name,
|
|
1816
|
+
modifier,
|
|
1817
|
+
handler,
|
|
1818
|
+
event,
|
|
1819
|
+
originAttr: `@on.${name}+${modifiers.join("+")}`
|
|
1820
|
+
});
|
|
1763
1821
|
}
|
|
1764
1822
|
}
|
|
1765
1823
|
}
|
|
@@ -1794,10 +1852,16 @@ function checkKnownHandlerNames(lx, view, Comp, referencedAlters, referencedComp
|
|
|
1794
1852
|
const { fields } = Class.getMetaClass();
|
|
1795
1853
|
for (const event of view.ctx.events) {
|
|
1796
1854
|
for (const handler of event.handlers) {
|
|
1797
|
-
const { args } = handler.handlerCall;
|
|
1855
|
+
const { args, handlerVal } = handler.handlerCall;
|
|
1856
|
+
const handlerName = handlerVal?.name;
|
|
1857
|
+
const eventName = handler.name;
|
|
1858
|
+
const errCtx = {
|
|
1859
|
+
eventName,
|
|
1860
|
+
handlerName,
|
|
1861
|
+
originAttr: `@on.${eventName}`
|
|
1862
|
+
};
|
|
1798
1863
|
for (let i = 0;i < args.length; i++) {
|
|
1799
|
-
|
|
1800
|
-
checkConsistentAttrVal(lx, arg, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
1864
|
+
checkConsistentAttrVal(lx, args[i], fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { ...errCtx, argIndex: i });
|
|
1801
1865
|
}
|
|
1802
1866
|
}
|
|
1803
1867
|
}
|
|
@@ -1812,19 +1876,25 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
|
1812
1876
|
for (const handler of event.handlers) {
|
|
1813
1877
|
const { handlerVal } = handler.handlerCall;
|
|
1814
1878
|
const hvName = handlerVal?.constructor.name;
|
|
1879
|
+
const eventName = handler.name;
|
|
1880
|
+
const originAttr = `@on.${eventName}`;
|
|
1815
1881
|
if (hvName === "InputHandlerNameVal") {
|
|
1816
1882
|
referencedInputs?.add(handlerVal.name);
|
|
1817
1883
|
if (input[handlerVal.name] === undefined) {
|
|
1818
1884
|
lx.error(INPUT_HANDLER_NOT_IMPLEMENTED, {
|
|
1819
1885
|
name: handlerVal.name,
|
|
1820
1886
|
handler,
|
|
1821
|
-
event
|
|
1887
|
+
event,
|
|
1888
|
+
eventName,
|
|
1889
|
+
originAttr
|
|
1822
1890
|
});
|
|
1823
1891
|
if (proto[handlerVal.name] !== undefined) {
|
|
1824
1892
|
lx.hint(INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER, {
|
|
1825
1893
|
name: handlerVal.name,
|
|
1826
1894
|
handler,
|
|
1827
|
-
event
|
|
1895
|
+
event,
|
|
1896
|
+
eventName,
|
|
1897
|
+
originAttr
|
|
1828
1898
|
});
|
|
1829
1899
|
}
|
|
1830
1900
|
}
|
|
@@ -1834,13 +1904,17 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
|
1834
1904
|
lx.error(INPUT_HANDLER_METHOD_NOT_IMPLEMENTED, {
|
|
1835
1905
|
name: handlerVal.name,
|
|
1836
1906
|
handler,
|
|
1837
|
-
event
|
|
1907
|
+
event,
|
|
1908
|
+
eventName,
|
|
1909
|
+
originAttr
|
|
1838
1910
|
});
|
|
1839
1911
|
if (input[handlerVal.name] !== undefined) {
|
|
1840
1912
|
lx.hint(INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD, {
|
|
1841
1913
|
name: handlerVal.name,
|
|
1842
1914
|
handler,
|
|
1843
|
-
event
|
|
1915
|
+
event,
|
|
1916
|
+
eventName,
|
|
1917
|
+
originAttr
|
|
1844
1918
|
});
|
|
1845
1919
|
}
|
|
1846
1920
|
}
|
|
@@ -1850,47 +1924,77 @@ function checkEventHandlersHaveImpls(lx, Comp, referencedInputs) {
|
|
|
1850
1924
|
});
|
|
1851
1925
|
}
|
|
1852
1926
|
}
|
|
1853
|
-
function checkConsistentAttrVal(lx, val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal = false) {
|
|
1927
|
+
function checkConsistentAttrVal(lx, val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal = false, errCtx = null) {
|
|
1854
1928
|
const valName = val?.constructor.name;
|
|
1855
1929
|
if (valName === "FieldVal" || valName === "RawFieldVal") {
|
|
1856
1930
|
const { name } = val;
|
|
1857
1931
|
if (fields[name] === undefined && proto[name] === undefined) {
|
|
1858
|
-
lx.error(FIELD_VAL_NOT_DEFINED, { val, name });
|
|
1932
|
+
lx.error(FIELD_VAL_NOT_DEFINED, { ...errCtx, val, name });
|
|
1859
1933
|
}
|
|
1860
1934
|
} else if (valName === "ComputedVal") {
|
|
1861
1935
|
const { name } = val;
|
|
1862
1936
|
referencedComputed?.add(name);
|
|
1863
1937
|
if (computed[name] === undefined) {
|
|
1864
|
-
lx.error(COMPUTED_VAL_NOT_DEFINED, { val, name });
|
|
1938
|
+
lx.error(COMPUTED_VAL_NOT_DEFINED, { ...errCtx, val, name });
|
|
1865
1939
|
}
|
|
1866
1940
|
} else if (valName === "SeqAccessVal") {
|
|
1867
|
-
checkConsistentAttrVal(lx, val.seqVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal);
|
|
1868
|
-
checkConsistentAttrVal(lx, val.keyVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal);
|
|
1941
|
+
checkConsistentAttrVal(lx, val.seqVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal, errCtx);
|
|
1942
|
+
checkConsistentAttrVal(lx, val.keyVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal, errCtx);
|
|
1869
1943
|
} else if (valName === "RequestVal") {
|
|
1870
1944
|
if (scope.lookupRequest(val.name) === null) {
|
|
1871
|
-
lx.error(UNKNOWN_REQUEST_NAME, { name: val.name });
|
|
1945
|
+
lx.error(UNKNOWN_REQUEST_NAME, { ...errCtx, name: val.name });
|
|
1872
1946
|
}
|
|
1873
1947
|
} else if (valName === "TypeVal") {
|
|
1874
1948
|
if (scope.lookupComponent(val.name) === null) {
|
|
1875
|
-
lx.error(UNKNOWN_COMPONENT_NAME, { name: val.name });
|
|
1949
|
+
lx.error(UNKNOWN_COMPONENT_NAME, { ...errCtx, name: val.name });
|
|
1876
1950
|
}
|
|
1877
1951
|
} else if (valName === "NameVal") {
|
|
1878
1952
|
if (!skipNameVal && !isKnownHandlerName(val.name)) {
|
|
1879
|
-
lx.error(UNKNOWN_HANDLER_ARG_NAME, { name: val.name });
|
|
1953
|
+
lx.error(UNKNOWN_HANDLER_ARG_NAME, { ...errCtx, name: val.name });
|
|
1880
1954
|
}
|
|
1881
1955
|
} else if (valName === "StrTplVal") {
|
|
1882
1956
|
for (const subVal of val.vals) {
|
|
1883
|
-
checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal);
|
|
1957
|
+
checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, skipNameVal, errCtx);
|
|
1884
1958
|
}
|
|
1885
1959
|
} else if (valName === "AlterHandlerNameVal") {
|
|
1886
1960
|
referencedAlters?.add(val.name);
|
|
1887
1961
|
if (alter[val.name] === undefined) {
|
|
1888
|
-
lx.error(ALT_HANDLER_NOT_DEFINED, { name: val.name });
|
|
1962
|
+
lx.error(ALT_HANDLER_NOT_DEFINED, { ...errCtx, name: val.name });
|
|
1889
1963
|
}
|
|
1890
1964
|
} else if (valName !== "ConstVal" && valName !== "BindVal" && valName !== "DynVal") {
|
|
1891
1965
|
console.log(val);
|
|
1892
1966
|
}
|
|
1893
1967
|
}
|
|
1968
|
+
var NODE_KIND_TO_CTX = {
|
|
1969
|
+
RenderTextNode: { originAttr: "<x text>" },
|
|
1970
|
+
RenderNode: { originAttr: "<x render>" },
|
|
1971
|
+
RenderItNode: { originAttr: "<x render-it>" },
|
|
1972
|
+
RenderEachNode: { originAttr: "<x render-each>" },
|
|
1973
|
+
ShowNode: { originAttr: "<x show>" },
|
|
1974
|
+
HideNode: { originAttr: "<x hide>" },
|
|
1975
|
+
PushViewNameNode: { originAttr: "<x push-view>" }
|
|
1976
|
+
};
|
|
1977
|
+
function nodeCtxForNode(nodeKind) {
|
|
1978
|
+
return NODE_KIND_TO_CTX[nodeKind] ?? null;
|
|
1979
|
+
}
|
|
1980
|
+
function attrSourceLabel(attr) {
|
|
1981
|
+
const cn = attr.constructor.name;
|
|
1982
|
+
if (cn === "ConstAttr")
|
|
1983
|
+
return "literal";
|
|
1984
|
+
if (cn === "IfAttr")
|
|
1985
|
+
return `@if.${attr.name}`;
|
|
1986
|
+
if (cn === "RawHtmlAttr")
|
|
1987
|
+
return "@dangerouslysetinnerhtml";
|
|
1988
|
+
return `:${attr.name}`;
|
|
1989
|
+
}
|
|
1990
|
+
function attrOriginAttr(attr) {
|
|
1991
|
+
const cn = attr.constructor.name;
|
|
1992
|
+
if (cn === "IfAttr")
|
|
1993
|
+
return `@if.${attr.name}`;
|
|
1994
|
+
if (cn === "RawHtmlAttr")
|
|
1995
|
+
return "@dangerouslysetinnerhtml";
|
|
1996
|
+
return `:${attr.name}`;
|
|
1997
|
+
}
|
|
1894
1998
|
function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
|
|
1895
1999
|
const { computed, scope, views, alter, Class } = Comp;
|
|
1896
2000
|
const { prototype: proto } = Class;
|
|
@@ -1898,25 +2002,39 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
|
|
|
1898
2002
|
for (const viewName in views) {
|
|
1899
2003
|
lx.push({ viewName }, () => {
|
|
1900
2004
|
const view = views[viewName];
|
|
1901
|
-
for (const
|
|
1902
|
-
const { attrs, wrapperAttrs, textChild, isMacroCall } =
|
|
2005
|
+
for (const entry of view.ctx.attrs) {
|
|
2006
|
+
const { attrs, wrapperAttrs, textChild, isMacroCall, tag } = entry;
|
|
1903
2007
|
if (attrs?.constructor.name === "DynAttrs") {
|
|
1904
|
-
const
|
|
1905
|
-
for (const
|
|
1906
|
-
const name =
|
|
2008
|
+
const sourcesByName = new Map;
|
|
2009
|
+
for (const attr of attrs.items) {
|
|
2010
|
+
const name = attr?.name;
|
|
1907
2011
|
if (name !== undefined && name !== "data-eid") {
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
2012
|
+
const sources = sourcesByName.get(name);
|
|
2013
|
+
const label = attrSourceLabel(attr);
|
|
2014
|
+
if (sources)
|
|
2015
|
+
sources.push(label);
|
|
2016
|
+
else
|
|
2017
|
+
sourcesByName.set(name, [label]);
|
|
1913
2018
|
}
|
|
1914
|
-
if (
|
|
1915
|
-
|
|
1916
|
-
|
|
2019
|
+
if (attr?.constructor.name === "IfAttr") {
|
|
2020
|
+
if (!attr.anyBranchIsSet) {
|
|
2021
|
+
lx.error(IF_NO_BRANCH_SET, { attr: attr.name, tag });
|
|
1917
2022
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
2023
|
+
const branches = [
|
|
2024
|
+
["@if", attr.condVal],
|
|
2025
|
+
["@then", attr.thenVal],
|
|
2026
|
+
["@else", attr.elseVal]
|
|
2027
|
+
];
|
|
2028
|
+
for (const [branch, subVal] of branches) {
|
|
2029
|
+
checkConsistentAttrVal(lx, subVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, isMacroCall, { tag, originAttr: `@if.${attr.name}`, branch });
|
|
2030
|
+
}
|
|
2031
|
+
} else if (attr?.val !== undefined) {
|
|
2032
|
+
checkConsistentAttrVal(lx, attr.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, isMacroCall, { tag, originAttr: attrOriginAttr(attr) });
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
for (const [name, sources] of sourcesByName) {
|
|
2036
|
+
if (sources.length > 1) {
|
|
2037
|
+
lx.error(DUPLICATE_ATTR_DEFINITION, { name, sources, tag });
|
|
1920
2038
|
}
|
|
1921
2039
|
}
|
|
1922
2040
|
}
|
|
@@ -1924,30 +2042,35 @@ function checkConsistentAttrs(lx, Comp, referencedAlters, referencedComputed) {
|
|
|
1924
2042
|
for (const w of wrapperAttrs) {
|
|
1925
2043
|
if (w.name === "each") {
|
|
1926
2044
|
if (w.whenVal)
|
|
1927
|
-
checkConsistentAttrVal(lx, w.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
2045
|
+
checkConsistentAttrVal(lx, w.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { tag, originAttr: "@when" });
|
|
1928
2046
|
if (w.enrichWithVal)
|
|
1929
|
-
checkConsistentAttrVal(lx, w.enrichWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
2047
|
+
checkConsistentAttrVal(lx, w.enrichWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { tag, originAttr: "@enrich-with" });
|
|
1930
2048
|
if (w.loopWithVal)
|
|
1931
|
-
checkConsistentAttrVal(lx, w.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
1932
|
-
} else
|
|
1933
|
-
|
|
2049
|
+
checkConsistentAttrVal(lx, w.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { tag, originAttr: "@loop-with" });
|
|
2050
|
+
} else {
|
|
2051
|
+
const originAttr = w.name === "scope" ? "@enrich-with" : `@${w.name}`;
|
|
2052
|
+
checkConsistentAttrVal(lx, w.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { tag, originAttr });
|
|
1934
2053
|
}
|
|
1935
2054
|
}
|
|
1936
2055
|
}
|
|
1937
2056
|
if (textChild) {
|
|
1938
|
-
checkConsistentAttrVal(lx, textChild, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
2057
|
+
checkConsistentAttrVal(lx, textChild, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { tag, originAttr: "@text" });
|
|
1939
2058
|
}
|
|
1940
2059
|
}
|
|
1941
2060
|
for (const node of view.ctx.nodes) {
|
|
2061
|
+
const nodeKind = node.constructor.name;
|
|
2062
|
+
if (nodeKind === "ScopeNode")
|
|
2063
|
+
continue;
|
|
2064
|
+
const baseCtx = nodeCtxForNode(nodeKind);
|
|
1942
2065
|
if (node.val) {
|
|
1943
|
-
checkConsistentAttrVal(lx, node.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
2066
|
+
checkConsistentAttrVal(lx, node.val, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, baseCtx);
|
|
1944
2067
|
}
|
|
1945
|
-
if (
|
|
2068
|
+
if (nodeKind === "RenderEachNode") {
|
|
1946
2069
|
const iter = node.iterInfo;
|
|
1947
2070
|
if (iter.whenVal)
|
|
1948
|
-
checkConsistentAttrVal(lx, iter.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
2071
|
+
checkConsistentAttrVal(lx, iter.whenVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { originAttr: "<x render-each when>" });
|
|
1949
2072
|
if (iter.loopWithVal)
|
|
1950
|
-
checkConsistentAttrVal(lx, iter.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed);
|
|
2073
|
+
checkConsistentAttrVal(lx, iter.loopWithVal, fields, proto, computed, scope, alter, referencedAlters, referencedComputed, false, { originAttr: "<x render-each loop-with>" });
|
|
1951
2074
|
}
|
|
1952
2075
|
}
|
|
1953
2076
|
});
|
|
@@ -2009,59 +2132,123 @@ class LintParseContext extends ParseContext {
|
|
|
2009
2132
|
this.attrs = [];
|
|
2010
2133
|
this.parseIssues = [];
|
|
2011
2134
|
}
|
|
2012
|
-
onAttributes(attrs, wrapperAttrs, textChild, isMacroCall = false) {
|
|
2013
|
-
this.attrs.push({ attrs, wrapperAttrs, textChild, isMacroCall });
|
|
2135
|
+
onAttributes(attrs, wrapperAttrs, textChild, isMacroCall = false, tag = null) {
|
|
2136
|
+
this.attrs.push({ attrs, wrapperAttrs, textChild, isMacroCall, tag });
|
|
2014
2137
|
}
|
|
2015
2138
|
onParseIssue(kind, info) {
|
|
2016
|
-
|
|
2139
|
+
const tag = this.currentTag;
|
|
2140
|
+
this.parseIssues.push({ kind, info: tag && info.tag === undefined ? { ...info, tag } : info });
|
|
2017
2141
|
}
|
|
2018
2142
|
}
|
|
2019
2143
|
|
|
2020
2144
|
// tools/format/lint.js
|
|
2145
|
+
function badValueMessage(info) {
|
|
2146
|
+
const v = JSON.stringify(info.value);
|
|
2147
|
+
switch (info.role) {
|
|
2148
|
+
case "attr":
|
|
2149
|
+
return `Cannot parse value ${v} for attribute ':${info.attr}'`;
|
|
2150
|
+
case "directive":
|
|
2151
|
+
return `Cannot parse value ${v} for directive '@${info.directive}'`;
|
|
2152
|
+
case "if":
|
|
2153
|
+
return `Cannot parse condition ${v} for '@if.${info.attr}'`;
|
|
2154
|
+
case "x-op":
|
|
2155
|
+
return `Cannot parse value ${v} for <x ${info.op}>`;
|
|
2156
|
+
case "handler-name":
|
|
2157
|
+
return `Cannot parse handler name ${v}`;
|
|
2158
|
+
case "handler-arg":
|
|
2159
|
+
return `Cannot parse handler argument ${v}`;
|
|
2160
|
+
case "macro-var":
|
|
2161
|
+
return `Macro variable '^${info.name}' is not defined`;
|
|
2162
|
+
default:
|
|
2163
|
+
return `Cannot parse value ${v}`;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2166
|
+
function tagDisplay(tag) {
|
|
2167
|
+
return tag ? String(tag).toLowerCase() : null;
|
|
2168
|
+
}
|
|
2169
|
+
function fmtTagSuffix(info) {
|
|
2170
|
+
const t = tagDisplay(info?.tag);
|
|
2171
|
+
return t && t !== "x" ? ` on <${t}>` : "";
|
|
2172
|
+
}
|
|
2173
|
+
function fmtOriginSuffix(info) {
|
|
2174
|
+
if (!info)
|
|
2175
|
+
return "";
|
|
2176
|
+
const parts = [];
|
|
2177
|
+
if (info.originAttr) {
|
|
2178
|
+
const branch = info.branch ? `[${info.branch}]` : "";
|
|
2179
|
+
parts.push(`in ${info.originAttr}${branch}`);
|
|
2180
|
+
}
|
|
2181
|
+
if (info.handlerName) {
|
|
2182
|
+
parts.push(`handler '${info.handlerName}'${info.argIndex !== undefined ? ` arg ${info.argIndex}` : ""}`);
|
|
2183
|
+
}
|
|
2184
|
+
const t = tagDisplay(info.tag);
|
|
2185
|
+
if (t && t !== "x")
|
|
2186
|
+
parts.push(`on <${t}>`);
|
|
2187
|
+
return parts.length ? ` (${parts.join(", ")})` : "";
|
|
2188
|
+
}
|
|
2189
|
+
function fmtEventSuffix(info) {
|
|
2190
|
+
if (info?.originAttr)
|
|
2191
|
+
return ` in ${info.originAttr}`;
|
|
2192
|
+
if (info?.eventName)
|
|
2193
|
+
return ` in @on.${info.eventName}`;
|
|
2194
|
+
return "";
|
|
2195
|
+
}
|
|
2021
2196
|
function lintIdToMessage(id, info) {
|
|
2022
2197
|
switch (id) {
|
|
2023
2198
|
case "RENDER_IT_OUTSIDE_OF_LOOP":
|
|
2024
2199
|
return "render-it used outside of a loop";
|
|
2025
|
-
case "UNKNOWN_EVENT_MODIFIER":
|
|
2026
|
-
|
|
2200
|
+
case "UNKNOWN_EVENT_MODIFIER": {
|
|
2201
|
+
const mods = info.handler?.modifiers ?? [info.modifier];
|
|
2202
|
+
const written = `@on.${info.name}+${mods.join("+")}`;
|
|
2203
|
+
return `Unknown modifier '+${info.modifier}' in '${written}'`;
|
|
2204
|
+
}
|
|
2027
2205
|
case "UNKNOWN_HANDLER_ARG_NAME":
|
|
2028
|
-
return `Unknown handler argument '${info.name}'`;
|
|
2206
|
+
return `Unknown handler argument '${info.name}'${fmtOriginSuffix(info)}`;
|
|
2029
2207
|
case "INPUT_HANDLER_NOT_IMPLEMENTED":
|
|
2030
|
-
return `Input handler '${info.name}' is not implemented`;
|
|
2208
|
+
return `Input handler '${info.name}' is not implemented${fmtEventSuffix(info)}`;
|
|
2031
2209
|
case "INPUT_HANDLER_NOT_REFERENCED":
|
|
2032
2210
|
return `Input handler '${info.name}' is defined but not referenced`;
|
|
2033
2211
|
case "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED":
|
|
2034
|
-
return `Method '.${info.name}' is not implemented`;
|
|
2212
|
+
return `Method '.${info.name}' is not implemented${fmtEventSuffix(info)}`;
|
|
2035
2213
|
case "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD":
|
|
2036
|
-
return `'${info.name}' exists as input handler — use without '.' prefix`;
|
|
2214
|
+
return `'${info.name}' exists as input handler — use without '.' prefix${fmtEventSuffix(info)}`;
|
|
2037
2215
|
case "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER":
|
|
2038
|
-
return `'${info.name}' exists as method — use with '.' prefix`;
|
|
2216
|
+
return `'${info.name}' exists as method — use with '.' prefix${fmtEventSuffix(info)}`;
|
|
2039
2217
|
case "FIELD_VAL_NOT_DEFINED":
|
|
2040
|
-
return `Field '.${info.name}' is not defined`;
|
|
2218
|
+
return `Field '.${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
2041
2219
|
case "COMPUTED_VAL_NOT_DEFINED":
|
|
2042
|
-
return `Computed property '$${info.name}' is not defined`;
|
|
2220
|
+
return `Computed property '$${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
2043
2221
|
case "COMPUTED_NOT_REFERENCED":
|
|
2044
2222
|
return `Computed property '$${info.name}' is defined but not referenced`;
|
|
2045
|
-
case "DUPLICATE_ATTR_DEFINITION":
|
|
2046
|
-
|
|
2223
|
+
case "DUPLICATE_ATTR_DEFINITION": {
|
|
2224
|
+
const sources = info.sources?.length ? ` (${info.sources.join(", ")})` : "";
|
|
2225
|
+
const tag = info.tag ? ` on <${String(info.tag).toLowerCase()}>` : "";
|
|
2226
|
+
return `Attribute '${info.name}' is set ${info.sources?.length ?? "multiple"} times${sources}${tag}`;
|
|
2227
|
+
}
|
|
2228
|
+
case "IF_NO_BRANCH_SET":
|
|
2229
|
+
return `'@if.${info.attr}' has no '@then' or '@else' branch — at least one must be set${fmtTagSuffix(info)}`;
|
|
2047
2230
|
case "UNKNOWN_REQUEST_NAME":
|
|
2048
|
-
return `Unknown request '!${info.name}'`;
|
|
2231
|
+
return `Unknown request '!${info.name}'${fmtOriginSuffix(info)}`;
|
|
2049
2232
|
case "UNKNOWN_COMPONENT_NAME":
|
|
2050
|
-
return `Unknown component '${info.name}'`;
|
|
2233
|
+
return `Unknown component '${info.name}'${fmtOriginSuffix(info)}`;
|
|
2051
2234
|
case "ALT_HANDLER_NOT_DEFINED":
|
|
2052
|
-
return `Alter handler '${info.name}' is not defined`;
|
|
2235
|
+
return `Alter handler '${info.name}' is not defined${fmtOriginSuffix(info)}`;
|
|
2053
2236
|
case "ALT_HANDLER_NOT_REFERENCED":
|
|
2054
2237
|
return `Alter handler '${info.name}' is defined but not referenced`;
|
|
2055
2238
|
case "UNKNOWN_MACRO_ARG":
|
|
2056
2239
|
return `Argument '${info.name}' is not declared in macro '${info.macroName}'`;
|
|
2057
2240
|
case "UNKNOWN_DIRECTIVE":
|
|
2058
|
-
return `Unknown directive '@${info.name}=${JSON.stringify(info.value)}'`;
|
|
2241
|
+
return `Unknown directive '@${info.name}=${JSON.stringify(info.value)}'${fmtTagSuffix(info)}`;
|
|
2059
2242
|
case "UNKNOWN_X_OP":
|
|
2060
|
-
return `Unknown <x> op '${info.name}=${JSON.stringify(info.value)}'`;
|
|
2243
|
+
return `Unknown <x> op '${info.name}=${JSON.stringify(info.value)}'${fmtTagSuffix(info)}`;
|
|
2061
2244
|
case "UNKNOWN_X_ATTR":
|
|
2062
|
-
return `Unknown attribute '${info.name}=${JSON.stringify(info.value)}' on <x ${info.op}
|
|
2063
|
-
case "MAYBE_DROP_AT_PREFIX":
|
|
2064
|
-
|
|
2245
|
+
return `Unknown attribute '${info.name}=${JSON.stringify(info.value)}' on <x ${info.op}>${fmtTagSuffix(info)}`;
|
|
2246
|
+
case "MAYBE_DROP_AT_PREFIX": {
|
|
2247
|
+
const written = info.value !== undefined ? `${info.name}=${JSON.stringify(info.value)}` : info.name;
|
|
2248
|
+
return `Did you mean '${info.suggestion}'? Drop the '@' from '${written}' on <x>.`;
|
|
2249
|
+
}
|
|
2250
|
+
case "BAD_VALUE":
|
|
2251
|
+
return `${badValueMessage(info)}${fmtTagSuffix(info)}`;
|
|
2065
2252
|
case "LINT_ERROR":
|
|
2066
2253
|
return info.message;
|
|
2067
2254
|
default:
|
|
@@ -7819,7 +8006,7 @@ initCollectionConversions();
|
|
|
7819
8006
|
var { version } = pkg;
|
|
7820
8007
|
|
|
7821
8008
|
// src/oo.js
|
|
7822
|
-
var
|
|
8009
|
+
var BAD_VALUE2 = Symbol("BadValue");
|
|
7823
8010
|
var nullCoercer = (v) => v;
|
|
7824
8011
|
|
|
7825
8012
|
class Field {
|
|
@@ -7866,8 +8053,8 @@ class Field {
|
|
|
7866
8053
|
const setName = `set${uname}`;
|
|
7867
8054
|
const that = this;
|
|
7868
8055
|
proto[setName] = function(v) {
|
|
7869
|
-
const v1 = that.coerceOr(v,
|
|
7870
|
-
if (v1 ===
|
|
8056
|
+
const v1 = that.coerceOr(v, BAD_VALUE2);
|
|
8057
|
+
if (v1 === BAD_VALUE2) {
|
|
7871
8058
|
console.warn("invalid value", v);
|
|
7872
8059
|
return this;
|
|
7873
8060
|
}
|
|
@@ -8741,12 +8928,13 @@ class LintClassCollectorCtx extends ParseCtxClassSetCollector {
|
|
|
8741
8928
|
v.parseIssues = this.parseIssues;
|
|
8742
8929
|
return v;
|
|
8743
8930
|
}
|
|
8744
|
-
onAttributes(attrs, wrapperAttrs, textChild, isMacroCall = false) {
|
|
8745
|
-
super.onAttributes(attrs, wrapperAttrs, textChild, isMacroCall);
|
|
8746
|
-
this.attrs.push({ attrs, wrapperAttrs, textChild, isMacroCall });
|
|
8931
|
+
onAttributes(attrs, wrapperAttrs, textChild, isMacroCall = false, tag = null) {
|
|
8932
|
+
super.onAttributes(attrs, wrapperAttrs, textChild, isMacroCall, tag);
|
|
8933
|
+
this.attrs.push({ attrs, wrapperAttrs, textChild, isMacroCall, tag });
|
|
8747
8934
|
}
|
|
8748
8935
|
onParseIssue(kind, info) {
|
|
8749
|
-
|
|
8936
|
+
const tag = this.currentTag;
|
|
8937
|
+
this.parseIssues.push({ kind, info: tag && info.tag === undefined ? { ...info, tag } : info });
|
|
8750
8938
|
}
|
|
8751
8939
|
}
|
|
8752
8940
|
export {
|
|
@@ -8834,12 +9022,14 @@ export {
|
|
|
8834
9022
|
INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER,
|
|
8835
9023
|
INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD,
|
|
8836
9024
|
Map2 as IMap,
|
|
9025
|
+
IF_NO_BRANCH_SET,
|
|
8837
9026
|
FIELD_VAL_NOT_DEFINED,
|
|
8838
9027
|
FIELD_CLASS,
|
|
8839
9028
|
DUPLICATE_ATTR_DEFINITION,
|
|
8840
9029
|
Collection,
|
|
8841
9030
|
COMPUTED_VAL_NOT_DEFINED,
|
|
8842
9031
|
COMPUTED_NOT_REFERENCED,
|
|
9032
|
+
BAD_VALUE,
|
|
8843
9033
|
ALT_HANDLER_NOT_REFERENCED,
|
|
8844
9034
|
ALT_HANDLER_NOT_DEFINED
|
|
8845
9035
|
};
|