@auscope/angular2parse 2.0.2 → 2.0.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 (70) hide show
  1. package/.editorconfig +13 -0
  2. package/angular.json +27 -0
  3. package/package.json +38 -41
  4. package/projects/angular2parse/README.md +49 -0
  5. package/projects/angular2parse/ng-package.json +7 -0
  6. package/projects/angular2parse/package.json +18 -0
  7. package/projects/angular2parse/src/lib/angular/compiler/assertions.ts +49 -0
  8. package/projects/angular2parse/src/lib/angular/compiler/ast.ts +393 -0
  9. package/projects/angular2parse/src/lib/angular/compiler/chars.ts +89 -0
  10. package/projects/angular2parse/src/lib/angular/compiler/interpolation-config.ts +25 -0
  11. package/projects/angular2parse/src/lib/angular/compiler/lexer.ts +383 -0
  12. package/projects/angular2parse/src/lib/angular/compiler/parser.ts +811 -0
  13. package/{lib/angular/compiler.d.ts → projects/angular2parse/src/lib/angular/compiler.ts} +1 -1
  14. package/projects/angular2parse/src/lib/angular/facade/lang.ts +124 -0
  15. package/projects/angular2parse/src/lib/angular/facade.ts +1 -0
  16. package/{lib/angular.d.ts → projects/angular2parse/src/lib/angular.ts} +1 -1
  17. package/projects/angular2parse/src/lib/module.ts +12 -0
  18. package/projects/angular2parse/src/lib/parse.ts +78 -0
  19. package/projects/angular2parse/src/lib/util/binary-operations.ts +17 -0
  20. package/projects/angular2parse/src/lib/util/lang.ts +15 -0
  21. package/{lib/util.d.ts → projects/angular2parse/src/lib/util.ts} +1 -1
  22. package/projects/angular2parse/src/lib/visitors/parse-visitor-compiler.ts +149 -0
  23. package/projects/angular2parse/src/lib/visitors/parse-visitor-resolver.ts +208 -0
  24. package/projects/angular2parse/src/lib/visitors.ts +2 -0
  25. package/projects/angular2parse/src/public-api.ts +5 -0
  26. package/projects/angular2parse/tsconfig.lib.json +20 -0
  27. package/projects/angular2parse/tsconfig.lib.prod.json +9 -0
  28. package/target/npmlist.json +1 -0
  29. package/tsconfig.json +32 -0
  30. package/auscope-angular2parse.d.ts +0 -5
  31. package/esm2020/auscope-angular2parse.mjs +0 -5
  32. package/esm2020/lib/angular/compiler/assertions.mjs +0 -45
  33. package/esm2020/lib/angular/compiler/ast.mjs +0 -393
  34. package/esm2020/lib/angular/compiler/chars.mjs +0 -78
  35. package/esm2020/lib/angular/compiler/interpolation-config.mjs +0 -24
  36. package/esm2020/lib/angular/compiler/lexer.mjs +0 -344
  37. package/esm2020/lib/angular/compiler/parser.mjs +0 -721
  38. package/esm2020/lib/angular/compiler.mjs +0 -7
  39. package/esm2020/lib/angular/facade/lang.mjs +0 -85
  40. package/esm2020/lib/angular/facade.mjs +0 -2
  41. package/esm2020/lib/angular.mjs +0 -3
  42. package/esm2020/lib/module.mjs +0 -18
  43. package/esm2020/lib/parse.mjs +0 -66
  44. package/esm2020/lib/util/binary-operations.mjs +0 -18
  45. package/esm2020/lib/util/lang.mjs +0 -13
  46. package/esm2020/lib/util.mjs +0 -3
  47. package/esm2020/lib/visitors/parse-visitor-compiler.mjs +0 -96
  48. package/esm2020/lib/visitors/parse-visitor-resolver.mjs +0 -141
  49. package/esm2020/lib/visitors.mjs +0 -3
  50. package/esm2020/public-api.mjs +0 -6
  51. package/fesm2015/auscope-angular2parse.mjs +0 -2035
  52. package/fesm2015/auscope-angular2parse.mjs.map +0 -1
  53. package/fesm2020/auscope-angular2parse.mjs +0 -2033
  54. package/fesm2020/auscope-angular2parse.mjs.map +0 -1
  55. package/lib/angular/compiler/assertions.d.ts +0 -9
  56. package/lib/angular/compiler/ast.d.ts +0 -242
  57. package/lib/angular/compiler/chars.d.ts +0 -69
  58. package/lib/angular/compiler/interpolation-config.d.ts +0 -14
  59. package/lib/angular/compiler/lexer.d.ts +0 -44
  60. package/lib/angular/compiler/parser.d.ts +0 -92
  61. package/lib/angular/facade/lang.d.ts +0 -44
  62. package/lib/angular/facade.d.ts +0 -1
  63. package/lib/module.d.ts +0 -9
  64. package/lib/parse.d.ts +0 -21
  65. package/lib/util/binary-operations.d.ts +0 -1
  66. package/lib/util/lang.d.ts +0 -4
  67. package/lib/visitors/parse-visitor-compiler.d.ts +0 -23
  68. package/lib/visitors/parse-visitor-resolver.d.ts +0 -25
  69. package/lib/visitors.d.ts +0 -2
  70. package/public-api.d.ts +0 -2
@@ -1,2035 +0,0 @@
1
- import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, Optional, Inject, NgModule } from '@angular/core';
3
-
4
- /**
5
- * @license
6
- * Copyright Google Inc. All Rights Reserved.
7
- *
8
- * Use of this source code is governed by an MIT-style license that can be
9
- * found in the LICENSE file at https://angular.io/license
10
- */
11
- function getTypeNameForDebugging(type) {
12
- return type['name'] || typeof type;
13
- }
14
- function isPresent$1(obj) {
15
- return obj != null;
16
- }
17
- function isBlank(obj) {
18
- return obj == null;
19
- }
20
- const STRING_MAP_PROTO = Object.getPrototypeOf({});
21
- function isStrictStringMap(obj) {
22
- return typeof obj === 'object' && obj !== null && Object.getPrototypeOf(obj) === STRING_MAP_PROTO;
23
- }
24
- function stringify(token) {
25
- if (typeof token === 'string') {
26
- return token;
27
- }
28
- if (token == null) {
29
- return '' + token;
30
- }
31
- if (token.overriddenName) {
32
- return `${token.overriddenName}`;
33
- }
34
- if (token.name) {
35
- return `${token.name}`;
36
- }
37
- const res = token.toString();
38
- const newLineIndex = res.indexOf('\n');
39
- return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
40
- }
41
- class NumberWrapper {
42
- static parseIntAutoRadix(text) {
43
- const result = parseInt(text);
44
- if (isNaN(result)) {
45
- throw new Error('Invalid integer literal when parsing ' + text);
46
- }
47
- return result;
48
- }
49
- static isNumeric(value) { return !isNaN(value - parseFloat(value)); }
50
- }
51
- // JS has NaN !== NaN
52
- function looseIdentical(a, b) {
53
- return a === b || typeof a === 'number' && typeof b === 'number' && isNaN(a) && isNaN(b);
54
- }
55
- function isJsObject$1(o) {
56
- return o !== null && (typeof o === 'function' || typeof o === 'object');
57
- }
58
- function print(obj) {
59
- // tslint:disable-next-line:no-console
60
- console.log(obj);
61
- }
62
- function warn(obj) {
63
- console.warn(obj);
64
- }
65
- function setValueOnPath(global, path, value) {
66
- const parts = path.split('.');
67
- let obj = global;
68
- while (parts.length > 1) {
69
- const name = parts.shift();
70
- if (obj.hasOwnProperty(name) && obj[name] != null) {
71
- obj = obj[name];
72
- }
73
- else {
74
- obj = obj[name] = {};
75
- }
76
- }
77
- if (obj === undefined || obj === null) {
78
- obj = {};
79
- }
80
- obj[parts.shift()] = value;
81
- }
82
- function isPrimitive(obj) {
83
- return !isJsObject$1(obj);
84
- }
85
- function escapeRegExp(s) {
86
- return s.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
87
- }
88
-
89
- /**
90
- * @license
91
- * Copyright Google Inc. All Rights Reserved.
92
- *
93
- * Use of this source code is governed by an MIT-style license that can be
94
- * found in the LICENSE file at https://angular.io/license
95
- */
96
- const isDevMode = () => false;
97
- function assertArrayOfStrings(identifier, value) {
98
- if (!isDevMode() || isBlank(value)) {
99
- return;
100
- }
101
- if (!Array.isArray(value)) {
102
- throw new Error(`Expected '${identifier}' to be an array of strings.`);
103
- }
104
- for (let i = 0; i < value.length; i += 1) {
105
- if (typeof value[i] !== 'string') {
106
- throw new Error(`Expected '${identifier}' to be an array of strings.`);
107
- }
108
- }
109
- }
110
- const INTERPOLATION_BLACKLIST_REGEXPS = [
111
- /^\s*$/,
112
- /[<>]/,
113
- /^[{}]$/,
114
- /&(#|[a-z])/i,
115
- /^\/\//, // comment
116
- ];
117
- function assertInterpolationSymbols(identifier, value) {
118
- if (isPresent$1(value) && !(Array.isArray(value) && value.length == 2)) {
119
- throw new Error(`Expected '${identifier}' to be an array, [start, end].`);
120
- }
121
- else if (isDevMode() && !isBlank(value)) {
122
- const start = value[0];
123
- const end = value[1];
124
- // black list checking
125
- INTERPOLATION_BLACKLIST_REGEXPS.forEach(regexp => {
126
- if (regexp.test(start) || regexp.test(end)) {
127
- throw new Error(`['${start}', '${end}'] contains unusable interpolation symbol.`);
128
- }
129
- });
130
- }
131
- }
132
-
133
- /**
134
- * @license
135
- * Copyright Google Inc. All Rights Reserved.
136
- *
137
- * Use of this source code is governed by an MIT-style license that can be
138
- * found in the LICENSE file at https://angular.io/license
139
- */
140
- class ParserError {
141
- constructor(message, input, errLocation, ctxLocation) {
142
- this.input = input;
143
- this.errLocation = errLocation;
144
- this.ctxLocation = ctxLocation;
145
- this.message = `Parser Error: ${message} ${errLocation} [${input}] in ${ctxLocation}`;
146
- }
147
- }
148
- class ParseSpan {
149
- constructor(start, end) {
150
- this.start = start;
151
- this.end = end;
152
- }
153
- }
154
- class AST {
155
- constructor(span) {
156
- this.span = span;
157
- }
158
- visit(visitor, context = null) { return null; }
159
- toString() { return 'AST'; }
160
- }
161
- /**
162
- * Represents a quoted expression of the form:
163
- *
164
- * quote = prefix `:` uninterpretedExpression
165
- * prefix = identifier
166
- * uninterpretedExpression = arbitrary string
167
- *
168
- * A quoted expression is meant to be pre-processed by an AST transformer that
169
- * converts it into another AST that no longer contains quoted expressions.
170
- * It is meant to allow third-party developers to extend Angular template
171
- * expression language. The `uninterpretedExpression` part of the quote is
172
- * therefore not interpreted by the Angular's own expression parser.
173
- */
174
- class Quote extends AST {
175
- constructor(span, prefix, uninterpretedExpression, location) {
176
- super(span);
177
- this.prefix = prefix;
178
- this.uninterpretedExpression = uninterpretedExpression;
179
- this.location = location;
180
- }
181
- visit(visitor, context = null) { return visitor.visitQuote(this, context); }
182
- toString() { return 'Quote'; }
183
- }
184
- class EmptyExpr extends AST {
185
- visit(visitor, context = null) {
186
- // do nothing
187
- }
188
- }
189
- class ImplicitReceiver extends AST {
190
- visit(visitor, context = null) {
191
- return visitor.visitImplicitReceiver(this, context);
192
- }
193
- }
194
- /**
195
- * Multiple expressions separated by a semicolon.
196
- */
197
- class Chain extends AST {
198
- constructor(span, expressions) {
199
- super(span);
200
- this.expressions = expressions;
201
- }
202
- visit(visitor, context = null) { return visitor.visitChain(this, context); }
203
- }
204
- class Conditional extends AST {
205
- constructor(span, condition, trueExp, falseExp) {
206
- super(span);
207
- this.condition = condition;
208
- this.trueExp = trueExp;
209
- this.falseExp = falseExp;
210
- }
211
- visit(visitor, context = null) {
212
- return visitor.visitConditional(this, context);
213
- }
214
- }
215
- class PropertyRead extends AST {
216
- constructor(span, receiver, name) {
217
- super(span);
218
- this.receiver = receiver;
219
- this.name = name;
220
- }
221
- visit(visitor, context = null) {
222
- return visitor.visitPropertyRead(this, context);
223
- }
224
- }
225
- class PropertyWrite extends AST {
226
- constructor(span, receiver, name, value) {
227
- super(span);
228
- this.receiver = receiver;
229
- this.name = name;
230
- this.value = value;
231
- }
232
- visit(visitor, context = null) {
233
- return visitor.visitPropertyWrite(this, context);
234
- }
235
- }
236
- class SafePropertyRead extends AST {
237
- constructor(span, receiver, name) {
238
- super(span);
239
- this.receiver = receiver;
240
- this.name = name;
241
- }
242
- visit(visitor, context = null) {
243
- return visitor.visitSafePropertyRead(this, context);
244
- }
245
- }
246
- class KeyedRead extends AST {
247
- constructor(span, obj, key) {
248
- super(span);
249
- this.obj = obj;
250
- this.key = key;
251
- }
252
- visit(visitor, context = null) {
253
- return visitor.visitKeyedRead(this, context);
254
- }
255
- }
256
- class KeyedWrite extends AST {
257
- constructor(span, obj, key, value) {
258
- super(span);
259
- this.obj = obj;
260
- this.key = key;
261
- this.value = value;
262
- }
263
- visit(visitor, context = null) {
264
- return visitor.visitKeyedWrite(this, context);
265
- }
266
- }
267
- class BindingPipe extends AST {
268
- constructor(span, exp, name, args) {
269
- super(span);
270
- this.exp = exp;
271
- this.name = name;
272
- this.args = args;
273
- }
274
- visit(visitor, context = null) { return visitor.visitPipe(this, context); }
275
- }
276
- class LiteralPrimitive extends AST {
277
- constructor(span, value) {
278
- super(span);
279
- this.value = value;
280
- }
281
- visit(visitor, context = null) {
282
- return visitor.visitLiteralPrimitive(this, context);
283
- }
284
- }
285
- class LiteralArray extends AST {
286
- constructor(span, expressions) {
287
- super(span);
288
- this.expressions = expressions;
289
- }
290
- visit(visitor, context = null) {
291
- return visitor.visitLiteralArray(this, context);
292
- }
293
- }
294
- class LiteralMap extends AST {
295
- constructor(span, keys, values) {
296
- super(span);
297
- this.keys = keys;
298
- this.values = values;
299
- }
300
- visit(visitor, context = null) {
301
- return visitor.visitLiteralMap(this, context);
302
- }
303
- }
304
- class Interpolation extends AST {
305
- constructor(span, strings, expressions) {
306
- super(span);
307
- this.strings = strings;
308
- this.expressions = expressions;
309
- }
310
- visit(visitor, context = null) {
311
- return visitor.visitInterpolation(this, context);
312
- }
313
- }
314
- class Binary extends AST {
315
- constructor(span, operation, left, right) {
316
- super(span);
317
- this.operation = operation;
318
- this.left = left;
319
- this.right = right;
320
- }
321
- visit(visitor, context = null) {
322
- return visitor.visitBinary(this, context);
323
- }
324
- }
325
- class PrefixNot extends AST {
326
- constructor(span, expression) {
327
- super(span);
328
- this.expression = expression;
329
- }
330
- visit(visitor, context = null) {
331
- return visitor.visitPrefixNot(this, context);
332
- }
333
- }
334
- class MethodCall extends AST {
335
- constructor(span, receiver, name, args) {
336
- super(span);
337
- this.receiver = receiver;
338
- this.name = name;
339
- this.args = args;
340
- }
341
- visit(visitor, context = null) {
342
- return visitor.visitMethodCall(this, context);
343
- }
344
- }
345
- class SafeMethodCall extends AST {
346
- constructor(span, receiver, name, args) {
347
- super(span);
348
- this.receiver = receiver;
349
- this.name = name;
350
- this.args = args;
351
- }
352
- visit(visitor, context = null) {
353
- return visitor.visitSafeMethodCall(this, context);
354
- }
355
- }
356
- class FunctionCall extends AST {
357
- constructor(span, target, args) {
358
- super(span);
359
- this.target = target;
360
- this.args = args;
361
- }
362
- visit(visitor, context = null) {
363
- return visitor.visitFunctionCall(this, context);
364
- }
365
- }
366
- class ASTWithSource extends AST {
367
- constructor(ast, source, location, errors) {
368
- super(new ParseSpan(0, isBlank(source) ? 0 : source.length));
369
- this.ast = ast;
370
- this.source = source;
371
- this.location = location;
372
- this.errors = errors;
373
- }
374
- visit(visitor, context = null) { return this.ast.visit(visitor, context); }
375
- toString() { return `${this.source} in ${this.location}`; }
376
- }
377
- class TemplateBinding {
378
- constructor(span, key, keyIsVar, name, expression) {
379
- this.span = span;
380
- this.key = key;
381
- this.keyIsVar = keyIsVar;
382
- this.name = name;
383
- this.expression = expression;
384
- }
385
- }
386
- class RecursiveAstVisitor {
387
- visitBinary(ast, context) {
388
- ast.left.visit(this);
389
- ast.right.visit(this);
390
- return null;
391
- }
392
- visitChain(ast, context) { return this.visitAll(ast.expressions, context); }
393
- visitConditional(ast, context) {
394
- ast.condition.visit(this);
395
- ast.trueExp.visit(this);
396
- ast.falseExp.visit(this);
397
- return null;
398
- }
399
- visitPipe(ast, context) {
400
- ast.exp.visit(this);
401
- this.visitAll(ast.args, context);
402
- return null;
403
- }
404
- visitFunctionCall(ast, context) {
405
- ast.target.visit(this);
406
- this.visitAll(ast.args, context);
407
- return null;
408
- }
409
- visitImplicitReceiver(ast, context) { return null; }
410
- visitInterpolation(ast, context) {
411
- return this.visitAll(ast.expressions, context);
412
- }
413
- visitKeyedRead(ast, context) {
414
- ast.obj.visit(this);
415
- ast.key.visit(this);
416
- return null;
417
- }
418
- visitKeyedWrite(ast, context) {
419
- ast.obj.visit(this);
420
- ast.key.visit(this);
421
- ast.value.visit(this);
422
- return null;
423
- }
424
- visitLiteralArray(ast, context) {
425
- return this.visitAll(ast.expressions, context);
426
- }
427
- visitLiteralMap(ast, context) { return this.visitAll(ast.values, context); }
428
- visitLiteralPrimitive(ast, context) { return null; }
429
- visitMethodCall(ast, context) {
430
- ast.receiver.visit(this);
431
- return this.visitAll(ast.args, context);
432
- }
433
- visitPrefixNot(ast, context) {
434
- ast.expression.visit(this);
435
- return null;
436
- }
437
- visitPropertyRead(ast, context) {
438
- ast.receiver.visit(this);
439
- return null;
440
- }
441
- visitPropertyWrite(ast, context) {
442
- ast.receiver.visit(this);
443
- ast.value.visit(this);
444
- return null;
445
- }
446
- visitSafePropertyRead(ast, context) {
447
- ast.receiver.visit(this);
448
- return null;
449
- }
450
- visitSafeMethodCall(ast, context) {
451
- ast.receiver.visit(this);
452
- return this.visitAll(ast.args, context);
453
- }
454
- visitAll(asts, context) {
455
- asts.forEach(ast => ast.visit(this, context));
456
- return null;
457
- }
458
- visitQuote(ast, context) { return null; }
459
- }
460
- class AstTransformer {
461
- visitImplicitReceiver(ast, context) { return ast; }
462
- visitInterpolation(ast, context) {
463
- return new Interpolation(ast.span, ast.strings, this.visitAll(ast.expressions));
464
- }
465
- visitLiteralPrimitive(ast, context) {
466
- return new LiteralPrimitive(ast.span, ast.value);
467
- }
468
- visitPropertyRead(ast, context) {
469
- return new PropertyRead(ast.span, ast.receiver.visit(this), ast.name);
470
- }
471
- visitPropertyWrite(ast, context) {
472
- return new PropertyWrite(ast.span, ast.receiver.visit(this), ast.name, ast.value);
473
- }
474
- visitSafePropertyRead(ast, context) {
475
- return new SafePropertyRead(ast.span, ast.receiver.visit(this), ast.name);
476
- }
477
- visitMethodCall(ast, context) {
478
- return new MethodCall(ast.span, ast.receiver.visit(this), ast.name, this.visitAll(ast.args));
479
- }
480
- visitSafeMethodCall(ast, context) {
481
- return new SafeMethodCall(ast.span, ast.receiver.visit(this), ast.name, this.visitAll(ast.args));
482
- }
483
- visitFunctionCall(ast, context) {
484
- return new FunctionCall(ast.span, ast.target.visit(this), this.visitAll(ast.args));
485
- }
486
- visitLiteralArray(ast, context) {
487
- return new LiteralArray(ast.span, this.visitAll(ast.expressions));
488
- }
489
- visitLiteralMap(ast, context) {
490
- return new LiteralMap(ast.span, ast.keys, this.visitAll(ast.values));
491
- }
492
- visitBinary(ast, context) {
493
- return new Binary(ast.span, ast.operation, ast.left.visit(this), ast.right.visit(this));
494
- }
495
- visitPrefixNot(ast, context) {
496
- return new PrefixNot(ast.span, ast.expression.visit(this));
497
- }
498
- visitConditional(ast, context) {
499
- return new Conditional(ast.span, ast.condition.visit(this), ast.trueExp.visit(this), ast.falseExp.visit(this));
500
- }
501
- visitPipe(ast, context) {
502
- return new BindingPipe(ast.span, ast.exp.visit(this), ast.name, this.visitAll(ast.args));
503
- }
504
- visitKeyedRead(ast, context) {
505
- return new KeyedRead(ast.span, ast.obj.visit(this), ast.key.visit(this));
506
- }
507
- visitKeyedWrite(ast, context) {
508
- return new KeyedWrite(ast.span, ast.obj.visit(this), ast.key.visit(this), ast.value.visit(this));
509
- }
510
- visitAll(asts) {
511
- const res = new Array(asts.length);
512
- for (let i = 0; i < asts.length; ++i) {
513
- res[i] = asts[i].visit(this);
514
- }
515
- return res;
516
- }
517
- visitChain(ast, context) {
518
- return new Chain(ast.span, this.visitAll(ast.expressions));
519
- }
520
- visitQuote(ast, context) {
521
- return new Quote(ast.span, ast.prefix, ast.uninterpretedExpression, ast.location);
522
- }
523
- }
524
-
525
- /**
526
- * @license
527
- * Copyright Google Inc. All Rights Reserved.
528
- *
529
- * Use of this source code is governed by an MIT-style license that can be
530
- * found in the LICENSE file at https://angular.io/license
531
- */
532
- const $EOF = 0;
533
- const $TAB = 9;
534
- const $LF = 10;
535
- const $VTAB = 11;
536
- const $FF = 12;
537
- const $CR = 13;
538
- const $SPACE = 32;
539
- const $BANG = 33;
540
- const $DQ = 34;
541
- const $HASH = 35;
542
- const $$ = 36;
543
- const $PERCENT = 37;
544
- const $AMPERSAND = 38;
545
- const $SQ = 39;
546
- const $LPAREN = 40;
547
- const $RPAREN = 41;
548
- const $STAR = 42;
549
- const $PLUS = 43;
550
- const $COMMA = 44;
551
- const $MINUS = 45;
552
- const $PERIOD = 46;
553
- const $SLASH = 47;
554
- const $COLON = 58;
555
- const $SEMICOLON = 59;
556
- const $LT = 60;
557
- const $EQ = 61;
558
- const $GT = 62;
559
- const $QUESTION = 63;
560
- const $0 = 48;
561
- const $9 = 57;
562
- const $A = 65;
563
- const $E = 69;
564
- const $F = 70;
565
- const $X = 88;
566
- const $Z = 90;
567
- const $LBRACKET = 91;
568
- const $BACKSLASH = 92;
569
- const $RBRACKET = 93;
570
- const $CARET = 94;
571
- const $_ = 95;
572
- const $a = 97;
573
- const $e = 101;
574
- const $f = 102;
575
- const $n = 110;
576
- const $r = 114;
577
- const $t = 116;
578
- const $u = 117;
579
- const $v = 118;
580
- const $x = 120;
581
- const $z = 122;
582
- const $LBRACE = 123;
583
- const $BAR = 124;
584
- const $RBRACE = 125;
585
- const $NBSP = 160;
586
- const $PIPE = 124;
587
- const $TILDA = 126;
588
- const $AT = 64;
589
- const $BT = 96;
590
- function isWhitespace(code) {
591
- return (code >= $TAB && code <= $SPACE) || (code == $NBSP);
592
- }
593
- function isDigit(code) {
594
- return $0 <= code && code <= $9;
595
- }
596
- function isAsciiLetter(code) {
597
- return code >= $a && code <= $z || code >= $A && code <= $Z;
598
- }
599
- function isAsciiHexDigit(code) {
600
- return code >= $a && code <= $f || code >= $A && code <= $F || isDigit(code);
601
- }
602
-
603
- /**
604
- * @license
605
- * Copyright Google Inc. All Rights Reserved.
606
- *
607
- * Use of this source code is governed by an MIT-style license that can be
608
- * found in the LICENSE file at https://angular.io/license
609
- */
610
- class InterpolationConfig {
611
- constructor(start, end) {
612
- this.start = start;
613
- this.end = end;
614
- }
615
- static fromArray(markers) {
616
- if (!markers) {
617
- return DEFAULT_INTERPOLATION_CONFIG;
618
- }
619
- assertInterpolationSymbols('interpolation', markers);
620
- return new InterpolationConfig(markers[0], markers[1]);
621
- }
622
- ;
623
- }
624
- const DEFAULT_INTERPOLATION_CONFIG = new InterpolationConfig('{{', '}}');
625
-
626
- /**
627
- * @license
628
- * Copyright Google Inc. All Rights Reserved.
629
- *
630
- * Use of this source code is governed by an MIT-style license that can be
631
- * found in the LICENSE file at https://angular.io/license
632
- */
633
- var TokenType;
634
- (function (TokenType) {
635
- TokenType[TokenType["Character"] = 0] = "Character";
636
- TokenType[TokenType["Identifier"] = 1] = "Identifier";
637
- TokenType[TokenType["Keyword"] = 2] = "Keyword";
638
- TokenType[TokenType["String"] = 3] = "String";
639
- TokenType[TokenType["Operator"] = 4] = "Operator";
640
- TokenType[TokenType["Number"] = 5] = "Number";
641
- TokenType[TokenType["Error"] = 6] = "Error";
642
- })(TokenType || (TokenType = {}));
643
- const KEYWORDS = ['var', 'let', 'null', 'undefined', 'true', 'false', 'if', 'else', 'this'];
644
- class Lexer {
645
- tokenize(text) {
646
- const scanner = new _Scanner(text);
647
- const tokens = [];
648
- let token = scanner.scanToken();
649
- while (token != null) {
650
- tokens.push(token);
651
- token = scanner.scanToken();
652
- }
653
- return tokens;
654
- }
655
- }
656
- class Token {
657
- constructor(index, type, numValue, strValue) {
658
- this.index = index;
659
- this.type = type;
660
- this.numValue = numValue;
661
- this.strValue = strValue;
662
- }
663
- isCharacter(code) {
664
- return this.type == TokenType.Character && this.numValue == code;
665
- }
666
- isNumber() { return this.type == TokenType.Number; }
667
- isString() { return this.type == TokenType.String; }
668
- isOperator(operater) {
669
- return this.type == TokenType.Operator && this.strValue == operater;
670
- }
671
- isIdentifier() { return this.type == TokenType.Identifier; }
672
- isKeyword() { return this.type == TokenType.Keyword; }
673
- isKeywordLet() { return this.type == TokenType.Keyword && this.strValue == 'let'; }
674
- isKeywordNull() { return this.type == TokenType.Keyword && this.strValue == 'null'; }
675
- isKeywordUndefined() {
676
- return this.type == TokenType.Keyword && this.strValue == 'undefined';
677
- }
678
- isKeywordTrue() { return this.type == TokenType.Keyword && this.strValue == 'true'; }
679
- isKeywordFalse() { return this.type == TokenType.Keyword && this.strValue == 'false'; }
680
- isKeywordThis() { return this.type == TokenType.Keyword && this.strValue == 'this'; }
681
- isError() { return this.type == TokenType.Error; }
682
- toNumber() { return this.type == TokenType.Number ? this.numValue : -1; }
683
- toString() {
684
- switch (this.type) {
685
- case TokenType.Character:
686
- case TokenType.Identifier:
687
- case TokenType.Keyword:
688
- case TokenType.Operator:
689
- case TokenType.String:
690
- case TokenType.Error:
691
- return this.strValue;
692
- case TokenType.Number:
693
- return this.numValue.toString();
694
- default:
695
- return null;
696
- }
697
- }
698
- }
699
- function newCharacterToken(index, code) {
700
- return new Token(index, TokenType.Character, code, String.fromCharCode(code));
701
- }
702
- function newIdentifierToken(index, text) {
703
- return new Token(index, TokenType.Identifier, 0, text);
704
- }
705
- function newKeywordToken(index, text) {
706
- return new Token(index, TokenType.Keyword, 0, text);
707
- }
708
- function newOperatorToken(index, text) {
709
- return new Token(index, TokenType.Operator, 0, text);
710
- }
711
- function newStringToken(index, text) {
712
- return new Token(index, TokenType.String, 0, text);
713
- }
714
- function newNumberToken(index, n) {
715
- return new Token(index, TokenType.Number, n, '');
716
- }
717
- function newErrorToken(index, message) {
718
- return new Token(index, TokenType.Error, 0, message);
719
- }
720
- const EOF = new Token(-1, TokenType.Character, 0, '');
721
- class _Scanner {
722
- constructor(input) {
723
- this.input = input;
724
- this.peek = 0;
725
- this.index = -1;
726
- this.length = input.length;
727
- this.advance();
728
- }
729
- advance() {
730
- this.peek = ++this.index >= this.length ? $EOF : this.input.charCodeAt(this.index);
731
- }
732
- scanToken() {
733
- const input = this.input, length = this.length;
734
- let peek = this.peek, index = this.index;
735
- // Skip whitespace.
736
- while (peek <= $SPACE) {
737
- if (++index >= length) {
738
- peek = $EOF;
739
- break;
740
- }
741
- else {
742
- peek = input.charCodeAt(index);
743
- }
744
- }
745
- this.peek = peek;
746
- this.index = index;
747
- if (index >= length) {
748
- return null;
749
- }
750
- // Handle identifiers and numbers.
751
- if (isIdentifierStart(peek))
752
- return this.scanIdentifier();
753
- if (isDigit(peek))
754
- return this.scanNumber(index);
755
- const start = index;
756
- switch (peek) {
757
- case $PERIOD:
758
- this.advance();
759
- return isDigit(this.peek) ? this.scanNumber(start) :
760
- newCharacterToken(start, $PERIOD);
761
- case $LPAREN:
762
- case $RPAREN:
763
- case $LBRACE:
764
- case $RBRACE:
765
- case $LBRACKET:
766
- case $RBRACKET:
767
- case $COMMA:
768
- case $COLON:
769
- case $SEMICOLON:
770
- return this.scanCharacter(start, peek);
771
- case $SQ:
772
- case $DQ:
773
- return this.scanString();
774
- case $HASH:
775
- case $PLUS:
776
- case $MINUS:
777
- case $STAR:
778
- case $SLASH:
779
- case $PERCENT:
780
- case $CARET:
781
- return this.scanOperator(start, String.fromCharCode(peek));
782
- case $QUESTION:
783
- return this.scanComplexOperator(start, '?', $PERIOD, '.');
784
- case $LT:
785
- case $GT:
786
- return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=');
787
- case $BANG:
788
- case $EQ:
789
- return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=', $EQ, '=');
790
- case $AMPERSAND:
791
- return this.scanComplexOperator(start, '&', $AMPERSAND, '&');
792
- case $BAR:
793
- return this.scanComplexOperator(start, '|', $BAR, '|');
794
- case $NBSP:
795
- while (isWhitespace(this.peek))
796
- this.advance();
797
- return this.scanToken();
798
- }
799
- this.advance();
800
- return this.error(`Unexpected character [${String.fromCharCode(peek)}]`, 0);
801
- }
802
- scanCharacter(start, code) {
803
- this.advance();
804
- return newCharacterToken(start, code);
805
- }
806
- scanOperator(start, str) {
807
- this.advance();
808
- return newOperatorToken(start, str);
809
- }
810
- /**
811
- * Tokenize a 2/3 char long operator
812
- *
813
- * @param start start index in the expression
814
- * @param one first symbol (always part of the operator)
815
- * @param twoCode code point for the second symbol
816
- * @param two second symbol (part of the operator when the second code point matches)
817
- * @param threeCode code point for the third symbol
818
- * @param three third symbol (part of the operator when provided and matches source expression)
819
- * @returns {Token}
820
- */
821
- scanComplexOperator(start, one, twoCode, two, threeCode, three) {
822
- this.advance();
823
- let str = one;
824
- if (this.peek == twoCode) {
825
- this.advance();
826
- str += two;
827
- }
828
- if (threeCode != null && this.peek == threeCode) {
829
- this.advance();
830
- str += three;
831
- }
832
- return newOperatorToken(start, str);
833
- }
834
- scanIdentifier() {
835
- const start = this.index;
836
- this.advance();
837
- while (isIdentifierPart(this.peek))
838
- this.advance();
839
- const str = this.input.substring(start, this.index);
840
- return KEYWORDS.indexOf(str) > -1 ? newKeywordToken(start, str) :
841
- newIdentifierToken(start, str);
842
- }
843
- scanNumber(start) {
844
- let simple = (this.index === start);
845
- this.advance(); // Skip initial digit.
846
- while (true) {
847
- if (isDigit(this.peek)) {
848
- // Do nothing.
849
- }
850
- else if (this.peek == $PERIOD) {
851
- simple = false;
852
- }
853
- else if (isExponentStart(this.peek)) {
854
- this.advance();
855
- if (isExponentSign(this.peek))
856
- this.advance();
857
- if (!isDigit(this.peek))
858
- return this.error('Invalid exponent', -1);
859
- simple = false;
860
- }
861
- else {
862
- break;
863
- }
864
- this.advance();
865
- }
866
- const str = this.input.substring(start, this.index);
867
- const value = simple ? NumberWrapper.parseIntAutoRadix(str) : parseFloat(str);
868
- return newNumberToken(start, value);
869
- }
870
- scanString() {
871
- const start = this.index;
872
- const quote = this.peek;
873
- this.advance(); // Skip initial quote.
874
- let buffer = '';
875
- let marker = this.index;
876
- const input = this.input;
877
- while (this.peek != quote) {
878
- if (this.peek == $BACKSLASH) {
879
- buffer += input.substring(marker, this.index);
880
- this.advance();
881
- let unescapedCode;
882
- // Workaround for TS2.1-introduced type strictness
883
- this.peek = this.peek;
884
- if (this.peek == $u) {
885
- // 4 character hex code for unicode character.
886
- const hex = input.substring(this.index + 1, this.index + 5);
887
- if (/^[0-9a-f]+$/i.test(hex)) {
888
- unescapedCode = parseInt(hex, 16);
889
- }
890
- else {
891
- return this.error(`Invalid unicode escape [\\u${hex}]`, 0);
892
- }
893
- for (let i = 0; i < 5; i++) {
894
- this.advance();
895
- }
896
- }
897
- else {
898
- unescapedCode = unescape(this.peek);
899
- this.advance();
900
- }
901
- buffer += String.fromCharCode(unescapedCode);
902
- marker = this.index;
903
- }
904
- else if (this.peek == $EOF) {
905
- return this.error('Unterminated quote', 0);
906
- }
907
- else {
908
- this.advance();
909
- }
910
- }
911
- const last = input.substring(marker, this.index);
912
- this.advance(); // Skip terminating quote.
913
- return newStringToken(start, buffer + last);
914
- }
915
- error(message, offset) {
916
- const position = this.index + offset;
917
- return newErrorToken(position, `Lexer Error: ${message} at column ${position} in expression [${this.input}]`);
918
- }
919
- }
920
- function isIdentifierStart(code) {
921
- return ($a <= code && code <= $z) || ($A <= code && code <= $Z) ||
922
- (code == $_) || (code == $$);
923
- }
924
- function isIdentifier(input) {
925
- if (input.length == 0)
926
- return false;
927
- const scanner = new _Scanner(input);
928
- if (!isIdentifierStart(scanner.peek))
929
- return false;
930
- scanner.advance();
931
- while (scanner.peek !== $EOF) {
932
- if (!isIdentifierPart(scanner.peek))
933
- return false;
934
- scanner.advance();
935
- }
936
- return true;
937
- }
938
- function isIdentifierPart(code) {
939
- return isAsciiLetter(code) || isDigit(code) || (code == $_) ||
940
- (code == $$);
941
- }
942
- function isExponentStart(code) {
943
- return code == $e || code == $E;
944
- }
945
- function isExponentSign(code) {
946
- return code == $MINUS || code == $PLUS;
947
- }
948
- function isQuote(code) {
949
- return code === $SQ || code === $DQ || code === $BT;
950
- }
951
- function unescape(code) {
952
- switch (code) {
953
- case $n:
954
- return $LF;
955
- case $f:
956
- return $FF;
957
- case $r:
958
- return $CR;
959
- case $t:
960
- return $TAB;
961
- case $v:
962
- return $VTAB;
963
- default:
964
- return code;
965
- }
966
- }
967
-
968
- /**
969
- * @license
970
- * Copyright Google Inc. All Rights Reserved.
971
- *
972
- * Use of this source code is governed by an MIT-style license that can be
973
- * found in the LICENSE file at https://angular.io/license
974
- */
975
- class SplitInterpolation {
976
- constructor(strings, expressions, offsets) {
977
- this.strings = strings;
978
- this.expressions = expressions;
979
- this.offsets = offsets;
980
- }
981
- }
982
- class TemplateBindingParseResult {
983
- constructor(templateBindings, warnings, errors) {
984
- this.templateBindings = templateBindings;
985
- this.warnings = warnings;
986
- this.errors = errors;
987
- }
988
- }
989
- function _createInterpolateRegExp(config) {
990
- const pattern = escapeRegExp(config.start) + '([\\s\\S]*?)' + escapeRegExp(config.end);
991
- return new RegExp(pattern, 'g');
992
- }
993
- class Parser {
994
- constructor(_lexer) {
995
- this._lexer = _lexer;
996
- this.errors = [];
997
- }
998
- parseAction(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
999
- this._checkNoInterpolation(input, location, interpolationConfig);
1000
- const sourceToLex = this._stripComments(input);
1001
- const tokens = this._lexer.tokenize(this._stripComments(input));
1002
- const ast = new _ParseAST(input, location, tokens, sourceToLex.length, true, this.errors, input.length - sourceToLex.length)
1003
- .parseChain();
1004
- return new ASTWithSource(ast, input, location, this.errors);
1005
- }
1006
- parseBinding(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
1007
- const ast = this._parseBindingAst(input, location, interpolationConfig);
1008
- return new ASTWithSource(ast, input, location, this.errors);
1009
- }
1010
- parseSimpleBinding(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
1011
- const ast = this._parseBindingAst(input, location, interpolationConfig);
1012
- const errors = SimpleExpressionChecker.check(ast);
1013
- if (errors.length > 0) {
1014
- this._reportError(`Host binding expression cannot contain ${errors.join(' ')}`, input, location);
1015
- }
1016
- return new ASTWithSource(ast, input, location, this.errors);
1017
- }
1018
- _reportError(message, input, errLocation, ctxLocation) {
1019
- this.errors.push(new ParserError(message, input, errLocation, ctxLocation));
1020
- }
1021
- _parseBindingAst(input, location, interpolationConfig) {
1022
- // Quotes expressions use 3rd-party expression language. We don't want to use
1023
- // our lexer or parser for that, so we check for that ahead of time.
1024
- const quote = this._parseQuote(input, location);
1025
- if (isPresent$1(quote)) {
1026
- return quote;
1027
- }
1028
- this._checkNoInterpolation(input, location, interpolationConfig);
1029
- const sourceToLex = this._stripComments(input);
1030
- const tokens = this._lexer.tokenize(sourceToLex);
1031
- return new _ParseAST(input, location, tokens, sourceToLex.length, false, this.errors, input.length - sourceToLex.length)
1032
- .parseChain();
1033
- }
1034
- _parseQuote(input, location) {
1035
- if (isBlank(input))
1036
- return null;
1037
- const prefixSeparatorIndex = input.indexOf(':');
1038
- if (prefixSeparatorIndex == -1)
1039
- return null;
1040
- const prefix = input.substring(0, prefixSeparatorIndex).trim();
1041
- if (!isIdentifier(prefix))
1042
- return null;
1043
- const uninterpretedExpression = input.substring(prefixSeparatorIndex + 1);
1044
- return new Quote(new ParseSpan(0, input.length), prefix, uninterpretedExpression, location);
1045
- }
1046
- parseTemplateBindings(prefixToken, input, location) {
1047
- const tokens = this._lexer.tokenize(input);
1048
- if (prefixToken) {
1049
- // Prefix the tokens with the tokens from prefixToken but have them take no space (0 index).
1050
- const prefixTokens = this._lexer.tokenize(prefixToken).map(t => {
1051
- t.index = 0;
1052
- return t;
1053
- });
1054
- tokens.unshift(...prefixTokens);
1055
- }
1056
- return new _ParseAST(input, location, tokens, input.length, false, this.errors, 0)
1057
- .parseTemplateBindings();
1058
- }
1059
- parseInterpolation(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
1060
- const split = this.splitInterpolation(input, location, interpolationConfig);
1061
- if (split == null)
1062
- return null;
1063
- const expressions = [];
1064
- for (let i = 0; i < split.expressions.length; ++i) {
1065
- const expressionText = split.expressions[i];
1066
- const sourceToLex = this._stripComments(expressionText);
1067
- const tokens = this._lexer.tokenize(this._stripComments(split.expressions[i]));
1068
- const ast = new _ParseAST(input, location, tokens, sourceToLex.length, false, this.errors, split.offsets[i] + (expressionText.length - sourceToLex.length))
1069
- .parseChain();
1070
- expressions.push(ast);
1071
- }
1072
- return new ASTWithSource(new Interpolation(new ParseSpan(0, isBlank(input) ? 0 : input.length), split.strings, expressions), input, location, this.errors);
1073
- }
1074
- splitInterpolation(input, location, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
1075
- const regexp = _createInterpolateRegExp(interpolationConfig);
1076
- const parts = input.split(regexp);
1077
- if (parts.length <= 1) {
1078
- return null;
1079
- }
1080
- const strings = [];
1081
- const expressions = [];
1082
- const offsets = [];
1083
- let offset = 0;
1084
- for (let i = 0; i < parts.length; i++) {
1085
- const part = parts[i];
1086
- if (i % 2 === 0) {
1087
- // fixed string
1088
- strings.push(part);
1089
- offset += part.length;
1090
- }
1091
- else if (part.trim().length > 0) {
1092
- offset += interpolationConfig.start.length;
1093
- expressions.push(part);
1094
- offsets.push(offset);
1095
- offset += part.length + interpolationConfig.end.length;
1096
- }
1097
- else {
1098
- this._reportError('Blank expressions are not allowed in interpolated strings', input, `at column ${this._findInterpolationErrorColumn(parts, i, interpolationConfig)} in`, location);
1099
- expressions.push('$implict');
1100
- offsets.push(offset);
1101
- }
1102
- }
1103
- return new SplitInterpolation(strings, expressions, offsets);
1104
- }
1105
- wrapLiteralPrimitive(input, location) {
1106
- return new ASTWithSource(new LiteralPrimitive(new ParseSpan(0, isBlank(input) ? 0 : input.length), input), input, location, this.errors);
1107
- }
1108
- _stripComments(input) {
1109
- const i = this._commentStart(input);
1110
- return isPresent$1(i) ? input.substring(0, i).trim() : input;
1111
- }
1112
- _commentStart(input) {
1113
- let outerQuote = null;
1114
- for (let i = 0; i < input.length - 1; i++) {
1115
- const char = input.charCodeAt(i);
1116
- const nextChar = input.charCodeAt(i + 1);
1117
- if (char === $SLASH && nextChar == $SLASH && isBlank(outerQuote))
1118
- return i;
1119
- if (outerQuote === char) {
1120
- outerQuote = null;
1121
- }
1122
- else if (isBlank(outerQuote) && isQuote(char)) {
1123
- outerQuote = char;
1124
- }
1125
- }
1126
- return null;
1127
- }
1128
- _checkNoInterpolation(input, location, interpolationConfig) {
1129
- const regexp = _createInterpolateRegExp(interpolationConfig);
1130
- const parts = input.split(regexp);
1131
- if (parts.length > 1) {
1132
- this._reportError(`Got interpolation (${interpolationConfig.start}${interpolationConfig.end}) where expression was expected`, input, `at column ${this._findInterpolationErrorColumn(parts, 1, interpolationConfig)} in`, location);
1133
- }
1134
- }
1135
- _findInterpolationErrorColumn(parts, partInErrIdx, interpolationConfig) {
1136
- let errLocation = '';
1137
- for (let j = 0; j < partInErrIdx; j++) {
1138
- errLocation += j % 2 === 0 ?
1139
- parts[j] :
1140
- `${interpolationConfig.start}${parts[j]}${interpolationConfig.end}`;
1141
- }
1142
- return errLocation.length;
1143
- }
1144
- }
1145
- class _ParseAST {
1146
- constructor(input, location, tokens, inputLength, parseAction, errors, offset) {
1147
- this.input = input;
1148
- this.location = location;
1149
- this.tokens = tokens;
1150
- this.inputLength = inputLength;
1151
- this.parseAction = parseAction;
1152
- this.errors = errors;
1153
- this.offset = offset;
1154
- this.rparensExpected = 0;
1155
- this.rbracketsExpected = 0;
1156
- this.rbracesExpected = 0;
1157
- this.index = 0;
1158
- }
1159
- peek(offset) {
1160
- const i = this.index + offset;
1161
- return i < this.tokens.length ? this.tokens[i] : EOF;
1162
- }
1163
- get next() { return this.peek(0); }
1164
- get inputIndex() {
1165
- return (this.index < this.tokens.length) ? this.next.index + this.offset :
1166
- this.inputLength + this.offset;
1167
- }
1168
- span(start) { return new ParseSpan(start, this.inputIndex); }
1169
- advance() { this.index++; }
1170
- optionalCharacter(code) {
1171
- if (this.next.isCharacter(code)) {
1172
- this.advance();
1173
- return true;
1174
- }
1175
- else {
1176
- return false;
1177
- }
1178
- }
1179
- peekKeywordLet() { return this.next.isKeywordLet(); }
1180
- expectCharacter(code) {
1181
- if (this.optionalCharacter(code))
1182
- return;
1183
- this.error(`Missing expected ${String.fromCharCode(code)}`);
1184
- }
1185
- optionalOperator(op) {
1186
- if (this.next.isOperator(op)) {
1187
- this.advance();
1188
- return true;
1189
- }
1190
- else {
1191
- return false;
1192
- }
1193
- }
1194
- expectOperator(operator) {
1195
- if (this.optionalOperator(operator))
1196
- return;
1197
- this.error(`Missing expected operator ${operator}`);
1198
- }
1199
- expectIdentifierOrKeyword() {
1200
- const n = this.next;
1201
- if (!n.isIdentifier() && !n.isKeyword()) {
1202
- this.error(`Unexpected token ${n}, expected identifier or keyword`);
1203
- return '';
1204
- }
1205
- this.advance();
1206
- return n.toString();
1207
- }
1208
- expectIdentifierOrKeywordOrString() {
1209
- const n = this.next;
1210
- if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) {
1211
- this.error(`Unexpected token ${n}, expected identifier, keyword, or string`);
1212
- return '';
1213
- }
1214
- this.advance();
1215
- return n.toString();
1216
- }
1217
- parseChain() {
1218
- const exprs = [];
1219
- const start = this.inputIndex;
1220
- while (this.index < this.tokens.length) {
1221
- const expr = this.parsePipe();
1222
- exprs.push(expr);
1223
- if (this.optionalCharacter($SEMICOLON)) {
1224
- if (!this.parseAction) {
1225
- this.error('Binding expression cannot contain chained expression');
1226
- }
1227
- while (this.optionalCharacter($SEMICOLON)) {
1228
- } // read all semicolons
1229
- }
1230
- else if (this.index < this.tokens.length) {
1231
- this.error(`Unexpected token '${this.next}'`);
1232
- }
1233
- }
1234
- if (exprs.length == 0)
1235
- return new EmptyExpr(this.span(start));
1236
- if (exprs.length == 1)
1237
- return exprs[0];
1238
- return new Chain(this.span(start), exprs);
1239
- }
1240
- parsePipe() {
1241
- let result = this.parseExpression();
1242
- if (this.optionalOperator('|')) {
1243
- if (this.parseAction) {
1244
- this.error('Cannot have a pipe in an action expression');
1245
- }
1246
- do {
1247
- const name = this.expectIdentifierOrKeyword();
1248
- const args = [];
1249
- while (this.optionalCharacter($COLON)) {
1250
- args.push(this.parseExpression());
1251
- }
1252
- result = new BindingPipe(this.span(result.span.start), result, name, args);
1253
- } while (this.optionalOperator('|'));
1254
- }
1255
- return result;
1256
- }
1257
- parseExpression() { return this.parseConditional(); }
1258
- parseConditional() {
1259
- const start = this.inputIndex;
1260
- const result = this.parseLogicalOr();
1261
- if (this.optionalOperator('?')) {
1262
- const yes = this.parsePipe();
1263
- let no;
1264
- if (!this.optionalCharacter($COLON)) {
1265
- const end = this.inputIndex;
1266
- const expression = this.input.substring(start, end);
1267
- this.error(`Conditional expression ${expression} requires all 3 expressions`);
1268
- no = new EmptyExpr(this.span(start));
1269
- }
1270
- else {
1271
- no = this.parsePipe();
1272
- }
1273
- return new Conditional(this.span(start), result, yes, no);
1274
- }
1275
- else {
1276
- return result;
1277
- }
1278
- }
1279
- parseLogicalOr() {
1280
- // '||'
1281
- let result = this.parseLogicalAnd();
1282
- while (this.optionalOperator('||')) {
1283
- const right = this.parseLogicalAnd();
1284
- result = new Binary(this.span(result.span.start), '||', result, right);
1285
- }
1286
- return result;
1287
- }
1288
- parseLogicalAnd() {
1289
- // '&&'
1290
- let result = this.parseEquality();
1291
- while (this.optionalOperator('&&')) {
1292
- const right = this.parseEquality();
1293
- result = new Binary(this.span(result.span.start), '&&', result, right);
1294
- }
1295
- return result;
1296
- }
1297
- parseEquality() {
1298
- // '==','!=','===','!=='
1299
- let result = this.parseRelational();
1300
- while (this.next.type == TokenType.Operator) {
1301
- const operator = this.next.strValue;
1302
- switch (operator) {
1303
- case '==':
1304
- case '===':
1305
- case '!=':
1306
- case '!==':
1307
- this.advance();
1308
- const right = this.parseRelational();
1309
- result = new Binary(this.span(result.span.start), operator, result, right);
1310
- continue;
1311
- }
1312
- break;
1313
- }
1314
- return result;
1315
- }
1316
- parseRelational() {
1317
- // '<', '>', '<=', '>='
1318
- let result = this.parseAdditive();
1319
- while (this.next.type == TokenType.Operator) {
1320
- const operator = this.next.strValue;
1321
- switch (operator) {
1322
- case '<':
1323
- case '>':
1324
- case '<=':
1325
- case '>=':
1326
- this.advance();
1327
- const right = this.parseAdditive();
1328
- result = new Binary(this.span(result.span.start), operator, result, right);
1329
- continue;
1330
- }
1331
- break;
1332
- }
1333
- return result;
1334
- }
1335
- parseAdditive() {
1336
- // '+', '-'
1337
- let result = this.parseMultiplicative();
1338
- while (this.next.type == TokenType.Operator) {
1339
- const operator = this.next.strValue;
1340
- switch (operator) {
1341
- case '+':
1342
- case '-':
1343
- this.advance();
1344
- let right = this.parseMultiplicative();
1345
- result = new Binary(this.span(result.span.start), operator, result, right);
1346
- continue;
1347
- }
1348
- break;
1349
- }
1350
- return result;
1351
- }
1352
- parseMultiplicative() {
1353
- // '*', '%', '/'
1354
- let result = this.parsePrefix();
1355
- while (this.next.type == TokenType.Operator) {
1356
- const operator = this.next.strValue;
1357
- switch (operator) {
1358
- case '*':
1359
- case '%':
1360
- case '/':
1361
- this.advance();
1362
- let right = this.parsePrefix();
1363
- result = new Binary(this.span(result.span.start), operator, result, right);
1364
- continue;
1365
- }
1366
- break;
1367
- }
1368
- return result;
1369
- }
1370
- parsePrefix() {
1371
- if (this.next.type == TokenType.Operator) {
1372
- const start = this.inputIndex;
1373
- const operator = this.next.strValue;
1374
- let result;
1375
- switch (operator) {
1376
- case '+':
1377
- this.advance();
1378
- return this.parsePrefix();
1379
- case '-':
1380
- this.advance();
1381
- result = this.parsePrefix();
1382
- return new Binary(this.span(start), operator, new LiteralPrimitive(new ParseSpan(start, start), 0), result);
1383
- case '!':
1384
- this.advance();
1385
- result = this.parsePrefix();
1386
- return new PrefixNot(this.span(start), result);
1387
- }
1388
- }
1389
- return this.parseCallChain();
1390
- }
1391
- parseCallChain() {
1392
- let result = this.parsePrimary();
1393
- while (true) {
1394
- if (this.optionalCharacter($PERIOD)) {
1395
- result = this.parseAccessMemberOrMethodCall(result, false);
1396
- }
1397
- else if (this.optionalOperator('?.')) {
1398
- result = this.parseAccessMemberOrMethodCall(result, true);
1399
- }
1400
- else if (this.optionalCharacter($LBRACKET)) {
1401
- this.rbracketsExpected++;
1402
- const key = this.parsePipe();
1403
- this.rbracketsExpected--;
1404
- this.expectCharacter($RBRACKET);
1405
- if (this.optionalOperator('=')) {
1406
- const value = this.parseConditional();
1407
- result = new KeyedWrite(this.span(result.span.start), result, key, value);
1408
- }
1409
- else {
1410
- result = new KeyedRead(this.span(result.span.start), result, key);
1411
- }
1412
- }
1413
- else if (this.optionalCharacter($LPAREN)) {
1414
- this.rparensExpected++;
1415
- const args = this.parseCallArguments();
1416
- this.rparensExpected--;
1417
- this.expectCharacter($RPAREN);
1418
- result = new FunctionCall(this.span(result.span.start), result, args);
1419
- }
1420
- else {
1421
- return result;
1422
- }
1423
- }
1424
- }
1425
- parsePrimary() {
1426
- const start = this.inputIndex;
1427
- if (this.optionalCharacter($LPAREN)) {
1428
- this.rparensExpected++;
1429
- const result = this.parsePipe();
1430
- this.rparensExpected--;
1431
- this.expectCharacter($RPAREN);
1432
- return result;
1433
- }
1434
- else if (this.next.isKeywordNull()) {
1435
- this.advance();
1436
- return new LiteralPrimitive(this.span(start), null);
1437
- }
1438
- else if (this.next.isKeywordUndefined()) {
1439
- this.advance();
1440
- return new LiteralPrimitive(this.span(start), void 0);
1441
- }
1442
- else if (this.next.isKeywordTrue()) {
1443
- this.advance();
1444
- return new LiteralPrimitive(this.span(start), true);
1445
- }
1446
- else if (this.next.isKeywordFalse()) {
1447
- this.advance();
1448
- return new LiteralPrimitive(this.span(start), false);
1449
- }
1450
- else if (this.next.isKeywordThis()) {
1451
- this.advance();
1452
- return new ImplicitReceiver(this.span(start));
1453
- }
1454
- else if (this.optionalCharacter($LBRACKET)) {
1455
- this.rbracketsExpected++;
1456
- const elements = this.parseExpressionList($RBRACKET);
1457
- this.rbracketsExpected--;
1458
- this.expectCharacter($RBRACKET);
1459
- return new LiteralArray(this.span(start), elements);
1460
- }
1461
- else if (this.next.isCharacter($LBRACE)) {
1462
- return this.parseLiteralMap();
1463
- }
1464
- else if (this.next.isIdentifier()) {
1465
- return this.parseAccessMemberOrMethodCall(new ImplicitReceiver(this.span(start)), false);
1466
- }
1467
- else if (this.next.isNumber()) {
1468
- const value = this.next.toNumber();
1469
- this.advance();
1470
- return new LiteralPrimitive(this.span(start), value);
1471
- }
1472
- else if (this.next.isString()) {
1473
- const literalValue = this.next.toString();
1474
- this.advance();
1475
- return new LiteralPrimitive(this.span(start), literalValue);
1476
- }
1477
- else if (this.index >= this.tokens.length) {
1478
- this.error(`Unexpected end of expression: ${this.input}`);
1479
- return new EmptyExpr(this.span(start));
1480
- }
1481
- else {
1482
- this.error(`Unexpected token ${this.next}`);
1483
- return new EmptyExpr(this.span(start));
1484
- }
1485
- }
1486
- parseExpressionList(terminator) {
1487
- const result = [];
1488
- if (!this.next.isCharacter(terminator)) {
1489
- do {
1490
- result.push(this.parsePipe());
1491
- } while (this.optionalCharacter($COMMA));
1492
- }
1493
- return result;
1494
- }
1495
- parseLiteralMap() {
1496
- const keys = [];
1497
- const values = [];
1498
- const start = this.inputIndex;
1499
- this.expectCharacter($LBRACE);
1500
- if (!this.optionalCharacter($RBRACE)) {
1501
- this.rbracesExpected++;
1502
- do {
1503
- const key = this.expectIdentifierOrKeywordOrString();
1504
- keys.push(key);
1505
- this.expectCharacter($COLON);
1506
- values.push(this.parsePipe());
1507
- } while (this.optionalCharacter($COMMA));
1508
- this.rbracesExpected--;
1509
- this.expectCharacter($RBRACE);
1510
- }
1511
- return new LiteralMap(this.span(start), keys, values);
1512
- }
1513
- parseAccessMemberOrMethodCall(receiver, isSafe = false) {
1514
- const start = receiver.span.start;
1515
- const id = this.expectIdentifierOrKeyword();
1516
- if (this.optionalCharacter($LPAREN)) {
1517
- this.rparensExpected++;
1518
- const args = this.parseCallArguments();
1519
- this.expectCharacter($RPAREN);
1520
- this.rparensExpected--;
1521
- const span = this.span(start);
1522
- return isSafe ? new SafeMethodCall(span, receiver, id, args) :
1523
- new MethodCall(span, receiver, id, args);
1524
- }
1525
- else {
1526
- if (isSafe) {
1527
- if (this.optionalOperator('=')) {
1528
- this.error('The \'?.\' operator cannot be used in the assignment');
1529
- return new EmptyExpr(this.span(start));
1530
- }
1531
- else {
1532
- return new SafePropertyRead(this.span(start), receiver, id);
1533
- }
1534
- }
1535
- else {
1536
- if (this.optionalOperator('=')) {
1537
- if (!this.parseAction) {
1538
- this.error('Bindings cannot contain assignments');
1539
- return new EmptyExpr(this.span(start));
1540
- }
1541
- const value = this.parseConditional();
1542
- return new PropertyWrite(this.span(start), receiver, id, value);
1543
- }
1544
- else {
1545
- return new PropertyRead(this.span(start), receiver, id);
1546
- }
1547
- }
1548
- }
1549
- }
1550
- parseCallArguments() {
1551
- if (this.next.isCharacter($RPAREN))
1552
- return [];
1553
- const positionals = [];
1554
- do {
1555
- positionals.push(this.parsePipe());
1556
- } while (this.optionalCharacter($COMMA));
1557
- return positionals;
1558
- }
1559
- /**
1560
- * An identifier, a keyword, a string with an optional `-` inbetween.
1561
- */
1562
- expectTemplateBindingKey() {
1563
- let result = '';
1564
- let operatorFound = false;
1565
- do {
1566
- result += this.expectIdentifierOrKeywordOrString();
1567
- operatorFound = this.optionalOperator('-');
1568
- if (operatorFound) {
1569
- result += '-';
1570
- }
1571
- } while (operatorFound);
1572
- return result.toString();
1573
- }
1574
- parseTemplateBindings() {
1575
- const bindings = [];
1576
- let prefix = null;
1577
- const warnings = [];
1578
- while (this.index < this.tokens.length) {
1579
- const start = this.inputIndex;
1580
- const keyIsVar = this.peekKeywordLet();
1581
- if (keyIsVar) {
1582
- this.advance();
1583
- }
1584
- let key = this.expectTemplateBindingKey();
1585
- if (!keyIsVar) {
1586
- if (prefix == null) {
1587
- prefix = key;
1588
- }
1589
- else {
1590
- key = prefix + key[0].toUpperCase() + key.substring(1);
1591
- }
1592
- }
1593
- this.optionalCharacter($COLON);
1594
- let name = null;
1595
- let expression = null;
1596
- if (keyIsVar) {
1597
- if (this.optionalOperator('=')) {
1598
- name = this.expectTemplateBindingKey();
1599
- }
1600
- else {
1601
- name = '\$implicit';
1602
- }
1603
- }
1604
- else if (this.next !== EOF && !this.peekKeywordLet()) {
1605
- const start = this.inputIndex;
1606
- const ast = this.parsePipe();
1607
- const source = this.input.substring(start - this.offset, this.inputIndex - this.offset);
1608
- expression = new ASTWithSource(ast, source, this.location, this.errors);
1609
- }
1610
- bindings.push(new TemplateBinding(this.span(start), key, keyIsVar, name, expression));
1611
- if (!this.optionalCharacter($SEMICOLON)) {
1612
- this.optionalCharacter($COMMA);
1613
- }
1614
- }
1615
- return new TemplateBindingParseResult(bindings, warnings, this.errors);
1616
- }
1617
- error(message, index = null) {
1618
- this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location));
1619
- this.skip();
1620
- }
1621
- locationText(index = null) {
1622
- if (isBlank(index))
1623
- index = this.index;
1624
- return (index < this.tokens.length) ? `at column ${this.tokens[index].index + 1} in` :
1625
- `at the end of the expression`;
1626
- }
1627
- // Error recovery should skip tokens until it encounters a recovery point. skip() treats
1628
- // the end of input and a ';' as unconditionally a recovery point. It also treats ')',
1629
- // '}' and ']' as conditional recovery points if one of calling productions is expecting
1630
- // one of these symbols. This allows skip() to recover from errors such as '(a.) + 1' allowing
1631
- // more of the AST to be retained (it doesn't skip any tokens as the ')' is retained because
1632
- // of the '(' begins an '(' <expr> ')' production). The recovery points of grouping symbols
1633
- // must be conditional as they must be skipped if none of the calling productions are not
1634
- // expecting the closing token else we will never make progress in the case of an
1635
- // extraneous group closing symbol (such as a stray ')'). This is not the case for ';' because
1636
- // parseChain() is always the root production and it expects a ';'.
1637
- // If a production expects one of these token it increments the corresponding nesting count,
1638
- // and then decrements it just prior to checking if the token is in the input.
1639
- skip() {
1640
- let n = this.next;
1641
- while (this.index < this.tokens.length && !n.isCharacter($SEMICOLON) &&
1642
- (this.rparensExpected <= 0 || !n.isCharacter($RPAREN)) &&
1643
- (this.rbracesExpected <= 0 || !n.isCharacter($RBRACE)) &&
1644
- (this.rbracketsExpected <= 0 || !n.isCharacter($RBRACKET))) {
1645
- if (this.next.isError()) {
1646
- this.errors.push(new ParserError(this.next.toString(), this.input, this.locationText(), this.location));
1647
- }
1648
- this.advance();
1649
- n = this.next;
1650
- }
1651
- }
1652
- }
1653
- class SimpleExpressionChecker {
1654
- constructor() {
1655
- this.errors = [];
1656
- }
1657
- static check(ast) {
1658
- const s = new SimpleExpressionChecker();
1659
- ast.visit(s);
1660
- return s.errors;
1661
- }
1662
- visitImplicitReceiver(ast, context) { }
1663
- visitInterpolation(ast, context) { }
1664
- visitLiteralPrimitive(ast, context) { }
1665
- visitPropertyRead(ast, context) { }
1666
- visitPropertyWrite(ast, context) { }
1667
- visitSafePropertyRead(ast, context) { }
1668
- visitMethodCall(ast, context) { }
1669
- visitSafeMethodCall(ast, context) { }
1670
- visitFunctionCall(ast, context) { }
1671
- visitLiteralArray(ast, context) { this.visitAll(ast.expressions); }
1672
- visitLiteralMap(ast, context) { this.visitAll(ast.values); }
1673
- visitBinary(ast, context) { }
1674
- visitPrefixNot(ast, context) { }
1675
- visitConditional(ast, context) { }
1676
- visitPipe(ast, context) { this.errors.push('pipes'); }
1677
- visitKeyedRead(ast, context) { }
1678
- visitKeyedWrite(ast, context) { }
1679
- visitAll(asts) { return asts.map(node => node.visit(this)); }
1680
- visitChain(ast, context) { }
1681
- visitQuote(ast, context) { }
1682
- }
1683
-
1684
- const BinaryOperations = new Map([
1685
- ['==', (left, right) => left == right],
1686
- ['===', (left, right) => left === right],
1687
- ['!=', (left, right) => left != right],
1688
- ['!==', (left, right) => left !== right],
1689
- ['&&', (left, right) => left && right],
1690
- ['||', (left, right) => left || right],
1691
- ['+', (left, right) => left + right],
1692
- ['-', (left, right) => left - right],
1693
- ['/', (left, right) => left / right],
1694
- ['*', (left, right) => left * right],
1695
- ['%', (left, right) => left % right],
1696
- ['<', (left, right) => left < right],
1697
- ['<=', (left, right) => left <= right],
1698
- ['>', (left, right) => left > right],
1699
- ['>=', (left, right) => left >= right],
1700
- ]);
1701
-
1702
- function compileToJSON(json) {
1703
- return JSON.stringify(json).replace(/"/g, '');
1704
- }
1705
- function isPresent(obj) {
1706
- return obj !== null && obj !== undefined;
1707
- }
1708
- function isJsObject(obj) {
1709
- return obj !== null && (typeof obj === 'function' || typeof obj === 'object');
1710
- }
1711
- function isFunction(val) {
1712
- return typeof val === 'function';
1713
- }
1714
-
1715
- class ParseVisitorCompiler extends RecursiveAstVisitor {
1716
- visitBinary(ast) {
1717
- const left = ast.left.visit(this);
1718
- const right = ast.right.visit(this);
1719
- return `${left} ${ast.operation} ${right}`;
1720
- }
1721
- // TODO
1722
- visitChain(ast) {
1723
- return compileToJSON(this.visitAll(ast.expressions));
1724
- }
1725
- visitConditional(ast) {
1726
- const condition = ast.condition.visit(this);
1727
- const trueExp = ast.trueExp.visit(this);
1728
- const falseExp = ast.falseExp.visit(this);
1729
- return `${condition} ? ${trueExp} : ${falseExp}`;
1730
- }
1731
- visitPipe(ast) {
1732
- const pipe = ast.name;
1733
- const args = this.visitAll(ast.args);
1734
- const value = ast.exp.visit(this);
1735
- args.unshift(value);
1736
- return `pipesCache.get('${pipe}').transform.apply(null, ${compileToJSON(args)})`;
1737
- }
1738
- // TODO
1739
- visitFunctionCall(ast) {
1740
- const target = ast.target.visit(this);
1741
- const args = compileToJSON(this.visitAll(ast.args));
1742
- return `${target}.apply(${target}, ${args})`;
1743
- }
1744
- visitImplicitReceiver(ast) {
1745
- return `context`;
1746
- }
1747
- visitInterpolation(ast) {
1748
- return this.visitAll(ast.expressions)[0];
1749
- }
1750
- visitKeyedRead(ast) {
1751
- const obj = ast.obj.visit(this);
1752
- const key = ast.key.visit(this);
1753
- return `${obj}[${key}]`;
1754
- }
1755
- visitKeyedWrite(ast) {
1756
- return null;
1757
- }
1758
- visitLiteralArray(ast) {
1759
- return compileToJSON(this.visitAll(ast.expressions));
1760
- }
1761
- visitLiteralMap(ast) {
1762
- const result = {};
1763
- const keys = ast.keys;
1764
- const values = this.visitAll(ast.values);
1765
- for (let i = 0, length = keys.length; i < length; i++) {
1766
- result[keys[i]] = values[i];
1767
- }
1768
- return compileToJSON(result);
1769
- }
1770
- visitLiteralPrimitive(ast) {
1771
- return typeof ast.value === 'string' ? `'${ast.value}'` : ast.value;
1772
- }
1773
- visitMethodCall(ast) {
1774
- const methodName = ast.name;
1775
- const receiver = ast.receiver.visit(this);
1776
- const args = compileToJSON(this.visitAll(ast.args));
1777
- return `${receiver}['${methodName}'].apply(${receiver}, ${args})`;
1778
- }
1779
- visitPrefixNot(ast) {
1780
- return ast.expression.visit(this);
1781
- }
1782
- visitPropertyRead(ast) {
1783
- const property = ast.name;
1784
- const receiver = ast.receiver.visit(this);
1785
- return `${receiver}['${property}']`;
1786
- }
1787
- visitPropertyWrite(ast) {
1788
- return null;
1789
- }
1790
- visitSafePropertyRead(ast) {
1791
- const property = ast.name;
1792
- const receiver = ast.receiver.visit(this);
1793
- return `${receiver}['${property}']`;
1794
- }
1795
- visitSafeMethodCall(ast) {
1796
- const methodName = ast.name;
1797
- const receiver = ast.receiver.visit(this);
1798
- const args = compileToJSON(this.visitAll(ast.args));
1799
- return `${receiver}['${methodName}'].apply(${receiver}, ${args})`;
1800
- }
1801
- visitAll(asts) {
1802
- return asts.map(ast => ast.visit(this));
1803
- }
1804
- visitQuote(ast) {
1805
- return null;
1806
- }
1807
- }
1808
-
1809
- class ParseVisitorResolver extends RecursiveAstVisitor {
1810
- constructor(pipes) {
1811
- super();
1812
- this.pipes = pipes;
1813
- }
1814
- ;
1815
- visitBinary(ast, context) {
1816
- const execFn = BinaryOperations.get(ast.operation);
1817
- if (!execFn) {
1818
- throw new Error(`Parse ERROR: on visitBinary, unknown operator ${ast.operation}`);
1819
- }
1820
- return execFn(ast.left.visit(this, context), ast.right.visit(this, context));
1821
- }
1822
- // TODO
1823
- visitChain(ast, context) {
1824
- return this.visitAll(ast.expressions, context);
1825
- }
1826
- visitConditional(ast, context) {
1827
- if (ast.condition.visit(this, context)) {
1828
- return ast.trueExp.visit(this, context);
1829
- }
1830
- else if (isPresent(ast.falseExp)) {
1831
- return ast.falseExp.visit(this, context);
1832
- }
1833
- return null;
1834
- }
1835
- visitPipe(ast, context) {
1836
- const pipe = this.pipes.get(ast.name);
1837
- if (!pipe) {
1838
- throw new Error(`pipe ${ast.name} not found.`);
1839
- }
1840
- if (!pipe.transform) {
1841
- throw new Error(`Parse ERROR: on visitPipe, transform method doesn't exist on pipe ${ast.name}.`);
1842
- }
1843
- const value = ast.exp.visit(this, context);
1844
- const pipeArgs = this.visitAll(ast.args, context);
1845
- pipeArgs.unshift(value);
1846
- return pipe.transform.apply(null, pipeArgs);
1847
- }
1848
- // TODO
1849
- visitFunctionCall(ast, context) {
1850
- const target = ast.target.visit(this, context);
1851
- if (!isFunction(target)) {
1852
- throw new Error(`Parse ERROR: on visitFunctionCall, target is not a function.`);
1853
- }
1854
- const args = this.visitAll(ast.args, context);
1855
- return target.apply(target, args);
1856
- }
1857
- visitImplicitReceiver(ast, context) {
1858
- return context;
1859
- }
1860
- visitInterpolation(ast, context) {
1861
- return this.visitAll(ast.expressions, context)[0];
1862
- }
1863
- visitKeyedRead(ast, context) {
1864
- const obj = ast.obj.visit(this, context);
1865
- const key = ast.key.visit(this, context);
1866
- return obj[key];
1867
- }
1868
- visitKeyedWrite(ast, context) {
1869
- const obj = ast.obj.visit(this, context);
1870
- const key = ast.key.visit(this, context);
1871
- const value = ast.value.visit(this, context);
1872
- obj[key] = value;
1873
- return null;
1874
- }
1875
- visitLiteralArray(ast, context) {
1876
- return this.visitAll(ast.expressions, context);
1877
- }
1878
- visitLiteralMap(ast, context) {
1879
- const result = {};
1880
- const keys = ast.keys;
1881
- const values = this.visitAll(ast.values, context);
1882
- for (let i = 0, length = keys.length; i < length; i++) {
1883
- result[keys[i]] = values[i];
1884
- }
1885
- return result;
1886
- }
1887
- visitLiteralPrimitive(ast, context) {
1888
- return ast.value;
1889
- }
1890
- visitMethodCall(ast, context) {
1891
- const receiver = ast.receiver.visit(this, context);
1892
- if (!isJsObject(receiver)) {
1893
- throw new Error(`Parse ERROR: on visitMethodCall, invalid method receiver.`);
1894
- }
1895
- const method = receiver[ast.name];
1896
- if (!isFunction(method)) {
1897
- throw new Error(`Parse ERROR: on visitMethodCall, method ${ast.name} doesn't exist on receiver.`);
1898
- }
1899
- const args = this.visitAll(ast.args, context);
1900
- return method.apply(receiver, args);
1901
- }
1902
- visitPrefixNot(ast, context) {
1903
- return ast.expression.visit(this, context);
1904
- }
1905
- visitPropertyRead(ast, context) {
1906
- const receiver = ast.receiver.visit(this, context);
1907
- if (!isJsObject(receiver)) {
1908
- throw new Error(`Parse ERROR: on visitPropertyRead, invalid property receiver.`);
1909
- }
1910
- return receiver[ast.name];
1911
- }
1912
- visitPropertyWrite(ast, context) {
1913
- const receiver = ast.receiver.visit(this, context);
1914
- if (!isJsObject(receiver)) {
1915
- throw new Error(`Parse ERROR: on visitPropertyRead, invalid property receiver.`);
1916
- }
1917
- receiver[ast.name] = ast.value.visit(this, context);
1918
- return null;
1919
- }
1920
- visitSafePropertyRead(ast, context) {
1921
- const receiver = ast.receiver.visit(this, context);
1922
- if (!isJsObject(receiver)) {
1923
- throw new Error(`Parse ERROR: on visitSafePropertyRead, invalid property receiver.`);
1924
- }
1925
- return receiver[ast.name];
1926
- }
1927
- visitSafeMethodCall(ast, context) {
1928
- const receiver = ast.receiver.visit(this, context);
1929
- if (!isJsObject(receiver)) {
1930
- throw new Error(`Parse ERROR: on visitSafeMethodCall, invalid method receiver.`);
1931
- }
1932
- const method = receiver[ast.name];
1933
- if (!isFunction(method)) {
1934
- throw new Error(`Parse ERROR: on visitSafeMethodCall, method ${ast.name} doesn't exist on receiver.`);
1935
- }
1936
- const args = this.visitAll(ast.args, context);
1937
- return method.apply(receiver, args);
1938
- }
1939
- visitAll(asts, context) {
1940
- return asts.map(ast => ast.visit(this, context));
1941
- }
1942
- visitQuote(ast, context) {
1943
- throw new Error(`Parse ERROR: on visitQuote, quote expression not allowed.`);
1944
- }
1945
- }
1946
-
1947
- const PIPES_CONFIG = new InjectionToken('PipesConfig');
1948
- class Parse {
1949
- /**
1950
- * Used to dependency inject the Angular 2 parser.
1951
- */
1952
- constructor(pipesConfigs) {
1953
- this._parser = new Parser(new Lexer());
1954
- this._pipesCache = new Map();
1955
- this._evalCache = new Map();
1956
- this._calcCache = new Map();
1957
- if (pipesConfigs && pipesConfigs.length) {
1958
- pipesConfigs
1959
- .filter(pipes => pipes && pipes.length)
1960
- .forEach(pipes => pipes.forEach((pipeData) => this._pipesCache.set(pipeData.pipeName, pipeData.pipeInstance)));
1961
- }
1962
- }
1963
- eval(expression) {
1964
- if (this._evalCache.has(expression)) {
1965
- return this._evalCache.get(expression);
1966
- }
1967
- const visitor = new ParseVisitorCompiler();
1968
- let ast = this._parser.parseInterpolation(expression, 'Parse');
1969
- if (!ast) {
1970
- ast = this._parser.parseBinding(expression, 'Parse');
1971
- }
1972
- const fnBody = ast.visit(visitor);
1973
- const pipesCache = this._pipesCache;
1974
- const getFn = new Function('context', 'pipesCache', `return ${fnBody};`);
1975
- const evalParse = function evalParse(context) {
1976
- return getFn(context, pipesCache);
1977
- };
1978
- this._evalCache.set(expression, evalParse);
1979
- return evalParse;
1980
- }
1981
- calc(expression) {
1982
- if (this._calcCache.has(expression)) {
1983
- return this._calcCache.get(expression);
1984
- }
1985
- const visitor = new ParseVisitorResolver(this._pipesCache);
1986
- let ast = this._parser.parseInterpolation(expression, 'Parse');
1987
- if (!ast) {
1988
- ast = this._parser.parseBinding(expression, 'Parse');
1989
- }
1990
- const calcParse = function calcParse(context) {
1991
- return ast.visit(visitor, context);
1992
- };
1993
- this._calcCache.set(expression, calcParse);
1994
- return calcParse;
1995
- }
1996
- }
1997
- Parse.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Parse, deps: [{ token: PIPES_CONFIG, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
1998
- Parse.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Parse, providedIn: 'root' });
1999
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Parse, decorators: [{
2000
- type: Injectable,
2001
- args: [{ providedIn: 'root' }]
2002
- }], ctorParameters: function () {
2003
- return [{ type: undefined, decorators: [{
2004
- type: Optional
2005
- }, {
2006
- type: Inject,
2007
- args: [PIPES_CONFIG]
2008
- }] }];
2009
- } });
2010
-
2011
- class Angular2ParseModule {
2012
- static forRoot(pipesConfigMap) {
2013
- return {
2014
- ngModule: Angular2ParseModule,
2015
- providers: [{ provide: PIPES_CONFIG, multi: true, useValue: pipesConfigMap || [] }]
2016
- };
2017
- }
2018
- }
2019
- Angular2ParseModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Angular2ParseModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2020
- Angular2ParseModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Angular2ParseModule });
2021
- Angular2ParseModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Angular2ParseModule });
2022
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.0", ngImport: i0, type: Angular2ParseModule, decorators: [{
2023
- type: NgModule
2024
- }] });
2025
-
2026
- /*
2027
- * Public API Surface of angular2parse
2028
- */
2029
-
2030
- /**
2031
- * Generated bundle index. Do not edit.
2032
- */
2033
-
2034
- export { Angular2ParseModule, PIPES_CONFIG, Parse };
2035
- //# sourceMappingURL=auscope-angular2parse.mjs.map