xmlui 0.5.2-beta.4 → 0.6.1-beta.6

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.
@@ -73,9 +73,12 @@ function viteUemlPlugin(pluginOptions = {}) {
73
73
  };
74
74
  if (xmluiExtension.test(id)) {
75
75
  const fileId = "" + itemIndex++;
76
- const componentDef = (0, xmlui_parser_1.parseXmlUiMarkup)(code, fileId, moduleResolver);
76
+ let { component, errors, erroneousCompoundComponentName } = (0, xmlui_parser_1.xmlUiMarkupToComponent)(code, fileId, moduleResolver);
77
+ if (errors.length > 0) {
78
+ component = (0, xmlui_parser_1.errReportComponent)(errors, id, erroneousCompoundComponentName);
79
+ }
77
80
  const file = {
78
- component: componentDef,
81
+ component,
79
82
  src: code,
80
83
  file: fileId,
81
84
  };
@@ -68,43 +68,45 @@ var TokenType;
68
68
  TokenType[TokenType["Dot"] = 56] = "Dot";
69
69
  TokenType[TokenType["Spread"] = 57] = "Spread";
70
70
  TokenType[TokenType["Global"] = 58] = "Global";
71
- TokenType[TokenType["Arrow"] = 59] = "Arrow";
72
- TokenType[TokenType["DecimalLiteral"] = 60] = "DecimalLiteral";
73
- TokenType[TokenType["HexadecimalLiteral"] = 61] = "HexadecimalLiteral";
74
- TokenType[TokenType["BinaryLiteral"] = 62] = "BinaryLiteral";
75
- TokenType[TokenType["RealLiteral"] = 63] = "RealLiteral";
76
- TokenType[TokenType["StringLiteral"] = 64] = "StringLiteral";
77
- TokenType[TokenType["Infinity"] = 65] = "Infinity";
78
- TokenType[TokenType["NaN"] = 66] = "NaN";
79
- TokenType[TokenType["True"] = 67] = "True";
80
- TokenType[TokenType["False"] = 68] = "False";
81
- TokenType[TokenType["Typeof"] = 69] = "Typeof";
82
- TokenType[TokenType["Null"] = 70] = "Null";
83
- TokenType[TokenType["Undefined"] = 71] = "Undefined";
84
- TokenType[TokenType["In"] = 72] = "In";
85
- TokenType[TokenType["Let"] = 73] = "Let";
86
- TokenType[TokenType["Const"] = 74] = "Const";
87
- TokenType[TokenType["Var"] = 75] = "Var";
88
- TokenType[TokenType["If"] = 76] = "If";
89
- TokenType[TokenType["Else"] = 77] = "Else";
90
- TokenType[TokenType["Return"] = 78] = "Return";
91
- TokenType[TokenType["Break"] = 79] = "Break";
92
- TokenType[TokenType["Continue"] = 80] = "Continue";
93
- TokenType[TokenType["Do"] = 81] = "Do";
94
- TokenType[TokenType["While"] = 82] = "While";
95
- TokenType[TokenType["For"] = 83] = "For";
96
- TokenType[TokenType["Of"] = 84] = "Of";
97
- TokenType[TokenType["Try"] = 85] = "Try";
98
- TokenType[TokenType["Catch"] = 86] = "Catch";
99
- TokenType[TokenType["Finally"] = 87] = "Finally";
100
- TokenType[TokenType["Throw"] = 88] = "Throw";
101
- TokenType[TokenType["Switch"] = 89] = "Switch";
102
- TokenType[TokenType["Case"] = 90] = "Case";
103
- TokenType[TokenType["Default"] = 91] = "Default";
104
- TokenType[TokenType["Delete"] = 92] = "Delete";
105
- TokenType[TokenType["Function"] = 93] = "Function";
106
- TokenType[TokenType["Export"] = 94] = "Export";
107
- TokenType[TokenType["Import"] = 95] = "Import";
108
- TokenType[TokenType["As"] = 96] = "As";
109
- TokenType[TokenType["From"] = 97] = "From";
71
+ TokenType[TokenType["Backtick"] = 59] = "Backtick";
72
+ TokenType[TokenType["DollarLBrace"] = 60] = "DollarLBrace";
73
+ TokenType[TokenType["Arrow"] = 61] = "Arrow";
74
+ TokenType[TokenType["DecimalLiteral"] = 62] = "DecimalLiteral";
75
+ TokenType[TokenType["HexadecimalLiteral"] = 63] = "HexadecimalLiteral";
76
+ TokenType[TokenType["BinaryLiteral"] = 64] = "BinaryLiteral";
77
+ TokenType[TokenType["RealLiteral"] = 65] = "RealLiteral";
78
+ TokenType[TokenType["StringLiteral"] = 66] = "StringLiteral";
79
+ TokenType[TokenType["Infinity"] = 67] = "Infinity";
80
+ TokenType[TokenType["NaN"] = 68] = "NaN";
81
+ TokenType[TokenType["True"] = 69] = "True";
82
+ TokenType[TokenType["False"] = 70] = "False";
83
+ TokenType[TokenType["Typeof"] = 71] = "Typeof";
84
+ TokenType[TokenType["Null"] = 72] = "Null";
85
+ TokenType[TokenType["Undefined"] = 73] = "Undefined";
86
+ TokenType[TokenType["In"] = 74] = "In";
87
+ TokenType[TokenType["Let"] = 75] = "Let";
88
+ TokenType[TokenType["Const"] = 76] = "Const";
89
+ TokenType[TokenType["Var"] = 77] = "Var";
90
+ TokenType[TokenType["If"] = 78] = "If";
91
+ TokenType[TokenType["Else"] = 79] = "Else";
92
+ TokenType[TokenType["Return"] = 80] = "Return";
93
+ TokenType[TokenType["Break"] = 81] = "Break";
94
+ TokenType[TokenType["Continue"] = 82] = "Continue";
95
+ TokenType[TokenType["Do"] = 83] = "Do";
96
+ TokenType[TokenType["While"] = 84] = "While";
97
+ TokenType[TokenType["For"] = 85] = "For";
98
+ TokenType[TokenType["Of"] = 86] = "Of";
99
+ TokenType[TokenType["Try"] = 87] = "Try";
100
+ TokenType[TokenType["Catch"] = 88] = "Catch";
101
+ TokenType[TokenType["Finally"] = 89] = "Finally";
102
+ TokenType[TokenType["Throw"] = 90] = "Throw";
103
+ TokenType[TokenType["Switch"] = 91] = "Switch";
104
+ TokenType[TokenType["Case"] = 92] = "Case";
105
+ TokenType[TokenType["Default"] = 93] = "Default";
106
+ TokenType[TokenType["Delete"] = 94] = "Delete";
107
+ TokenType[TokenType["Function"] = 95] = "Function";
108
+ TokenType[TokenType["Export"] = 96] = "Export";
109
+ TokenType[TokenType["Import"] = 97] = "Import";
110
+ TokenType[TokenType["As"] = 98] = "As";
111
+ TokenType[TokenType["From"] = 99] = "From";
110
112
  })(TokenType || (exports.TokenType = TokenType = {}));
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.paddingSubject = paddingSubject;
4
+ exports.borderSubject = borderSubject;
5
+ function paddingSubject(name, valueSpec) {
6
+ var _a, _b, _c, _d, _e, _f, _g;
7
+ return {
8
+ [`padding-left-${name}`]: (_a = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.left) !== null && _a !== void 0 ? _a : `$padding-horizontal-${name}`,
9
+ [`padding-right-${name}`]: (_b = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.right) !== null && _b !== void 0 ? _b : `$padding-horizontal-${name}`,
10
+ [`padding-top-${name}`]: (_c = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.top) !== null && _c !== void 0 ? _c : `$padding-vertical-${name}`,
11
+ [`padding-bottom-${name}`]: (_d = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.bottom) !== null && _d !== void 0 ? _d : `$padding-vertical-${name}`,
12
+ [`padding-horizontal-${name}`]: (_e = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.horizontal) !== null && _e !== void 0 ? _e : "",
13
+ [`padding-vertical-${name}`]: (_f = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.vertical) !== null && _f !== void 0 ? _f : "",
14
+ [`padding-${name}`]: (_g = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) !== null && _g !== void 0 ? _g : `$padding-top-${name} $padding-right-${name} $padding-bottom-${name} $padding-left-${name}`,
15
+ };
16
+ }
17
+ function borderSubject(name, valueSpec) {
18
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
19
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ [`radius-${name}`]: "$radius" }, borderEdgeSubject("left", (_b = (_a = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.left) !== null && _a !== void 0 ? _a : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.horizontal) !== null && _b !== void 0 ? _b : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all)), borderEdgeSubject("right", (_d = (_c = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.right) !== null && _c !== void 0 ? _c : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.horizontal) !== null && _d !== void 0 ? _d : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all)), borderEdgeSubject("top", (_f = (_e = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.top) !== null && _e !== void 0 ? _e : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.vertical) !== null && _f !== void 0 ? _f : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all)), borderEdgeSubject("bottom", (_h = (_g = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.bottom) !== null && _g !== void 0 ? _g : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.vertical) !== null && _h !== void 0 ? _h : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all)), borderEdgeSubject("horizontal", (_j = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.horizontal) !== null && _j !== void 0 ? _j : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all)), borderEdgeSubject("vertical", (_k = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.vertical) !== null && _k !== void 0 ? _k : valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all)), { [`color-border-${name}`]: (_m = (_l = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) === null || _l === void 0 ? void 0 : _l.color) !== null && _m !== void 0 ? _m : "", [`thickness-border-${name}`]: (_p = (_o = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) === null || _o === void 0 ? void 0 : _o.thickness) !== null && _p !== void 0 ? _p : "", [`style-border-${name}`]: (_r = (_q = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) === null || _q === void 0 ? void 0 : _q.style) !== null && _r !== void 0 ? _r : "", [`border-${name}`]: `${(_t = (_s = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) === null || _s === void 0 ? void 0 : _s.thickness) !== null && _t !== void 0 ? _t : `$thickness-border-${name}`} ` +
20
+ `${(_v = (_u = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) === null || _u === void 0 ? void 0 : _u.style) !== null && _v !== void 0 ? _v : `$style-border-${name}`} ` +
21
+ `${(_x = (_w = valueSpec === null || valueSpec === void 0 ? void 0 : valueSpec.all) === null || _w === void 0 ? void 0 : _w.color) !== null && _x !== void 0 ? _x : `$color-border-${name}`} ` });
22
+ function borderEdgeSubject(edge, edgeSpec) {
23
+ var _a, _b, _c, _d;
24
+ return {
25
+ [`color-border-${edge}-${name}`]: (_a = edgeSpec === null || edgeSpec === void 0 ? void 0 : edgeSpec.color) !== null && _a !== void 0 ? _a : "",
26
+ [`thickness-border-${edge}-${name}`]: (_b = edgeSpec === null || edgeSpec === void 0 ? void 0 : edgeSpec.thickness) !== null && _b !== void 0 ? _b : "",
27
+ [`style-border-${edge}-${name}`]: (_c = edgeSpec === null || edgeSpec === void 0 ? void 0 : edgeSpec.style) !== null && _c !== void 0 ? _c : "",
28
+ [`border-${edge}-${name}`]: (_d = edgeSpec === null || edgeSpec === void 0 ? void 0 : edgeSpec.all) !== null && _d !== void 0 ? _d : `$thickness-border-${edge}-${name} $style-border-${edge}-${name} $color-border-${edge}-${name}`,
29
+ };
30
+ }
31
+ }
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseXmlUiMarkup = parseXmlUiMarkup;
3
+ exports.xmlUiMarkupToComponent = xmlUiMarkupToComponent;
4
+ exports.errReportComponent = errReportComponent;
4
5
  const parser_1 = require("../parsers/xmlui-parser/parser");
5
6
  const transform_1 = require("../parsers/xmlui-parser/transform");
6
- function parseXmlUiMarkup(source, fileId = 0, moduleResolver) {
7
+ const diagnostics_1 = require("../parsers/xmlui-parser/diagnostics");
8
+ const syntax_kind_1 = require("../parsers/xmlui-parser/syntax-kind");
9
+ function xmlUiMarkupToComponent(source, fileId = 0, moduleResolver) {
7
10
  const { parse, getText } = (0, parser_1.createXmlUiParser)(source);
8
11
  const { node, errors } = parse();
9
12
  if (errors.length > 0) {
@@ -13,13 +16,92 @@ function parseXmlUiMarkup(source, fileId = 0, moduleResolver) {
13
16
  newlinePositions.push(i);
14
17
  }
15
18
  }
16
- const errorWithLines = addPositions(errors, newlinePositions);
17
- const errorMessages = errorWithLines
18
- .map((e) => `Error at line: ${e.line}, column: ${e.col}:\n ${e.message}\n`)
19
- .join("\n");
20
- throw new Error(errorMessages);
19
+ const errorsWithLines = addPositions(errors, newlinePositions);
20
+ const erroneousCompoundComponentName = getCompoundCompName(node, getText);
21
+ return { component: null, errors: errorsWithLines, erroneousCompoundComponentName };
21
22
  }
22
- return (0, transform_1.nodeToComponentDef)(node, getText, fileId, moduleResolver);
23
+ try {
24
+ return { component: (0, transform_1.nodeToComponentDef)(node, getText, fileId, moduleResolver), errors: [] };
25
+ }
26
+ catch (e) {
27
+ const erroneousCompoundComponentName = getCompoundCompName(node, getText);
28
+ const singleErr = {
29
+ message: e.message,
30
+ col: 0,
31
+ line: 0,
32
+ code: diagnostics_1.ErrCodes.expEq,
33
+ category: diagnostics_1.DiagnosticCategory.Error,
34
+ pos: 0,
35
+ end: 0,
36
+ };
37
+ return {
38
+ component: null,
39
+ erroneousCompoundComponentName,
40
+ errors: [singleErr],
41
+ };
42
+ }
43
+ }
44
+ /** returns a component definition containing the errors.
45
+ * It is a component and a compound component definition at the same time,
46
+ * so that it can be used to render the errors for a compound component as well*/
47
+ function errReportComponent(errors, fileName, compoundCompName) {
48
+ function makeComponent() {
49
+ const errList = errors
50
+ .sort((a, b) => a.pos - b.pos)
51
+ .map((e, idx) => {
52
+ return {
53
+ type: "VStack",
54
+ props: { gap: "0px" },
55
+ children: [
56
+ {
57
+ type: "HStack",
58
+ props: { gap: "0" },
59
+ children: [
60
+ {
61
+ type: "Text",
62
+ props: {
63
+ value: `#${idx + 1}: ${fileName} (${e.line}:${e.col}):\xa0`,
64
+ color: "$color-info",
65
+ },
66
+ },
67
+ {
68
+ type: "Text",
69
+ props: { value: ` ${e.message}`, fontWeight: "bold" },
70
+ },
71
+ ],
72
+ },
73
+ ],
74
+ };
75
+ });
76
+ const comp = {
77
+ type: "VStack",
78
+ props: { padding: "$padding-normal", gap: 0 },
79
+ children: [
80
+ {
81
+ type: "H1",
82
+ props: {
83
+ value: `${errList.length} ${errList.length > 1 ? "Errors" : "Error"} found while processing XMLUI markup`,
84
+ padding: "$padding-normal",
85
+ backgroundColor: "$color-error",
86
+ color: "white",
87
+ },
88
+ },
89
+ {
90
+ type: "VStack",
91
+ props: {
92
+ gap: "$gap-tight",
93
+ padding: "$padding-normal",
94
+ },
95
+ children: errList,
96
+ },
97
+ ],
98
+ };
99
+ return comp;
100
+ }
101
+ const comp = makeComponent();
102
+ comp.name = compoundCompName;
103
+ comp.component = makeComponent();
104
+ return comp;
23
105
  }
24
106
  function addPositions(errors, newlinePositions) {
25
107
  var _a;
@@ -36,8 +118,7 @@ function addPositions(errors, newlinePositions) {
36
118
  const newlinePos = newlinePositions[i];
37
119
  if (err.pos < newlinePos) {
38
120
  err.line = i + 1;
39
- err.col =
40
- err.pos - ((_a = newlinePositions[i - 1]) !== null && _a !== void 0 ? _a : 0) + 1;
121
+ err.col = err.pos - ((_a = newlinePositions[i - 1]) !== null && _a !== void 0 ? _a : 0) + 1;
41
122
  break;
42
123
  }
43
124
  }
@@ -49,3 +130,20 @@ function addPositions(errors, newlinePositions) {
49
130
  }
50
131
  return errors;
51
132
  }
133
+ function getCompoundCompName(node, getText) {
134
+ var _a, _b, _c, _d, _e, _f;
135
+ const rootTag = (_a = node === null || node === void 0 ? void 0 : node.children) === null || _a === void 0 ? void 0 : _a[0];
136
+ const rootTagNameTokens = (_c = (_b = rootTag === null || rootTag === void 0 ? void 0 : rootTag.children) === null || _b === void 0 ? void 0 : _b.find((c) => c.kind === syntax_kind_1.SyntaxKind.TagNameNode)) === null || _c === void 0 ? void 0 : _c.children;
137
+ const rootTagName = rootTagNameTokens === null || rootTagNameTokens === void 0 ? void 0 : rootTagNameTokens[rootTagNameTokens.length - 1];
138
+ if (rootTagName === undefined || getText(rootTagName) !== "Component") {
139
+ return undefined;
140
+ }
141
+ const attrs = (_e = (_d = rootTag.children) === null || _d === void 0 ? void 0 : _d.find((c) => c.kind === syntax_kind_1.SyntaxKind.AttributeListNode)) === null || _e === void 0 ? void 0 : _e.children;
142
+ const nameAttrTokens = (_f = attrs === null || attrs === void 0 ? void 0 : attrs.find((c) => c.kind === syntax_kind_1.SyntaxKind.AttributeNode && getText(c === null || c === void 0 ? void 0 : c.children[0]) === "name")) === null || _f === void 0 ? void 0 : _f.children;
143
+ const nameValueToken = nameAttrTokens === null || nameAttrTokens === void 0 ? void 0 : nameAttrTokens[nameAttrTokens.length - 1];
144
+ if (nameValueToken !== undefined && nameValueToken.kind === syntax_kind_1.SyntaxKind.StringLiteral) {
145
+ const strLit = getText(nameValueToken);
146
+ return strLit.substring(1, strLit.length - 1);
147
+ }
148
+ return undefined;
149
+ }
@@ -18,61 +18,64 @@ var LexerPhase;
18
18
  LexerPhase[LexerPhase["BlockCommentTrail2"] = 4] = "BlockCommentTrail2";
19
19
  // Multi-char tokens
20
20
  LexerPhase[LexerPhase["Slash"] = 5] = "Slash";
21
- LexerPhase[LexerPhase["Or"] = 6] = "Or";
22
- LexerPhase[LexerPhase["Asterisk"] = 7] = "Asterisk";
23
- LexerPhase[LexerPhase["Ampersand"] = 8] = "Ampersand";
24
- LexerPhase[LexerPhase["Equal"] = 9] = "Equal";
25
- LexerPhase[LexerPhase["DoubleEqual"] = 10] = "DoubleEqual";
26
- LexerPhase[LexerPhase["NotEqual"] = 11] = "NotEqual";
27
- LexerPhase[LexerPhase["Exclamation"] = 12] = "Exclamation";
28
- LexerPhase[LexerPhase["AngleLeft"] = 13] = "AngleLeft";
29
- LexerPhase[LexerPhase["AngleRight"] = 14] = "AngleRight";
30
- LexerPhase[LexerPhase["SignedShiftRight"] = 15] = "SignedShiftRight";
31
- LexerPhase[LexerPhase["IdTail"] = 16] = "IdTail";
32
- LexerPhase[LexerPhase["Dot"] = 17] = "Dot";
33
- LexerPhase[LexerPhase["DotDot"] = 18] = "DotDot";
34
- LexerPhase[LexerPhase["Colon"] = 19] = "Colon";
35
- LexerPhase[LexerPhase["Zero"] = 20] = "Zero";
36
- LexerPhase[LexerPhase["QuestionMark"] = 21] = "QuestionMark";
37
- LexerPhase[LexerPhase["HexaFirst"] = 22] = "HexaFirst";
38
- LexerPhase[LexerPhase["HexaTail"] = 23] = "HexaTail";
39
- LexerPhase[LexerPhase["BinaryFirst"] = 24] = "BinaryFirst";
40
- LexerPhase[LexerPhase["BinaryTail"] = 25] = "BinaryTail";
41
- LexerPhase[LexerPhase["DecimalOrReal"] = 26] = "DecimalOrReal";
42
- LexerPhase[LexerPhase["RealFractionalFirst"] = 27] = "RealFractionalFirst";
43
- LexerPhase[LexerPhase["RealFractionalTail"] = 28] = "RealFractionalTail";
44
- LexerPhase[LexerPhase["RealExponent"] = 29] = "RealExponent";
45
- LexerPhase[LexerPhase["RealExponentSign"] = 30] = "RealExponentSign";
46
- LexerPhase[LexerPhase["RealExponentTail"] = 31] = "RealExponentTail";
47
- LexerPhase[LexerPhase["String"] = 32] = "String";
48
- LexerPhase[LexerPhase["StringBackSlash"] = 33] = "StringBackSlash";
49
- LexerPhase[LexerPhase["StringHexa1"] = 34] = "StringHexa1";
50
- LexerPhase[LexerPhase["StringHexa2"] = 35] = "StringHexa2";
51
- LexerPhase[LexerPhase["StringUHexa1"] = 36] = "StringUHexa1";
52
- LexerPhase[LexerPhase["StringUHexa2"] = 37] = "StringUHexa2";
53
- LexerPhase[LexerPhase["StringUHexa3"] = 38] = "StringUHexa3";
54
- LexerPhase[LexerPhase["StringUHexa4"] = 39] = "StringUHexa4";
55
- LexerPhase[LexerPhase["StringUcp1"] = 40] = "StringUcp1";
56
- LexerPhase[LexerPhase["StringUcp2"] = 41] = "StringUcp2";
57
- LexerPhase[LexerPhase["StringUcp3"] = 42] = "StringUcp3";
58
- LexerPhase[LexerPhase["StringUcp4"] = 43] = "StringUcp4";
59
- LexerPhase[LexerPhase["StringUcp5"] = 44] = "StringUcp5";
60
- LexerPhase[LexerPhase["StringUcp6"] = 45] = "StringUcp6";
61
- LexerPhase[LexerPhase["StringUcpTail"] = 46] = "StringUcpTail";
21
+ LexerPhase[LexerPhase["Dollar"] = 6] = "Dollar";
22
+ LexerPhase[LexerPhase["Or"] = 7] = "Or";
23
+ LexerPhase[LexerPhase["Asterisk"] = 8] = "Asterisk";
24
+ LexerPhase[LexerPhase["Ampersand"] = 9] = "Ampersand";
25
+ LexerPhase[LexerPhase["Equal"] = 10] = "Equal";
26
+ LexerPhase[LexerPhase["DoubleEqual"] = 11] = "DoubleEqual";
27
+ LexerPhase[LexerPhase["NotEqual"] = 12] = "NotEqual";
28
+ LexerPhase[LexerPhase["Exclamation"] = 13] = "Exclamation";
29
+ LexerPhase[LexerPhase["AngleLeft"] = 14] = "AngleLeft";
30
+ LexerPhase[LexerPhase["AngleRight"] = 15] = "AngleRight";
31
+ LexerPhase[LexerPhase["SignedShiftRight"] = 16] = "SignedShiftRight";
32
+ LexerPhase[LexerPhase["IdTail"] = 17] = "IdTail";
33
+ LexerPhase[LexerPhase["Dot"] = 18] = "Dot";
34
+ LexerPhase[LexerPhase["DotDot"] = 19] = "DotDot";
35
+ LexerPhase[LexerPhase["Colon"] = 20] = "Colon";
36
+ LexerPhase[LexerPhase["Zero"] = 21] = "Zero";
37
+ LexerPhase[LexerPhase["QuestionMark"] = 22] = "QuestionMark";
38
+ LexerPhase[LexerPhase["HexaFirst"] = 23] = "HexaFirst";
39
+ LexerPhase[LexerPhase["HexaTail"] = 24] = "HexaTail";
40
+ LexerPhase[LexerPhase["BinaryFirst"] = 25] = "BinaryFirst";
41
+ LexerPhase[LexerPhase["BinaryTail"] = 26] = "BinaryTail";
42
+ LexerPhase[LexerPhase["DecimalOrReal"] = 27] = "DecimalOrReal";
43
+ LexerPhase[LexerPhase["RealFractionalFirst"] = 28] = "RealFractionalFirst";
44
+ LexerPhase[LexerPhase["RealFractionalTail"] = 29] = "RealFractionalTail";
45
+ LexerPhase[LexerPhase["RealExponent"] = 30] = "RealExponent";
46
+ LexerPhase[LexerPhase["RealExponentSign"] = 31] = "RealExponentSign";
47
+ LexerPhase[LexerPhase["RealExponentTail"] = 32] = "RealExponentTail";
48
+ LexerPhase[LexerPhase["StringTemplateLiteral"] = 33] = "StringTemplateLiteral";
49
+ LexerPhase[LexerPhase["StringTemplateLiteralBackSlash"] = 34] = "StringTemplateLiteralBackSlash";
50
+ LexerPhase[LexerPhase["String"] = 35] = "String";
51
+ LexerPhase[LexerPhase["StringBackSlash"] = 36] = "StringBackSlash";
52
+ LexerPhase[LexerPhase["StringHexa1"] = 37] = "StringHexa1";
53
+ LexerPhase[LexerPhase["StringHexa2"] = 38] = "StringHexa2";
54
+ LexerPhase[LexerPhase["StringUHexa1"] = 39] = "StringUHexa1";
55
+ LexerPhase[LexerPhase["StringUHexa2"] = 40] = "StringUHexa2";
56
+ LexerPhase[LexerPhase["StringUHexa3"] = 41] = "StringUHexa3";
57
+ LexerPhase[LexerPhase["StringUHexa4"] = 42] = "StringUHexa4";
58
+ LexerPhase[LexerPhase["StringUcp1"] = 43] = "StringUcp1";
59
+ LexerPhase[LexerPhase["StringUcp2"] = 44] = "StringUcp2";
60
+ LexerPhase[LexerPhase["StringUcp3"] = 45] = "StringUcp3";
61
+ LexerPhase[LexerPhase["StringUcp4"] = 46] = "StringUcp4";
62
+ LexerPhase[LexerPhase["StringUcp5"] = 47] = "StringUcp5";
63
+ LexerPhase[LexerPhase["StringUcp6"] = 48] = "StringUcp6";
64
+ LexerPhase[LexerPhase["StringUcpTail"] = 49] = "StringUcpTail";
62
65
  // --- Assignments
63
- LexerPhase[LexerPhase["Exponent"] = 47] = "Exponent";
64
- LexerPhase[LexerPhase["Plus"] = 48] = "Plus";
65
- LexerPhase[LexerPhase["Minus"] = 49] = "Minus";
66
- LexerPhase[LexerPhase["Divide"] = 50] = "Divide";
67
- LexerPhase[LexerPhase["Remainder"] = 51] = "Remainder";
68
- LexerPhase[LexerPhase["ShiftLeft"] = 52] = "ShiftLeft";
69
- LexerPhase[LexerPhase["ShiftRight"] = 53] = "ShiftRight";
70
- LexerPhase[LexerPhase["LogicalAnd"] = 54] = "LogicalAnd";
71
- LexerPhase[LexerPhase["BitwiseXor"] = 55] = "BitwiseXor";
72
- LexerPhase[LexerPhase["LogicalOr"] = 56] = "LogicalOr";
73
- LexerPhase[LexerPhase["NullCoalesce"] = 57] = "NullCoalesce";
66
+ LexerPhase[LexerPhase["Exponent"] = 50] = "Exponent";
67
+ LexerPhase[LexerPhase["Plus"] = 51] = "Plus";
68
+ LexerPhase[LexerPhase["Minus"] = 52] = "Minus";
69
+ LexerPhase[LexerPhase["Divide"] = 53] = "Divide";
70
+ LexerPhase[LexerPhase["Remainder"] = 54] = "Remainder";
71
+ LexerPhase[LexerPhase["ShiftLeft"] = 55] = "ShiftLeft";
72
+ LexerPhase[LexerPhase["ShiftRight"] = 56] = "ShiftRight";
73
+ LexerPhase[LexerPhase["LogicalAnd"] = 57] = "LogicalAnd";
74
+ LexerPhase[LexerPhase["BitwiseXor"] = 58] = "BitwiseXor";
75
+ LexerPhase[LexerPhase["LogicalOr"] = 59] = "LogicalOr";
76
+ LexerPhase[LexerPhase["NullCoalesce"] = 60] = "NullCoalesce";
74
77
  // --- Other
75
- LexerPhase[LexerPhase["RegEx"] = 58] = "RegEx";
78
+ LexerPhase[LexerPhase["RegEx"] = 61] = "RegEx";
76
79
  })(LexerPhase || (LexerPhase = {}));
77
80
  /**
78
81
  * This class implements the lexer of binding expressions
@@ -94,6 +97,7 @@ class Lexer {
94
97
  this._prefetchedColumn = null;
95
98
  // --- input position at the beginning of last fetch
96
99
  this._lastFetchPosition = 0;
100
+ this._phaseExternallySet = null;
97
101
  }
98
102
  /**
99
103
  * Fetches the next token without advancing to its position
@@ -156,6 +160,14 @@ class Lexer {
156
160
  ? this.input.getTail(this._ahead[0].location.startPosition)
157
161
  : this.input.getTail(this._lastFetchPosition);
158
162
  }
163
+ /**
164
+ * Parsing template literals requires a context sensitive lexer.
165
+ * This method has to be called by the parser when the lexer needs to scan a string inside a template literal.
166
+ * Call this after the first opening backing and after the parser is done with parsing a placeholder, after the right brace.
167
+ */
168
+ setStartingPhaseToTemplateLiteral() {
169
+ this._phaseExternallySet = LexerPhase.StringTemplateLiteral;
170
+ }
159
171
  /**
160
172
  * Fetches the next character from the input stream
161
173
  */
@@ -187,7 +199,7 @@ class Lexer {
187
199
  let ch = null;
188
200
  let useResolver = false;
189
201
  // --- Start from the beginning
190
- let phase = LexerPhase.Start;
202
+ let phase = this.getStartingPhaseThenReset();
191
203
  // --- Process all token characters
192
204
  while (true) {
193
205
  // --- Get the next character
@@ -201,7 +213,7 @@ class Lexer {
201
213
  tokenType = Token_1.TokenType.Unknown;
202
214
  }
203
215
  // --- Follow the lexer state machine
204
- switch (phase) {
216
+ phaseSwitch: switch (phase) {
205
217
  // ====================================================================
206
218
  // Process the first character
207
219
  case LexerPhase.Start:
@@ -219,6 +231,10 @@ class Lexer {
219
231
  phase = LexerPhase.Slash;
220
232
  tokenType = Token_1.TokenType.Divide;
221
233
  break;
234
+ case "$":
235
+ phase = LexerPhase.Dollar;
236
+ tokenType = Token_1.TokenType.Identifier;
237
+ break;
222
238
  case "*":
223
239
  phase = LexerPhase.Asterisk;
224
240
  tokenType = Token_1.TokenType.Multiply;
@@ -267,6 +283,8 @@ class Lexer {
267
283
  phase = LexerPhase.Colon;
268
284
  tokenType = Token_1.TokenType.Colon;
269
285
  break;
286
+ case "`":
287
+ return completeToken(Token_1.TokenType.Backtick);
270
288
  case "[":
271
289
  return completeToken(Token_1.TokenType.LSquare);
272
290
  case "]":
@@ -330,6 +348,18 @@ class Lexer {
330
348
  break;
331
349
  // ====================================================================
332
350
  // Process comments
351
+ // A dollar sign is also a valid variable name. When it isn't a dollar left brace, we continue as if it was an identifier
352
+ case LexerPhase.Dollar:
353
+ if (ch === "{") {
354
+ return completeToken(Token_1.TokenType.DollarLBrace);
355
+ }
356
+ phase = LexerPhase.IdTail;
357
+ useResolver = true;
358
+ tokenType = Token_1.TokenType.Identifier;
359
+ if (!isIdContinuation(ch)) {
360
+ makeToken();
361
+ }
362
+ break;
333
363
  // --- Looking for the end of whitespace
334
364
  case LexerPhase.InWhiteSpace:
335
365
  if (ch !== " " && ch !== "\t" && ch !== "\r" && ch !== "\n") {
@@ -571,7 +601,8 @@ class Lexer {
571
601
  if (isDecimalDigit(ch) || ch === "_") {
572
602
  break;
573
603
  }
574
- else if (ch === "." && (this.input.peek() === null || isDecimalDigit(this.input.peek()))) {
604
+ else if (ch === "." &&
605
+ (this.input.peek() === null || isDecimalDigit(this.input.peek()))) {
575
606
  phase = LexerPhase.RealFractionalFirst;
576
607
  tokenType = Token_1.TokenType.Unknown;
577
608
  }
@@ -630,6 +661,37 @@ class Lexer {
630
661
  return makeToken();
631
662
  }
632
663
  break;
664
+ case LexerPhase.StringTemplateLiteralBackSlash: {
665
+ phase = LexerPhase.StringTemplateLiteral;
666
+ const charAhead1 = this.input.ahead(0);
667
+ const charAhead2 = this.input.ahead(1);
668
+ if (charAhead1 === "`" || (charAhead1 === "$" && charAhead2 === "{")) {
669
+ return completeToken(Token_1.TokenType.StringLiteral);
670
+ }
671
+ break;
672
+ }
673
+ case LexerPhase.StringTemplateLiteral:
674
+ switch (ch) {
675
+ case "\\":
676
+ phase = LexerPhase.StringTemplateLiteralBackSlash;
677
+ tokenType = Token_1.TokenType.Unknown;
678
+ break phaseSwitch;
679
+ case "`":
680
+ return completeToken(Token_1.TokenType.Backtick);
681
+ case "$":
682
+ const charAhead = this.input.ahead(0);
683
+ if (charAhead === "{") {
684
+ appendTokenChar();
685
+ this.fetchNextChar();
686
+ return completeToken(Token_1.TokenType.DollarLBrace);
687
+ }
688
+ }
689
+ const charAhead1 = this.input.ahead(0);
690
+ const charAhead2 = this.input.ahead(1);
691
+ if (charAhead1 === "`" || (charAhead1 === "$" && charAhead2 === "{")) {
692
+ return completeToken(Token_1.TokenType.StringLiteral);
693
+ }
694
+ break;
633
695
  case LexerPhase.String:
634
696
  if (ch === stringState) {
635
697
  return completeToken(Token_1.TokenType.StringLiteral);
@@ -833,7 +895,9 @@ class Lexer {
833
895
  var _a;
834
896
  if (useResolver) {
835
897
  tokenType =
836
- (_a = resolverHash.get(text)) !== null && _a !== void 0 ? _a : (isIdStart(text[0]) && text[text.length - 1] !== "'" ? Token_1.TokenType.Identifier : Token_1.TokenType.Unknown);
898
+ (_a = resolverHash.get(text)) !== null && _a !== void 0 ? _a : (isIdStart(text[0]) && text[text.length - 1] !== "'"
899
+ ? Token_1.TokenType.Identifier
900
+ : Token_1.TokenType.Unknown);
837
901
  }
838
902
  return {
839
903
  text,
@@ -860,6 +924,14 @@ class Lexer {
860
924
  return makeToken();
861
925
  }
862
926
  }
927
+ getStartingPhaseThenReset() {
928
+ if (this._phaseExternallySet !== null) {
929
+ const phase = this._phaseExternallySet;
930
+ this._phaseExternallySet = null;
931
+ return phase;
932
+ }
933
+ return LexerPhase.Start;
934
+ }
863
935
  /**
864
936
  * Fetches the next RegEx token from the input stream
865
937
  */
@@ -996,7 +1068,11 @@ function isIdStart(ch) {
996
1068
  * @param ch Character to test
997
1069
  */
998
1070
  function isIdContinuation(ch) {
999
- return (ch >= "a" && ch <= "z") || (ch >= "A" && ch <= "Z") || (ch >= "0" && ch <= "9") || ch === "_" || ch === "$";
1071
+ return ((ch >= "a" && ch <= "z") ||
1072
+ (ch >= "A" && ch <= "Z") ||
1073
+ (ch >= "0" && ch <= "9") ||
1074
+ ch === "_" ||
1075
+ ch === "$");
1000
1076
  }
1001
1077
  /**
1002
1078
  * Tests if a character is a binary digit