@angular/core 20.1.0-next.2 → 20.1.0-next.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 (76) hide show
  1. package/{api.d-Dwpmmn5j.d.ts → api.d.d.ts} +2 -2
  2. package/{chrome_dev_tools_performance.d-Dk_7kdX9.d.ts → chrome_dev_tools_performance.d.d.ts} +4 -4
  3. package/{discovery.d-AiW64LSq.d.ts → discovery.d.d.ts} +10 -5
  4. package/{event_dispatcher.d-BReQpZfC.d.ts → event_dispatcher.d.d.ts} +1 -1
  5. package/fesm2022/{attribute-BWp59EjE.mjs → attribute.mjs} +2 -2
  6. package/fesm2022/attribute.mjs.map +1 -0
  7. package/fesm2022/core.mjs +13 -13
  8. package/fesm2022/core.mjs.map +1 -1
  9. package/fesm2022/{debug_node-BFi6TVHr.mjs → debug_node.mjs} +239 -16
  10. package/fesm2022/debug_node.mjs.map +1 -0
  11. package/fesm2022/injector.mjs +53 -0
  12. package/fesm2022/injector.mjs.map +1 -0
  13. package/fesm2022/primitives/di.mjs +6 -37
  14. package/fesm2022/primitives/di.mjs.map +1 -1
  15. package/fesm2022/primitives/event-dispatch.mjs +2 -2
  16. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  17. package/fesm2022/primitives/signals.mjs +5 -5
  18. package/fesm2022/primitives/signals.mjs.map +1 -1
  19. package/fesm2022/{resource-BwChsGJq.mjs → resource.mjs} +12 -8
  20. package/fesm2022/resource.mjs.map +1 -0
  21. package/fesm2022/{root_effect_scheduler-BkoRKl64.mjs → root_effect_scheduler.mjs} +13 -6
  22. package/fesm2022/root_effect_scheduler.mjs.map +1 -0
  23. package/fesm2022/rxjs-interop.mjs +6 -6
  24. package/fesm2022/rxjs-interop.mjs.map +1 -1
  25. package/fesm2022/{signal-nCiHhWf6.mjs → signal.mjs} +2 -2
  26. package/fesm2022/signal.mjs.map +1 -0
  27. package/fesm2022/testing.mjs +143 -54
  28. package/fesm2022/testing.mjs.map +1 -1
  29. package/fesm2022/{untracked-DmD_2MlC.mjs → untracked.mjs} +3 -3
  30. package/fesm2022/untracked.mjs.map +1 -0
  31. package/fesm2022/{weak_ref-BaIq-pgY.mjs → weak_ref.mjs} +2 -2
  32. package/fesm2022/weak_ref.mjs.map +1 -0
  33. package/{graph.d-BcIOep_B.d.ts → graph.d.d.ts} +1 -1
  34. package/index.d.ts +101 -12
  35. package/package.json +2 -2
  36. package/primitives/di/index.d.ts +4 -2
  37. package/primitives/event-dispatch/index.d.ts +3 -3
  38. package/primitives/signals/index.d.ts +6 -6
  39. package/rxjs-interop/index.d.ts +5 -5
  40. package/schematics/bundles/{apply_import_manager-BsIRDO9W.cjs → apply_import_manager-C11Q8021.cjs} +3 -3
  41. package/schematics/bundles/{checker-CY7a8ko8.cjs → checker-BVnpy__J.cjs} +547 -308
  42. package/schematics/bundles/cleanup-unused-imports.cjs +5 -5
  43. package/schematics/bundles/{compiler_host-DNYQkH4l.cjs → compiler_host-j95cyBKm.cjs} +2 -2
  44. package/schematics/bundles/control-flow-migration.cjs +3 -3
  45. package/schematics/bundles/document-core.cjs +5 -5
  46. package/schematics/bundles/imports-CIX-JgAN.cjs +1 -1
  47. package/schematics/bundles/{index-BUgQDm-J.cjs → index-BkA2Tb_u.cjs} +32 -17
  48. package/schematics/bundles/{index-BJ3PYYwQ.cjs → index-DYpSE68_.cjs} +4 -4
  49. package/schematics/bundles/inject-flags.cjs +5 -5
  50. package/schematics/bundles/inject-migration.cjs +3 -3
  51. package/schematics/bundles/leading_space-D9nQ8UQC.cjs +1 -1
  52. package/schematics/bundles/{migrate_ts_type_references-MBd4NBjn.cjs → migrate_ts_type_references-Covsxz7y.cjs} +27 -5
  53. package/schematics/bundles/ng_decorators-B5HCqr20.cjs +1 -1
  54. package/schematics/bundles/nodes-B16H9JUd.cjs +1 -1
  55. package/schematics/bundles/output-migration.cjs +6 -6
  56. package/schematics/bundles/{project_paths-C5Df24y1.cjs → project_paths-3GwjSb-R.cjs} +3 -3
  57. package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.cjs +1 -1
  58. package/schematics/bundles/property_name-BBwFuqMe.cjs +1 -1
  59. package/schematics/bundles/route-lazy-loading.cjs +3 -3
  60. package/schematics/bundles/self-closing-tags-migration.cjs +4 -4
  61. package/schematics/bundles/signal-input-migration.cjs +7 -7
  62. package/schematics/bundles/signal-queries-migration.cjs +7 -7
  63. package/schematics/bundles/signals.cjs +7 -7
  64. package/schematics/bundles/standalone-migration.cjs +4 -4
  65. package/schematics/bundles/symbol-VPWguRxr.cjs +1 -1
  66. package/schematics/bundles/test-bed-get.cjs +4 -4
  67. package/{signal.d-BcmOdASA.d.ts → signal.d.d.ts} +2 -2
  68. package/testing/index.d.ts +73 -6
  69. package/{weak_ref.d-eGOEP9S1.d.ts → weak_ref.d.d.ts} +1 -1
  70. package/fesm2022/attribute-BWp59EjE.mjs.map +0 -1
  71. package/fesm2022/debug_node-BFi6TVHr.mjs.map +0 -1
  72. package/fesm2022/resource-BwChsGJq.mjs.map +0 -1
  73. package/fesm2022/root_effect_scheduler-BkoRKl64.mjs.map +0 -1
  74. package/fesm2022/signal-nCiHhWf6.mjs.map +0 -1
  75. package/fesm2022/untracked-DmD_2MlC.mjs.map +0 -1
  76. package/fesm2022/weak_ref-BaIq-pgY.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.1.0-next.2
3
+ * @license Angular v20.1.0-next.3
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
@@ -955,6 +955,15 @@ var BinaryOperator;
955
955
  BinaryOperator[BinaryOperator["NullishCoalesce"] = 18] = "NullishCoalesce";
956
956
  BinaryOperator[BinaryOperator["Exponentiation"] = 19] = "Exponentiation";
957
957
  BinaryOperator[BinaryOperator["In"] = 20] = "In";
958
+ BinaryOperator[BinaryOperator["AdditionAssignment"] = 21] = "AdditionAssignment";
959
+ BinaryOperator[BinaryOperator["SubtractionAssignment"] = 22] = "SubtractionAssignment";
960
+ BinaryOperator[BinaryOperator["MultiplicationAssignment"] = 23] = "MultiplicationAssignment";
961
+ BinaryOperator[BinaryOperator["DivisionAssignment"] = 24] = "DivisionAssignment";
962
+ BinaryOperator[BinaryOperator["RemainderAssignment"] = 25] = "RemainderAssignment";
963
+ BinaryOperator[BinaryOperator["ExponentiationAssignment"] = 26] = "ExponentiationAssignment";
964
+ BinaryOperator[BinaryOperator["AndAssignment"] = 27] = "AndAssignment";
965
+ BinaryOperator[BinaryOperator["OrAssignment"] = 28] = "OrAssignment";
966
+ BinaryOperator[BinaryOperator["NullishCoalesceAssignment"] = 29] = "NullishCoalesceAssignment";
958
967
  })(BinaryOperator || (BinaryOperator = {}));
959
968
  function nullSafeIsEquivalent(base, other) {
960
969
  if (base == null || other == null) {
@@ -1674,6 +1683,19 @@ class BinaryOperatorExpr extends Expression {
1674
1683
  clone() {
1675
1684
  return new BinaryOperatorExpr(this.operator, this.lhs.clone(), this.rhs.clone(), this.type, this.sourceSpan);
1676
1685
  }
1686
+ isAssignment() {
1687
+ const op = this.operator;
1688
+ return (op === BinaryOperator.Assign ||
1689
+ op === BinaryOperator.AdditionAssignment ||
1690
+ op === BinaryOperator.SubtractionAssignment ||
1691
+ op === BinaryOperator.MultiplicationAssignment ||
1692
+ op === BinaryOperator.DivisionAssignment ||
1693
+ op === BinaryOperator.RemainderAssignment ||
1694
+ op === BinaryOperator.ExponentiationAssignment ||
1695
+ op === BinaryOperator.AndAssignment ||
1696
+ op === BinaryOperator.OrAssignment ||
1697
+ op === BinaryOperator.NullishCoalesceAssignment);
1698
+ }
1677
1699
  }
1678
1700
  class ReadPropExpr extends Expression {
1679
1701
  receiver;
@@ -2476,6 +2498,23 @@ class Identifiers {
2476
2498
  static element = { name: 'ɵɵelement', moduleName: CORE };
2477
2499
  static elementStart = { name: 'ɵɵelementStart', moduleName: CORE };
2478
2500
  static elementEnd = { name: 'ɵɵelementEnd', moduleName: CORE };
2501
+ static domElement = { name: 'ɵɵdomElement', moduleName: CORE };
2502
+ static domElementStart = { name: 'ɵɵdomElementStart', moduleName: CORE };
2503
+ static domElementEnd = { name: 'ɵɵdomElementEnd', moduleName: CORE };
2504
+ static domElementContainer = {
2505
+ name: 'ɵɵdomElementContainer',
2506
+ moduleName: CORE,
2507
+ };
2508
+ static domElementContainerStart = {
2509
+ name: 'ɵɵdomElementContainerStart',
2510
+ moduleName: CORE,
2511
+ };
2512
+ static domElementContainerEnd = {
2513
+ name: 'ɵɵdomElementContainerEnd',
2514
+ moduleName: CORE,
2515
+ };
2516
+ static domTemplate = { name: 'ɵɵdomTemplate', moduleName: CORE };
2517
+ static domListener = { name: 'ɵɵdomListener', moduleName: CORE };
2479
2518
  static advance = { name: 'ɵɵadvance', moduleName: CORE };
2480
2519
  static syntheticHostProperty = {
2481
2520
  name: 'ɵɵsyntheticHostProperty',
@@ -3083,6 +3122,38 @@ class _EmittedLine {
3083
3122
  this.indent = indent;
3084
3123
  }
3085
3124
  }
3125
+ const BINARY_OPERATORS$4 = new Map([
3126
+ [BinaryOperator.And, '&&'],
3127
+ [BinaryOperator.Bigger, '>'],
3128
+ [BinaryOperator.BiggerEquals, '>='],
3129
+ [BinaryOperator.BitwiseOr, '|'],
3130
+ [BinaryOperator.BitwiseAnd, '&'],
3131
+ [BinaryOperator.Divide, '/'],
3132
+ [BinaryOperator.Assign, '='],
3133
+ [BinaryOperator.Equals, '=='],
3134
+ [BinaryOperator.Identical, '==='],
3135
+ [BinaryOperator.Lower, '<'],
3136
+ [BinaryOperator.LowerEquals, '<='],
3137
+ [BinaryOperator.Minus, '-'],
3138
+ [BinaryOperator.Modulo, '%'],
3139
+ [BinaryOperator.Exponentiation, '**'],
3140
+ [BinaryOperator.Multiply, '*'],
3141
+ [BinaryOperator.NotEquals, '!='],
3142
+ [BinaryOperator.NotIdentical, '!=='],
3143
+ [BinaryOperator.NullishCoalesce, '??'],
3144
+ [BinaryOperator.Or, '||'],
3145
+ [BinaryOperator.Plus, '+'],
3146
+ [BinaryOperator.In, 'in'],
3147
+ [BinaryOperator.AdditionAssignment, '+='],
3148
+ [BinaryOperator.SubtractionAssignment, '-='],
3149
+ [BinaryOperator.MultiplicationAssignment, '*='],
3150
+ [BinaryOperator.DivisionAssignment, '/='],
3151
+ [BinaryOperator.RemainderAssignment, '%='],
3152
+ [BinaryOperator.ExponentiationAssignment, '**='],
3153
+ [BinaryOperator.AndAssignment, '&&='],
3154
+ [BinaryOperator.OrAssignment, '||='],
3155
+ [BinaryOperator.NullishCoalesceAssignment, '??='],
3156
+ ]);
3086
3157
  class EmitterVisitorContext {
3087
3158
  _indent;
3088
3159
  static createRoot() {
@@ -3405,79 +3476,15 @@ class AbstractEmitterVisitor {
3405
3476
  return null;
3406
3477
  }
3407
3478
  visitBinaryOperatorExpr(ast, ctx) {
3408
- let opStr;
3409
- switch (ast.operator) {
3410
- case BinaryOperator.Assign:
3411
- opStr = '=';
3412
- break;
3413
- case BinaryOperator.Equals:
3414
- opStr = '==';
3415
- break;
3416
- case BinaryOperator.Identical:
3417
- opStr = '===';
3418
- break;
3419
- case BinaryOperator.NotEquals:
3420
- opStr = '!=';
3421
- break;
3422
- case BinaryOperator.NotIdentical:
3423
- opStr = '!==';
3424
- break;
3425
- case BinaryOperator.And:
3426
- opStr = '&&';
3427
- break;
3428
- case BinaryOperator.BitwiseOr:
3429
- opStr = '|';
3430
- break;
3431
- case BinaryOperator.BitwiseAnd:
3432
- opStr = '&';
3433
- break;
3434
- case BinaryOperator.Or:
3435
- opStr = '||';
3436
- break;
3437
- case BinaryOperator.Plus:
3438
- opStr = '+';
3439
- break;
3440
- case BinaryOperator.Minus:
3441
- opStr = '-';
3442
- break;
3443
- case BinaryOperator.Divide:
3444
- opStr = '/';
3445
- break;
3446
- case BinaryOperator.Multiply:
3447
- opStr = '*';
3448
- break;
3449
- case BinaryOperator.Modulo:
3450
- opStr = '%';
3451
- break;
3452
- case BinaryOperator.Exponentiation:
3453
- opStr = '**';
3454
- break;
3455
- case BinaryOperator.Lower:
3456
- opStr = '<';
3457
- break;
3458
- case BinaryOperator.LowerEquals:
3459
- opStr = '<=';
3460
- break;
3461
- case BinaryOperator.Bigger:
3462
- opStr = '>';
3463
- break;
3464
- case BinaryOperator.BiggerEquals:
3465
- opStr = '>=';
3466
- break;
3467
- case BinaryOperator.NullishCoalesce:
3468
- opStr = '??';
3469
- break;
3470
- case BinaryOperator.In:
3471
- opStr = 'in';
3472
- break;
3473
- default:
3474
- throw new Error(`Unknown operator ${ast.operator}`);
3479
+ const operator = BINARY_OPERATORS$4.get(ast.operator);
3480
+ if (!operator) {
3481
+ throw new Error(`Unknown operator ${ast.operator}`);
3475
3482
  }
3476
3483
  const parens = ast !== this.lastIfCondition;
3477
3484
  if (parens)
3478
3485
  ctx.print(ast, `(`);
3479
3486
  ast.lhs.visitExpression(this, ctx);
3480
- ctx.print(ast, ` ${opStr} `);
3487
+ ctx.print(ast, ` ${operator} `);
3481
3488
  ast.rhs.visitExpression(this, ctx);
3482
3489
  if (parens)
3483
3490
  ctx.print(ast, `)`);
@@ -3842,18 +3849,6 @@ function getInjectFn(target) {
3842
3849
  }
3843
3850
  }
3844
3851
 
3845
- class ParserError {
3846
- input;
3847
- errLocation;
3848
- ctxLocation;
3849
- message;
3850
- constructor(message, input, errLocation, ctxLocation) {
3851
- this.input = input;
3852
- this.errLocation = errLocation;
3853
- this.ctxLocation = ctxLocation;
3854
- this.message = `Parser Error: ${message} ${errLocation} [${input}] in ${ctxLocation}`;
3855
- }
3856
- }
3857
3852
  class ParseSpan {
3858
3853
  start;
3859
3854
  end;
@@ -4072,6 +4067,18 @@ class Binary extends AST {
4072
4067
  visit(visitor, context = null) {
4073
4068
  return visitor.visitBinary(this, context);
4074
4069
  }
4070
+ static isAssignmentOperation(op) {
4071
+ return (op === '=' ||
4072
+ op === '+=' ||
4073
+ op === '-=' ||
4074
+ op === '*=' ||
4075
+ op === '/=' ||
4076
+ op === '%=' ||
4077
+ op === '**=' ||
4078
+ op === '&&=' ||
4079
+ op === '||=' ||
4080
+ op === '??=');
4081
+ }
4075
4082
  }
4076
4083
  /**
4077
4084
  * For backwards compatibility reasons, `Unary` inherits from `Binary` and mimics the binary AST
@@ -11021,6 +11028,14 @@ var CompilationJobKind;
11021
11028
  CompilationJobKind[CompilationJobKind["Host"] = 1] = "Host";
11022
11029
  CompilationJobKind[CompilationJobKind["Both"] = 2] = "Both";
11023
11030
  })(CompilationJobKind || (CompilationJobKind = {}));
11031
+ /** Possible modes in which a component's template can be compiled. */
11032
+ var TemplateCompilationMode;
11033
+ (function (TemplateCompilationMode) {
11034
+ /** Supports the full instruction set, including directives. */
11035
+ TemplateCompilationMode[TemplateCompilationMode["Full"] = 0] = "Full";
11036
+ /** Uses a narrower instruction set that doesn't support directives and allows optimizations. */
11037
+ TemplateCompilationMode[TemplateCompilationMode["DomOnly"] = 1] = "DomOnly";
11038
+ })(TemplateCompilationMode || (TemplateCompilationMode = {}));
11024
11039
  /**
11025
11040
  * An entire ongoing compilation, which will result in one or more template functions when complete.
11026
11041
  * Contains one or more corresponding compilation units.
@@ -11029,10 +11044,12 @@ class CompilationJob {
11029
11044
  componentName;
11030
11045
  pool;
11031
11046
  compatibility;
11032
- constructor(componentName, pool, compatibility) {
11047
+ mode;
11048
+ constructor(componentName, pool, compatibility, mode) {
11033
11049
  this.componentName = componentName;
11034
11050
  this.pool = pool;
11035
11051
  this.compatibility = compatibility;
11052
+ this.mode = mode;
11036
11053
  }
11037
11054
  kind = CompilationJobKind.Both;
11038
11055
  /**
@@ -11057,8 +11074,8 @@ class ComponentCompilationJob extends CompilationJob {
11057
11074
  allDeferrableDepsFn;
11058
11075
  relativeTemplatePath;
11059
11076
  enableDebugLocations;
11060
- constructor(componentName, pool, compatibility, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations) {
11061
- super(componentName, pool, compatibility);
11077
+ constructor(componentName, pool, compatibility, mode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations) {
11078
+ super(componentName, pool, compatibility, mode);
11062
11079
  this.relativeContextFilePath = relativeContextFilePath;
11063
11080
  this.i18nUseExternalIds = i18nUseExternalIds;
11064
11081
  this.deferMeta = deferMeta;
@@ -11203,8 +11220,8 @@ class ViewCompilationUnit extends CompilationUnit {
11203
11220
  * Compilation-in-progress of a host binding, which contains a single unit for that host binding.
11204
11221
  */
11205
11222
  class HostBindingCompilationJob extends CompilationJob {
11206
- constructor(componentName, pool, compatibility) {
11207
- super(componentName, pool, compatibility);
11223
+ constructor(componentName, pool, compatibility, mode) {
11224
+ super(componentName, pool, compatibility, mode);
11208
11225
  this.root = new HostBindingCompilationUnit(this);
11209
11226
  }
11210
11227
  kind = CompilationJobKind.Host;
@@ -11637,6 +11654,14 @@ const CHAIN_COMPATIBILITY = new Map([
11637
11654
  [Identifiers.declareLet, Identifiers.declareLet],
11638
11655
  [Identifiers.conditionalCreate, Identifiers.conditionalBranchCreate],
11639
11656
  [Identifiers.conditionalBranchCreate, Identifiers.conditionalBranchCreate],
11657
+ [Identifiers.domElement, Identifiers.domElement],
11658
+ [Identifiers.domElementStart, Identifiers.domElementStart],
11659
+ [Identifiers.domElementEnd, Identifiers.domElementEnd],
11660
+ [Identifiers.domElementContainer, Identifiers.domElementContainer],
11661
+ [Identifiers.domElementContainerStart, Identifiers.domElementContainerStart],
11662
+ [Identifiers.domElementContainerEnd, Identifiers.domElementContainerEnd],
11663
+ [Identifiers.domListener, Identifiers.domListener],
11664
+ [Identifiers.domTemplate, Identifiers.domTemplate],
11640
11665
  ]);
11641
11666
  /**
11642
11667
  * Chaining results in repeated call expressions, causing a deep AST of receiver expressions. To prevent running out of
@@ -11809,6 +11834,15 @@ const BINARY_OPERATORS$3 = new Map([
11809
11834
  ['||', BinaryOperator.Or],
11810
11835
  ['+', BinaryOperator.Plus],
11811
11836
  ['in', BinaryOperator.In],
11837
+ ['+=', BinaryOperator.AdditionAssignment],
11838
+ ['-=', BinaryOperator.SubtractionAssignment],
11839
+ ['*=', BinaryOperator.MultiplicationAssignment],
11840
+ ['/=', BinaryOperator.DivisionAssignment],
11841
+ ['%=', BinaryOperator.RemainderAssignment],
11842
+ ['**=', BinaryOperator.ExponentiationAssignment],
11843
+ ['&&=', BinaryOperator.AndAssignment],
11844
+ ['||=', BinaryOperator.OrAssignment],
11845
+ ['??=', BinaryOperator.NullishCoalesceAssignment],
11812
11846
  ]);
11813
11847
  function namespaceForKey(namespacePrefixKey) {
11814
11848
  const NAMESPACES = new Map([
@@ -15596,13 +15630,6 @@ const NAMED_ENTITIES = {
15596
15630
  const NGSP_UNICODE = '\uE500';
15597
15631
  NAMED_ENTITIES['ngsp'] = NGSP_UNICODE;
15598
15632
 
15599
- class TokenError extends ParseError {
15600
- tokenType;
15601
- constructor(errorMsg, tokenType, span) {
15602
- super(span, errorMsg);
15603
- this.tokenType = tokenType;
15604
- }
15605
- }
15606
15633
  class TokenizeResult {
15607
15634
  tokens;
15608
15635
  errors;
@@ -15634,12 +15661,6 @@ var CharacterReferenceType;
15634
15661
  CharacterReferenceType["HEX"] = "hexadecimal";
15635
15662
  CharacterReferenceType["DEC"] = "decimal";
15636
15663
  })(CharacterReferenceType || (CharacterReferenceType = {}));
15637
- class _ControlFlowError {
15638
- error;
15639
- constructor(error) {
15640
- this.error = error;
15641
- }
15642
- }
15643
15664
  // See https://www.w3.org/TR/html51/syntax.html#writing-html-documents
15644
15665
  class _Tokenizer {
15645
15666
  _getTagDefinition;
@@ -15949,10 +15970,10 @@ class _Tokenizer {
15949
15970
  }
15950
15971
  _endToken(parts, end) {
15951
15972
  if (this._currentTokenStart === null) {
15952
- throw new TokenError('Programming error - attempted to end a token when there was no start to the token', this._currentTokenType, this._cursor.getSpan(end));
15973
+ throw new ParseError(this._cursor.getSpan(end), 'Programming error - attempted to end a token when there was no start to the token');
15953
15974
  }
15954
15975
  if (this._currentTokenType === null) {
15955
- throw new TokenError('Programming error - attempted to end a token which has no token type', null, this._cursor.getSpan(this._currentTokenStart));
15976
+ throw new ParseError(this._cursor.getSpan(this._currentTokenStart), 'Programming error - attempted to end a token which has no token type');
15956
15977
  }
15957
15978
  const token = {
15958
15979
  type: this._currentTokenType,
@@ -15968,17 +15989,17 @@ class _Tokenizer {
15968
15989
  if (this._isInExpansionForm()) {
15969
15990
  msg += ` (Do you have an unescaped "{" in your template? Use "{{ '{' }}") to escape it.)`;
15970
15991
  }
15971
- const error = new TokenError(msg, this._currentTokenType, span);
15992
+ const error = new ParseError(span, msg);
15972
15993
  this._currentTokenStart = null;
15973
15994
  this._currentTokenType = null;
15974
- return new _ControlFlowError(error);
15995
+ return error;
15975
15996
  }
15976
15997
  handleError(e) {
15977
15998
  if (e instanceof CursorError) {
15978
15999
  e = this._createError(e.msg, this._cursor.getSpan(e.cursor));
15979
16000
  }
15980
- if (e instanceof _ControlFlowError) {
15981
- this.errors.push(e.error);
16001
+ if (e instanceof ParseError) {
16002
+ this.errors.push(e);
15982
16003
  }
15983
16004
  else {
15984
16005
  throw e;
@@ -16218,7 +16239,7 @@ class _Tokenizer {
16218
16239
  }
16219
16240
  }
16220
16241
  catch (e) {
16221
- if (e instanceof _ControlFlowError) {
16242
+ if (e instanceof ParseError) {
16222
16243
  if (openToken) {
16223
16244
  // We errored before we could close the opening tag, so it is incomplete.
16224
16245
  openToken.type =
@@ -16999,7 +17020,7 @@ let Parser$1 = class Parser {
16999
17020
  const tokenizeResult = tokenize(source, url, this.getTagDefinition, options);
17000
17021
  const parser = new _TreeBuilder(tokenizeResult.tokens, this.getTagDefinition);
17001
17022
  parser.build();
17002
- return new ParseTreeResult(parser.rootNodes, tokenizeResult.errors.concat(parser.errors));
17023
+ return new ParseTreeResult(parser.rootNodes, [...tokenizeResult.errors, ...parser.errors]);
17003
17024
  }
17004
17025
  };
17005
17026
  class _TreeBuilder {
@@ -18090,13 +18111,17 @@ class _Scanner {
18090
18111
  case $HASH:
18091
18112
  return this.scanPrivateIdentifier();
18092
18113
  case $PLUS:
18114
+ return this.scanComplexOperator(start, '+', $EQ, '=');
18093
18115
  case $MINUS:
18116
+ return this.scanComplexOperator(start, '-', $EQ, '=');
18094
18117
  case $SLASH:
18118
+ return this.scanComplexOperator(start, '/', $EQ, '=');
18095
18119
  case $PERCENT:
18120
+ return this.scanComplexOperator(start, '%', $EQ, '=');
18096
18121
  case $CARET:
18097
- return this.scanOperator(start, String.fromCharCode(peek));
18122
+ return this.scanOperator(start, '^');
18098
18123
  case $STAR:
18099
- return this.scanComplexOperator(start, '*', $STAR, '*');
18124
+ return this.scanStar(start);
18100
18125
  case $QUESTION:
18101
18126
  return this.scanQuestion(start);
18102
18127
  case $LT:
@@ -18106,9 +18131,9 @@ class _Scanner {
18106
18131
  case $EQ:
18107
18132
  return this.scanComplexOperator(start, String.fromCharCode(peek), $EQ, '=', $EQ, '=');
18108
18133
  case $AMPERSAND:
18109
- return this.scanComplexOperator(start, '&', $AMPERSAND, '&');
18134
+ return this.scanComplexOperator(start, '&', $AMPERSAND, '&', $EQ, '=');
18110
18135
  case $BAR:
18111
- return this.scanComplexOperator(start, '|', $BAR, '|');
18136
+ return this.scanComplexOperator(start, '|', $BAR, '|', $EQ, '=');
18112
18137
  case $NBSP:
18113
18138
  while (isWhitespace(this.peek))
18114
18139
  this.advance();
@@ -18254,13 +18279,23 @@ class _Scanner {
18254
18279
  }
18255
18280
  scanQuestion(start) {
18256
18281
  this.advance();
18257
- let str = '?';
18258
- // Either `a ?? b` or 'a?.b'.
18259
- if (this.peek === $QUESTION || this.peek === $PERIOD) {
18260
- str += this.peek === $PERIOD ? '.' : '?';
18282
+ let operator = '?';
18283
+ // `a ?? b` or `a ??= b`.
18284
+ if (this.peek === $QUESTION) {
18285
+ operator += '?';
18261
18286
  this.advance();
18287
+ // @ts-expect-error
18288
+ if (this.peek === $EQ) {
18289
+ operator += '=';
18290
+ this.advance();
18291
+ }
18262
18292
  }
18263
- return newOperatorToken(start, this.index, str);
18293
+ else if (this.peek === $PERIOD) {
18294
+ // `a?.b`
18295
+ operator += '.';
18296
+ this.advance();
18297
+ }
18298
+ return newOperatorToken(start, this.index, operator);
18264
18299
  }
18265
18300
  scanTemplateLiteralPart(start) {
18266
18301
  let buffer = '';
@@ -18324,6 +18359,25 @@ class _Scanner {
18324
18359
  buffer += String.fromCharCode(unescapedCode);
18325
18360
  return buffer;
18326
18361
  }
18362
+ scanStar(start) {
18363
+ this.advance();
18364
+ // `*`, `**`, `**=` or `*=`
18365
+ let operator = '*';
18366
+ if (this.peek === $STAR) {
18367
+ operator += '*';
18368
+ this.advance();
18369
+ // @ts-expect-error
18370
+ if (this.peek === $EQ) {
18371
+ operator += '=';
18372
+ this.advance();
18373
+ }
18374
+ }
18375
+ else if (this.peek === $EQ) {
18376
+ operator += '=';
18377
+ this.advance();
18378
+ }
18379
+ return newOperatorToken(start, this.index, operator);
18380
+ }
18327
18381
  }
18328
18382
  function isIdentifierStart(code) {
18329
18383
  return (($a <= code && code <= $z) ||
@@ -18384,6 +18438,9 @@ class TemplateBindingParseResult {
18384
18438
  this.errors = errors;
18385
18439
  }
18386
18440
  }
18441
+ function getLocation(span) {
18442
+ return span.start.toString() || '(unknown)';
18443
+ }
18387
18444
  class Parser {
18388
18445
  _lexer;
18389
18446
  _supportsDirectPipeReferences;
@@ -18391,18 +18448,18 @@ class Parser {
18391
18448
  this._lexer = _lexer;
18392
18449
  this._supportsDirectPipeReferences = _supportsDirectPipeReferences;
18393
18450
  }
18394
- parseAction(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18451
+ parseAction(input, parseSourceSpan, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18395
18452
  const errors = [];
18396
- this._checkNoInterpolation(errors, input, location, interpolationConfig);
18453
+ this._checkNoInterpolation(errors, input, parseSourceSpan, interpolationConfig);
18397
18454
  const sourceToLex = this._stripComments(input);
18398
18455
  const tokens = this._lexer.tokenize(sourceToLex);
18399
- const ast = new _ParseAST(input, location, absoluteOffset, tokens, 1 /* ParseFlags.Action */, errors, 0, this._supportsDirectPipeReferences).parseChain();
18400
- return new ASTWithSource(ast, input, location, absoluteOffset, errors);
18456
+ const ast = new _ParseAST(input, parseSourceSpan, absoluteOffset, tokens, 1 /* ParseFlags.Action */, errors, 0, this._supportsDirectPipeReferences).parseChain();
18457
+ return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
18401
18458
  }
18402
- parseBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18459
+ parseBinding(input, parseSourceSpan, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18403
18460
  const errors = [];
18404
- const ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig, errors);
18405
- return new ASTWithSource(ast, input, location, absoluteOffset, errors);
18461
+ const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, interpolationConfig, errors);
18462
+ return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
18406
18463
  }
18407
18464
  checkSimpleExpression(ast) {
18408
18465
  const checker = new SimpleExpressionChecker();
@@ -18410,20 +18467,20 @@ class Parser {
18410
18467
  return checker.errors;
18411
18468
  }
18412
18469
  // Host bindings parsed here
18413
- parseSimpleBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18470
+ parseSimpleBinding(input, parseSourceSpan, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18414
18471
  const errors = [];
18415
- const ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig, errors);
18472
+ const ast = this._parseBindingAst(input, parseSourceSpan, absoluteOffset, interpolationConfig, errors);
18416
18473
  const simplExpressionErrors = this.checkSimpleExpression(ast);
18417
18474
  if (simplExpressionErrors.length > 0) {
18418
- errors.push(new ParserError(`Host binding expression cannot contain ${simplExpressionErrors.join(' ')}`, input, location));
18475
+ errors.push(getParseError(`Host binding expression cannot contain ${simplExpressionErrors.join(' ')}`, input, '', parseSourceSpan));
18419
18476
  }
18420
- return new ASTWithSource(ast, input, location, absoluteOffset, errors);
18477
+ return new ASTWithSource(ast, input, getLocation(parseSourceSpan), absoluteOffset, errors);
18421
18478
  }
18422
- _parseBindingAst(input, location, absoluteOffset, interpolationConfig, errors) {
18423
- this._checkNoInterpolation(errors, input, location, interpolationConfig);
18479
+ _parseBindingAst(input, parseSourceSpan, absoluteOffset, interpolationConfig, errors) {
18480
+ this._checkNoInterpolation(errors, input, parseSourceSpan, interpolationConfig);
18424
18481
  const sourceToLex = this._stripComments(input);
18425
18482
  const tokens = this._lexer.tokenize(sourceToLex);
18426
- return new _ParseAST(input, location, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, 0, this._supportsDirectPipeReferences).parseChain();
18483
+ return new _ParseAST(input, parseSourceSpan, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, 0, this._supportsDirectPipeReferences).parseChain();
18427
18484
  }
18428
18485
  /**
18429
18486
  * Parse microsyntax template expression and return a list of bindings or
@@ -18451,18 +18508,18 @@ class Parser {
18451
18508
  * @param absoluteKeyOffset start of the `templateKey`
18452
18509
  * @param absoluteValueOffset start of the `templateValue`
18453
18510
  */
18454
- parseTemplateBindings(templateKey, templateValue, templateUrl, absoluteKeyOffset, absoluteValueOffset) {
18511
+ parseTemplateBindings(templateKey, templateValue, parseSourceSpan, absoluteKeyOffset, absoluteValueOffset) {
18455
18512
  const tokens = this._lexer.tokenize(templateValue);
18456
18513
  const errors = [];
18457
- const parser = new _ParseAST(templateValue, templateUrl, absoluteValueOffset, tokens, 0 /* ParseFlags.None */, errors, 0 /* relative offset */, this._supportsDirectPipeReferences);
18514
+ const parser = new _ParseAST(templateValue, parseSourceSpan, absoluteValueOffset, tokens, 0 /* ParseFlags.None */, errors, 0 /* relative offset */, this._supportsDirectPipeReferences);
18458
18515
  return parser.parseTemplateBindings({
18459
18516
  source: templateKey,
18460
18517
  span: new AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length),
18461
18518
  });
18462
18519
  }
18463
- parseInterpolation(input, location, absoluteOffset, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18520
+ parseInterpolation(input, parseSourceSpan, absoluteOffset, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18464
18521
  const errors = [];
18465
- const { strings, expressions, offsets } = this.splitInterpolation(input, location, errors, interpolatedTokens, interpolationConfig);
18522
+ const { strings, expressions, offsets } = this.splitInterpolation(input, parseSourceSpan, errors, interpolatedTokens, interpolationConfig);
18466
18523
  if (expressions.length === 0)
18467
18524
  return null;
18468
18525
  const expressionNodes = [];
@@ -18470,23 +18527,23 @@ class Parser {
18470
18527
  const expressionText = expressions[i].text;
18471
18528
  const sourceToLex = this._stripComments(expressionText);
18472
18529
  const tokens = this._lexer.tokenize(sourceToLex);
18473
- const ast = new _ParseAST(input, location, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, offsets[i], this._supportsDirectPipeReferences).parseChain();
18530
+ const ast = new _ParseAST(input, parseSourceSpan, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, offsets[i], this._supportsDirectPipeReferences).parseChain();
18474
18531
  expressionNodes.push(ast);
18475
18532
  }
18476
- return this.createInterpolationAst(strings.map((s) => s.text), expressionNodes, input, location, absoluteOffset, errors);
18533
+ return this.createInterpolationAst(strings.map((s) => s.text), expressionNodes, input, getLocation(parseSourceSpan), absoluteOffset, errors);
18477
18534
  }
18478
18535
  /**
18479
18536
  * Similar to `parseInterpolation`, but treats the provided string as a single expression
18480
18537
  * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
18481
18538
  * This is used for parsing the switch expression in ICUs.
18482
18539
  */
18483
- parseInterpolationExpression(expression, location, absoluteOffset) {
18540
+ parseInterpolationExpression(expression, parseSourceSpan, absoluteOffset) {
18484
18541
  const sourceToLex = this._stripComments(expression);
18485
18542
  const tokens = this._lexer.tokenize(sourceToLex);
18486
18543
  const errors = [];
18487
- const ast = new _ParseAST(expression, location, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, 0, this._supportsDirectPipeReferences).parseChain();
18544
+ const ast = new _ParseAST(expression, parseSourceSpan, absoluteOffset, tokens, 0 /* ParseFlags.None */, errors, 0, this._supportsDirectPipeReferences).parseChain();
18488
18545
  const strings = ['', '']; // The prefix and suffix strings are both empty
18489
- return this.createInterpolationAst(strings, [ast], expression, location, absoluteOffset, errors);
18546
+ return this.createInterpolationAst(strings, [ast], expression, getLocation(parseSourceSpan), absoluteOffset, errors);
18490
18547
  }
18491
18548
  createInterpolationAst(strings, expressions, input, location, absoluteOffset, errors) {
18492
18549
  const span = new ParseSpan(0, input.length);
@@ -18500,7 +18557,7 @@ class Parser {
18500
18557
  * `SplitInterpolation` with splits that look like
18501
18558
  * <raw text> <expression> <raw text> ... <raw text> <expression> <raw text>
18502
18559
  */
18503
- splitInterpolation(input, location, errors, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18560
+ splitInterpolation(input, parseSourceSpan, errors, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
18504
18561
  const strings = [];
18505
18562
  const expressions = [];
18506
18563
  const offsets = [];
@@ -18538,7 +18595,7 @@ class Parser {
18538
18595
  const fullEnd = exprEnd + interpEnd.length;
18539
18596
  const text = input.substring(exprStart, exprEnd);
18540
18597
  if (text.trim().length === 0) {
18541
- errors.push(new ParserError('Blank expressions are not allowed in interpolated strings', input, `at column ${i} in`, location));
18598
+ errors.push(getParseError('Blank expressions are not allowed in interpolated strings', input, `at column ${i} in`, parseSourceSpan));
18542
18599
  }
18543
18600
  expressions.push({ text, start: fullStart, end: fullEnd });
18544
18601
  const startInOriginalTemplate = inputToTemplateIndexMap?.get(fullStart) ?? fullStart;
@@ -18561,9 +18618,11 @@ class Parser {
18561
18618
  }
18562
18619
  return new SplitInterpolation(strings, expressions, offsets);
18563
18620
  }
18564
- wrapLiteralPrimitive(input, location, absoluteOffset) {
18621
+ wrapLiteralPrimitive(input, sourceSpanOrLocation, absoluteOffset) {
18565
18622
  const span = new ParseSpan(0, input == null ? 0 : input.length);
18566
- return new ASTWithSource(new LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, location, absoluteOffset, []);
18623
+ return new ASTWithSource(new LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, typeof sourceSpanOrLocation === 'string'
18624
+ ? sourceSpanOrLocation
18625
+ : getLocation(sourceSpanOrLocation), absoluteOffset, []);
18567
18626
  }
18568
18627
  _stripComments(input) {
18569
18628
  const i = this._commentStart(input);
@@ -18585,7 +18644,7 @@ class Parser {
18585
18644
  }
18586
18645
  return null;
18587
18646
  }
18588
- _checkNoInterpolation(errors, input, location, { start, end }) {
18647
+ _checkNoInterpolation(errors, input, parseSourceSpan, { start, end }) {
18589
18648
  let startIndex = -1;
18590
18649
  let endIndex = -1;
18591
18650
  for (const charIndex of this._forEachUnquotedChar(input, 0)) {
@@ -18602,7 +18661,7 @@ class Parser {
18602
18661
  }
18603
18662
  }
18604
18663
  if (startIndex > -1 && endIndex > -1) {
18605
- errors.push(new ParserError(`Got interpolation (${start}${end}) where expression was expected`, input, `at column ${startIndex} in`, location));
18664
+ errors.push(getParseError(`Got interpolation (${start}${end}) where expression was expected`, input, `at column ${startIndex} in`, parseSourceSpan));
18606
18665
  }
18607
18666
  }
18608
18667
  /**
@@ -18661,7 +18720,7 @@ var ParseContextFlags;
18661
18720
  })(ParseContextFlags || (ParseContextFlags = {}));
18662
18721
  class _ParseAST {
18663
18722
  input;
18664
- location;
18723
+ parseSourceSpan;
18665
18724
  absoluteOffset;
18666
18725
  tokens;
18667
18726
  parseFlags;
@@ -18678,9 +18737,9 @@ class _ParseAST {
18678
18737
  // and may change for subsequent expressions visited by the parser.
18679
18738
  sourceSpanCache = new Map();
18680
18739
  index = 0;
18681
- constructor(input, location, absoluteOffset, tokens, parseFlags, errors, offset, supportsDirectPipeReferences) {
18740
+ constructor(input, parseSourceSpan, absoluteOffset, tokens, parseFlags, errors, offset, supportsDirectPipeReferences) {
18682
18741
  this.input = input;
18683
- this.location = location;
18742
+ this.parseSourceSpan = parseSourceSpan;
18684
18743
  this.absoluteOffset = absoluteOffset;
18685
18744
  this.tokens = tokens;
18686
18745
  this.parseFlags = parseFlags;
@@ -18808,6 +18867,9 @@ class _ParseAST {
18808
18867
  return false;
18809
18868
  }
18810
18869
  }
18870
+ isAssignmentOperator(token) {
18871
+ return token.type === TokenType.Operator && Binary.isAssignmentOperation(token.strValue);
18872
+ }
18811
18873
  expectOperator(operator) {
18812
18874
  if (this.consumeOptionalOperator(operator))
18813
18875
  return;
@@ -19291,7 +19353,8 @@ class _ParseAST {
19291
19353
  });
19292
19354
  const nameSpan = this.sourceSpan(nameStart);
19293
19355
  if (isSafe) {
19294
- if (this.consumeOptionalOperator('=')) {
19356
+ if (this.isAssignmentOperator(this.next)) {
19357
+ this.advance();
19295
19358
  this.error("The '?.' operator cannot be used in the assignment");
19296
19359
  return new EmptyExpr$1(this.span(start), this.sourceSpan(start));
19297
19360
  }
@@ -19300,14 +19363,16 @@ class _ParseAST {
19300
19363
  }
19301
19364
  }
19302
19365
  else {
19303
- if (this.consumeOptionalOperator('=')) {
19366
+ if (this.isAssignmentOperator(this.next)) {
19367
+ const operation = this.next.strValue;
19368
+ this.advance();
19304
19369
  if (!(this.parseFlags & 1 /* ParseFlags.Action */)) {
19305
19370
  this.error('Bindings cannot contain assignments');
19306
19371
  return new EmptyExpr$1(this.span(start), this.sourceSpan(start));
19307
19372
  }
19308
19373
  const receiver = new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
19309
19374
  const value = this.parseConditional();
19310
- return new Binary(this.span(start), this.sourceSpan(start), '=', receiver, value);
19375
+ return new Binary(this.span(start), this.sourceSpan(start), operation, receiver, value);
19311
19376
  }
19312
19377
  else {
19313
19378
  return new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
@@ -19422,14 +19487,16 @@ class _ParseAST {
19422
19487
  }
19423
19488
  this.rbracketsExpected--;
19424
19489
  this.expectCharacter($RBRACKET);
19425
- if (this.consumeOptionalOperator('=')) {
19490
+ if (this.isAssignmentOperator(this.next)) {
19491
+ const operation = this.next.strValue;
19492
+ this.advance();
19426
19493
  if (isSafe) {
19427
19494
  this.error("The '?.' operator cannot be used in the assignment");
19428
19495
  }
19429
19496
  else {
19430
19497
  const binaryReceiver = new KeyedRead(this.span(start), this.sourceSpan(start), receiver, key);
19431
19498
  const value = this.parseConditional();
19432
- return new Binary(this.span(start), this.sourceSpan(start), '=', binaryReceiver, value);
19499
+ return new Binary(this.span(start), this.sourceSpan(start), operation, binaryReceiver, value);
19433
19500
  }
19434
19501
  }
19435
19502
  else {
@@ -19493,7 +19560,7 @@ class _ParseAST {
19493
19560
  const ast = this.parsePipe(); // example: "condition | async"
19494
19561
  const { start, end } = ast.span;
19495
19562
  const value = this.input.substring(start, end);
19496
- return new ASTWithSource(ast, value, this.location, this.absoluteOffset + start, this.errors);
19563
+ return new ASTWithSource(ast, value, getLocation(this.parseSourceSpan), this.absoluteOffset + start, this.errors);
19497
19564
  }
19498
19565
  /**
19499
19566
  * Return the binding for a variable declared using `as`. Note that the order
@@ -19597,13 +19664,11 @@ class _ParseAST {
19597
19664
  * Records an error and skips over the token stream until reaching a recoverable point. See
19598
19665
  * `this.skip` for more details on token skipping.
19599
19666
  */
19600
- error(message, index = null) {
19601
- this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location));
19667
+ error(message, index = this.index) {
19668
+ this.errors.push(getParseError(message, this.input, this.getErrorLocationText(index), this.parseSourceSpan));
19602
19669
  this.skip();
19603
19670
  }
19604
- locationText(index = null) {
19605
- if (index == null)
19606
- index = this.index;
19671
+ getErrorLocationText(index) {
19607
19672
  return index < this.tokens.length
19608
19673
  ? `at column ${this.tokens[index].index + 1} in`
19609
19674
  : `at the end of the expression`;
@@ -19637,7 +19702,7 @@ class _ParseAST {
19637
19702
  * none of the calling productions are not expecting the closing token else we will never
19638
19703
  * make progress in the case of an extraneous group closing symbol (such as a stray ')').
19639
19704
  * That is, we skip a closing symbol if we are not in a grouping production.
19640
- * - '=' in a `Writable` context
19705
+ * - Assignment in a `Writable` context
19641
19706
  * - In this context, we are able to recover after seeing the `=` operator, which
19642
19707
  * signals the presence of an independent rvalue expression following the `=` operator.
19643
19708
  *
@@ -19652,15 +19717,23 @@ class _ParseAST {
19652
19717
  (this.rparensExpected <= 0 || !n.isCharacter($RPAREN)) &&
19653
19718
  (this.rbracesExpected <= 0 || !n.isCharacter($RBRACE)) &&
19654
19719
  (this.rbracketsExpected <= 0 || !n.isCharacter($RBRACKET)) &&
19655
- (!(this.context & ParseContextFlags.Writable) || !n.isOperator('='))) {
19720
+ (!(this.context & ParseContextFlags.Writable) || !this.isAssignmentOperator(n))) {
19656
19721
  if (this.next.isError()) {
19657
- this.errors.push(new ParserError(this.next.toString(), this.input, this.locationText(), this.location));
19722
+ this.errors.push(getParseError(this.next.toString(), this.input, this.getErrorLocationText(this.next.index), this.parseSourceSpan));
19658
19723
  }
19659
19724
  this.advance();
19660
19725
  n = this.next;
19661
19726
  }
19662
19727
  }
19663
19728
  }
19729
+ function getParseError(message, input, locationText, parseSourceSpan) {
19730
+ if (locationText.length > 0) {
19731
+ locationText = ` ${locationText} `;
19732
+ }
19733
+ const location = getLocation(parseSourceSpan);
19734
+ const error = `Parser Error: ${message}${locationText}[${input}] in ${location}`;
19735
+ return new ParseError(parseSourceSpan, error);
19736
+ }
19664
19737
  class SimpleExpressionChecker extends RecursiveAstVisitor {
19665
19738
  errors = [];
19666
19739
  visitPipe() {
@@ -20915,7 +20988,7 @@ class _I18nVisitor {
20915
20988
  normalizeExpression(token) {
20916
20989
  const expression = token.parts[1];
20917
20990
  const expr = this._expressionParser.parseBinding(expression,
20918
- /* location */ token.sourceSpan.start.toString(),
20991
+ /* location */ token.sourceSpan,
20919
20992
  /* absoluteOffset */ token.sourceSpan.start.offset, this._interpolationConfig);
20920
20993
  return serialize(expr);
20921
20994
  }
@@ -20981,15 +21054,6 @@ function extractPlaceholderName(input) {
20981
21054
  return input.split(_CUSTOM_PH_EXP)[2];
20982
21055
  }
20983
21056
 
20984
- /**
20985
- * An i18n error.
20986
- */
20987
- class I18nError extends ParseError {
20988
- constructor(span, msg) {
20989
- super(span, msg);
20990
- }
20991
- }
20992
-
20993
21057
  /**
20994
21058
  * Set of tagName|propertyName corresponding to Trusted Types sinks. Properties applying to all
20995
21059
  * tags use '*'.
@@ -21271,7 +21335,7 @@ class I18nMetaVisitor {
21271
21335
  }
21272
21336
  }
21273
21337
  _reportError(node, msg) {
21274
- this._errors.push(new I18nError(node.sourceSpan, msg));
21338
+ this._errors.push(new ParseError(node.sourceSpan, msg));
21275
21339
  }
21276
21340
  }
21277
21341
  /** I18n separators for metadata **/
@@ -22855,21 +22919,7 @@ function elementOrContainerBase(instruction, slot, tag, constIndex, localRefInde
22855
22919
  }
22856
22920
  return call(instruction, args, sourceSpan);
22857
22921
  }
22858
- function elementEnd(sourceSpan) {
22859
- return call(Identifiers.elementEnd, [], sourceSpan);
22860
- }
22861
- function elementContainerStart(slot, constIndex, localRefIndex, sourceSpan) {
22862
- return elementOrContainerBase(Identifiers.elementContainerStart, slot,
22863
- /* tag */ null, constIndex, localRefIndex, sourceSpan);
22864
- }
22865
- function elementContainer(slot, constIndex, localRefIndex, sourceSpan) {
22866
- return elementOrContainerBase(Identifiers.elementContainer, slot,
22867
- /* tag */ null, constIndex, localRefIndex, sourceSpan);
22868
- }
22869
- function elementContainerEnd() {
22870
- return call(Identifiers.elementContainerEnd, [], null);
22871
- }
22872
- function template(slot, templateFnRef, decls, vars, tag, constIndex, localRefs, sourceSpan) {
22922
+ function templateBase(instruction, slot, templateFnRef, decls, vars, tag, constIndex, localRefs, sourceSpan) {
22873
22923
  const args = [
22874
22924
  literal$1(slot),
22875
22925
  templateFnRef,
@@ -22885,7 +22935,37 @@ function template(slot, templateFnRef, decls, vars, tag, constIndex, localRefs,
22885
22935
  while (args[args.length - 1].isEquivalent(NULL_EXPR)) {
22886
22936
  args.pop();
22887
22937
  }
22888
- return call(Identifiers.templateCreate, args, sourceSpan);
22938
+ return call(instruction, args, sourceSpan);
22939
+ }
22940
+ function propertyBase(instruction, name, expression, sanitizer, sourceSpan) {
22941
+ const args = [literal$1(name)];
22942
+ if (expression instanceof Interpolation) {
22943
+ args.push(interpolationToExpression(expression, sourceSpan));
22944
+ }
22945
+ else {
22946
+ args.push(expression);
22947
+ }
22948
+ if (sanitizer !== null) {
22949
+ args.push(sanitizer);
22950
+ }
22951
+ return call(instruction, args, sourceSpan);
22952
+ }
22953
+ function elementEnd(sourceSpan) {
22954
+ return call(Identifiers.elementEnd, [], sourceSpan);
22955
+ }
22956
+ function elementContainerStart(slot, constIndex, localRefIndex, sourceSpan) {
22957
+ return elementOrContainerBase(Identifiers.elementContainerStart, slot,
22958
+ /* tag */ null, constIndex, localRefIndex, sourceSpan);
22959
+ }
22960
+ function elementContainer(slot, constIndex, localRefIndex, sourceSpan) {
22961
+ return elementOrContainerBase(Identifiers.elementContainer, slot,
22962
+ /* tag */ null, constIndex, localRefIndex, sourceSpan);
22963
+ }
22964
+ function elementContainerEnd() {
22965
+ return call(Identifiers.elementContainerEnd, [], null);
22966
+ }
22967
+ function template(slot, templateFnRef, decls, vars, tag, constIndex, localRefs, sourceSpan) {
22968
+ return templateBase(Identifiers.templateCreate, slot, templateFnRef, decls, vars, tag, constIndex, localRefs, sourceSpan);
22889
22969
  }
22890
22970
  function disableBindings() {
22891
22971
  return call(Identifiers.disableBindings, [], null);
@@ -23151,17 +23231,7 @@ function i18nAttributes(slot, i18nAttributesConfig) {
23151
23231
  return call(Identifiers.i18nAttributes, args, null);
23152
23232
  }
23153
23233
  function property(name, expression, sanitizer, sourceSpan) {
23154
- const args = [literal$1(name)];
23155
- if (expression instanceof Interpolation) {
23156
- args.push(interpolationToExpression(expression, sourceSpan));
23157
- }
23158
- else {
23159
- args.push(expression);
23160
- }
23161
- if (sanitizer !== null) {
23162
- args.push(sanitizer);
23163
- }
23164
- return call(Identifiers.property, args, sourceSpan);
23234
+ return propertyBase(Identifiers.property, name, expression, sanitizer, sourceSpan);
23165
23235
  }
23166
23236
  function twoWayProperty(name, expression, sanitizer, sourceSpan) {
23167
23237
  const args = [literal$1(name), expression];
@@ -23214,6 +23284,36 @@ function classMap(expression, sourceSpan) {
23214
23284
  : expression;
23215
23285
  return call(Identifiers.classMap, [value], sourceSpan);
23216
23286
  }
23287
+ function domElement(slot, tag, constIndex, localRefIndex, sourceSpan) {
23288
+ return elementOrContainerBase(Identifiers.domElement, slot, tag, constIndex, localRefIndex, sourceSpan);
23289
+ }
23290
+ function domElementStart(slot, tag, constIndex, localRefIndex, sourceSpan) {
23291
+ return elementOrContainerBase(Identifiers.domElementStart, slot, tag, constIndex, localRefIndex, sourceSpan);
23292
+ }
23293
+ function domElementEnd(sourceSpan) {
23294
+ return call(Identifiers.domElementEnd, [], sourceSpan);
23295
+ }
23296
+ function domElementContainerStart(slot, constIndex, localRefIndex, sourceSpan) {
23297
+ return elementOrContainerBase(Identifiers.domElementContainerStart, slot,
23298
+ /* tag */ null, constIndex, localRefIndex, sourceSpan);
23299
+ }
23300
+ function domElementContainer(slot, constIndex, localRefIndex, sourceSpan) {
23301
+ return elementOrContainerBase(Identifiers.domElementContainer, slot,
23302
+ /* tag */ null, constIndex, localRefIndex, sourceSpan);
23303
+ }
23304
+ function domElementContainerEnd() {
23305
+ return call(Identifiers.domElementContainerEnd, [], null);
23306
+ }
23307
+ function domListener(name, handlerFn, eventTargetResolver, sourceSpan) {
23308
+ const args = [literal$1(name), handlerFn];
23309
+ if (eventTargetResolver !== null) {
23310
+ args.push(importExpr(eventTargetResolver));
23311
+ }
23312
+ return call(Identifiers.domListener, args, sourceSpan);
23313
+ }
23314
+ function domTemplate(slot, templateFnRef, decls, vars, tag, constIndex, localRefs, sourceSpan) {
23315
+ return templateBase(Identifiers.domTemplate, slot, templateFnRef, decls, vars, tag, constIndex, localRefs, sourceSpan);
23316
+ }
23217
23317
  const PIPE_BINDINGS = [
23218
23318
  Identifiers.pipeBind1,
23219
23319
  Identifiers.pipeBind2,
@@ -23241,11 +23341,7 @@ function i18nApply(slot, sourceSpan) {
23241
23341
  return call(Identifiers.i18nApply, [literal$1(slot)], sourceSpan);
23242
23342
  }
23243
23343
  function domProperty(name, expression, sanitizer, sourceSpan) {
23244
- const args = [literal$1(name), expression];
23245
- if (sanitizer !== null) {
23246
- args.push(sanitizer);
23247
- }
23248
- return call(Identifiers.domProperty, args, sourceSpan);
23344
+ return propertyBase(Identifiers.domProperty, name, expression, sanitizer, sourceSpan);
23249
23345
  }
23250
23346
  function syntheticHostProperty(name, expression, sourceSpan) {
23251
23347
  return call(Identifiers.syntheticHostProperty, [literal$1(name), expression], sourceSpan);
@@ -23410,22 +23506,34 @@ function reifyCreateOperations(unit, ops) {
23410
23506
  OpList.replace(op, text(op.handle.slot, op.initialValue, op.sourceSpan));
23411
23507
  break;
23412
23508
  case OpKind.ElementStart:
23413
- OpList.replace(op, elementStart(op.handle.slot, op.tag, op.attributes, op.localRefs, op.startSourceSpan));
23509
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly
23510
+ ? domElementStart(op.handle.slot, op.tag, op.attributes, op.localRefs, op.startSourceSpan)
23511
+ : elementStart(op.handle.slot, op.tag, op.attributes, op.localRefs, op.startSourceSpan));
23414
23512
  break;
23415
23513
  case OpKind.Element:
23416
- OpList.replace(op, element(op.handle.slot, op.tag, op.attributes, op.localRefs, op.wholeSourceSpan));
23514
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly
23515
+ ? domElement(op.handle.slot, op.tag, op.attributes, op.localRefs, op.wholeSourceSpan)
23516
+ : element(op.handle.slot, op.tag, op.attributes, op.localRefs, op.wholeSourceSpan));
23417
23517
  break;
23418
23518
  case OpKind.ElementEnd:
23419
- OpList.replace(op, elementEnd(op.sourceSpan));
23519
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly
23520
+ ? domElementEnd(op.sourceSpan)
23521
+ : elementEnd(op.sourceSpan));
23420
23522
  break;
23421
23523
  case OpKind.ContainerStart:
23422
- OpList.replace(op, elementContainerStart(op.handle.slot, op.attributes, op.localRefs, op.startSourceSpan));
23524
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly
23525
+ ? domElementContainerStart(op.handle.slot, op.attributes, op.localRefs, op.startSourceSpan)
23526
+ : elementContainerStart(op.handle.slot, op.attributes, op.localRefs, op.startSourceSpan));
23423
23527
  break;
23424
23528
  case OpKind.Container:
23425
- OpList.replace(op, elementContainer(op.handle.slot, op.attributes, op.localRefs, op.wholeSourceSpan));
23529
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly
23530
+ ? domElementContainer(op.handle.slot, op.attributes, op.localRefs, op.wholeSourceSpan)
23531
+ : elementContainer(op.handle.slot, op.attributes, op.localRefs, op.wholeSourceSpan));
23426
23532
  break;
23427
23533
  case OpKind.ContainerEnd:
23428
- OpList.replace(op, elementContainerEnd());
23534
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly
23535
+ ? domElementContainerEnd()
23536
+ : elementContainerEnd());
23429
23537
  break;
23430
23538
  case OpKind.I18nStart:
23431
23539
  OpList.replace(op, i18nStart(op.handle.slot, op.messageIndex, op.subTemplateIndex, op.sourceSpan));
@@ -23450,7 +23558,12 @@ function reifyCreateOperations(unit, ops) {
23450
23558
  throw new Error(`AssertionError: local refs array should have been extracted into a constant`);
23451
23559
  }
23452
23560
  const childView = unit.job.views.get(op.xref);
23453
- OpList.replace(op, template(op.handle.slot, variable(childView.fnName), childView.decls, childView.vars, op.tag, op.attributes, op.localRefs, op.startSourceSpan));
23561
+ OpList.replace(op,
23562
+ // Block templates can't have directives so we can always generate them as DOM-only.
23563
+ op.templateKind === TemplateKind.Block ||
23564
+ unit.job.mode === TemplateCompilationMode.DomOnly
23565
+ ? domTemplate(op.handle.slot, variable(childView.fnName), childView.decls, childView.vars, op.tag, op.attributes, op.localRefs, op.startSourceSpan)
23566
+ : template(op.handle.slot, variable(childView.fnName), childView.decls, childView.vars, op.tag, op.attributes, op.localRefs, op.startSourceSpan));
23454
23567
  break;
23455
23568
  case OpKind.DisableBindings:
23456
23569
  OpList.replace(op, disableBindings());
@@ -23472,7 +23585,11 @@ function reifyCreateOperations(unit, ops) {
23472
23585
  if (eventTargetResolver === undefined) {
23473
23586
  throw new Error(`Unexpected global target '${op.eventTarget}' defined for '${op.name}' event. Supported list of global targets: window,document,body.`);
23474
23587
  }
23475
- OpList.replace(op, listener(op.name, listenerFn, eventTargetResolver, op.hostListener && op.isAnimationListener, op.sourceSpan));
23588
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly &&
23589
+ !op.hostListener &&
23590
+ !op.isAnimationListener
23591
+ ? domListener(op.name, listenerFn, eventTargetResolver, op.sourceSpan)
23592
+ : listener(op.name, listenerFn, eventTargetResolver, op.hostListener && op.isAnimationListener, op.sourceSpan));
23476
23593
  break;
23477
23594
  case OpKind.TwoWayListener:
23478
23595
  OpList.replace(op, twoWayListener(op.name, reifyListenerHandler(unit, op.handlerFnName, op.handlerOps, true), op.sourceSpan));
@@ -23630,7 +23747,7 @@ function reifyCreateOperations(unit, ops) {
23630
23747
  }
23631
23748
  }
23632
23749
  }
23633
- function reifyUpdateOperations(_unit, ops) {
23750
+ function reifyUpdateOperations(unit, ops) {
23634
23751
  for (const op of ops) {
23635
23752
  transformExpressionsInOp(op, reifyIrExpression, VisitorContextFlag.None);
23636
23753
  switch (op.kind) {
@@ -23638,7 +23755,9 @@ function reifyUpdateOperations(_unit, ops) {
23638
23755
  OpList.replace(op, advance(op.delta, op.sourceSpan));
23639
23756
  break;
23640
23757
  case OpKind.Property:
23641
- OpList.replace(op, property(op.name, op.expression, op.sanitizer, op.sourceSpan));
23758
+ OpList.replace(op, unit.job.mode === TemplateCompilationMode.DomOnly && !op.isAnimationTrigger
23759
+ ? domProperty(op.name, op.expression, op.sanitizer, op.sourceSpan)
23760
+ : property(op.name, op.expression, op.sanitizer, op.sourceSpan));
23642
23761
  break;
23643
23762
  case OpKind.TwoWayProperty:
23644
23763
  OpList.replace(op, twoWayProperty(op.name, op.expression, op.sanitizer, op.sourceSpan));
@@ -25876,8 +25995,8 @@ function isSingleI18nIcu(meta) {
25876
25995
  * representation.
25877
25996
  * TODO: Refactor more of the ingestion code into phases.
25878
25997
  */
25879
- function ingestComponent(componentName, template, constantPool, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations) {
25880
- const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations);
25998
+ function ingestComponent(componentName, template, constantPool, compilationMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations) {
25999
+ const job = new ComponentCompilationJob(componentName, constantPool, compatibilityMode, compilationMode, relativeContextFilePath, i18nUseExternalIds, deferMeta, allDeferrableDepsFn, relativeTemplatePath, enableDebugLocations);
25881
26000
  ingestNodes(job.root, template);
25882
26001
  return job;
25883
26002
  }
@@ -25886,7 +26005,7 @@ function ingestComponent(componentName, template, constantPool, relativeContextF
25886
26005
  * representation.
25887
26006
  */
25888
26007
  function ingestHostBinding(input, bindingParser, constantPool) {
25889
- const job = new HostBindingCompilationJob(input.componentName, constantPool, compatibilityMode);
26008
+ const job = new HostBindingCompilationJob(input.componentName, constantPool, compatibilityMode, TemplateCompilationMode.DomOnly);
25890
26009
  for (const property of input.properties ?? []) {
25891
26010
  let bindingKind = BindingKind.Property;
25892
26011
  // TODO: this should really be handled in the parser.
@@ -27173,17 +27292,17 @@ class BindingParser {
27173
27292
  return targetEvents;
27174
27293
  }
27175
27294
  parseInterpolation(value, sourceSpan, interpolatedTokens) {
27176
- const sourceInfo = sourceSpan.start.toString();
27177
27295
  const absoluteOffset = sourceSpan.fullStart.offset;
27178
27296
  try {
27179
- const ast = this._exprParser.parseInterpolation(value, sourceInfo, absoluteOffset, interpolatedTokens, this._interpolationConfig);
27180
- if (ast)
27181
- this._reportExpressionParserErrors(ast.errors, sourceSpan);
27297
+ const ast = this._exprParser.parseInterpolation(value, sourceSpan, absoluteOffset, interpolatedTokens, this._interpolationConfig);
27298
+ if (ast) {
27299
+ this.errors.push(...ast.errors);
27300
+ }
27182
27301
  return ast;
27183
27302
  }
27184
27303
  catch (e) {
27185
27304
  this._reportError(`${e}`, sourceSpan);
27186
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
27305
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
27187
27306
  }
27188
27307
  }
27189
27308
  /**
@@ -27192,17 +27311,17 @@ class BindingParser {
27192
27311
  * This is used for parsing the switch expression in ICUs.
27193
27312
  */
27194
27313
  parseInterpolationExpression(expression, sourceSpan) {
27195
- const sourceInfo = sourceSpan.start.toString();
27196
27314
  const absoluteOffset = sourceSpan.start.offset;
27197
27315
  try {
27198
- const ast = this._exprParser.parseInterpolationExpression(expression, sourceInfo, absoluteOffset);
27199
- if (ast)
27200
- this._reportExpressionParserErrors(ast.errors, sourceSpan);
27316
+ const ast = this._exprParser.parseInterpolationExpression(expression, sourceSpan, absoluteOffset);
27317
+ if (ast) {
27318
+ this.errors.push(...ast.errors);
27319
+ }
27201
27320
  return ast;
27202
27321
  }
27203
27322
  catch (e) {
27204
27323
  this._reportError(`${e}`, sourceSpan);
27205
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
27324
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
27206
27325
  }
27207
27326
  }
27208
27327
  /**
@@ -27259,10 +27378,9 @@ class BindingParser {
27259
27378
  * @param absoluteValueOffset start of the `tplValue`
27260
27379
  */
27261
27380
  _parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset) {
27262
- const sourceInfo = sourceSpan.start.toString();
27263
27381
  try {
27264
- const bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceInfo, absoluteKeyOffset, absoluteValueOffset);
27265
- this._reportExpressionParserErrors(bindingsResult.errors, sourceSpan);
27382
+ const bindingsResult = this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteKeyOffset, absoluteValueOffset);
27383
+ bindingsResult.errors.forEach((e) => this.errors.push(e));
27266
27384
  bindingsResult.warnings.forEach((warning) => {
27267
27385
  this._reportError(warning, sourceSpan, ParseErrorLevel.WARNING);
27268
27386
  });
@@ -27339,18 +27457,18 @@ class BindingParser {
27339
27457
  targetProps.push(new ParsedProperty(name, ast, ParsedPropertyType.ANIMATION, sourceSpan, keySpan, valueSpan));
27340
27458
  }
27341
27459
  parseBinding(value, isHostBinding, sourceSpan, absoluteOffset) {
27342
- const sourceInfo = ((sourceSpan && sourceSpan.start) || '(unknown)').toString();
27343
27460
  try {
27344
27461
  const ast = isHostBinding
27345
- ? this._exprParser.parseSimpleBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig)
27346
- : this._exprParser.parseBinding(value, sourceInfo, absoluteOffset, this._interpolationConfig);
27347
- if (ast)
27348
- this._reportExpressionParserErrors(ast.errors, sourceSpan);
27462
+ ? this._exprParser.parseSimpleBinding(value, sourceSpan, absoluteOffset, this._interpolationConfig)
27463
+ : this._exprParser.parseBinding(value, sourceSpan, absoluteOffset, this._interpolationConfig);
27464
+ if (ast) {
27465
+ this.errors.push(...ast.errors);
27466
+ }
27349
27467
  return ast;
27350
27468
  }
27351
27469
  catch (e) {
27352
27470
  this._reportError(`${e}`, sourceSpan);
27353
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
27471
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
27354
27472
  }
27355
27473
  }
27356
27474
  createBoundElementProperty(elementSelector, boundProp, skipValidation = false, mapPropertyName = true) {
@@ -27464,31 +27582,25 @@ class BindingParser {
27464
27582
  // so don't add the event name to the matchableAttrs
27465
27583
  }
27466
27584
  _parseAction(value, sourceSpan) {
27467
- const sourceInfo = ((sourceSpan && sourceSpan.start) || '(unknown').toString();
27468
27585
  const absoluteOffset = sourceSpan && sourceSpan.start ? sourceSpan.start.offset : 0;
27469
27586
  try {
27470
- const ast = this._exprParser.parseAction(value, sourceInfo, absoluteOffset, this._interpolationConfig);
27587
+ const ast = this._exprParser.parseAction(value, sourceSpan, absoluteOffset, this._interpolationConfig);
27471
27588
  if (ast) {
27472
- this._reportExpressionParserErrors(ast.errors, sourceSpan);
27589
+ this.errors.push(...ast.errors);
27473
27590
  }
27474
27591
  if (!ast || ast.ast instanceof EmptyExpr$1) {
27475
27592
  this._reportError(`Empty expressions are not allowed`, sourceSpan);
27476
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
27593
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
27477
27594
  }
27478
27595
  return ast;
27479
27596
  }
27480
27597
  catch (e) {
27481
27598
  this._reportError(`${e}`, sourceSpan);
27482
- return this._exprParser.wrapLiteralPrimitive('ERROR', sourceInfo, absoluteOffset);
27599
+ return this._exprParser.wrapLiteralPrimitive('ERROR', sourceSpan, absoluteOffset);
27483
27600
  }
27484
27601
  }
27485
- _reportError(message, sourceSpan, level = ParseErrorLevel.ERROR, relatedError) {
27486
- this.errors.push(new ParseError(sourceSpan, message, level, relatedError));
27487
- }
27488
- _reportExpressionParserErrors(errors, sourceSpan) {
27489
- for (const error of errors) {
27490
- this._reportError(error.message, sourceSpan, undefined, error);
27491
- }
27602
+ _reportError(message, sourceSpan, level = ParseErrorLevel.ERROR) {
27603
+ this.errors.push(new ParseError(sourceSpan, message, level));
27492
27604
  }
27493
27605
  /**
27494
27606
  * @param propName the name of the property / attribute
@@ -29526,8 +29638,11 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
29526
29638
  constantPool.statements.push(new DeclareVarStmt(fnName, meta.defer.dependenciesFn, undefined, exports.StmtModifier.Final));
29527
29639
  allDeferrableDepsFn = variable(fnName);
29528
29640
  }
29641
+ const compilationMode = meta.isStandalone && !meta.hasDirectiveDependencies
29642
+ ? TemplateCompilationMode.DomOnly
29643
+ : TemplateCompilationMode.Full;
29529
29644
  // First the template is ingested into IR:
29530
- const tpl = ingestComponent(meta.name, meta.template.nodes, constantPool, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.defer, allDeferrableDepsFn, meta.relativeTemplatePath, getTemplateSourceLocationsEnabled());
29645
+ const tpl = ingestComponent(meta.name, meta.template.nodes, constantPool, compilationMode, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.defer, allDeferrableDepsFn, meta.relativeTemplatePath, getTemplateSourceLocationsEnabled());
29531
29646
  // Then the IR is transformed to prepare it for cod egeneration.
29532
29647
  transform(tpl, CompilationJobKind.Tmpl);
29533
29648
  // Finally we emit the template function:
@@ -31307,6 +31422,7 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
31307
31422
  declarations.push(...decl.directives.map((dir) => convertDirectiveDeclarationToMetadata(dir)));
31308
31423
  decl.pipes && declarations.push(...convertPipeMapToMetadata(decl.pipes));
31309
31424
  }
31425
+ const hasDirectiveDependencies = declarations.every(({ kind }) => kind === exports.R3TemplateDependencyKind.Directive || kind === exports.R3TemplateDependencyKind.NgModule);
31310
31426
  return {
31311
31427
  ...convertDeclareDirectiveFacadeToMetadata(decl, typeSourceSpan),
31312
31428
  template,
@@ -31322,6 +31438,7 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
31322
31438
  relativeContextFilePath: '',
31323
31439
  i18nUseExternalIds: true,
31324
31440
  relativeTemplatePath: null,
31441
+ hasDirectiveDependencies,
31325
31442
  };
31326
31443
  }
31327
31444
  function convertDeclarationFacadeToMetadata(declaration) {
@@ -32047,7 +32164,7 @@ class _Visitor {
32047
32164
  this._msgCountAtSectionStart = undefined;
32048
32165
  }
32049
32166
  _reportError(node, msg) {
32050
- this._errors.push(new I18nError(node.sourceSpan, msg));
32167
+ this._errors.push(new ParseError(node.sourceSpan, msg));
32051
32168
  }
32052
32169
  }
32053
32170
  function _isOpeningComment(n) {
@@ -32082,7 +32199,7 @@ function isAttrNode(ast) {
32082
32199
  * @description
32083
32200
  * Entry point for all public APIs of the compiler package.
32084
32201
  */
32085
- new Version('20.1.0-next.2');
32202
+ new Version('20.1.0-next.3');
32086
32203
 
32087
32204
  //////////////////////////////////////
32088
32205
  // THIS FILE HAS GLOBAL SIDE EFFECT //
@@ -33102,7 +33219,7 @@ class NodeJSPathManipulation {
33102
33219
  // G3-ESM-MARKER: G3 uses CommonJS, but externally everything in ESM.
33103
33220
  // CommonJS/ESM interop for determining the current file name and containing dir.
33104
33221
  const isCommonJS = typeof __filename !== 'undefined';
33105
- const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('checker-CY7a8ko8.cjs', document.baseURI).href));
33222
+ const currentFileUrl = isCommonJS ? null : (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('checker-BVnpy__J.cjs', document.baseURI).href));
33106
33223
  const currentFileName = isCommonJS ? __filename : url.fileURLToPath(currentFileUrl);
33107
33224
  /**
33108
33225
  * A wrapper around the Node.js file-system that supports readonly operations and path manipulation.
@@ -37345,26 +37462,30 @@ exports.PerfPhase = void 0;
37345
37462
  * Time spent by the Angular Language Service calculating outlining spans.
37346
37463
  */
37347
37464
  PerfPhase[PerfPhase["OutliningSpans"] = 24] = "OutliningSpans";
37348
- /**
37349
- * Tracks the number of `PerfPhase`s, and must appear at the end of the list.
37350
- */
37351
- PerfPhase[PerfPhase["LAST"] = 25] = "LAST";
37352
37465
  /**
37353
37466
  * Time spent by the Angular Language Service calculating code fixes.
37354
37467
  */
37355
- PerfPhase[PerfPhase["LsCodeFixes"] = 26] = "LsCodeFixes";
37468
+ PerfPhase[PerfPhase["LsCodeFixes"] = 25] = "LsCodeFixes";
37356
37469
  /**
37357
37470
  * Time spent by the Angular Language Service to fix all detected same type errors.
37358
37471
  */
37359
- PerfPhase[PerfPhase["LsCodeFixesAll"] = 27] = "LsCodeFixesAll";
37472
+ PerfPhase[PerfPhase["LsCodeFixesAll"] = 26] = "LsCodeFixesAll";
37360
37473
  /**
37361
37474
  * Time spent computing possible Angular refactorings.
37362
37475
  */
37363
- PerfPhase[PerfPhase["LSComputeApplicableRefactorings"] = 28] = "LSComputeApplicableRefactorings";
37476
+ PerfPhase[PerfPhase["LSComputeApplicableRefactorings"] = 27] = "LSComputeApplicableRefactorings";
37364
37477
  /**
37365
37478
  * Time spent computing changes for applying a given refactoring.
37366
37479
  */
37367
- PerfPhase[PerfPhase["LSApplyRefactoring"] = 29] = "LSApplyRefactoring";
37480
+ PerfPhase[PerfPhase["LSApplyRefactoring"] = 28] = "LSApplyRefactoring";
37481
+ /**
37482
+ * Time spent by the Angular Language Service calculating semantic classifications.
37483
+ */
37484
+ PerfPhase[PerfPhase["LSSemanticClassification"] = 29] = "LSSemanticClassification";
37485
+ /**
37486
+ * Tracks the number of `PerfPhase`s, and must appear at the end of the list.
37487
+ */
37488
+ PerfPhase[PerfPhase["LAST"] = 30] = "LAST";
37368
37489
  })(exports.PerfPhase || (exports.PerfPhase = {}));
37369
37490
  /**
37370
37491
  * Represents some occurrence during compilation, and is tracked with a counter.
@@ -38196,6 +38317,16 @@ const BINARY_OPERATORS$1 = /* @__PURE__ */ new Map([
38196
38317
  [BinaryOperator.NullishCoalesce, '??'],
38197
38318
  [BinaryOperator.Exponentiation, '**'],
38198
38319
  [BinaryOperator.In, 'in'],
38320
+ [BinaryOperator.Assign, '='],
38321
+ [BinaryOperator.AdditionAssignment, '+='],
38322
+ [BinaryOperator.SubtractionAssignment, '-='],
38323
+ [BinaryOperator.MultiplicationAssignment, '*='],
38324
+ [BinaryOperator.DivisionAssignment, '/='],
38325
+ [BinaryOperator.RemainderAssignment, '%='],
38326
+ [BinaryOperator.ExponentiationAssignment, '**='],
38327
+ [BinaryOperator.AndAssignment, '&&='],
38328
+ [BinaryOperator.OrAssignment, '||='],
38329
+ [BinaryOperator.NullishCoalesceAssignment, '??='],
38199
38330
  ]);
38200
38331
  class ExpressionTranslatorVisitor {
38201
38332
  factory;
@@ -38359,13 +38490,14 @@ class ExpressionTranslatorVisitor {
38359
38490
  : ast.body.visitExpression(this, context));
38360
38491
  }
38361
38492
  visitBinaryOperatorExpr(ast, context) {
38362
- if (ast.operator === BinaryOperator.Assign) {
38363
- return this.factory.createAssignment(ast.lhs.visitExpression(this, context), ast.rhs.visitExpression(this, context));
38364
- }
38365
38493
  if (!BINARY_OPERATORS$1.has(ast.operator)) {
38366
38494
  throw new Error(`Unknown binary operator: ${BinaryOperator[ast.operator]}`);
38367
38495
  }
38368
- return this.factory.createBinaryExpression(ast.lhs.visitExpression(this, context), BINARY_OPERATORS$1.get(ast.operator), ast.rhs.visitExpression(this, context));
38496
+ const operator = BINARY_OPERATORS$1.get(ast.operator);
38497
+ if (ast.isAssignment()) {
38498
+ return this.factory.createAssignment(ast.lhs.visitExpression(this, context), operator, ast.rhs.visitExpression(this, context));
38499
+ }
38500
+ return this.factory.createBinaryExpression(ast.lhs.visitExpression(this, context), operator, ast.rhs.visitExpression(this, context));
38369
38501
  }
38370
38502
  visitReadPropExpr(ast, context) {
38371
38503
  return this.factory.createPropertyAccess(ast.receiver.visitExpression(this, context), ast.name);
@@ -38897,6 +39029,16 @@ const BINARY_OPERATORS = /* @__PURE__ */ (() => ({
38897
39029
  '+': ts.SyntaxKind.PlusToken,
38898
39030
  '??': ts.SyntaxKind.QuestionQuestionToken,
38899
39031
  'in': ts.SyntaxKind.InKeyword,
39032
+ '=': ts.SyntaxKind.EqualsToken,
39033
+ '+=': ts.SyntaxKind.PlusEqualsToken,
39034
+ '-=': ts.SyntaxKind.MinusEqualsToken,
39035
+ '*=': ts.SyntaxKind.AsteriskEqualsToken,
39036
+ '/=': ts.SyntaxKind.SlashEqualsToken,
39037
+ '%=': ts.SyntaxKind.PercentEqualsToken,
39038
+ '**=': ts.SyntaxKind.AsteriskAsteriskEqualsToken,
39039
+ '&&=': ts.SyntaxKind.AmpersandAmpersandEqualsToken,
39040
+ '||=': ts.SyntaxKind.BarBarEqualsToken,
39041
+ '??=': ts.SyntaxKind.QuestionQuestionEqualsToken,
38900
39042
  }))();
38901
39043
  const VAR_TYPES = /* @__PURE__ */ (() => ({
38902
39044
  'const': ts.NodeFlags.Const,
@@ -38914,8 +39056,8 @@ class TypeScriptAstFactory {
38914
39056
  }
38915
39057
  attachComments = attachComments;
38916
39058
  createArrayLiteral = ts.factory.createArrayLiteralExpression;
38917
- createAssignment(target, value) {
38918
- return ts.factory.createBinaryExpression(target, ts.SyntaxKind.EqualsToken, value);
39059
+ createAssignment(target, operator, value) {
39060
+ return ts.factory.createBinaryExpression(target, BINARY_OPERATORS[operator], value);
38919
39061
  }
38920
39062
  createBinaryExpression(leftOperand, operator, rightOperand) {
38921
39063
  return ts.factory.createBinaryExpression(leftOperand, BINARY_OPERATORS[operator], rightOperand);
@@ -39414,6 +39556,9 @@ function validateAccessOfInitializerApiMember({ api, call }, member) {
39414
39556
  * @returns The parsed initializer API, or null if none was found.
39415
39557
  */
39416
39558
  function tryParseInitializerApi(functions, expression, reflector, importTracker) {
39559
+ if (ts.isAsExpression(expression) || ts.isParenthesizedExpression(expression)) {
39560
+ return tryParseInitializerApi(functions, expression.expression, reflector, importTracker);
39561
+ }
39417
39562
  if (!ts.isCallExpression(expression)) {
39418
39563
  return null;
39419
39564
  }
@@ -40727,11 +40872,11 @@ function getHostBindingErrorNode(error, hostExpr) {
40727
40872
  // confidently match the error to its expression by looking at the string value that the parser
40728
40873
  // failed to parse and the initializers for each of the properties. If we fail to match, we fall
40729
40874
  // back to the old behavior where the error is reported on the entire `host` object.
40730
- if (ts.isObjectLiteralExpression(hostExpr) && error.relatedError instanceof ParserError) {
40875
+ if (ts.isObjectLiteralExpression(hostExpr)) {
40731
40876
  for (const prop of hostExpr.properties) {
40732
40877
  if (ts.isPropertyAssignment(prop) &&
40733
40878
  ts.isStringLiteralLike(prop.initializer) &&
40734
- prop.initializer.text === error.relatedError.input) {
40879
+ error.msg.includes(`[${prop.initializer.text}]`)) {
40735
40880
  return prop.initializer;
40736
40881
  }
40737
40882
  }
@@ -44201,6 +44346,22 @@ class OutOfBandDiagnosticRecorderImpl {
44201
44346
  * is ever produced per node.
44202
44347
  */
44203
44348
  recordedPipes = new Set();
44349
+ /** Common pipes that can be suggested to users. */
44350
+ pipeSuggestions = new Map([
44351
+ ['async', 'AsyncPipe'],
44352
+ ['uppercase', 'UpperCasePipe'],
44353
+ ['lowercase', 'LowerCasePipe'],
44354
+ ['json', 'JsonPipe'],
44355
+ ['slice', 'SlicePipe'],
44356
+ ['number', 'DecimalPipe'],
44357
+ ['percent', 'PercentPipe'],
44358
+ ['titlecase', 'TitleCasePipe'],
44359
+ ['currency', 'CurrencyPipe'],
44360
+ ['date', 'DatePipe'],
44361
+ ['i18nPlural', 'I18nPluralPipe'],
44362
+ ['i18nSelect', 'I18nSelectPipe'],
44363
+ ['keyvalue', 'KeyValuePipe'],
44364
+ ]);
44204
44365
  constructor(resolver) {
44205
44366
  this.resolver = resolver;
44206
44367
  }
@@ -44213,16 +44374,30 @@ class OutOfBandDiagnosticRecorderImpl {
44213
44374
  const errorMsg = `No directive found with exportAs '${value}'.`;
44214
44375
  this._diagnostics.push(makeTemplateDiagnostic(id, mapping, ref.valueSpan || ref.sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.MISSING_REFERENCE_TARGET), errorMsg));
44215
44376
  }
44216
- missingPipe(id, ast) {
44377
+ missingPipe(id, ast, isStandalone) {
44217
44378
  if (this.recordedPipes.has(ast)) {
44218
44379
  return;
44219
44380
  }
44220
- const mapping = this.resolver.getTemplateSourceMapping(id);
44221
- const errorMsg = `No pipe found with name '${ast.name}'.`;
44222
44381
  const sourceSpan = this.resolver.toTemplateParseSourceSpan(id, ast.nameSpan);
44223
44382
  if (sourceSpan === null) {
44224
44383
  throw new Error(`Assertion failure: no SourceLocation found for usage of pipe '${ast.name}'.`);
44225
44384
  }
44385
+ const mapping = this.resolver.getTemplateSourceMapping(id);
44386
+ let errorMsg = `No pipe found with name '${ast.name}'.`;
44387
+ if (this.pipeSuggestions.has(ast.name)) {
44388
+ const suggestedClassName = this.pipeSuggestions.get(ast.name);
44389
+ const suggestedImport = '@angular/common';
44390
+ if (isStandalone) {
44391
+ errorMsg +=
44392
+ `\nTo fix this, import the "${suggestedClassName}" class from "${suggestedImport}"` +
44393
+ ` and add it to the "imports" array of the component.`;
44394
+ }
44395
+ else {
44396
+ errorMsg +=
44397
+ `\nTo fix this, import the "${suggestedClassName}" class from "${suggestedImport}"` +
44398
+ ` and add it to the "imports" array of the module declaring the component.`;
44399
+ }
44400
+ }
44226
44401
  this._diagnostics.push(makeTemplateDiagnostic(id, mapping, sourceSpan, ts.DiagnosticCategory.Error, ngErrorCode(exports.ErrorCode.MISSING_PIPE), errorMsg));
44227
44402
  this.recordedPipes.add(ast);
44228
44403
  }
@@ -44595,6 +44770,16 @@ const BINARY_OPS = new Map([
44595
44770
  ['|', ts.SyntaxKind.BarToken],
44596
44771
  ['??', ts.SyntaxKind.QuestionQuestionToken],
44597
44772
  ['in', ts.SyntaxKind.InKeyword],
44773
+ ['=', ts.SyntaxKind.EqualsToken],
44774
+ ['+=', ts.SyntaxKind.PlusEqualsToken],
44775
+ ['-=', ts.SyntaxKind.MinusEqualsToken],
44776
+ ['*=', ts.SyntaxKind.AsteriskEqualsToken],
44777
+ ['/=', ts.SyntaxKind.SlashEqualsToken],
44778
+ ['%=', ts.SyntaxKind.PercentEqualsToken],
44779
+ ['**=', ts.SyntaxKind.AsteriskAsteriskEqualsToken],
44780
+ ['&&=', ts.SyntaxKind.AmpersandAmpersandEqualsToken],
44781
+ ['||=', ts.SyntaxKind.BarBarEqualsToken],
44782
+ ['??=', ts.SyntaxKind.QuestionQuestionEqualsToken],
44598
44783
  ]);
44599
44784
  /**
44600
44785
  * Convert an `AST` to TypeScript code directly, without going through an intermediate `Expression`
@@ -47470,7 +47655,7 @@ class TcbExpressionTranslator {
47470
47655
  return targetExpression;
47471
47656
  }
47472
47657
  else if (ast instanceof Binary &&
47473
- ast.operation === '=' &&
47658
+ Binary.isAssignmentOperation(ast.operation) &&
47474
47659
  ast.left instanceof PropertyRead &&
47475
47660
  ast.left.receiver instanceof ImplicitReceiver) {
47476
47661
  const read = ast.left;
@@ -47512,7 +47697,7 @@ class TcbExpressionTranslator {
47512
47697
  let pipe;
47513
47698
  if (pipeMeta === null) {
47514
47699
  // No pipe by that name exists in scope. Record this as an error.
47515
- this.tcb.oobRecorder.missingPipe(this.tcb.id, ast);
47700
+ this.tcb.oobRecorder.missingPipe(this.tcb.id, ast, this.tcb.hostIsStandalone);
47516
47701
  // Use an 'any' value to at least allow the rest of the expression to be checked.
47517
47702
  pipe = ANY_EXPRESSION;
47518
47703
  }
@@ -48603,7 +48788,7 @@ class SymbolBuilder {
48603
48788
  isStructural: meta.isStructural,
48604
48789
  isInScope: true,
48605
48790
  isHostDirective: false,
48606
- tsCompletionEntryInfo: null,
48791
+ tsCompletionEntryInfos: null,
48607
48792
  };
48608
48793
  symbols.push(directiveSymbol);
48609
48794
  seenDirectives.add(declaration);
@@ -48639,7 +48824,7 @@ class SymbolBuilder {
48639
48824
  kind: exports.SymbolKind.Directive,
48640
48825
  isStructural: meta.isStructural,
48641
48826
  isInScope: true,
48642
- tsCompletionEntryInfo: null,
48827
+ tsCompletionEntryInfos: null,
48643
48828
  };
48644
48829
  symbols.push(directiveSymbol);
48645
48830
  seenDirectives.add(node);
@@ -48898,7 +49083,7 @@ class SymbolBuilder {
48898
49083
  ngModule,
48899
49084
  isHostDirective: false,
48900
49085
  isInScope: true, // TODO: this should always be in scope in this context, right?
48901
- tsCompletionEntryInfo: null,
49086
+ tsCompletionEntryInfos: null,
48902
49087
  };
48903
49088
  }
48904
49089
  getSymbolOfVariable(variable) {
@@ -49059,7 +49244,7 @@ class SymbolBuilder {
49059
49244
  // AST so there is no way to retrieve a `Symbol` for just the `name` via a specific node.
49060
49245
  // Also skipping SafePropertyReads as it breaks nullish coalescing not nullable extended diagnostic
49061
49246
  if (expression instanceof Binary &&
49062
- expression.operation === '=' &&
49247
+ Binary.isAssignmentOperation(expression.operation) &&
49063
49248
  expression.left instanceof PropertyRead) {
49064
49249
  withSpan = expression.left.nameSpan;
49065
49250
  }
@@ -49797,7 +49982,11 @@ class TemplateTypeCheckerImpl {
49797
49982
  return {
49798
49983
  ...withScope,
49799
49984
  isInScope,
49800
- tsCompletionEntryInfo,
49985
+ /**
49986
+ * The Angular LS only supports displaying one directive at a time when
49987
+ * providing the completion item, even if it's exported by multiple modules.
49988
+ */
49989
+ tsCompletionEntryInfos: tsCompletionEntryInfo !== null ? [tsCompletionEntryInfo] : null,
49801
49990
  };
49802
49991
  }
49803
49992
  getElementsInFileScope(component) {
@@ -49839,7 +50028,8 @@ class TemplateTypeCheckerImpl {
49839
50028
  const currentComponentFileName = component.getSourceFile().fileName;
49840
50029
  for (const { symbol, data } of entries ?? []) {
49841
50030
  const symbolFileName = symbol?.declarations?.[0]?.getSourceFile().fileName;
49842
- if (symbolFileName === undefined) {
50031
+ const symbolName = symbol?.name;
50032
+ if (symbolFileName === undefined || symbolName === undefined) {
49843
50033
  continue;
49844
50034
  }
49845
50035
  if (symbolFileName === currentComponentFileName) {
@@ -49859,23 +50049,22 @@ class TemplateTypeCheckerImpl {
49859
50049
  });
49860
50050
  }
49861
50051
  else {
49862
- const ngModuleMeta = this.metaReader.getNgModuleMetadata(ref);
49863
- if (ngModuleMeta === null) {
49864
- continue;
49865
- }
49866
- for (const moduleExports of ngModuleMeta.exports) {
49867
- const directiveMeta = this.metaReader.getDirectiveMetadata(moduleExports);
49868
- if (directiveMeta === null) {
49869
- continue;
49870
- }
49871
- directiveDecls.push({
49872
- meta: directiveMeta,
49873
- ref: moduleExports,
49874
- });
49875
- }
50052
+ const directiveDeclsForNgModule = this.getDirectiveDeclsForNgModule(ref);
50053
+ directiveDecls.push(...directiveDeclsForNgModule);
49876
50054
  }
49877
50055
  for (const directiveDecl of directiveDecls) {
50056
+ const cachedCompletionEntryInfos = resultingDirectives.get(directiveDecl.ref.node)?.tsCompletionEntryInfos ?? [];
50057
+ cachedCompletionEntryInfos.push({
50058
+ tsCompletionEntryData: data,
50059
+ tsCompletionEntrySymbolFileName: symbolFileName,
50060
+ tsCompletionEntrySymbolName: symbolName,
50061
+ });
49878
50062
  if (resultingDirectives.has(directiveDecl.ref.node)) {
50063
+ const directiveInfo = resultingDirectives.get(directiveDecl.ref.node);
50064
+ resultingDirectives.set(directiveDecl.ref.node, {
50065
+ ...directiveInfo,
50066
+ tsCompletionEntryInfos: cachedCompletionEntryInfos,
50067
+ });
49879
50068
  continue;
49880
50069
  }
49881
50070
  const withScope = this.scopeDataOfDirectiveMeta(typeChecker, directiveDecl.meta);
@@ -49885,15 +50074,41 @@ class TemplateTypeCheckerImpl {
49885
50074
  resultingDirectives.set(directiveDecl.ref.node, {
49886
50075
  ...withScope,
49887
50076
  isInScope: false,
49888
- tsCompletionEntryInfo: {
49889
- tsCompletionEntryData: data,
49890
- tsCompletionEntrySymbolFileName: symbolFileName,
49891
- },
50077
+ tsCompletionEntryInfos: cachedCompletionEntryInfos,
49892
50078
  });
49893
50079
  }
49894
50080
  }
49895
50081
  return Array.from(resultingDirectives.values());
49896
50082
  }
50083
+ /**
50084
+ * If the NgModule exports a new module, we need to recursively get its directives.
50085
+ */
50086
+ getDirectiveDeclsForNgModule(ref) {
50087
+ const ngModuleMeta = this.metaReader.getNgModuleMetadata(ref);
50088
+ if (ngModuleMeta === null) {
50089
+ return [];
50090
+ }
50091
+ const directiveDecls = [];
50092
+ for (const moduleExports of ngModuleMeta.exports) {
50093
+ const directiveMeta = this.metaReader.getDirectiveMetadata(moduleExports);
50094
+ if (directiveMeta !== null) {
50095
+ directiveDecls.push({
50096
+ meta: directiveMeta,
50097
+ ref: moduleExports,
50098
+ });
50099
+ }
50100
+ else {
50101
+ const ngModuleMeta = this.metaReader.getNgModuleMetadata(moduleExports);
50102
+ if (ngModuleMeta === null) {
50103
+ continue;
50104
+ }
50105
+ // If the export is an NgModule, we need to recursively get its directives.
50106
+ const nestedDirectiveDecls = this.getDirectiveDeclsForNgModule(moduleExports);
50107
+ directiveDecls.push(...nestedDirectiveDecls);
50108
+ }
50109
+ }
50110
+ return directiveDecls;
50111
+ }
49897
50112
  getPotentialElementTags(component, tsLs, options) {
49898
50113
  if (this.elementTagCache.has(component)) {
49899
50114
  return this.elementTagCache.get(component);
@@ -50002,27 +50217,51 @@ class TemplateTypeCheckerImpl {
50002
50217
  }
50003
50218
  return null;
50004
50219
  }
50005
- getPotentialImportsFor(toImport, inContext, importMode) {
50220
+ getPotentialImportsFor(toImport, inContext, importMode, potentialDirectiveModuleSpecifierResolver) {
50006
50221
  const imports = [];
50007
50222
  const meta = this.metaReader.getDirectiveMetadata(toImport) ?? this.metaReader.getPipeMetadata(toImport);
50008
50223
  if (meta === null) {
50009
50224
  return imports;
50010
50225
  }
50226
+ /**
50227
+ * When providing completion items, the Angular Language Service only supports displaying
50228
+ * one directive at a time. If a directive is exported by two different modules,
50229
+ * the Language Service will select the first module. To ensure the most appropriate directive
50230
+ * is shown, move the likely one to the top of the import list.
50231
+ *
50232
+ * When providing the code action for the directive. All the imports will show for the developer to choose.
50233
+ */
50234
+ let highestImportPriority = -1;
50235
+ const collectImports = (emit, moduleSpecifier) => {
50236
+ if (emit === null) {
50237
+ return;
50238
+ }
50239
+ imports.push({
50240
+ ...emit,
50241
+ moduleSpecifier: moduleSpecifier ?? emit.moduleSpecifier,
50242
+ });
50243
+ if (moduleSpecifier !== undefined && highestImportPriority === -1) {
50244
+ highestImportPriority = imports.length - 1;
50245
+ }
50246
+ };
50011
50247
  if (meta.isStandalone || importMode === exports.PotentialImportMode.ForceDirect) {
50012
50248
  const emitted = this.emit(exports.PotentialImportKind.Standalone, toImport, inContext);
50013
- if (emitted !== null) {
50014
- imports.push(emitted);
50015
- }
50249
+ const moduleSpecifier = potentialDirectiveModuleSpecifierResolver?.resolve(toImport, inContext);
50250
+ collectImports(emitted, moduleSpecifier);
50016
50251
  }
50017
50252
  const exportingNgModules = this.ngModuleIndex.getNgModulesExporting(meta.ref.node);
50018
50253
  if (exportingNgModules !== null) {
50019
50254
  for (const exporter of exportingNgModules) {
50020
50255
  const emittedRef = this.emit(exports.PotentialImportKind.NgModule, exporter, inContext);
50021
- if (emittedRef !== null) {
50022
- imports.push(emittedRef);
50023
- }
50256
+ const moduleSpecifier = potentialDirectiveModuleSpecifierResolver?.resolve(exporter, inContext);
50257
+ collectImports(emittedRef, moduleSpecifier);
50024
50258
  }
50025
50259
  }
50260
+ // move the import with module specifier from the tsLs to top in the imports array
50261
+ if (highestImportPriority > 0) {
50262
+ const highImport = imports.splice(highestImportPriority, 1)[0];
50263
+ imports.unshift(highImport);
50264
+ }
50026
50265
  return imports;
50027
50266
  }
50028
50267
  getComponentScope(component) {
@@ -50084,7 +50323,7 @@ class TemplateTypeCheckerImpl {
50084
50323
  selector: dep.selector,
50085
50324
  tsSymbol,
50086
50325
  ngModule,
50087
- tsCompletionEntryInfo: null,
50326
+ tsCompletionEntryInfos: null,
50088
50327
  };
50089
50328
  }
50090
50329
  scopeDataOfPipeMeta(typeChecker, dep) {
@@ -50096,7 +50335,7 @@ class TemplateTypeCheckerImpl {
50096
50335
  ref: dep.ref,
50097
50336
  name: dep.name,
50098
50337
  tsSymbol,
50099
- tsCompletionEntryInfo: null,
50338
+ tsCompletionEntryInfos: null,
50100
50339
  };
50101
50340
  }
50102
50341
  }
@@ -50277,7 +50516,6 @@ exports.FnParam = FnParam;
50277
50516
  exports.ForLoopBlock = ForLoopBlock;
50278
50517
  exports.FunctionExpr = FunctionExpr;
50279
50518
  exports.HtmlParser = HtmlParser;
50280
- exports.I18nError = I18nError;
50281
50519
  exports.INPUT_INITIALIZER_FN = INPUT_INITIALIZER_FN;
50282
50520
  exports.Icu = Icu;
50283
50521
  exports.IcuPlaceholder = IcuPlaceholder;
@@ -50300,6 +50538,7 @@ exports.NULL_EXPR = NULL_EXPR;
50300
50538
  exports.NgOriginalFile = NgOriginalFile;
50301
50539
  exports.NodeJSFileSystem = NodeJSFileSystem;
50302
50540
  exports.OUTPUT_INITIALIZER_FNS = OUTPUT_INITIALIZER_FNS;
50541
+ exports.ParseError = ParseError;
50303
50542
  exports.ParseLocation = ParseLocation;
50304
50543
  exports.ParseSourceFile = ParseSourceFile;
50305
50544
  exports.ParseSourceSpan = ParseSourceSpan;