xmlui 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/{apiInterceptorWorker-230V_-Ds.mjs → apiInterceptorWorker-Y5MxQ95G.mjs} +1 -1
  2. package/dist/{core-XLM8cuFP.mjs → core-DowI-7YH.mjs} +2 -52
  3. package/dist/{index-DUwwx3L4.mjs → index-DHAz4bv_.mjs} +14904 -1512
  4. package/dist/index.css +309 -233
  5. package/dist/scripts/bin/vite-xmlui-plugin.js +1 -1
  6. package/dist/scripts/src/abstractions/scripting/ScriptingSourceTree.js +48 -0
  7. package/dist/scripts/src/components/HtmlTags/HtmlTags.js +11 -1
  8. package/dist/scripts/src/components/Markdown/Markdown.js +17 -13
  9. package/dist/scripts/src/components/Markdown/MarkdownNative.js +40 -21
  10. package/dist/scripts/src/components/Slider/Slider.js +25 -6
  11. package/dist/scripts/src/components/Slider/SliderNative.js +78 -18
  12. package/dist/scripts/src/components/Theme/ThemeNative.js +1 -1
  13. package/dist/scripts/src/components-core/InspectorContext.js +1 -1
  14. package/dist/scripts/src/components-core/RestApiProxy.js +21 -11
  15. package/dist/scripts/src/components-core/{DevTools.js → devtools/DevTools.js} +71 -10
  16. package/dist/scripts/src/components-core/rendering/Container.js +3 -3
  17. package/dist/scripts/src/components-core/rendering/StateContainer.js +3 -3
  18. package/dist/scripts/src/components-core/script-runner/ParameterParser.js +1 -1
  19. package/dist/scripts/src/components-core/script-runner/eval-tree-async.js +37 -37
  20. package/dist/scripts/src/components-core/script-runner/eval-tree-common.js +8 -8
  21. package/dist/scripts/src/components-core/script-runner/eval-tree-sync.js +37 -37
  22. package/dist/scripts/src/components-core/script-runner/process-statement-async.js +29 -29
  23. package/dist/scripts/src/components-core/script-runner/process-statement-common.js +5 -5
  24. package/dist/scripts/src/components-core/script-runner/process-statement-sync.js +29 -29
  25. package/dist/scripts/src/components-core/script-runner/visitors.js +47 -47
  26. package/dist/scripts/src/components-core/theming/ThemeProvider.js +2 -2
  27. package/dist/scripts/src/components-core/theming/themes/root.js +1 -1
  28. package/dist/scripts/src/components-core/utils/statementUtils.js +32 -32
  29. package/dist/scripts/src/parsers/scripting/Lexer.js +166 -178
  30. package/dist/scripts/src/parsers/scripting/Parser.js +555 -701
  31. package/dist/scripts/src/parsers/scripting/ParserError.js +3 -3
  32. package/dist/scripts/src/parsers/scripting/TokenTrait.js +103 -105
  33. package/dist/scripts/src/parsers/{scripting-exp → scripting}/code-behind-collect.js +4 -4
  34. package/dist/scripts/src/parsers/{scripting-exp → scripting}/modules.js +2 -2
  35. package/dist/scripts/src/parsers/{scripting-exp → scripting}/tree-visitor.js +45 -45
  36. package/dist/scripts/src/parsers/xmlui-parser/transform.js +2 -2
  37. package/dist/scripts/src/syntax/monaco/grammar.monacoLanguage.js +286 -0
  38. package/dist/scripts/src/syntax/monaco/xmlui-dark.js +27 -0
  39. package/dist/scripts/src/syntax/monaco/xmlui-light.js +26 -0
  40. package/dist/scripts/src/syntax/monaco/xmluiscript.monacoLanguage.js +310 -0
  41. package/dist/style.css +222 -152
  42. package/dist/xmlui-metadata.mjs +307 -478
  43. package/dist/xmlui-metadata.umd.js +309 -477
  44. package/dist/xmlui-parser.d.ts +1 -11
  45. package/dist/xmlui-standalone.umd.js +34047 -29191
  46. package/dist/xmlui.d.ts +2 -75
  47. package/dist/xmlui.mjs +10 -10
  48. package/package.json +5 -6
  49. package/dist/scripts/src/abstractions/scripting/ScriptingSourceTreeExp.js +0 -50
  50. package/dist/scripts/src/abstractions/scripting/Token.js +0 -112
  51. package/dist/scripts/src/components-core/theming/abstractions.js +0 -11
  52. package/dist/scripts/src/parsers/scripting-exp/Lexer.js +0 -1092
  53. package/dist/scripts/src/parsers/scripting-exp/Parser.js +0 -2635
  54. package/dist/scripts/src/parsers/scripting-exp/ParserError.js +0 -47
  55. package/dist/scripts/src/parsers/scripting-exp/TokenTrait.js +0 -109
  56. /package/dist/scripts/src/abstractions/scripting/{LogicalThreadExp.js → LogicalThread.js} +0 -0
  57. /package/dist/scripts/src/parsers/{scripting-exp → scripting}/TokenType.js +0 -0
@@ -1,2635 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Parser = void 0;
4
- exports.createXmlUiTreeNodeId = createXmlUiTreeNodeId;
5
- const ScriptingSourceTreeExp_1 = require("../../abstractions/scripting/ScriptingSourceTreeExp");
6
- const InputStream_1 = require("../common/InputStream");
7
- const Lexer_1 = require("./Lexer");
8
- const ParserError_1 = require("./ParserError");
9
- const TokenTrait_1 = require("./TokenTrait");
10
- const TokenType_1 = require("./TokenType");
11
- /**
12
- * States of the string parsing
13
- */
14
- var StrParseState;
15
- (function (StrParseState) {
16
- StrParseState[StrParseState["Normal"] = 0] = "Normal";
17
- StrParseState[StrParseState["Backslash"] = 1] = "Backslash";
18
- StrParseState[StrParseState["X"] = 2] = "X";
19
- StrParseState[StrParseState["Xh"] = 3] = "Xh";
20
- StrParseState[StrParseState["UX1"] = 4] = "UX1";
21
- StrParseState[StrParseState["UX2"] = 5] = "UX2";
22
- StrParseState[StrParseState["UX3"] = 6] = "UX3";
23
- StrParseState[StrParseState["UX4"] = 7] = "UX4";
24
- StrParseState[StrParseState["Ucp1"] = 8] = "Ucp1";
25
- StrParseState[StrParseState["Ucp2"] = 9] = "Ucp2";
26
- StrParseState[StrParseState["Ucp3"] = 10] = "Ucp3";
27
- StrParseState[StrParseState["Ucp4"] = 11] = "Ucp4";
28
- StrParseState[StrParseState["Ucp5"] = 12] = "Ucp5";
29
- StrParseState[StrParseState["Ucp6"] = 13] = "Ucp6";
30
- StrParseState[StrParseState["UcpTail"] = 14] = "UcpTail";
31
- })(StrParseState || (StrParseState = {}));
32
- let lastNodeId = 0;
33
- function createXmlUiTreeNodeId() {
34
- return ++lastNodeId;
35
- }
36
- /**
37
- * This class parses a binding expression and transforms it into an evaluable expression tree
38
- */
39
- class Parser {
40
- /**
41
- * Initializes the parser with the specified source code
42
- * @param source Source code to parse
43
- */
44
- constructor(source) {
45
- // --- Keep track of error messages
46
- this._parseErrors = [];
47
- // --- Indicates the parsing level
48
- this._statementLevel = 0;
49
- this._lexer = new Lexer_1.Lexer(new InputStream_1.InputStream(source !== null && source !== void 0 ? source : ""));
50
- }
51
- /**
52
- * Sets the source code to parse
53
- * @param source Source code to parse
54
- */
55
- setSource(source) {
56
- this._lexer = new Lexer_1.Lexer(new InputStream_1.InputStream(source));
57
- }
58
- /**
59
- * The errors raised during the parse phase
60
- */
61
- get errors() {
62
- return this._parseErrors;
63
- }
64
- /**
65
- * Gets the current token
66
- */
67
- get current() {
68
- return this._lexer.peek();
69
- }
70
- /**
71
- * Checks if we're at the end of the expression
72
- */
73
- get isEof() {
74
- return this._lexer.peek().type === TokenType_1.TokenType.Eof;
75
- }
76
- /**
77
- * Gets the characters remaining after parsing
78
- */
79
- getTail() {
80
- return this._lexer.getTail();
81
- }
82
- // ==========================================================================
83
- // Statement parsing
84
- /**
85
- * Parses a list of statements:
86
- *
87
- * statements
88
- * : statement*
89
- * ;
90
- *
91
- * statement
92
- * : emptyStatement
93
- * | expressionStatement
94
- * | letStatement
95
- * | returnStatement
96
- * ;
97
- */
98
- parseStatements() {
99
- this._statementLevel = 0;
100
- const statements = [];
101
- while (!this.isEof) {
102
- const statement = this.parseStatement();
103
- if (!statement)
104
- return null;
105
- statements.push(statement);
106
- if (statement.type !== ScriptingSourceTreeExp_1.T_EMPTY_STATEMENT) {
107
- this.skipToken(TokenType_1.TokenType.Semicolon);
108
- }
109
- }
110
- return statements;
111
- }
112
- /**
113
- * Parses a single statement
114
- */
115
- parseStatement(allowSequence = true) {
116
- this._statementLevel++;
117
- try {
118
- const startToken = this._lexer.peek();
119
- switch (startToken.type) {
120
- case TokenType_1.TokenType.Semicolon:
121
- return this.parseEmptyStatement();
122
- case TokenType_1.TokenType.Let:
123
- return this.parseLetStatement();
124
- case TokenType_1.TokenType.Const:
125
- return this.parseConstStatement();
126
- case TokenType_1.TokenType.Var:
127
- return this.parseVarStatement();
128
- case TokenType_1.TokenType.LBrace:
129
- return this.parseBlockStatement();
130
- case TokenType_1.TokenType.If:
131
- return this.parseIfStatement();
132
- case TokenType_1.TokenType.Do:
133
- return this.parseDoWhileStatement();
134
- case TokenType_1.TokenType.While:
135
- return this.parseWhileStatement();
136
- case TokenType_1.TokenType.Return:
137
- return this.parseReturnStatement();
138
- case TokenType_1.TokenType.Break:
139
- this._lexer.get();
140
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_BREAK_STATEMENT, {}, startToken, startToken);
141
- case TokenType_1.TokenType.Continue:
142
- this._lexer.get();
143
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_CONTINUE_STATEMENT, {}, startToken, startToken);
144
- case TokenType_1.TokenType.For:
145
- return this.parseForStatement();
146
- case TokenType_1.TokenType.Throw:
147
- return this.parseThrowStatement();
148
- case TokenType_1.TokenType.Try:
149
- return this.parseTryStatement();
150
- case TokenType_1.TokenType.Switch:
151
- return this.parseSwitchStatement();
152
- case TokenType_1.TokenType.Function:
153
- return this.parseFunctionDeclaration();
154
- default:
155
- return this.isExpressionStart(startToken)
156
- ? this.parseExpressionStatement(allowSequence)
157
- : null;
158
- }
159
- }
160
- finally {
161
- this._statementLevel--;
162
- }
163
- }
164
- /**
165
- * Parses an empty statement
166
- *
167
- * emptyStatement
168
- * : ";"
169
- * ;
170
- */
171
- parseEmptyStatement() {
172
- const startToken = this._lexer.get();
173
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_EMPTY_STATEMENT, {}, startToken, startToken);
174
- }
175
- /**
176
- * Parses an expression statement
177
- *
178
- * expressionStatement
179
- * : expression
180
- * ;
181
- */
182
- parseExpressionStatement(allowSequence = true) {
183
- const startToken = this._lexer.peek();
184
- const expr = this.getExpression(allowSequence);
185
- return expr
186
- ? this.createStatementNode(ScriptingSourceTreeExp_1.T_EXPRESSION_STATEMENT, {
187
- expr,
188
- }, startToken, expr.endToken)
189
- : null;
190
- }
191
- /**
192
- * Parses a let statement
193
- *
194
- * letStatement
195
- * : "let" id ["=" expression] ("," id ["=" expression])*
196
- * ;
197
- */
198
- parseLetStatement() {
199
- const startToken = this._lexer.get();
200
- let endToken = startToken;
201
- const decls = [];
202
- while (true) {
203
- const declStart = this._lexer.peek();
204
- let declarationProps = {};
205
- if (declStart.type === TokenType_1.TokenType.LBrace) {
206
- // --- This is object destructure
207
- endToken = this._lexer.ahead(1);
208
- const oDestr = this.parseObjectDestructure();
209
- if (oDestr === null)
210
- return null;
211
- declarationProps = {
212
- oDestr,
213
- };
214
- endToken = oDestr.length > 0 ? oDestr[oDestr.length - 1].endToken : endToken;
215
- }
216
- else if (declStart.type === TokenType_1.TokenType.LSquare) {
217
- // --- This is array destructure
218
- endToken = this._lexer.ahead(1);
219
- const aDestr = this.parseArrayDestructure();
220
- if (aDestr === null)
221
- return null;
222
- declarationProps = {
223
- aDestr,
224
- };
225
- endToken = aDestr.length > 0 ? aDestr[aDestr.length - 1].endToken : endToken;
226
- }
227
- else if (declStart.type === TokenType_1.TokenType.Identifier) {
228
- if (declStart.text.startsWith("$")) {
229
- this.reportError("W031");
230
- return null;
231
- }
232
- endToken = this._lexer.get();
233
- declarationProps = {
234
- id: declStart.text,
235
- };
236
- }
237
- else {
238
- this.reportError("W003");
239
- return null;
240
- }
241
- // --- Optional initialization
242
- const initToken = this._lexer.peek();
243
- let expr = null;
244
- if (initToken.type === TokenType_1.TokenType.Assignment) {
245
- this._lexer.get();
246
- expr = this.getExpression(false);
247
- if (expr === null)
248
- return null;
249
- declarationProps.expr = expr;
250
- endToken = expr.endToken;
251
- }
252
- else if (declarationProps.aDestr || declarationProps.oDestr) {
253
- this.reportError("W009", initToken);
254
- return null;
255
- }
256
- // --- New declaration reached
257
- decls.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_VAR_DECLARATION, declarationProps, declStart, endToken));
258
- // --- Check for more declarations
259
- if (this._lexer.peek().type !== TokenType_1.TokenType.Comma)
260
- break;
261
- this._lexer.get();
262
- }
263
- // --- Done
264
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_LET_STATEMENT, {
265
- decls,
266
- }, startToken, endToken);
267
- }
268
- /**
269
- * Parses a const statement
270
- *
271
- * constStatement
272
- * : "const" id "=" expression
273
- * ;
274
- */
275
- parseConstStatement() {
276
- const startToken = this._lexer.get();
277
- let endToken = startToken;
278
- const decls = [];
279
- while (true) {
280
- const declStart = this._lexer.peek();
281
- let declarationProps = {};
282
- if (declStart.type === TokenType_1.TokenType.LBrace) {
283
- // --- This is object destructure
284
- endToken = this._lexer.ahead(1);
285
- const oDestr = this.parseObjectDestructure();
286
- if (oDestr === null)
287
- return null;
288
- declarationProps = {
289
- oDestr,
290
- };
291
- endToken = oDestr.length > 0 ? oDestr[oDestr.length - 1].endToken : endToken;
292
- }
293
- else if (declStart.type === TokenType_1.TokenType.LSquare) {
294
- // --- This is array destructure
295
- endToken = this._lexer.ahead(1);
296
- const aDestr = this.parseArrayDestructure();
297
- if (aDestr === null)
298
- return null;
299
- declarationProps = {
300
- aDestr,
301
- };
302
- endToken = aDestr.length > 0 ? aDestr[aDestr.length - 1].endToken : endToken;
303
- }
304
- else if (declStart.type === TokenType_1.TokenType.Identifier) {
305
- if (declStart.text.startsWith("$")) {
306
- this.reportError("W031");
307
- return null;
308
- }
309
- endToken = this._lexer.get();
310
- declarationProps = {
311
- id: declStart.text,
312
- };
313
- }
314
- else {
315
- this.reportError("W003");
316
- return null;
317
- }
318
- this.expectToken(TokenType_1.TokenType.Assignment);
319
- const expr = this.getExpression(false);
320
- if (expr === null)
321
- return null;
322
- declarationProps.expr = expr;
323
- endToken = expr.endToken;
324
- // --- New declaration reached
325
- decls.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_VAR_DECLARATION, declarationProps, declStart, endToken));
326
- // --- Check for more declarations
327
- if (this._lexer.peek().type !== TokenType_1.TokenType.Comma)
328
- break;
329
- this._lexer.get();
330
- }
331
- // --- Done
332
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_CONST_STATEMENT, {
333
- decls,
334
- }, startToken, endToken);
335
- }
336
- /**
337
- * Parses a var statement
338
- *
339
- * constStatement
340
- * : "var" id "=" expression
341
- * ;
342
- */
343
- parseVarStatement() {
344
- const startToken = this._lexer.get();
345
- let endToken = startToken;
346
- const decls = [];
347
- while (true) {
348
- const declStart = this._lexer.peek();
349
- let declarationProps = {};
350
- if (declStart.type === TokenType_1.TokenType.Identifier) {
351
- if (declStart.text.startsWith("$")) {
352
- this.reportError("W031");
353
- return null;
354
- }
355
- endToken = this._lexer.get();
356
- declarationProps = {
357
- id: {
358
- type: ScriptingSourceTreeExp_1.T_IDENTIFIER,
359
- name: declStart.text,
360
- startToken: declStart,
361
- endToken,
362
- },
363
- };
364
- }
365
- else {
366
- this.reportError("W003");
367
- return null;
368
- }
369
- // --- Mandatory initialization
370
- this.expectToken(TokenType_1.TokenType.Assignment);
371
- const expr = this.getExpression(false);
372
- if (expr === null)
373
- return null;
374
- declarationProps.expr = expr;
375
- endToken = expr.endToken;
376
- // --- New declaration reached
377
- decls.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_REACTIVE_VAR_DECLARATION, declarationProps, declStart, endToken));
378
- // --- Check for more declarations
379
- if (this._lexer.peek().type !== TokenType_1.TokenType.Comma)
380
- break;
381
- this._lexer.get();
382
- }
383
- // --- Done
384
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_VAR_STATEMENT, {
385
- decls,
386
- }, startToken, endToken);
387
- }
388
- /**
389
- * Parses an object destructure expression
390
- */
391
- parseObjectDestructure() {
392
- const result = [];
393
- // --- Skip the starting left brace
394
- const startToken = this._lexer.get();
395
- let endToken = startToken;
396
- let nextToken = this._lexer.peek();
397
- while (nextToken.type === TokenType_1.TokenType.Identifier) {
398
- // --- Obtain the ID
399
- const id = nextToken.text;
400
- if (id.startsWith("$")) {
401
- this.reportError("W031");
402
- return null;
403
- }
404
- let alias;
405
- let aDestr;
406
- let oDestr;
407
- this._lexer.get();
408
- nextToken = this._lexer.peek();
409
- if (nextToken.type === TokenType_1.TokenType.Colon) {
410
- // --- Check the available cases
411
- this._lexer.get();
412
- nextToken = this._lexer.peek();
413
- if (nextToken.type === TokenType_1.TokenType.Identifier) {
414
- alias = nextToken.text;
415
- endToken = nextToken;
416
- this._lexer.get();
417
- }
418
- else if (nextToken.type === TokenType_1.TokenType.LSquare) {
419
- aDestr = this.parseArrayDestructure();
420
- if (aDestr === null)
421
- return null;
422
- endToken = aDestr[aDestr.length - 1].endToken;
423
- }
424
- else if (nextToken.type === TokenType_1.TokenType.LBrace) {
425
- oDestr = this.parseObjectDestructure();
426
- if (oDestr === null)
427
- return null;
428
- endToken = oDestr[oDestr.length - 1].endToken;
429
- }
430
- }
431
- // --- Check for next segment
432
- nextToken = this._lexer.peek();
433
- if (nextToken.type === TokenType_1.TokenType.Comma || nextToken.type === TokenType_1.TokenType.RBrace) {
434
- result.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE, { id, alias, aDestr, oDestr }, startToken, endToken));
435
- if (nextToken.type === TokenType_1.TokenType.Comma) {
436
- // --- Skip the delimiter comma
437
- this._lexer.get();
438
- nextToken = this._lexer.peek();
439
- }
440
- }
441
- }
442
- // --- Expect a closing right brace
443
- this.expectToken(TokenType_1.TokenType.RBrace, "W004");
444
- return result;
445
- }
446
- parseArrayDestructure() {
447
- const result = [];
448
- // --- Skip the starting left square
449
- const startToken = this._lexer.get();
450
- let endToken = startToken;
451
- do {
452
- let nextToken = this._lexer.peek();
453
- let id;
454
- let aDestr;
455
- let oDestr;
456
- if (nextToken.type === TokenType_1.TokenType.Identifier) {
457
- id = nextToken.text;
458
- if (id.startsWith("$")) {
459
- this.reportError("W031");
460
- return null;
461
- }
462
- endToken = nextToken;
463
- nextToken = this._lexer.get();
464
- }
465
- else if (nextToken.type === TokenType_1.TokenType.LSquare) {
466
- aDestr = this.parseArrayDestructure();
467
- if (aDestr === null)
468
- return null;
469
- endToken = aDestr[aDestr.length - 1].endToken;
470
- }
471
- else if (nextToken.type === TokenType_1.TokenType.LBrace) {
472
- oDestr = this.parseObjectDestructure();
473
- if (oDestr === null)
474
- return null;
475
- endToken = oDestr[oDestr.length - 1].endToken;
476
- }
477
- nextToken = this._lexer.peek();
478
- if (nextToken.type === TokenType_1.TokenType.Comma) {
479
- // --- Store the segment
480
- result.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, { id, aDestr, oDestr }, startToken, endToken));
481
- this._lexer.get();
482
- }
483
- else if (nextToken.type === TokenType_1.TokenType.RSquare) {
484
- if (id || aDestr || oDestr) {
485
- // --- Store a non-empty the segment
486
- result.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, { id, aDestr, oDestr }, startToken, endToken));
487
- }
488
- break;
489
- }
490
- else {
491
- this.reportError("W002", nextToken);
492
- return null;
493
- }
494
- } while (true);
495
- // --- Expect a closing right square
496
- this.expectToken(TokenType_1.TokenType.RSquare, "W005");
497
- return result;
498
- }
499
- /**
500
- * Parses a block statement
501
- *
502
- * blockStatement
503
- * : "{" (statement [";"])* "}"
504
- * ;
505
- */
506
- parseBlockStatement() {
507
- const startToken = this._lexer.get();
508
- const stmts = [];
509
- while (this._lexer.peek().type !== TokenType_1.TokenType.RBrace) {
510
- const statement = this.parseStatement();
511
- if (!statement)
512
- return null;
513
- stmts.push(statement);
514
- if (statement.type !== ScriptingSourceTreeExp_1.T_EMPTY_STATEMENT) {
515
- this.skipToken(TokenType_1.TokenType.Semicolon);
516
- }
517
- }
518
- const endToken = this._lexer.get();
519
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_BLOCK_STATEMENT, { stmts }, startToken, endToken);
520
- }
521
- /**
522
- * Parses an if statement
523
- *
524
- * ifStatement
525
- * : "if" "(" expression ")" statement ["else" statement]
526
- * ;
527
- */
528
- parseIfStatement() {
529
- const startToken = this._lexer.get();
530
- let endToken = startToken;
531
- this.expectToken(TokenType_1.TokenType.LParent, "W014");
532
- const cond = this.getExpression();
533
- if (!cond)
534
- return null;
535
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
536
- const thenB = this.parseStatement();
537
- if (!thenB)
538
- return null;
539
- endToken = thenB.endToken;
540
- let elseCanFollow = true;
541
- if (thenB.type !== ScriptingSourceTreeExp_1.T_BLOCK_STATEMENT) {
542
- // --- We need a closing semicolon before else
543
- if (this._lexer.peek().type === TokenType_1.TokenType.Semicolon) {
544
- this._lexer.get();
545
- }
546
- else {
547
- elseCanFollow = false;
548
- }
549
- }
550
- let elseB = null;
551
- if (elseCanFollow && this._lexer.peek().type === TokenType_1.TokenType.Else) {
552
- this._lexer.get();
553
- elseB = this.parseStatement();
554
- if (!elseB)
555
- return null;
556
- endToken = elseB.endToken;
557
- }
558
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_IF_STATEMENT, {
559
- cond,
560
- thenB,
561
- elseB,
562
- }, startToken, endToken);
563
- }
564
- /**
565
- * Parses a while statement
566
- *
567
- * whileStatement
568
- * : "while" "(" condition ")" statement
569
- * ;
570
- */
571
- parseWhileStatement() {
572
- const startToken = this._lexer.get();
573
- this.expectToken(TokenType_1.TokenType.LParent, "W014");
574
- const cond = this.getExpression();
575
- if (!cond)
576
- return null;
577
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
578
- const body = this.parseStatement();
579
- if (!body)
580
- return null;
581
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_WHILE_STATEMENT, {
582
- cond,
583
- body,
584
- }, startToken, body.endToken);
585
- }
586
- /**
587
- * Parses a do-while statement
588
- *
589
- * doWhileStatement
590
- * : "do" statement "while" "(" condition ")"
591
- * ;
592
- */
593
- parseDoWhileStatement() {
594
- const startToken = this._lexer.get();
595
- const body = this.parseStatement();
596
- if (!body)
597
- return null;
598
- if (body.type !== ScriptingSourceTreeExp_1.T_BLOCK_STATEMENT && body.type !== ScriptingSourceTreeExp_1.T_EMPTY_STATEMENT) {
599
- this.expectToken(TokenType_1.TokenType.Semicolon);
600
- }
601
- this.expectToken(TokenType_1.TokenType.While);
602
- this.expectToken(TokenType_1.TokenType.LParent, "W014");
603
- const cond = this.getExpression();
604
- if (!cond)
605
- return null;
606
- const endToken = this._lexer.peek();
607
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
608
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_DO_WHILE_STATEMENT, {
609
- cond,
610
- body,
611
- }, startToken, endToken);
612
- }
613
- /**
614
- * Parses an expression statement
615
- *
616
- * returnStatement
617
- * : "return" expression?
618
- * ;
619
- */
620
- parseReturnStatement() {
621
- const startToken = this._lexer.peek();
622
- let endToken = this._lexer.get();
623
- let expr;
624
- if (TokenTrait_1.tokenTraits[this._lexer.peek().type].expressionStart) {
625
- expr = this.getExpression();
626
- if (expr === null)
627
- return null;
628
- endToken = expr.endToken;
629
- }
630
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_RETURN_STATEMENT, {
631
- expr,
632
- }, startToken, endToken);
633
- }
634
- /**
635
- * forStatement
636
- * : "for" "(" initStatement? ";" expression? ";" expression? ")" statement
637
- * | forInOfStatement
638
- * ;
639
- */
640
- parseForStatement() {
641
- const startToken = this._lexer.peek();
642
- this._lexer.get();
643
- this.expectToken(TokenType_1.TokenType.LParent, "W014");
644
- // --- Check for..in and for..of
645
- let nextToken = this._lexer.peek();
646
- if (nextToken.type === TokenType_1.TokenType.Identifier) {
647
- if (this._lexer.ahead(1).type === TokenType_1.TokenType.In) {
648
- return this.parseForInOfStatement(startToken, "none", nextToken, ScriptingSourceTreeExp_1.T_FOR_IN_STATEMENT);
649
- }
650
- else if (this._lexer.ahead(1).type === TokenType_1.TokenType.Of) {
651
- return this.parseForInOfStatement(startToken, "none", nextToken, ScriptingSourceTreeExp_1.T_FOR_OF_STATEMENT);
652
- }
653
- }
654
- else if (nextToken.type === TokenType_1.TokenType.Let) {
655
- const idToken = this._lexer.ahead(1);
656
- if (idToken.type === TokenType_1.TokenType.Identifier) {
657
- const inOfToken = this._lexer.ahead(2);
658
- if (inOfToken.type === TokenType_1.TokenType.In) {
659
- return this.parseForInOfStatement(startToken, "let", idToken, ScriptingSourceTreeExp_1.T_FOR_IN_STATEMENT);
660
- }
661
- else if (inOfToken.type === TokenType_1.TokenType.Of) {
662
- return this.parseForInOfStatement(startToken, "let", idToken, ScriptingSourceTreeExp_1.T_FOR_OF_STATEMENT);
663
- }
664
- }
665
- }
666
- else if (nextToken.type === TokenType_1.TokenType.Const) {
667
- const idToken = this._lexer.ahead(1);
668
- if (idToken.type === TokenType_1.TokenType.Identifier) {
669
- const inOfToken = this._lexer.ahead(2);
670
- if (inOfToken.type === TokenType_1.TokenType.In) {
671
- return this.parseForInOfStatement(startToken, "const", idToken, ScriptingSourceTreeExp_1.T_FOR_IN_STATEMENT);
672
- }
673
- else if (inOfToken.type === TokenType_1.TokenType.Of) {
674
- return this.parseForInOfStatement(startToken, "const", idToken, ScriptingSourceTreeExp_1.T_FOR_OF_STATEMENT);
675
- }
676
- }
677
- }
678
- // --- We accept only let statement, empty statement, and expression
679
- let init;
680
- nextToken = this._lexer.peek();
681
- if (nextToken.type === TokenType_1.TokenType.Semicolon) {
682
- // --- Empty statement: no init in the for loop
683
- this._lexer.get();
684
- }
685
- else if (nextToken.type === TokenType_1.TokenType.Let) {
686
- // --- Let statement
687
- const letStmt = this.parseLetStatement();
688
- if (letStmt === null) {
689
- return null;
690
- }
691
- init = letStmt;
692
- if (init.decls.some((d) => !d.expr)) {
693
- this.reportError("W011");
694
- return null;
695
- }
696
- this.expectToken(TokenType_1.TokenType.Semicolon);
697
- }
698
- else if (TokenTrait_1.tokenTraits[nextToken.type].expressionStart) {
699
- // --- Expression statement
700
- const exprStmt = this.parseExpressionStatement();
701
- if (exprStmt === null) {
702
- return null;
703
- }
704
- init = exprStmt;
705
- this.expectToken(TokenType_1.TokenType.Semicolon);
706
- }
707
- // --- Parse the condition
708
- let cond;
709
- nextToken = this._lexer.peek();
710
- if (nextToken.type === TokenType_1.TokenType.Semicolon) {
711
- // --- No condition
712
- this._lexer.get();
713
- }
714
- else {
715
- cond = this.getExpression();
716
- if (cond === null) {
717
- return null;
718
- }
719
- this.expectToken(TokenType_1.TokenType.Semicolon);
720
- }
721
- // --- Parse the update expression
722
- let upd;
723
- nextToken = this._lexer.peek();
724
- if (nextToken.type !== TokenType_1.TokenType.RParent) {
725
- upd = this.getExpression();
726
- if (upd === null) {
727
- return null;
728
- }
729
- }
730
- // --- Close the declaration part
731
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
732
- // --- Get the body
733
- const body = this.parseStatement();
734
- if (!body)
735
- return null;
736
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_FOR_STATEMENT, {
737
- init,
738
- cond,
739
- upd,
740
- body,
741
- }, startToken, body.endToken);
742
- }
743
- /**
744
- * forInOfStatement
745
- * : "for" "(" [ "let" | "const" ] identifier ( "in" | "of" ) expression? ")" statement
746
- * | forInOfStatement
747
- * ;
748
- *
749
- * @param startToken Statement start token
750
- * @param varB Variable binding of the for..in/of statement
751
- * @param id ID name
752
- * @param type Is it a for..in or a for..of?
753
- */
754
- parseForInOfStatement(startToken, varB, idToken, type) {
755
- if (varB !== "none") {
756
- // --- Skip variable binding type
757
- if (idToken.text.startsWith("$")) {
758
- this.reportError("W031");
759
- return null;
760
- }
761
- this._lexer.get();
762
- }
763
- // --- Skip variable name, in/of token
764
- this._lexer.get();
765
- this._lexer.get();
766
- // --- Get the expression
767
- const expr = this.getExpression(true);
768
- // --- Close the declaration part
769
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
770
- // --- Get the body
771
- const body = this.parseStatement();
772
- if (!body)
773
- return null;
774
- return type === ScriptingSourceTreeExp_1.T_FOR_IN_STATEMENT
775
- ? this.createStatementNode(ScriptingSourceTreeExp_1.T_FOR_IN_STATEMENT, {
776
- varB,
777
- id: {
778
- type: ScriptingSourceTreeExp_1.T_IDENTIFIER,
779
- name: idToken.text,
780
- startToken: idToken,
781
- endToken: idToken,
782
- },
783
- expr,
784
- body,
785
- }, startToken, body.endToken)
786
- : this.createStatementNode(ScriptingSourceTreeExp_1.T_FOR_OF_STATEMENT, {
787
- varB,
788
- id: {
789
- type: ScriptingSourceTreeExp_1.T_IDENTIFIER,
790
- name: idToken.text,
791
- startToken: idToken,
792
- endToken: idToken,
793
- },
794
- expr,
795
- body,
796
- }, startToken, body.endToken);
797
- }
798
- /**
799
- * Parses a throw statement
800
- *
801
- * throwStatement
802
- * : "throw" expression
803
- * ;
804
- */
805
- parseThrowStatement() {
806
- const startToken = this._lexer.peek();
807
- this._lexer.get();
808
- let expr;
809
- expr = this.getExpression();
810
- if (expr === null)
811
- return null;
812
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_THROW_STATEMENT, {
813
- expr,
814
- }, startToken, expr.endToken);
815
- }
816
- /**
817
- * Parses a try..catch..finally statement
818
- *
819
- * tryStatement
820
- * : "try" blockStatement catchClause finallyClause?
821
- * | "try" blockStatement catchClause? finallyClause
822
- * ;
823
- *
824
- * catchClause
825
- * : "catch" [ "(" identifier ") ]? blockStatement
826
- * ;
827
- *
828
- * finallyClause
829
- * : "finally" blockStatement
830
- */
831
- parseTryStatement() {
832
- const startToken = this._lexer.peek();
833
- let endToken = this._lexer.get();
834
- const parser = this;
835
- // --- Get "try" block
836
- const tryB = getBlock();
837
- let catchB;
838
- let catchV;
839
- let finallyB;
840
- let nextToken = this._lexer.peek();
841
- if (nextToken.type === TokenType_1.TokenType.Catch) {
842
- // --- Catch found
843
- this._lexer.get();
844
- nextToken = this._lexer.peek();
845
- if (nextToken.type === TokenType_1.TokenType.LParent) {
846
- // --- Catch variable found
847
- this._lexer.get();
848
- nextToken = this._lexer.peek();
849
- if (nextToken.type !== TokenType_1.TokenType.Identifier) {
850
- this.reportError("W003", nextToken);
851
- return null;
852
- }
853
- catchV = {
854
- type: ScriptingSourceTreeExp_1.T_IDENTIFIER,
855
- nodeId: createXmlUiTreeNodeId(),
856
- name: nextToken.text,
857
- startToken: nextToken,
858
- endToken: nextToken,
859
- };
860
- this._lexer.get();
861
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
862
- }
863
- // --- Get catch block
864
- catchB = getBlock();
865
- endToken = catchB.endToken;
866
- if (this._lexer.peek().type === TokenType_1.TokenType.Finally) {
867
- // --- Finally after catch
868
- this._lexer.get();
869
- finallyB = getBlock();
870
- endToken = finallyB.endToken;
871
- }
872
- }
873
- else if (nextToken.type === TokenType_1.TokenType.Finally) {
874
- // --- Finally found
875
- this._lexer.get();
876
- finallyB = getBlock();
877
- endToken = finallyB.endToken;
878
- }
879
- else {
880
- this.reportError("W013", nextToken);
881
- return null;
882
- }
883
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_TRY_STATEMENT, {
884
- tryB,
885
- catchB,
886
- catchV,
887
- finallyB,
888
- }, startToken, endToken);
889
- function getBlock() {
890
- const nextToken = parser._lexer.peek();
891
- if (nextToken.type !== TokenType_1.TokenType.LBrace) {
892
- parser.reportError("W012", nextToken);
893
- return null;
894
- }
895
- return parser.parseBlockStatement();
896
- }
897
- }
898
- /**
899
- * Parses a switch statement
900
- *
901
- * switchStatement
902
- * : "switch" "(" expression ")" "{" caseClauses "}"
903
- * ;
904
- *
905
- * caseClauses
906
- * : "case" expression ":" statement*
907
- * | "default" ":" statement*
908
- * ;
909
- */
910
- parseSwitchStatement() {
911
- const startToken = this._lexer.get();
912
- // --- Parse the switch expression
913
- this.expectToken(TokenType_1.TokenType.LParent, "W014");
914
- const expr = this.getExpression();
915
- if (!expr)
916
- return null;
917
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
918
- // --- Parse the case blocks
919
- this.expectToken(TokenType_1.TokenType.LBrace, "W012");
920
- const cases = [];
921
- let defaultCaseFound = false;
922
- while (true) {
923
- let nextToken = this._lexer.peek();
924
- let caseE;
925
- if (nextToken.type === TokenType_1.TokenType.Case) {
926
- // --- Process "case"
927
- this._lexer.get();
928
- caseE = this.getExpression();
929
- if (!caseE)
930
- return null;
931
- }
932
- else if (nextToken.type === TokenType_1.TokenType.Default) {
933
- // --- Process "default"
934
- if (defaultCaseFound) {
935
- this.reportError("W016");
936
- return null;
937
- }
938
- defaultCaseFound = true;
939
- this._lexer.get();
940
- }
941
- else if (nextToken.type === TokenType_1.TokenType.RBrace) {
942
- break;
943
- }
944
- else {
945
- this.reportError("W015");
946
- return null;
947
- }
948
- // --- Process label statements
949
- this.expectToken(TokenType_1.TokenType.Colon, "W008");
950
- let stmts = [];
951
- let collected = false;
952
- while (!collected) {
953
- const stmtToken = this._lexer.peek();
954
- switch (stmtToken.type) {
955
- case TokenType_1.TokenType.Case:
956
- case TokenType_1.TokenType.Default:
957
- case TokenType_1.TokenType.RBrace:
958
- // --- No more case to process
959
- collected = true;
960
- break;
961
- default:
962
- // --- Try to get the next statement
963
- const stmt = this.parseStatement();
964
- if (stmt === null) {
965
- collected = true;
966
- break;
967
- }
968
- stmts.push(stmt);
969
- if (stmt.type !== ScriptingSourceTreeExp_1.T_EMPTY_STATEMENT) {
970
- this.skipToken(TokenType_1.TokenType.Semicolon);
971
- }
972
- }
973
- }
974
- cases.push(this.createNode(ScriptingSourceTreeExp_1.T_SWITCH_CASE, {
975
- caseE,
976
- stmts,
977
- }, startToken));
978
- }
979
- // --- Closing
980
- const endToken = this._lexer.peek();
981
- this.expectToken(TokenType_1.TokenType.RBrace, "W004");
982
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_SWITCH_STATEMENT, {
983
- expr,
984
- cases,
985
- }, startToken, endToken);
986
- }
987
- /**
988
- * Parses a function declaration
989
- *
990
- * functionDeclaration
991
- * : "function" identifier "(" [parameterList] ")" blockStatement
992
- * ;
993
- */
994
- parseFunctionDeclaration(allowNoName = false) {
995
- var _a;
996
- const startToken = this._lexer.get();
997
- // --- Get the function name
998
- let functionName;
999
- const funcId = this._lexer.peek();
1000
- if (allowNoName) {
1001
- if (funcId.type !== TokenType_1.TokenType.LParent) {
1002
- if (funcId.type !== TokenType_1.TokenType.Identifier) {
1003
- this.reportError("W003", funcId);
1004
- return null;
1005
- }
1006
- functionName = funcId.text;
1007
- this._lexer.get();
1008
- }
1009
- }
1010
- else {
1011
- if (funcId.type !== TokenType_1.TokenType.Identifier) {
1012
- this.reportError("W003", funcId);
1013
- return null;
1014
- }
1015
- functionName = funcId.text;
1016
- this._lexer.get();
1017
- }
1018
- // --- Get the parameter list;
1019
- const nextToken = this._lexer.peek();
1020
- if (nextToken.type !== TokenType_1.TokenType.LParent) {
1021
- this.reportError("W014", nextToken);
1022
- return null;
1023
- }
1024
- // --- Now, get the parameter list as an expression
1025
- const exprList = this.getExpression(true);
1026
- // --- We turn the expression into a parameter list
1027
- let isValid;
1028
- const args = [];
1029
- switch (exprList.type) {
1030
- case ScriptingSourceTreeExp_1.T_NO_ARG_EXPRESSION:
1031
- isValid = true;
1032
- break;
1033
- case ScriptingSourceTreeExp_1.T_IDENTIFIER:
1034
- isValid = ((_a = exprList.parenthesized) !== null && _a !== void 0 ? _a : 0) <= 1;
1035
- args.push(exprList);
1036
- break;
1037
- case ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION:
1038
- isValid = exprList.parenthesized === 1;
1039
- let spreadFound = false;
1040
- if (isValid) {
1041
- for (const expr of exprList.exprs) {
1042
- // --- Spread operator can be used only in the last position
1043
- if (spreadFound) {
1044
- isValid = false;
1045
- break;
1046
- }
1047
- switch (expr.type) {
1048
- case ScriptingSourceTreeExp_1.T_IDENTIFIER:
1049
- isValid = !expr.parenthesized;
1050
- args.push(expr);
1051
- break;
1052
- case ScriptingSourceTreeExp_1.T_OBJECT_LITERAL: {
1053
- isValid = !expr.parenthesized;
1054
- if (isValid) {
1055
- const des = this.convertToObjectDestructure(expr);
1056
- if (des)
1057
- args.push(des);
1058
- }
1059
- break;
1060
- }
1061
- case ScriptingSourceTreeExp_1.T_ARRAY_LITERAL: {
1062
- isValid = !expr.parenthesized;
1063
- if (isValid) {
1064
- const des = this.convertToArrayDestructure(expr);
1065
- if (des)
1066
- args.push(des);
1067
- }
1068
- break;
1069
- }
1070
- case ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION: {
1071
- spreadFound = true;
1072
- if (expr.expr.type !== ScriptingSourceTreeExp_1.T_IDENTIFIER) {
1073
- isValid = false;
1074
- break;
1075
- }
1076
- args.push(expr);
1077
- break;
1078
- }
1079
- default:
1080
- isValid = false;
1081
- break;
1082
- }
1083
- }
1084
- }
1085
- break;
1086
- case ScriptingSourceTreeExp_1.T_OBJECT_LITERAL:
1087
- isValid = exprList.parenthesized === 1;
1088
- if (isValid) {
1089
- const des = this.convertToObjectDestructure(exprList);
1090
- if (des)
1091
- args.push(des);
1092
- }
1093
- break;
1094
- case ScriptingSourceTreeExp_1.T_ARRAY_LITERAL:
1095
- isValid = exprList.parenthesized === 1;
1096
- if (isValid) {
1097
- const des = this.convertToArrayDestructure(exprList);
1098
- if (des)
1099
- args.push(des);
1100
- }
1101
- break;
1102
- case ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION:
1103
- if (exprList.expr.type !== ScriptingSourceTreeExp_1.T_IDENTIFIER) {
1104
- isValid = false;
1105
- break;
1106
- }
1107
- isValid = true;
1108
- args.push(exprList);
1109
- break;
1110
- default:
1111
- isValid = false;
1112
- }
1113
- if (!isValid) {
1114
- this.reportError("W010", startToken);
1115
- return null;
1116
- }
1117
- // --- Get the function body (statement block)
1118
- if (this._lexer.peek().type !== TokenType_1.TokenType.LBrace) {
1119
- this.reportError("W012", this._lexer.peek());
1120
- return null;
1121
- }
1122
- const stmt = this.parseBlockStatement();
1123
- if (!stmt)
1124
- return null;
1125
- // --- Done.
1126
- return this.createStatementNode(ScriptingSourceTreeExp_1.T_FUNCTION_DECLARATION, {
1127
- id: { type: ScriptingSourceTreeExp_1.T_IDENTIFIER, name: functionName },
1128
- args,
1129
- stmt,
1130
- }, startToken, stmt.endToken);
1131
- }
1132
- // ==========================================================================
1133
- // Expression parsing
1134
- /**
1135
- * Parses an expression:
1136
- *
1137
- * expr
1138
- * : sequenceExpr
1139
- * ;
1140
- */
1141
- parseExpr(allowSequence = true) {
1142
- return allowSequence
1143
- ? this.parseSequenceExpression()
1144
- : this.parseCondOrSpreadOrAsgnOrArrowExpr();
1145
- }
1146
- /**
1147
- * sequenceExpr
1148
- * : conditionalExpr ( "," conditionalExpr )?
1149
- */
1150
- parseSequenceExpression() {
1151
- const start = this._lexer.peek();
1152
- let endToken = start;
1153
- let leftExpr = this.parseCondOrSpreadOrAsgnOrArrowExpr();
1154
- if (!leftExpr) {
1155
- return null;
1156
- }
1157
- endToken = leftExpr.endToken;
1158
- const exprs = [];
1159
- let loose = false;
1160
- if (this._lexer.peek().type === TokenType_1.TokenType.Comma) {
1161
- exprs.push(leftExpr);
1162
- while (this.skipToken(TokenType_1.TokenType.Comma)) {
1163
- if (this._lexer.peek().type === TokenType_1.TokenType.Comma) {
1164
- loose = true;
1165
- endToken = this._lexer.peek();
1166
- exprs.push(this.createExpressionNode(ScriptingSourceTreeExp_1.T_NO_ARG_EXPRESSION, {}, endToken, endToken));
1167
- }
1168
- else {
1169
- const nextExpr = this.parseCondOrSpreadOrAsgnOrArrowExpr();
1170
- if (!nextExpr) {
1171
- break;
1172
- }
1173
- endToken = nextExpr.endToken;
1174
- exprs.push(nextExpr);
1175
- }
1176
- }
1177
- }
1178
- if (!exprs.length) {
1179
- // --- No sequence
1180
- return leftExpr;
1181
- }
1182
- // --- Create the sequence expression
1183
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION, {
1184
- exprs,
1185
- loose,
1186
- }, start, endToken);
1187
- // --- Check for "loose" sequence expression
1188
- if (loose) {
1189
- leftExpr = this.convertToArrayDestructure(leftExpr);
1190
- }
1191
- // --- Done.
1192
- return leftExpr;
1193
- }
1194
- /**
1195
- * conditionalOrSpreadOrAsgnOrArrowExpr
1196
- * : nullCoalescingExpr ( "?" expr ":" expr )?
1197
- * | "..." nullCoalescingExpr
1198
- * | identifier "=" expr
1199
- * ;
1200
- */
1201
- parseCondOrSpreadOrAsgnOrArrowExpr() {
1202
- const startToken = this._lexer.peek();
1203
- if (startToken.type === TokenType_1.TokenType.Spread) {
1204
- // --- Spread expression
1205
- this._lexer.get();
1206
- const spreadOperand = this.parseNullCoalescingExpr();
1207
- return spreadOperand
1208
- ? this.createExpressionNode(ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION, {
1209
- expr: spreadOperand,
1210
- }, startToken, spreadOperand.endToken)
1211
- : null;
1212
- }
1213
- if (startToken.type === TokenType_1.TokenType.Function) {
1214
- const funcDecl = this.parseFunctionDeclaration(true);
1215
- return funcDecl
1216
- ? this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARROW_EXPRESSION, {
1217
- name: funcDecl.id.name,
1218
- args: funcDecl.args,
1219
- statement: funcDecl.stmt,
1220
- }, startToken, funcDecl.endToken)
1221
- : null;
1222
- }
1223
- const otherExpr = this.parseNullCoalescingExpr();
1224
- if (!otherExpr) {
1225
- return null;
1226
- }
1227
- const nextToken = this._lexer.peek();
1228
- if (nextToken.type === TokenType_1.TokenType.Arrow) {
1229
- // --- It is an arrow expression
1230
- return this.parseArrowExpression(startToken, otherExpr);
1231
- }
1232
- if (nextToken.type === TokenType_1.TokenType.QuestionMark) {
1233
- this._lexer.get();
1234
- // --- Conditional expression
1235
- const trueExpr = this.getExpression(false);
1236
- this.expectToken(TokenType_1.TokenType.Colon);
1237
- const falseExpr = this.getExpression(false);
1238
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_CONDITIONAL_EXPRESSION, {
1239
- cond: otherExpr,
1240
- thenE: trueExpr,
1241
- elseE: falseExpr,
1242
- }, startToken, falseExpr.endToken);
1243
- }
1244
- if (TokenTrait_1.tokenTraits[nextToken.type].isAssignment) {
1245
- // --- Assignment
1246
- this._lexer.get();
1247
- const expr = this.getExpression();
1248
- return expr
1249
- ? this.createExpressionNode(ScriptingSourceTreeExp_1.T_ASSIGNMENT_EXPRESSION, {
1250
- leftValue: otherExpr,
1251
- op: nextToken.text,
1252
- expr,
1253
- }, startToken, expr.endToken)
1254
- : null;
1255
- }
1256
- return otherExpr;
1257
- }
1258
- /**
1259
- * Parses an arrow expression
1260
- * @param start Start token
1261
- * @param left Expression to the left from the arrow
1262
- */
1263
- parseArrowExpression(start, left) {
1264
- var _a;
1265
- // --- Check the left expression
1266
- let isValid;
1267
- const args = [];
1268
- switch (left.type) {
1269
- case ScriptingSourceTreeExp_1.T_NO_ARG_EXPRESSION:
1270
- isValid = true;
1271
- break;
1272
- case ScriptingSourceTreeExp_1.T_IDENTIFIER:
1273
- isValid = ((_a = left.parenthesized) !== null && _a !== void 0 ? _a : 0) <= 1;
1274
- args.push(left);
1275
- break;
1276
- case ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION:
1277
- isValid = left.parenthesized === 1;
1278
- let spreadFound = false;
1279
- if (isValid) {
1280
- for (const expr of left.exprs) {
1281
- if (spreadFound) {
1282
- isValid = false;
1283
- break;
1284
- }
1285
- switch (expr.type) {
1286
- case ScriptingSourceTreeExp_1.T_IDENTIFIER:
1287
- isValid = !expr.parenthesized;
1288
- args.push(expr);
1289
- break;
1290
- case ScriptingSourceTreeExp_1.T_OBJECT_LITERAL: {
1291
- isValid = !expr.parenthesized;
1292
- if (isValid) {
1293
- const des = this.convertToObjectDestructure(expr);
1294
- if (des)
1295
- args.push(des);
1296
- }
1297
- break;
1298
- }
1299
- case ScriptingSourceTreeExp_1.T_ARRAY_LITERAL: {
1300
- isValid = !expr.parenthesized;
1301
- if (isValid) {
1302
- const des = this.convertToArrayDestructure(expr);
1303
- if (des)
1304
- args.push(des);
1305
- }
1306
- break;
1307
- }
1308
- case ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION: {
1309
- spreadFound = true;
1310
- if (expr.expr.type !== ScriptingSourceTreeExp_1.T_IDENTIFIER) {
1311
- isValid = false;
1312
- break;
1313
- }
1314
- args.push(expr);
1315
- break;
1316
- }
1317
- default:
1318
- isValid = false;
1319
- break;
1320
- }
1321
- }
1322
- }
1323
- break;
1324
- case ScriptingSourceTreeExp_1.T_OBJECT_LITERAL:
1325
- isValid = left.parenthesized === 1;
1326
- if (isValid) {
1327
- const des = this.convertToObjectDestructure(left);
1328
- if (des)
1329
- args.push(des);
1330
- }
1331
- break;
1332
- case ScriptingSourceTreeExp_1.T_ARRAY_LITERAL:
1333
- isValid = left.parenthesized === 1;
1334
- if (isValid) {
1335
- const des = this.convertToArrayDestructure(left);
1336
- if (des)
1337
- args.push(des);
1338
- }
1339
- break;
1340
- case ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION:
1341
- isValid = left.expr.type === ScriptingSourceTreeExp_1.T_IDENTIFIER;
1342
- if (isValid) {
1343
- args.push(left);
1344
- }
1345
- break;
1346
- default:
1347
- isValid = false;
1348
- }
1349
- if (!isValid) {
1350
- this.reportError("W010", start);
1351
- return null;
1352
- }
1353
- // --- Skip the arrow token
1354
- this._lexer.get();
1355
- // --- Get arrow expression statements
1356
- const statement = this.parseStatement(false);
1357
- return statement
1358
- ? this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARROW_EXPRESSION, {
1359
- args,
1360
- statement,
1361
- }, start, statement.endToken)
1362
- : null;
1363
- }
1364
- /**
1365
- * nullCoalescingExpr
1366
- * : logicalOrExpr ( "??" logicalOrExpr )?
1367
- * ;
1368
- */
1369
- parseNullCoalescingExpr() {
1370
- const startToken = this._lexer.peek();
1371
- let leftExpr = this.parseLogicalOrExpr();
1372
- if (!leftExpr) {
1373
- return null;
1374
- }
1375
- while (this.skipToken(TokenType_1.TokenType.NullCoalesce)) {
1376
- const rightExpr = this.parseLogicalOrExpr();
1377
- if (!rightExpr) {
1378
- this.reportError("W001");
1379
- return null;
1380
- }
1381
- let endToken = rightExpr.endToken;
1382
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1383
- op: "??",
1384
- left: leftExpr,
1385
- right: rightExpr,
1386
- }, startToken, endToken);
1387
- }
1388
- return leftExpr;
1389
- }
1390
- /**
1391
- * logicalOrExpr
1392
- * : logicalAndExpr ( "||" logicalAndExpr )?
1393
- * ;
1394
- */
1395
- parseLogicalOrExpr() {
1396
- const startToken = this._lexer.peek();
1397
- let leftExpr = this.parseLogicalAndExpr();
1398
- if (!leftExpr) {
1399
- return null;
1400
- }
1401
- while (this.skipToken(TokenType_1.TokenType.LogicalOr)) {
1402
- const rightExpr = this.parseLogicalAndExpr();
1403
- if (!rightExpr) {
1404
- this.reportError("W001");
1405
- return null;
1406
- }
1407
- let endToken = rightExpr.endToken;
1408
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1409
- op: "||",
1410
- left: leftExpr,
1411
- right: rightExpr,
1412
- }, startToken, endToken);
1413
- }
1414
- return leftExpr;
1415
- }
1416
- /**
1417
- * logicalAndExpr
1418
- * : bitwiseOrExpr ( "&&" bitwiseOrExpr )?
1419
- * ;
1420
- */
1421
- parseLogicalAndExpr() {
1422
- const startToken = this._lexer.peek();
1423
- let leftExpr = this.parseBitwiseOrExpr();
1424
- if (!leftExpr) {
1425
- return null;
1426
- }
1427
- while (this.skipToken(TokenType_1.TokenType.LogicalAnd)) {
1428
- const rightExpr = this.parseBitwiseOrExpr();
1429
- if (!rightExpr) {
1430
- this.reportError("W001");
1431
- return null;
1432
- }
1433
- let endToken = rightExpr.endToken;
1434
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1435
- op: "&&",
1436
- left: leftExpr,
1437
- right: rightExpr,
1438
- }, startToken, endToken);
1439
- }
1440
- return leftExpr;
1441
- }
1442
- /**
1443
- * bitwiseOrExpr
1444
- * : bitwiseXorExpr ( "|" bitwiseXorExpr )?
1445
- * ;
1446
- */
1447
- parseBitwiseOrExpr() {
1448
- const startToken = this._lexer.peek();
1449
- let leftExpr = this.parseBitwiseXorExpr();
1450
- if (!leftExpr) {
1451
- return null;
1452
- }
1453
- while (this.skipToken(TokenType_1.TokenType.BitwiseOr)) {
1454
- const rightExpr = this.parseBitwiseXorExpr();
1455
- if (!rightExpr) {
1456
- this.reportError("W001");
1457
- return null;
1458
- }
1459
- let endToken = rightExpr.endToken;
1460
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1461
- op: "|",
1462
- left: leftExpr,
1463
- right: rightExpr,
1464
- }, startToken, endToken);
1465
- }
1466
- return leftExpr;
1467
- }
1468
- /**
1469
- * bitwiseXorExpr
1470
- * : bitwiseAndExpr ( "^" bitwiseAndExpr )?
1471
- * ;
1472
- */
1473
- parseBitwiseXorExpr() {
1474
- const startToken = this._lexer.peek();
1475
- let leftExpr = this.parseBitwiseAndExpr();
1476
- if (!leftExpr) {
1477
- return null;
1478
- }
1479
- while (this.skipToken(TokenType_1.TokenType.BitwiseXor)) {
1480
- const rightExpr = this.parseBitwiseAndExpr();
1481
- if (!rightExpr) {
1482
- this.reportError("W001");
1483
- return null;
1484
- }
1485
- let endToken = rightExpr.endToken;
1486
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1487
- op: "^",
1488
- left: leftExpr,
1489
- right: rightExpr,
1490
- }, startToken, endToken);
1491
- }
1492
- return leftExpr;
1493
- }
1494
- /**
1495
- * bitwiseAndExpr
1496
- * : equExpr ( "&" equExpr )?
1497
- * ;
1498
- */
1499
- parseBitwiseAndExpr() {
1500
- const startToken = this._lexer.peek();
1501
- let leftExpr = this.parseEquExpr();
1502
- if (!leftExpr) {
1503
- return null;
1504
- }
1505
- while (this.skipToken(TokenType_1.TokenType.BitwiseAnd)) {
1506
- const rightExpr = this.parseEquExpr();
1507
- if (!rightExpr) {
1508
- this.reportError("W001");
1509
- return null;
1510
- }
1511
- let endToken = rightExpr.endToken;
1512
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1513
- op: "&",
1514
- left: leftExpr,
1515
- right: rightExpr,
1516
- }, startToken, endToken);
1517
- }
1518
- return leftExpr;
1519
- }
1520
- /**
1521
- * equExpr
1522
- * : relOrInExpr ( ( "==" | "!=" | "===" | "!==" ) relOrInExpr )?
1523
- * ;
1524
- */
1525
- parseEquExpr() {
1526
- const startToken = this._lexer.peek();
1527
- let leftExpr = this.parseRelOrInExpr();
1528
- if (!leftExpr) {
1529
- return null;
1530
- }
1531
- let opType;
1532
- while ((opType = this.skipTokens(TokenType_1.TokenType.Equal, TokenType_1.TokenType.StrictEqual, TokenType_1.TokenType.NotEqual, TokenType_1.TokenType.StrictNotEqual))) {
1533
- const rightExpr = this.parseRelOrInExpr();
1534
- if (!rightExpr) {
1535
- this.reportError("W001");
1536
- return null;
1537
- }
1538
- let endToken = rightExpr.endToken;
1539
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1540
- op: opType.text,
1541
- left: leftExpr,
1542
- right: rightExpr,
1543
- }, startToken, endToken);
1544
- }
1545
- return leftExpr;
1546
- }
1547
- /**
1548
- * relOrInExpr
1549
- * : shiftExpr ( ( "<" | "<=" | ">" | ">=", "in" ) shiftExpr )?
1550
- * ;
1551
- */
1552
- parseRelOrInExpr() {
1553
- const startToken = this._lexer.peek();
1554
- let leftExpr = this.parseShiftExpr();
1555
- if (!leftExpr) {
1556
- return null;
1557
- }
1558
- let opType;
1559
- while ((opType = this.skipTokens(TokenType_1.TokenType.LessThan, TokenType_1.TokenType.LessThanOrEqual, TokenType_1.TokenType.GreaterThan, TokenType_1.TokenType.GreaterThanOrEqual, TokenType_1.TokenType.In))) {
1560
- const rightExpr = this.parseShiftExpr();
1561
- if (!rightExpr) {
1562
- this.reportError("W001");
1563
- return null;
1564
- }
1565
- let endToken = rightExpr.endToken;
1566
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1567
- op: opType.text,
1568
- left: leftExpr,
1569
- right: rightExpr,
1570
- }, startToken, endToken);
1571
- }
1572
- return leftExpr;
1573
- }
1574
- /**
1575
- * shiftExpr
1576
- * : addExpr ( ( "<<" | ">>" | ">>>" ) addExpr )?
1577
- * ;
1578
- */
1579
- parseShiftExpr() {
1580
- const startToken = this._lexer.peek();
1581
- let leftExpr = this.parseAddExpr();
1582
- if (!leftExpr) {
1583
- return null;
1584
- }
1585
- let opType;
1586
- while ((opType = this.skipTokens(TokenType_1.TokenType.ShiftLeft, TokenType_1.TokenType.ShiftRight, TokenType_1.TokenType.SignedShiftRight))) {
1587
- const rightExpr = this.parseAddExpr();
1588
- if (!rightExpr) {
1589
- this.reportError("W001");
1590
- return null;
1591
- }
1592
- let endToken = rightExpr.endToken;
1593
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1594
- op: opType.text,
1595
- left: leftExpr,
1596
- right: rightExpr,
1597
- }, startToken, endToken);
1598
- }
1599
- return leftExpr;
1600
- }
1601
- /**
1602
- * addExpr
1603
- * : multExpr ( ( "+" | "-" ) multExpr )?
1604
- * ;
1605
- */
1606
- parseAddExpr() {
1607
- const startToken = this._lexer.peek();
1608
- let leftExpr = this.parseMultExpr();
1609
- if (!leftExpr) {
1610
- return null;
1611
- }
1612
- let opType;
1613
- while ((opType = this.skipTokens(TokenType_1.TokenType.Plus, TokenType_1.TokenType.Minus))) {
1614
- const rightExpr = this.parseMultExpr();
1615
- if (!rightExpr) {
1616
- this.reportError("W001");
1617
- return null;
1618
- }
1619
- let endToken = rightExpr.endToken;
1620
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1621
- op: opType.text,
1622
- left: leftExpr,
1623
- right: rightExpr,
1624
- }, startToken, endToken);
1625
- }
1626
- return leftExpr;
1627
- }
1628
- /**
1629
- * multExpr
1630
- * : exponentialExpr ( ( "*" | "/" | "%") exponentialExpr )?
1631
- * ;
1632
- */
1633
- parseMultExpr() {
1634
- const startToken = this._lexer.peek();
1635
- let leftExpr = this.parseExponentialExpr();
1636
- if (!leftExpr) {
1637
- return null;
1638
- }
1639
- let opType;
1640
- while ((opType = this.skipTokens(TokenType_1.TokenType.Multiply, TokenType_1.TokenType.Divide, TokenType_1.TokenType.Remainder))) {
1641
- const rightExpr = this.parseExponentialExpr();
1642
- if (!rightExpr) {
1643
- this.reportError("W001");
1644
- return null;
1645
- }
1646
- let endToken = rightExpr.endToken;
1647
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1648
- op: opType.text,
1649
- left: leftExpr,
1650
- right: rightExpr,
1651
- }, startToken, endToken);
1652
- }
1653
- return leftExpr;
1654
- }
1655
- /**
1656
- * exponentialExpr
1657
- * : unaryExpr ( "**" unaryExpr )?
1658
- * ;
1659
- */
1660
- parseExponentialExpr() {
1661
- const startToken = this._lexer.peek();
1662
- let leftExpr = this.parseUnaryOrPrefixExpr();
1663
- if (!leftExpr) {
1664
- return null;
1665
- }
1666
- let opType;
1667
- let count = 0;
1668
- while ((opType = this.skipToken(TokenType_1.TokenType.Exponent))) {
1669
- let rightExpr = this.parseUnaryOrPrefixExpr();
1670
- if (!rightExpr) {
1671
- this.reportError("W001");
1672
- return null;
1673
- }
1674
- let endToken = rightExpr.endToken;
1675
- if (count === 0) {
1676
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1677
- op: opType.text,
1678
- left: leftExpr,
1679
- right: rightExpr,
1680
- }, startToken, endToken);
1681
- }
1682
- else {
1683
- const prevLeft = leftExpr;
1684
- leftExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION, {
1685
- op: opType.text,
1686
- left: prevLeft.left,
1687
- right: {
1688
- type: ScriptingSourceTreeExp_1.T_BINARY_EXPRESSION,
1689
- op: opType.text,
1690
- left: prevLeft.right,
1691
- right: rightExpr,
1692
- },
1693
- }, startToken, endToken);
1694
- }
1695
- count++;
1696
- }
1697
- return leftExpr;
1698
- }
1699
- /**
1700
- * unaryExpr
1701
- * : ( "typeof" | "delete" | "+" | "-" | "~" | "!" ) memberOrInvocationExpr
1702
- * | memberOrInvocationExpr
1703
- * ;
1704
- */
1705
- parseUnaryOrPrefixExpr() {
1706
- const startToken = this._lexer.peek();
1707
- if (TokenTrait_1.tokenTraits[startToken.type].canBeUnary) {
1708
- this._lexer.get();
1709
- const unaryOperand = this.parseUnaryOrPrefixExpr();
1710
- if (!unaryOperand) {
1711
- return null;
1712
- }
1713
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_UNARY_EXPRESSION, {
1714
- op: startToken.text,
1715
- expr: unaryOperand,
1716
- }, startToken, unaryOperand.endToken);
1717
- }
1718
- if (startToken.type === TokenType_1.TokenType.IncOp || startToken.type === TokenType_1.TokenType.DecOp) {
1719
- this._lexer.get();
1720
- const prefixOperand = this.parseMemberOrInvocationExpr();
1721
- if (!prefixOperand) {
1722
- return null;
1723
- }
1724
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_PREFIX_OP_EXPRESSION, {
1725
- op: startToken.text,
1726
- expr: prefixOperand,
1727
- }, startToken, prefixOperand.endToken);
1728
- }
1729
- // --- Not unary or prefix
1730
- return this.parseMemberOrInvocationExpr();
1731
- }
1732
- /**
1733
- * memberOrInvocationExpr
1734
- * : primaryExpr "(" functionArgs ")"
1735
- * | primaryExpr "." identifier
1736
- * | primaryExpr "?." identifier
1737
- * | primaryExpr "[" expr "]"
1738
- * ;
1739
- */
1740
- parseMemberOrInvocationExpr() {
1741
- const startToken = this._lexer.peek();
1742
- let primary = this.parsePrimaryExpr();
1743
- if (!primary) {
1744
- return null;
1745
- }
1746
- let exitLoop = false;
1747
- do {
1748
- const currentStart = this._lexer.peek();
1749
- switch (currentStart.type) {
1750
- case TokenType_1.TokenType.LParent: {
1751
- this._lexer.get();
1752
- let args = [];
1753
- if (this._lexer.peek().type !== TokenType_1.TokenType.RParent) {
1754
- const expr = this.parseExpr();
1755
- if (!expr) {
1756
- this.reportError("W001");
1757
- return null;
1758
- }
1759
- args = expr.type === ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION ? expr.exprs : [expr];
1760
- }
1761
- const endToken = this._lexer.peek();
1762
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
1763
- primary = this.createExpressionNode(ScriptingSourceTreeExp_1.T_FUNCTION_INVOCATION_EXPRESSION, {
1764
- obj: primary,
1765
- arguments: args,
1766
- }, startToken, endToken);
1767
- break;
1768
- }
1769
- case TokenType_1.TokenType.Dot:
1770
- case TokenType_1.TokenType.OptionalChaining:
1771
- this._lexer.get();
1772
- const member = this._lexer.get();
1773
- const memberTrait = TokenTrait_1.tokenTraits[member.type];
1774
- if (!memberTrait.keywordLike) {
1775
- this.reportError("W003");
1776
- return null;
1777
- }
1778
- primary = this.createExpressionNode(ScriptingSourceTreeExp_1.T_MEMBER_ACCESS_EXPRESSION, {
1779
- obj: primary,
1780
- member: member.text,
1781
- opt: currentStart.type === TokenType_1.TokenType.OptionalChaining,
1782
- }, startToken, member);
1783
- break;
1784
- case TokenType_1.TokenType.LSquare:
1785
- this._lexer.get();
1786
- const memberExpr = this.getExpression();
1787
- if (!memberExpr) {
1788
- return null;
1789
- }
1790
- const endToken = this._lexer.peek();
1791
- this.expectToken(TokenType_1.TokenType.RSquare, "W005");
1792
- primary = this.createExpressionNode(ScriptingSourceTreeExp_1.T_CALCULATED_MEMBER_ACCESS_EXPRESSION, {
1793
- obj: primary,
1794
- member: memberExpr,
1795
- }, startToken, endToken);
1796
- break;
1797
- default:
1798
- exitLoop = true;
1799
- break;
1800
- }
1801
- } while (!exitLoop);
1802
- // --- Check for postfix operators
1803
- const nextToken = this._lexer.peek();
1804
- if (nextToken.type === TokenType_1.TokenType.IncOp || nextToken.type === TokenType_1.TokenType.DecOp) {
1805
- this._lexer.get();
1806
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_POSTFIX_OP_EXPRESSION, {
1807
- op: nextToken.text,
1808
- expr: primary,
1809
- }, startToken, nextToken);
1810
- }
1811
- return primary;
1812
- }
1813
- /**
1814
- * primaryExpr
1815
- * : literal
1816
- * | identifier
1817
- * | "::" identifier
1818
- * | "$item"
1819
- * | "(" expr ")"
1820
- * ;
1821
- */
1822
- parsePrimaryExpr() {
1823
- var _a;
1824
- const start = this._lexer.peek();
1825
- switch (start.type) {
1826
- case TokenType_1.TokenType.LParent:
1827
- // --- Parenthesised or no-arg expression
1828
- this._lexer.get();
1829
- if (this._lexer.peek().type === TokenType_1.TokenType.RParent) {
1830
- // --- No-arg
1831
- const endToken = this._lexer.get();
1832
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_NO_ARG_EXPRESSION, {}, start, endToken);
1833
- }
1834
- // --- Parenthesized
1835
- let parenthesizedExpr = this.parseExpr();
1836
- if (!parenthesizedExpr) {
1837
- return null;
1838
- }
1839
- const endToken = this._lexer.peek();
1840
- this.expectToken(TokenType_1.TokenType.RParent, "W006");
1841
- return Object.assign(Object.assign({}, parenthesizedExpr), { parenthesized: ((_a = parenthesizedExpr.parenthesized) !== null && _a !== void 0 ? _a : 0) + 1, startToken: start, endToken });
1842
- case TokenType_1.TokenType.Identifier: {
1843
- const idToken = this._lexer.get();
1844
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_IDENTIFIER, {
1845
- name: idToken.text,
1846
- }, idToken, idToken);
1847
- }
1848
- case TokenType_1.TokenType.Global: {
1849
- this._lexer.get();
1850
- const idToken = this._lexer.get();
1851
- if (idToken.type !== TokenType_1.TokenType.Identifier) {
1852
- this.reportError("W003");
1853
- return null;
1854
- }
1855
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_IDENTIFIER, {
1856
- name: idToken.text,
1857
- isGlobal: true,
1858
- }, idToken, idToken);
1859
- }
1860
- case TokenType_1.TokenType.Backtick:
1861
- return this.parseTemplateLiteral();
1862
- case TokenType_1.TokenType.False:
1863
- case TokenType_1.TokenType.True:
1864
- this._lexer.get();
1865
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
1866
- value: start.type === TokenType_1.TokenType.True,
1867
- }, start, start);
1868
- case TokenType_1.TokenType.BinaryLiteral:
1869
- this._lexer.get();
1870
- return this.parseBinaryLiteral(start);
1871
- case TokenType_1.TokenType.DecimalLiteral:
1872
- this._lexer.get();
1873
- return this.parseDecimalLiteral(start);
1874
- case TokenType_1.TokenType.HexadecimalLiteral:
1875
- this._lexer.get();
1876
- return this.parseHexadecimalLiteral(start);
1877
- case TokenType_1.TokenType.RealLiteral:
1878
- this._lexer.get();
1879
- return this.parseRealLiteral(start);
1880
- case TokenType_1.TokenType.StringLiteral:
1881
- this._lexer.get();
1882
- return this.parseStringLiteral(start);
1883
- case TokenType_1.TokenType.Infinity:
1884
- this._lexer.get();
1885
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
1886
- value: Infinity,
1887
- }, start, start);
1888
- case TokenType_1.TokenType.NaN:
1889
- this._lexer.get();
1890
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
1891
- value: NaN,
1892
- }, start, start);
1893
- case TokenType_1.TokenType.Null:
1894
- this._lexer.get();
1895
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
1896
- value: null,
1897
- }, start, start);
1898
- case TokenType_1.TokenType.Undefined:
1899
- this._lexer.get();
1900
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
1901
- value: undefined,
1902
- }, start, start);
1903
- case TokenType_1.TokenType.LSquare:
1904
- return this.parseArrayLiteral();
1905
- case TokenType_1.TokenType.LBrace:
1906
- return this.parseObjectLiteral();
1907
- case TokenType_1.TokenType.Divide:
1908
- return this.parseRegExpLiteral();
1909
- }
1910
- return null;
1911
- }
1912
- parseTemplateLiteral() {
1913
- const startToken = this._lexer.get();
1914
- this._lexer.setStartingPhaseToTemplateLiteral();
1915
- const segments = [];
1916
- loop: while (true) {
1917
- let nextToken = this._lexer.peek();
1918
- switch (nextToken.type) {
1919
- case TokenType_1.TokenType.StringLiteral:
1920
- this._lexer.get();
1921
- const str = this.parseStringLiteral(nextToken, false);
1922
- segments.push(str);
1923
- break;
1924
- case TokenType_1.TokenType.DollarLBrace:
1925
- this._lexer.get();
1926
- const innerExpr = this.parseExpr();
1927
- segments.push(innerExpr);
1928
- this.expectToken(TokenType_1.TokenType.RBrace, "W004");
1929
- this._lexer.setStartingPhaseToTemplateLiteral();
1930
- break;
1931
- case TokenType_1.TokenType.Backtick:
1932
- break loop;
1933
- default:
1934
- this.reportError("W004");
1935
- }
1936
- }
1937
- const endToken = this._lexer.get();
1938
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_TEMPLATE_LITERAL_EXPRESSION, { segments }, startToken, endToken);
1939
- }
1940
- /**
1941
- * Parses an array literal
1942
- */
1943
- parseArrayLiteral() {
1944
- const start = this._lexer.get();
1945
- let expressions = [];
1946
- if (this._lexer.peek().type !== TokenType_1.TokenType.RSquare) {
1947
- const expr = this.getExpression();
1948
- if (expr) {
1949
- expressions = expr.type === ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION ? expr.exprs : [expr];
1950
- }
1951
- }
1952
- const endToken = this._lexer.peek();
1953
- this.expectToken(TokenType_1.TokenType.RSquare);
1954
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_LITERAL, {
1955
- items: expressions,
1956
- }, start, endToken);
1957
- }
1958
- /**
1959
- * Parses an object literal
1960
- */
1961
- parseObjectLiteral() {
1962
- const start = this._lexer.get();
1963
- let props = [];
1964
- if (this._lexer.peek().type !== TokenType_1.TokenType.RBrace) {
1965
- while (this._lexer.peek().type !== TokenType_1.TokenType.RBrace) {
1966
- // --- Check the next token
1967
- const nextToken = this._lexer.peek();
1968
- const traits = TokenTrait_1.tokenTraits[nextToken.type];
1969
- let nameExpr;
1970
- // --- Get property name or calculated property name
1971
- if (traits.expressionStart) {
1972
- if (nextToken.type === TokenType_1.TokenType.LSquare) {
1973
- this._lexer.get();
1974
- nameExpr = this.getExpression();
1975
- if (!nameExpr) {
1976
- return null;
1977
- }
1978
- this.expectToken(TokenType_1.TokenType.RSquare, "W005");
1979
- nameExpr = this.createExpressionNode(ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION, {
1980
- exprs: [nameExpr],
1981
- }, start);
1982
- }
1983
- else if (traits.isPropLiteral) {
1984
- nameExpr = this.getExpression(false);
1985
- if (!nameExpr) {
1986
- return null;
1987
- }
1988
- if (nameExpr.type !== ScriptingSourceTreeExp_1.T_IDENTIFIER &&
1989
- nameExpr.type !== ScriptingSourceTreeExp_1.T_LITERAL &&
1990
- nameExpr.type !== ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION) {
1991
- this.reportError("W007");
1992
- return null;
1993
- }
1994
- }
1995
- else {
1996
- this.reportError("W007");
1997
- return null;
1998
- }
1999
- }
2000
- else if (traits.keywordLike) {
2001
- nameExpr = {
2002
- type: ScriptingSourceTreeExp_1.T_IDENTIFIER,
2003
- nodeId: createXmlUiTreeNodeId(),
2004
- name: nextToken.text,
2005
- startToken: nextToken,
2006
- endToken: nextToken,
2007
- };
2008
- this._lexer.get();
2009
- }
2010
- else {
2011
- this.reportError("W001");
2012
- return null;
2013
- }
2014
- const nameType = nameExpr.type;
2015
- if (nameType === ScriptingSourceTreeExp_1.T_SPREAD_EXPRESSION) {
2016
- props.push(nameExpr);
2017
- }
2018
- else {
2019
- if (nameType === ScriptingSourceTreeExp_1.T_LITERAL) {
2020
- const val = nameExpr.value;
2021
- if (typeof val !== "number" && typeof val !== "string") {
2022
- this.expectToken(TokenType_1.TokenType.RBrace, "W007");
2023
- return null;
2024
- }
2025
- }
2026
- // --- Value is optional, when we have a name
2027
- let valueExpr = null;
2028
- if (nameType === ScriptingSourceTreeExp_1.T_IDENTIFIER) {
2029
- const nameFollowerToken = this._lexer.peek();
2030
- if (nameFollowerToken.type === TokenType_1.TokenType.Comma ||
2031
- nameFollowerToken.type === TokenType_1.TokenType.RBrace) {
2032
- valueExpr = Object.assign({}, nameExpr);
2033
- }
2034
- }
2035
- // --- Move to property value
2036
- if (!valueExpr) {
2037
- this.expectToken(TokenType_1.TokenType.Colon, "W008");
2038
- valueExpr = this.getExpression(false);
2039
- if (!valueExpr) {
2040
- return null;
2041
- }
2042
- }
2043
- props.push([nameExpr, valueExpr]);
2044
- }
2045
- // --- Test property termination
2046
- const next = this._lexer.peek().type;
2047
- if (next === TokenType_1.TokenType.Comma) {
2048
- this._lexer.get();
2049
- }
2050
- else {
2051
- if (next !== TokenType_1.TokenType.RBrace) {
2052
- break;
2053
- }
2054
- }
2055
- }
2056
- }
2057
- const endToken = this._lexer.peek();
2058
- this.expectToken(TokenType_1.TokenType.RBrace, "W004");
2059
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_LITERAL, {
2060
- props,
2061
- }, start, endToken);
2062
- }
2063
- parseRegExpLiteral() {
2064
- var _a;
2065
- const startToken = this._lexer.peek();
2066
- const result = this._lexer.getRegEx();
2067
- if (result.success) {
2068
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
2069
- value: new RegExp(result.pattern, result.flags),
2070
- }, startToken, this._lexer.peek());
2071
- }
2072
- this.reportError("W002", startToken, (_a = result.pattern) !== null && _a !== void 0 ? _a : "");
2073
- return null;
2074
- }
2075
- /**
2076
- * Gets an expression
2077
- */
2078
- getExpression(allowSequence = true) {
2079
- const expr = this.parseExpr(allowSequence);
2080
- if (expr) {
2081
- return expr;
2082
- }
2083
- this.reportError("W001");
2084
- return null;
2085
- }
2086
- // ==========================================================================
2087
- // Helpers
2088
- /**
2089
- * Tests the type of the next token
2090
- * @param type Expected token type
2091
- * @param errorCode Error to raise if the next token is not expected
2092
- * @param allowEof Allow an EOF instead of the expected token?
2093
- */
2094
- expectToken(type, errorCode, allowEof) {
2095
- const next = this._lexer.peek();
2096
- if (next.type === type || (allowEof && next.type === TokenType_1.TokenType.Eof)) {
2097
- // --- Skip the expected token
2098
- return this._lexer.get();
2099
- }
2100
- this.reportError(errorCode !== null && errorCode !== void 0 ? errorCode : "W002", next, next.text);
2101
- return null;
2102
- }
2103
- /**
2104
- * Skips the next token if the type is the specified one
2105
- * @param type Token type to check
2106
- */
2107
- skipToken(type) {
2108
- const next = this._lexer.peek();
2109
- if (next.type === type) {
2110
- this._lexer.get();
2111
- return next;
2112
- }
2113
- return null;
2114
- }
2115
- /**
2116
- * Skips the next token if the type is the specified one
2117
- * @param types Token types to check
2118
- */
2119
- skipTokens(...types) {
2120
- const next = this._lexer.peek();
2121
- for (const type of types) {
2122
- if (next.type === type) {
2123
- this._lexer.get();
2124
- return next;
2125
- }
2126
- }
2127
- return null;
2128
- }
2129
- /**
2130
- * Reports the specified error
2131
- * @param errorCode Error code
2132
- * @param token Token that represents the error's position
2133
- * @param options Error message options
2134
- */
2135
- reportError(errorCode, token, ...options) {
2136
- var _a;
2137
- let errorText = (_a = ParserError_1.errorMessages[errorCode]) !== null && _a !== void 0 ? _a : "Unkonwn error";
2138
- if (options) {
2139
- options.forEach((o, idx) => (errorText = replace(errorText, `{${idx}}`, options[idx].toString())));
2140
- }
2141
- if (!token) {
2142
- token = this._lexer.peek();
2143
- }
2144
- this._parseErrors.push({
2145
- code: errorCode,
2146
- text: errorText,
2147
- });
2148
- throw new ParserError_1.ParserError(errorText, errorCode);
2149
- function replace(input, placeholder, replacement) {
2150
- do {
2151
- input = input.replace(placeholder, replacement);
2152
- } while (input.includes(placeholder));
2153
- return input;
2154
- }
2155
- }
2156
- /**
2157
- * Creates an expression node
2158
- * @param type Expression type
2159
- * @param stump Stump properties
2160
- * @param startToken The token that starts the expression
2161
- * @param endToken The token that ends the expression
2162
- * @param source Expression source code to store to the node
2163
- */
2164
- createNode(type, stump, startToken, endToken) {
2165
- if (!endToken) {
2166
- endToken = this._lexer.peek();
2167
- }
2168
- return Object.assign({}, stump, {
2169
- type,
2170
- startToken,
2171
- endToken,
2172
- });
2173
- }
2174
- /**
2175
- * Creates an expression node
2176
- * @param type Expression type
2177
- * @param stump Stump properties
2178
- * @param startToken The token that starts the expression
2179
- * @param endToken The token that ends the expression
2180
- * @param source Expression source code to store to the node
2181
- */
2182
- createExpressionNode(type, stump = {}, startToken, endToken) {
2183
- if (!endToken) {
2184
- endToken = this._lexer.peek();
2185
- }
2186
- if (!startToken) {
2187
- startToken = endToken;
2188
- }
2189
- return Object.assign({}, stump, {
2190
- type,
2191
- nodeId: createXmlUiTreeNodeId(),
2192
- startToken,
2193
- endToken,
2194
- });
2195
- }
2196
- /**
2197
- * Creates a statement node
2198
- * @param type Statement type
2199
- * @param stump Stump properties
2200
- * @param startToken The token that starts the statement
2201
- * @param endToken The token that ends the statement
2202
- */
2203
- createStatementNode(type, stump, startToken, endToken) {
2204
- return Object.assign({}, stump, {
2205
- type,
2206
- nodeId: createXmlUiTreeNodeId(),
2207
- startToken,
2208
- endToken,
2209
- });
2210
- }
2211
- /**
2212
- * Parses a binary literal
2213
- * @param token Literal token
2214
- */
2215
- parseBinaryLiteral(token) {
2216
- let value;
2217
- const bigValue = BigInt(token.text.replace(/[_']/g, ""));
2218
- if (bigValue < Number.MIN_SAFE_INTEGER || bigValue > Number.MAX_SAFE_INTEGER) {
2219
- value = bigValue;
2220
- }
2221
- else {
2222
- value = parseInt(token.text.substring(2).replace(/[_']/g, ""), 2);
2223
- }
2224
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
2225
- value,
2226
- }, token, token);
2227
- }
2228
- /**
2229
- * Parses a decimal literal
2230
- * @param token Literal token
2231
- */
2232
- parseDecimalLiteral(token) {
2233
- let value;
2234
- const bigValue = BigInt(token.text.replace(/[_']/g, ""));
2235
- if (bigValue < Number.MIN_SAFE_INTEGER || bigValue > Number.MAX_SAFE_INTEGER) {
2236
- value = bigValue;
2237
- }
2238
- else {
2239
- value = parseInt(token.text.replace(/[_']/g, ""), 10);
2240
- }
2241
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
2242
- value,
2243
- }, token, token);
2244
- }
2245
- /**
2246
- * Parses a hexadecimal literal
2247
- * @param token Literal token
2248
- */
2249
- parseHexadecimalLiteral(token) {
2250
- let value;
2251
- const bigValue = BigInt(token.text.replace(/[_']/g, ""));
2252
- if (bigValue < Number.MIN_SAFE_INTEGER || bigValue > Number.MAX_SAFE_INTEGER) {
2253
- value = bigValue;
2254
- }
2255
- else {
2256
- value = parseInt(token.text.substring(2).replace(/[_']/g, ""), 16);
2257
- }
2258
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
2259
- value,
2260
- }, token, token);
2261
- }
2262
- /**
2263
- * Parses a real literal
2264
- * @param token Literal token
2265
- */
2266
- parseRealLiteral(token) {
2267
- let value = parseFloat(token.text.replace(/[_']/g, ""));
2268
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
2269
- value,
2270
- }, token, token);
2271
- }
2272
- /**
2273
- * Converts a string token to intrinsic string
2274
- * @param token Literal token
2275
- */
2276
- parseStringLiteral(token, quoteSurrounded = true) {
2277
- let input = token.text;
2278
- if (quoteSurrounded) {
2279
- input = token.text.length < 2 ? "" : input.substring(1, input.length - 1);
2280
- }
2281
- let result = "";
2282
- let state = StrParseState.Normal;
2283
- let collect = 0;
2284
- for (const ch of input) {
2285
- switch (state) {
2286
- case StrParseState.Normal:
2287
- if (ch === "\\") {
2288
- state = StrParseState.Backslash;
2289
- }
2290
- else {
2291
- result += ch;
2292
- }
2293
- break;
2294
- case StrParseState.Backslash:
2295
- state = StrParseState.Normal;
2296
- switch (ch) {
2297
- case "b":
2298
- result += "\b";
2299
- break;
2300
- case "f":
2301
- result += "\f";
2302
- break;
2303
- case "n":
2304
- result += "\n";
2305
- break;
2306
- case "r":
2307
- result += "\r";
2308
- break;
2309
- case "t":
2310
- result += "\t";
2311
- break;
2312
- case "v":
2313
- result += "\v";
2314
- break;
2315
- case "S":
2316
- result += "\xa0";
2317
- break;
2318
- case "0":
2319
- result += String.fromCharCode(0x00);
2320
- break;
2321
- case "'":
2322
- result += "'";
2323
- break;
2324
- case '"':
2325
- result += '"';
2326
- break;
2327
- case "\\":
2328
- result += "\\";
2329
- break;
2330
- case "x":
2331
- state = StrParseState.X;
2332
- break;
2333
- case "u":
2334
- state = StrParseState.UX1;
2335
- break;
2336
- default:
2337
- result += ch;
2338
- break;
2339
- }
2340
- break;
2341
- case StrParseState.X:
2342
- if (isHexaDecimal(ch)) {
2343
- collect = parseInt(ch, 16);
2344
- state = StrParseState.Xh;
2345
- }
2346
- else {
2347
- result += "x";
2348
- state = StrParseState.Normal;
2349
- }
2350
- break;
2351
- case StrParseState.Xh:
2352
- if (isHexaDecimal(ch)) {
2353
- collect = collect * 0x10 + parseInt(ch, 16);
2354
- result += String.fromCharCode(collect);
2355
- state = StrParseState.Normal;
2356
- }
2357
- else {
2358
- result += String.fromCharCode(collect);
2359
- result += ch;
2360
- state = StrParseState.Normal;
2361
- }
2362
- break;
2363
- case StrParseState.UX1:
2364
- if (ch === "{") {
2365
- state = StrParseState.Ucp1;
2366
- break;
2367
- }
2368
- if (isHexaDecimal(ch)) {
2369
- collect = parseInt(ch, 16);
2370
- state = StrParseState.UX2;
2371
- }
2372
- else {
2373
- result += "x";
2374
- state = StrParseState.Normal;
2375
- }
2376
- break;
2377
- case StrParseState.UX2:
2378
- if (isHexaDecimal(ch)) {
2379
- collect = collect * 0x10 + parseInt(ch, 16);
2380
- state = StrParseState.UX3;
2381
- }
2382
- else {
2383
- result += String.fromCharCode(collect);
2384
- result += ch;
2385
- state = StrParseState.Normal;
2386
- }
2387
- break;
2388
- case StrParseState.UX3:
2389
- if (isHexaDecimal(ch)) {
2390
- collect = collect * 0x10 + parseInt(ch, 16);
2391
- state = StrParseState.UX4;
2392
- }
2393
- else {
2394
- result += String.fromCharCode(collect);
2395
- result += ch;
2396
- state = StrParseState.Normal;
2397
- }
2398
- break;
2399
- case StrParseState.UX4:
2400
- if (isHexaDecimal(ch)) {
2401
- collect = collect * 0x10 + parseInt(ch, 16);
2402
- result += String.fromCharCode(collect);
2403
- state = StrParseState.Normal;
2404
- }
2405
- else {
2406
- result += String.fromCharCode(collect);
2407
- result += ch;
2408
- state = StrParseState.Normal;
2409
- }
2410
- break;
2411
- case StrParseState.Ucp1:
2412
- if (isHexaDecimal(ch)) {
2413
- collect = parseInt(ch, 16);
2414
- state = StrParseState.Ucp2;
2415
- }
2416
- else {
2417
- result += "x";
2418
- state = StrParseState.Normal;
2419
- }
2420
- break;
2421
- case StrParseState.Ucp2:
2422
- if (isHexaDecimal(ch)) {
2423
- collect = collect * 0x10 + parseInt(ch, 16);
2424
- state = StrParseState.Ucp3;
2425
- }
2426
- else {
2427
- result += String.fromCharCode(collect);
2428
- result += ch;
2429
- state = StrParseState.Normal;
2430
- }
2431
- break;
2432
- case StrParseState.Ucp3:
2433
- if (isHexaDecimal(ch)) {
2434
- collect = collect * 0x10 + parseInt(ch, 16);
2435
- state = StrParseState.Ucp4;
2436
- }
2437
- else {
2438
- result += String.fromCharCode(collect);
2439
- result += ch;
2440
- state = StrParseState.Normal;
2441
- }
2442
- break;
2443
- case StrParseState.Ucp4:
2444
- if (isHexaDecimal(ch)) {
2445
- collect = collect * 0x10 + parseInt(ch, 16);
2446
- state = StrParseState.Ucp5;
2447
- }
2448
- else {
2449
- result += String.fromCharCode(collect);
2450
- result += ch;
2451
- state = StrParseState.Normal;
2452
- }
2453
- break;
2454
- case StrParseState.Ucp5:
2455
- if (isHexaDecimal(ch)) {
2456
- collect = collect * 0x10 + parseInt(ch, 16);
2457
- state = StrParseState.Ucp6;
2458
- }
2459
- else {
2460
- result += String.fromCharCode(collect);
2461
- result += ch;
2462
- state = StrParseState.Normal;
2463
- }
2464
- break;
2465
- case StrParseState.Ucp6:
2466
- if (isHexaDecimal(ch)) {
2467
- collect = collect * 0x10 + parseInt(ch, 16);
2468
- state = StrParseState.UcpTail;
2469
- }
2470
- else {
2471
- result += String.fromCharCode(collect);
2472
- result += ch;
2473
- state = StrParseState.Normal;
2474
- }
2475
- break;
2476
- case StrParseState.UcpTail:
2477
- result += String.fromCharCode(collect);
2478
- if (ch !== "}") {
2479
- result += ch;
2480
- }
2481
- state = StrParseState.Normal;
2482
- break;
2483
- }
2484
- }
2485
- // --- Handle the final machine state
2486
- switch (state) {
2487
- case StrParseState.Backslash:
2488
- result += "\\";
2489
- break;
2490
- case StrParseState.X:
2491
- result += "x";
2492
- break;
2493
- case StrParseState.Xh:
2494
- result += String.fromCharCode(collect);
2495
- break;
2496
- }
2497
- // --- Done
2498
- return this.createExpressionNode(ScriptingSourceTreeExp_1.T_LITERAL, {
2499
- value: result,
2500
- }, token, token);
2501
- function isHexaDecimal(ch) {
2502
- return (ch >= "0" && ch <= "9") || (ch >= "a" && ch <= "f") || (ch >= "A" && ch <= "F");
2503
- }
2504
- }
2505
- convertToArrayDestructure(seq) {
2506
- var _a;
2507
- const items = seq.type === ScriptingSourceTreeExp_1.T_SEQUENCE_EXPRESSION ? seq.exprs : seq.items;
2508
- const result = this.createExpressionNode(ScriptingSourceTreeExp_1.T_DESTRUCTURE, { aDestr: [] }, seq.startToken, seq.endToken);
2509
- // --- Convert all items
2510
- for (const item of items) {
2511
- let arrayD;
2512
- switch (item.type) {
2513
- case ScriptingSourceTreeExp_1.T_NO_ARG_EXPRESSION:
2514
- arrayD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, {}, item.startToken, item.endToken);
2515
- break;
2516
- case ScriptingSourceTreeExp_1.T_IDENTIFIER:
2517
- arrayD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, { id: item.name }, item.startToken, item.endToken);
2518
- break;
2519
- case ScriptingSourceTreeExp_1.T_DESTRUCTURE:
2520
- result.aDestr.push(...item.aDestr);
2521
- break;
2522
- case ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE:
2523
- arrayD = item;
2524
- break;
2525
- case ScriptingSourceTreeExp_1.T_ARRAY_LITERAL: {
2526
- const destructure = this.convertToArrayDestructure(item);
2527
- if (destructure) {
2528
- arrayD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, {
2529
- aDestr: destructure.aDestr,
2530
- }, item.startToken, item.endToken);
2531
- }
2532
- break;
2533
- }
2534
- case ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE:
2535
- arrayD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, {
2536
- oDestr: item,
2537
- }, item.startToken, item.endToken);
2538
- break;
2539
- case ScriptingSourceTreeExp_1.T_OBJECT_LITERAL: {
2540
- const destructure = this.convertToObjectDestructure(item);
2541
- if (destructure) {
2542
- arrayD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE, {
2543
- oDestr: destructure.oDestr,
2544
- }, item.startToken, item.endToken);
2545
- }
2546
- break;
2547
- }
2548
- default:
2549
- this.reportError("W017");
2550
- return null;
2551
- }
2552
- if (arrayD)
2553
- (_a = result.aDestr) === null || _a === void 0 ? void 0 : _a.push(arrayD);
2554
- }
2555
- // --- Done.
2556
- return result;
2557
- }
2558
- convertToObjectDestructure(objLit) {
2559
- var _a;
2560
- const result = this.createExpressionNode(ScriptingSourceTreeExp_1.T_DESTRUCTURE, { oDestr: [] }, objLit.startToken, objLit.endToken);
2561
- // --- Convert all items
2562
- for (const prop of objLit.props) {
2563
- if (Array.isArray(prop)) {
2564
- }
2565
- else {
2566
- reportError("W018");
2567
- return null;
2568
- }
2569
- const [propKey, propValue] = prop;
2570
- if (propKey.type !== ScriptingSourceTreeExp_1.T_IDENTIFIER) {
2571
- reportError("W018");
2572
- return null;
2573
- }
2574
- let objD;
2575
- switch (propValue.type) {
2576
- case ScriptingSourceTreeExp_1.T_IDENTIFIER:
2577
- if (propValue.name === propKey.name) {
2578
- objD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE, { id: propKey.name }, propValue.startToken, propValue.endToken);
2579
- }
2580
- else {
2581
- objD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE, {
2582
- id: propKey.name,
2583
- alias: propValue.name,
2584
- }, propValue.startToken, propValue.endToken);
2585
- }
2586
- break;
2587
- case ScriptingSourceTreeExp_1.T_ARRAY_DESTRUCTURE: {
2588
- objD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE, {
2589
- id: propKey.name,
2590
- aDestr: propValue,
2591
- }, propKey.startToken, propValue.endToken);
2592
- break;
2593
- }
2594
- case ScriptingSourceTreeExp_1.T_ARRAY_LITERAL: {
2595
- const destructure = this.convertToArrayDestructure(propValue);
2596
- if (destructure) {
2597
- objD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE, {
2598
- id: propKey.name,
2599
- aDestr: destructure.aDestr,
2600
- }, propKey.startToken, propValue.endToken);
2601
- }
2602
- break;
2603
- }
2604
- case ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE:
2605
- objD = propValue;
2606
- break;
2607
- case ScriptingSourceTreeExp_1.T_OBJECT_LITERAL: {
2608
- const destructure = this.convertToObjectDestructure(propValue);
2609
- if (destructure) {
2610
- objD = this.createExpressionNode(ScriptingSourceTreeExp_1.T_OBJECT_DESTRUCTURE, {
2611
- id: propKey.name,
2612
- oDestr: destructure.oDestr,
2613
- }, propKey.startToken, propValue.endToken);
2614
- }
2615
- break;
2616
- }
2617
- default:
2618
- this.reportError("W018");
2619
- return null;
2620
- }
2621
- if (objD)
2622
- (_a = result.oDestr) === null || _a === void 0 ? void 0 : _a.push(objD);
2623
- }
2624
- // --- Done.
2625
- return result;
2626
- }
2627
- /**
2628
- * Tests if the specified token can be the start of an expression
2629
- */
2630
- isExpressionStart(token) {
2631
- var _a, _b;
2632
- return (_b = (_a = TokenTrait_1.tokenTraits[token.type]) === null || _a === void 0 ? void 0 : _a.expressionStart) !== null && _b !== void 0 ? _b : false;
2633
- }
2634
- }
2635
- exports.Parser = Parser;