@angular/compiler 17.0.0-next.3 → 17.0.0-next.5

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 (41) hide show
  1. package/esm2022/src/i18n/digest.mjs +8 -49
  2. package/esm2022/src/ml_parser/parser.mjs +2 -2
  3. package/esm2022/src/output/output_jit_trusted_types.mjs +7 -7
  4. package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
  5. package/esm2022/src/render3/partial/directive.mjs +1 -1
  6. package/esm2022/src/render3/partial/factory.mjs +1 -1
  7. package/esm2022/src/render3/partial/injectable.mjs +1 -1
  8. package/esm2022/src/render3/partial/injector.mjs +1 -1
  9. package/esm2022/src/render3/partial/ng_module.mjs +1 -1
  10. package/esm2022/src/render3/partial/pipe.mjs +1 -1
  11. package/esm2022/src/render3/r3_ast.mjs +10 -3
  12. package/esm2022/src/render3/r3_control_flow.mjs +16 -9
  13. package/esm2022/src/render3/r3_deferred_triggers.mjs +7 -7
  14. package/esm2022/src/render3/r3_module_compiler.mjs +9 -11
  15. package/esm2022/src/render3/view/compiler.mjs +6 -3
  16. package/esm2022/src/render3/view/t2_api.mjs +1 -1
  17. package/esm2022/src/render3/view/t2_binder.mjs +178 -78
  18. package/esm2022/src/render3/view/template.mjs +32 -46
  19. package/esm2022/src/template/pipeline/ir/src/enums.mjs +14 -7
  20. package/esm2022/src/template/pipeline/ir/src/expression.mjs +3 -1
  21. package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +28 -3
  22. package/esm2022/src/template/pipeline/src/compilation.mjs +6 -1
  23. package/esm2022/src/template/pipeline/src/conversion.mjs +7 -1
  24. package/esm2022/src/template/pipeline/src/emit.mjs +7 -1
  25. package/esm2022/src/template/pipeline/src/ingest.mjs +16 -3
  26. package/esm2022/src/template/pipeline/src/instruction.mjs +19 -3
  27. package/esm2022/src/template/pipeline/src/phases/align_pipe_variadic_var_offset.mjs +2 -1
  28. package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +22 -29
  29. package/esm2022/src/template/pipeline/src/phases/generate_projection_def.mjs +46 -0
  30. package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +33 -0
  31. package/esm2022/src/template/pipeline/src/phases/next_context_merging.mjs +2 -1
  32. package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +39 -0
  33. package/esm2022/src/template/pipeline/src/phases/reify.mjs +11 -2
  34. package/esm2022/src/version.mjs +1 -1
  35. package/fesm2022/compiler.mjs +534 -476
  36. package/fesm2022/compiler.mjs.map +1 -1
  37. package/fesm2022/testing.mjs +1 -1
  38. package/index.d.ts +53 -40
  39. package/package.json +3 -3
  40. package/testing/index.d.ts +1 -1
  41. package/esm2022/src/i18n/big_integer.mjs +0 -180
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v17.0.0-next.3
2
+ * @license Angular v17.0.0-next.5
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -480,179 +480,6 @@ var core = /*#__PURE__*/Object.freeze({
480
480
  parseSelectorToR3Selector: parseSelectorToR3Selector
481
481
  });
482
482
 
483
- /**
484
- * Represents a big integer using a buffer of its individual digits, with the least significant
485
- * digit stored at the beginning of the array (little endian).
486
- *
487
- * For performance reasons, each instance is mutable. The addition operation can be done in-place
488
- * to reduce memory pressure of allocation for the digits array.
489
- */
490
- class BigInteger {
491
- static zero() {
492
- return new BigInteger([0]);
493
- }
494
- static one() {
495
- return new BigInteger([1]);
496
- }
497
- /**
498
- * Creates a big integer using its individual digits in little endian storage.
499
- */
500
- constructor(digits) {
501
- this.digits = digits;
502
- }
503
- /**
504
- * Creates a clone of this instance.
505
- */
506
- clone() {
507
- return new BigInteger(this.digits.slice());
508
- }
509
- /**
510
- * Returns a new big integer with the sum of `this` and `other` as its value. This does not mutate
511
- * `this` but instead returns a new instance, unlike `addToSelf`.
512
- */
513
- add(other) {
514
- const result = this.clone();
515
- result.addToSelf(other);
516
- return result;
517
- }
518
- /**
519
- * Adds `other` to the instance itself, thereby mutating its value.
520
- */
521
- addToSelf(other) {
522
- const maxNrOfDigits = Math.max(this.digits.length, other.digits.length);
523
- let carry = 0;
524
- for (let i = 0; i < maxNrOfDigits; i++) {
525
- let digitSum = carry;
526
- if (i < this.digits.length) {
527
- digitSum += this.digits[i];
528
- }
529
- if (i < other.digits.length) {
530
- digitSum += other.digits[i];
531
- }
532
- if (digitSum >= 10) {
533
- this.digits[i] = digitSum - 10;
534
- carry = 1;
535
- }
536
- else {
537
- this.digits[i] = digitSum;
538
- carry = 0;
539
- }
540
- }
541
- // Apply a remaining carry if needed.
542
- if (carry > 0) {
543
- this.digits[maxNrOfDigits] = 1;
544
- }
545
- }
546
- /**
547
- * Builds the decimal string representation of the big integer. As this is stored in
548
- * little endian, the digits are concatenated in reverse order.
549
- */
550
- toString() {
551
- let res = '';
552
- for (let i = this.digits.length - 1; i >= 0; i--) {
553
- res += this.digits[i];
554
- }
555
- return res;
556
- }
557
- }
558
- /**
559
- * Represents a big integer which is optimized for multiplication operations, as its power-of-twos
560
- * are memoized. See `multiplyBy()` for details on the multiplication algorithm.
561
- */
562
- class BigIntForMultiplication {
563
- constructor(value) {
564
- this.powerOfTwos = [value];
565
- }
566
- /**
567
- * Returns the big integer itself.
568
- */
569
- getValue() {
570
- return this.powerOfTwos[0];
571
- }
572
- /**
573
- * Computes the value for `num * b`, where `num` is a JS number and `b` is a big integer. The
574
- * value for `b` is represented by a storage model that is optimized for this computation.
575
- *
576
- * This operation is implemented in N(log2(num)) by continuous halving of the number, where the
577
- * least-significant bit (LSB) is tested in each iteration. If the bit is set, the bit's index is
578
- * used as exponent into the power-of-two multiplication of `b`.
579
- *
580
- * As an example, consider the multiplication num=42, b=1337. In binary 42 is 0b00101010 and the
581
- * algorithm unrolls into the following iterations:
582
- *
583
- * Iteration | num | LSB | b * 2^iter | Add? | product
584
- * -----------|------------|------|------------|------|--------
585
- * 0 | 0b00101010 | 0 | 1337 | No | 0
586
- * 1 | 0b00010101 | 1 | 2674 | Yes | 2674
587
- * 2 | 0b00001010 | 0 | 5348 | No | 2674
588
- * 3 | 0b00000101 | 1 | 10696 | Yes | 13370
589
- * 4 | 0b00000010 | 0 | 21392 | No | 13370
590
- * 5 | 0b00000001 | 1 | 42784 | Yes | 56154
591
- * 6 | 0b00000000 | 0 | 85568 | No | 56154
592
- *
593
- * The computed product of 56154 is indeed the correct result.
594
- *
595
- * The `BigIntForMultiplication` representation for a big integer provides memoized access to the
596
- * power-of-two values to reduce the workload in computing those values.
597
- */
598
- multiplyBy(num) {
599
- const product = BigInteger.zero();
600
- this.multiplyByAndAddTo(num, product);
601
- return product;
602
- }
603
- /**
604
- * See `multiplyBy()` for details. This function allows for the computed product to be added
605
- * directly to the provided result big integer.
606
- */
607
- multiplyByAndAddTo(num, result) {
608
- for (let exponent = 0; num !== 0; num = num >>> 1, exponent++) {
609
- if (num & 1) {
610
- const value = this.getMultipliedByPowerOfTwo(exponent);
611
- result.addToSelf(value);
612
- }
613
- }
614
- }
615
- /**
616
- * Computes and memoizes the big integer value for `this.number * 2^exponent`.
617
- */
618
- getMultipliedByPowerOfTwo(exponent) {
619
- // Compute the powers up until the requested exponent, where each value is computed from its
620
- // predecessor. This is simple as `this.number * 2^(exponent - 1)` only has to be doubled (i.e.
621
- // added to itself) to reach `this.number * 2^exponent`.
622
- for (let i = this.powerOfTwos.length; i <= exponent; i++) {
623
- const previousPower = this.powerOfTwos[i - 1];
624
- this.powerOfTwos[i] = previousPower.add(previousPower);
625
- }
626
- return this.powerOfTwos[exponent];
627
- }
628
- }
629
- /**
630
- * Represents an exponentiation operation for the provided base, of which exponents are computed and
631
- * memoized. The results are represented by a `BigIntForMultiplication` which is tailored for
632
- * multiplication operations by memoizing the power-of-twos. This effectively results in a matrix
633
- * representation that is lazily computed upon request.
634
- */
635
- class BigIntExponentiation {
636
- constructor(base) {
637
- this.base = base;
638
- this.exponents = [new BigIntForMultiplication(BigInteger.one())];
639
- }
640
- /**
641
- * Compute the value for `this.base^exponent`, resulting in a big integer that is optimized for
642
- * further multiplication operations.
643
- */
644
- toThePowerOf(exponent) {
645
- // Compute the results up until the requested exponent, where every value is computed from its
646
- // predecessor. This is because `this.base^(exponent - 1)` only has to be multiplied by `base`
647
- // to reach `this.base^exponent`.
648
- for (let i = this.exponents.length; i <= exponent; i++) {
649
- const value = this.exponents[i - 1].multiplyBy(this.base);
650
- this.exponents[i] = new BigIntForMultiplication(value);
651
- }
652
- return this.exponents[exponent];
653
- }
654
- }
655
-
656
483
  /**
657
484
  * A lazily created TextEncoder instance for converting strings into UTF-8 bytes
658
485
  */
@@ -815,17 +642,18 @@ function fingerprint(str) {
815
642
  hi = hi ^ 0x130f9bef;
816
643
  lo = lo ^ -0x6b5f56d8;
817
644
  }
818
- return [hi, lo];
645
+ return (BigInt.asUintN(32, BigInt(hi)) << BigInt(32)) | BigInt.asUintN(32, BigInt(lo));
819
646
  }
820
647
  function computeMsgId(msg, meaning = '') {
821
648
  let msgFingerprint = fingerprint(msg);
822
649
  if (meaning) {
823
- const meaningFingerprint = fingerprint(meaning);
824
- msgFingerprint = add64(rol64(msgFingerprint, 1), meaningFingerprint);
650
+ // Rotate the 64-bit message fingerprint one bit to the left and then add the meaning
651
+ // fingerprint.
652
+ msgFingerprint = BigInt.asUintN(64, msgFingerprint << BigInt(1)) |
653
+ ((msgFingerprint >> BigInt(63)) & BigInt(1));
654
+ msgFingerprint += fingerprint(meaning);
825
655
  }
826
- const hi = msgFingerprint[0];
827
- const lo = msgFingerprint[1];
828
- return wordsToDecimalString(hi & 0x7fffffff, lo);
656
+ return BigInt.asUintN(63, msgFingerprint).toString();
829
657
  }
830
658
  function hash32(view, length, c) {
831
659
  let a = 0x9e3779b9, b = 0x9e3779b9;
@@ -931,26 +759,10 @@ function add32to64(a, b) {
931
759
  const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
932
760
  return [high >>> 16, (high << 16) | (low & 0xffff)];
933
761
  }
934
- function add64(a, b) {
935
- const ah = a[0], al = a[1];
936
- const bh = b[0], bl = b[1];
937
- const result = add32to64(al, bl);
938
- const carry = result[0];
939
- const l = result[1];
940
- const h = add32(add32(ah, bh), carry);
941
- return [h, l];
942
- }
943
762
  // Rotate a 32b number left `count` position
944
763
  function rol32(a, count) {
945
764
  return (a << count) | (a >>> (32 - count));
946
765
  }
947
- // Rotate a 64b number left `count` position
948
- function rol64(num, count) {
949
- const hi = num[0], lo = num[1];
950
- const h = (hi << count) | (lo >>> (32 - count));
951
- const l = (lo << count) | (hi >>> (32 - count));
952
- return [h, l];
953
- }
954
766
  function bytesToWords32(bytes, endian) {
955
767
  const size = (bytes.length + 3) >>> 2;
956
768
  const words32 = [];
@@ -976,31 +788,6 @@ function wordAt(bytes, index, endian) {
976
788
  }
977
789
  return word;
978
790
  }
979
- /**
980
- * Create a shared exponentiation pool for base-256 computations. This shared pool provides memoized
981
- * power-of-256 results with memoized power-of-two computations for efficient multiplication.
982
- *
983
- * For our purposes, this can be safely stored as a global without memory concerns. The reason is
984
- * that we encode two words, so only need the 0th (for the low word) and 4th (for the high word)
985
- * exponent.
986
- */
987
- const base256 = new BigIntExponentiation(256);
988
- /**
989
- * Represents two 32-bit words as a single decimal number. This requires a big integer storage
990
- * model as JS numbers are not accurate enough to represent the 64-bit number.
991
- *
992
- * Based on https://www.danvk.org/hex2dec.html
993
- */
994
- function wordsToDecimalString(hi, lo) {
995
- // Encode the four bytes in lo in the lower digits of the decimal number.
996
- // Note: the multiplication results in lo itself but represented by a big integer using its
997
- // decimal digits.
998
- const decimal = base256.toThePowerOf(0).multiplyBy(lo);
999
- // Encode the four bytes in hi above the four lo bytes. lo is a maximum of (2^8)^4, which is why
1000
- // this multiplication factor is applied.
1001
- base256.toThePowerOf(4).multiplyByAndAddTo(hi, decimal);
1002
- return decimal.toString();
1003
- }
1004
791
 
1005
792
  //// Types
1006
793
  var TypeModifier;
@@ -4014,6 +3801,10 @@ class IdleDeferredTrigger extends DeferredTrigger {
4014
3801
  class ImmediateDeferredTrigger extends DeferredTrigger {
4015
3802
  }
4016
3803
  class HoverDeferredTrigger extends DeferredTrigger {
3804
+ constructor(reference, sourceSpan) {
3805
+ super(sourceSpan);
3806
+ this.reference = reference;
3807
+ }
4017
3808
  }
4018
3809
  class TimerDeferredTrigger extends DeferredTrigger {
4019
3810
  constructor(delay, sourceSpan) {
@@ -4126,8 +3917,8 @@ class SwitchBlockCase {
4126
3917
  }
4127
3918
  }
4128
3919
  class ForLoopBlock {
4129
- constructor(itemName, expression, trackBy, contextVariables, children, empty, sourceSpan, startSourceSpan, endSourceSpan) {
4130
- this.itemName = itemName;
3920
+ constructor(item, expression, trackBy, contextVariables, children, empty, sourceSpan, startSourceSpan, endSourceSpan) {
3921
+ this.item = item;
4131
3922
  this.expression = expression;
4132
3923
  this.trackBy = trackBy;
4133
3924
  this.contextVariables = contextVariables;
@@ -4280,6 +4071,8 @@ class RecursiveVisitor$1 {
4280
4071
  visitAll$1(this, block.children);
4281
4072
  }
4282
4073
  visitForLoopBlock(block) {
4074
+ block.item.visit(this);
4075
+ visitAll$1(this, Object.values(block.contextVariables));
4283
4076
  visitAll$1(this, block.children);
4284
4077
  block.empty?.visit(this);
4285
4078
  }
@@ -4291,6 +4084,7 @@ class RecursiveVisitor$1 {
4291
4084
  }
4292
4085
  visitIfBlockBranch(block) {
4293
4086
  visitAll$1(this, block.children);
4087
+ block.expressionAlias?.visit(this);
4294
4088
  }
4295
4089
  visitContent(content) { }
4296
4090
  visitVariable(variable) { }
@@ -5803,13 +5597,13 @@ let policy;
5803
5597
  */
5804
5598
  function getPolicy() {
5805
5599
  if (policy === undefined) {
5600
+ const trustedTypes = _global['trustedTypes'];
5806
5601
  policy = null;
5807
- if (_global.trustedTypes) {
5602
+ if (trustedTypes) {
5808
5603
  try {
5809
- policy =
5810
- _global.trustedTypes.createPolicy('angular#unsafe-jit', {
5811
- createScript: (s) => s,
5812
- });
5604
+ policy = trustedTypes.createPolicy('angular#unsafe-jit', {
5605
+ createScript: (s) => s,
5606
+ });
5813
5607
  }
5814
5608
  catch {
5815
5609
  // trustedTypes.createPolicy throws if called with a name that is
@@ -5839,7 +5633,7 @@ function trustedScriptFromString(script) {
5839
5633
  * vulnerabilities.
5840
5634
  */
5841
5635
  function newTrustedFunctionForJIT(...args) {
5842
- if (!_global.trustedTypes) {
5636
+ if (!_global['trustedTypes']) {
5843
5637
  // In environments that don't support Trusted Types, fall back to the most
5844
5638
  // straightforward implementation:
5845
5639
  return new Function(...args);
@@ -6089,16 +5883,11 @@ function compileNgModule(meta) {
6089
5883
  const statements = [];
6090
5884
  const definitionMap = new DefinitionMap();
6091
5885
  definitionMap.set('type', meta.type.value);
6092
- // Assign bootstrap definition
6093
- if (meta.kind === R3NgModuleMetadataKind.Global) {
6094
- if (meta.bootstrap.length > 0) {
6095
- definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
6096
- }
6097
- }
6098
- else {
6099
- if (meta.bootstrapExpression) {
6100
- definitionMap.set('bootstrap', meta.bootstrapExpression);
6101
- }
5886
+ // Assign bootstrap definition. In local compilation mode (i.e., for
5887
+ // `R3NgModuleMetadataKind.LOCAL`) we assign the bootstrap field using the runtime
5888
+ // `ɵɵsetNgModuleScope`.
5889
+ if (meta.kind === R3NgModuleMetadataKind.Global && meta.bootstrap.length > 0) {
5890
+ definitionMap.set('bootstrap', refsToArray(meta.bootstrap, meta.containsForwardDecls));
6102
5891
  }
6103
5892
  if (meta.selectorScopeMode === R3SelectorScopeMode.Inline) {
6104
5893
  // If requested to emit scope information inline, pass the `declarations`, `imports` and
@@ -6217,6 +6006,9 @@ function generateSetNgModuleScopeCall(meta) {
6217
6006
  scopeMap.set('exports', meta.exportsExpression);
6218
6007
  }
6219
6008
  }
6009
+ if (meta.kind === R3NgModuleMetadataKind.Local && meta.bootstrapExpression) {
6010
+ scopeMap.set('bootstrap', meta.bootstrapExpression);
6011
+ }
6220
6012
  if (Object.keys(scopeMap.values).length === 0) {
6221
6013
  return null;
6222
6014
  }
@@ -8979,19 +8771,26 @@ var OpKind;
8979
8771
  * A namespace change, which causes the subsequent elements to be processed as either HTML or SVG.
8980
8772
  */
8981
8773
  OpKind[OpKind["Namespace"] = 28] = "Namespace";
8774
+ /**
8775
+ * Configure a content projeciton definition for the view.
8776
+ */
8777
+ OpKind[OpKind["ProjectionDef"] = 29] = "ProjectionDef";
8778
+ /**
8779
+ * Create a content projection slot.
8780
+ */
8781
+ OpKind[OpKind["Projection"] = 30] = "Projection";
8982
8782
  /**
8983
8783
  * The start of an i18n block.
8984
8784
  */
8985
- OpKind[OpKind["I18nStart"] = 29] = "I18nStart";
8785
+ OpKind[OpKind["I18nStart"] = 31] = "I18nStart";
8986
8786
  /**
8987
8787
  * A self-closing i18n on a single element.
8988
8788
  */
8989
- OpKind[OpKind["I18n"] = 30] = "I18n";
8789
+ OpKind[OpKind["I18n"] = 32] = "I18n";
8990
8790
  /**
8991
8791
  * The end of an i18n block.
8992
8792
  */
8993
- OpKind[OpKind["I18nEnd"] = 31] = "I18nEnd";
8994
- // TODO: Add Host Listeners, and possibly other host ops also.
8793
+ OpKind[OpKind["I18nEnd"] = 33] = "I18nEnd";
8995
8794
  })(OpKind || (OpKind = {}));
8996
8795
  /**
8997
8796
  * Distinguishes different kinds of IR expressions.
@@ -9103,8 +8902,8 @@ var SemanticVariableKind;
9103
8902
  })(SemanticVariableKind || (SemanticVariableKind = {}));
9104
8903
  /**
9105
8904
  * Whether to compile in compatibilty mode. In compatibility mode, the template pipeline will
9106
- * attempt to match the output of `TemplateDefinitionBuilder` as exactly as possible, at the cost of
9107
- * producing quirky or larger code in some cases.
8905
+ * attempt to match the output of `TemplateDefinitionBuilder` as exactly as possible, at the cost
8906
+ * of producing quirky or larger code in some cases.
9108
8907
  */
9109
8908
  var CompatibilityMode;
9110
8909
  (function (CompatibilityMode) {
@@ -10094,6 +9893,8 @@ function transformExpressionsInOp(op, transform, flags) {
10094
9893
  transformExpressionsInExpression(op.tagNameParams[placeholder], transform, flags);
10095
9894
  }
10096
9895
  break;
9896
+ case OpKind.Projection:
9897
+ case OpKind.ProjectionDef:
10097
9898
  case OpKind.Element:
10098
9899
  case OpKind.ElementStart:
10099
9900
  case OpKind.ElementEnd:
@@ -10484,7 +10285,8 @@ class OpList {
10484
10285
  * The set of OpKinds that represent the creation of an element or container
10485
10286
  */
10486
10287
  const elementContainerOpKinds = new Set([
10487
- OpKind.Element, OpKind.ElementStart, OpKind.Container, OpKind.ContainerStart, OpKind.Template
10288
+ OpKind.Element, OpKind.ElementStart, OpKind.Container, OpKind.ContainerStart, OpKind.Template,
10289
+ OpKind.Projection
10488
10290
  ]);
10489
10291
  /**
10490
10292
  * Checks whether the given operation represents the creation of an element or container.
@@ -10513,12 +10315,13 @@ function createElementStartOp(tag, xref, namespace, i18n, sourceSpan) {
10513
10315
  /**
10514
10316
  * Create a `TemplateOp`.
10515
10317
  */
10516
- function createTemplateOp(xref, tag, namespace, i18n, sourceSpan) {
10318
+ function createTemplateOp(xref, tag, namespace, controlFlow, i18n, sourceSpan) {
10517
10319
  return {
10518
10320
  kind: OpKind.Template,
10519
10321
  xref,
10520
10322
  attributes: null,
10521
10323
  tag,
10324
+ controlFlow,
10522
10325
  decls: null,
10523
10326
  vars: null,
10524
10327
  localRefs: [],
@@ -10612,6 +10415,29 @@ function createNamespaceOp(namespace) {
10612
10415
  ...NEW_OP,
10613
10416
  };
10614
10417
  }
10418
+ function createProjectionDefOp(def) {
10419
+ return {
10420
+ kind: OpKind.ProjectionDef,
10421
+ def,
10422
+ ...NEW_OP,
10423
+ };
10424
+ }
10425
+ function createProjectionOp(xref, selector) {
10426
+ return {
10427
+ kind: OpKind.Projection,
10428
+ xref,
10429
+ selector,
10430
+ projectionSlotIndex: 0,
10431
+ attributes: null,
10432
+ localRefs: [],
10433
+ nonBindable: false,
10434
+ i18n: undefined,
10435
+ sourceSpan: null,
10436
+ ...NEW_OP,
10437
+ ...TRAIT_CONSUMES_SLOT,
10438
+ ...TRAIT_USES_SLOT_INDEX,
10439
+ };
10440
+ }
10615
10441
  /**
10616
10442
  * Create an `ExtractedAttributeOp`.
10617
10443
  */
@@ -10714,6 +10540,11 @@ class ComponentCompilationJob extends CompilationJob {
10714
10540
  this.kind = CompilationJobKind.Tmpl;
10715
10541
  this.fnSuffix = 'Template';
10716
10542
  this.views = new Map();
10543
+ /**
10544
+ * Causes ngContentSelectors to be emitted, for content projection slots in the view. Possibly a
10545
+ * reference into the constant pool.
10546
+ */
10547
+ this.contentSelectors = null;
10717
10548
  /**
10718
10549
  * Constant expressions used by operations within this component's compilation.
10719
10550
  *
@@ -10964,6 +10795,7 @@ function phaseAlignPipeVariadicVarOffset(job) {
10964
10795
  expr.varOffset = expr.args.varOffset;
10965
10796
  // Put the PureFunction vars following the PipeBindingVariadic vars.
10966
10797
  expr.args.varOffset = expr.varOffset + varsUsedByIrExpression(expr);
10798
+ return undefined;
10967
10799
  });
10968
10800
  }
10969
10801
  }
@@ -11018,7 +10850,7 @@ function phaseAttributeExtraction(job) {
11018
10850
  break;
11019
10851
  case OpKind.Property:
11020
10852
  if (!op.isAnimationTrigger) {
11021
- OpList.insertBefore(createExtractedAttributeOp(op.target, op.isTemplate ? BindingKind.Template : BindingKind.Property, op.name, null), lookupElement$2(elements, op.target));
10853
+ OpList.insertBefore(createExtractedAttributeOp(op.target, op.isTemplate ? BindingKind.Template : BindingKind.Property, op.name, null), lookupElement$3(elements, op.target));
11022
10854
  }
11023
10855
  break;
11024
10856
  case OpKind.StyleProp:
@@ -11028,7 +10860,7 @@ function phaseAttributeExtraction(job) {
11028
10860
  // mode.
11029
10861
  if (unit.job.compatibility === CompatibilityMode.TemplateDefinitionBuilder &&
11030
10862
  op.expression instanceof EmptyExpr) {
11031
- OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, op.name, null), lookupElement$2(elements, op.target));
10863
+ OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, op.name, null), lookupElement$3(elements, op.target));
11032
10864
  }
11033
10865
  break;
11034
10866
  case OpKind.Listener:
@@ -11040,7 +10872,7 @@ function phaseAttributeExtraction(job) {
11040
10872
  unit.create.push(extractedAttributeOp);
11041
10873
  }
11042
10874
  else {
11043
- OpList.insertBefore(extractedAttributeOp, lookupElement$2(elements, op.target));
10875
+ OpList.insertBefore(extractedAttributeOp, lookupElement$3(elements, op.target));
11044
10876
  }
11045
10877
  }
11046
10878
  break;
@@ -11051,7 +10883,7 @@ function phaseAttributeExtraction(job) {
11051
10883
  /**
11052
10884
  * Looks up an element in the given map by xref ID.
11053
10885
  */
11054
- function lookupElement$2(elements, xref) {
10886
+ function lookupElement$3(elements, xref) {
11055
10887
  const el = elements.get(xref);
11056
10888
  if (el === undefined) {
11057
10889
  throw new Error('All attributes should have an element-like target.');
@@ -11089,7 +10921,7 @@ function extractAttributeOp(unit, op, elements) {
11089
10921
  unit.create.push(extractedAttributeOp);
11090
10922
  }
11091
10923
  else {
11092
- const ownerOp = lookupElement$2(elements, op.target);
10924
+ const ownerOp = lookupElement$3(elements, op.target);
11093
10925
  OpList.insertBefore(extractedAttributeOp, ownerOp);
11094
10926
  }
11095
10927
  OpList.remove(op);
@@ -11099,7 +10931,7 @@ function extractAttributeOp(unit, op, elements) {
11099
10931
  /**
11100
10932
  * Looks up an element in the given map by xref ID.
11101
10933
  */
11102
- function lookupElement$1(elements, xref) {
10934
+ function lookupElement$2(elements, xref) {
11103
10935
  const el = elements.get(xref);
11104
10936
  if (el === undefined) {
11105
10937
  throw new Error('All attributes should have an element-like target.');
@@ -11125,7 +10957,7 @@ function phaseBindingSpecialization(job) {
11125
10957
  case BindingKind.Attribute:
11126
10958
  if (op.name === 'ngNonBindable') {
11127
10959
  OpList.remove(op);
11128
- const target = lookupElement$1(elements, op.target);
10960
+ const target = lookupElement$2(elements, op.target);
11129
10961
  target.nonBindable = true;
11130
10962
  }
11131
10963
  else {
@@ -11310,38 +11142,65 @@ function mergeNsAndName(prefix, localName) {
11310
11142
  return prefix ? `:${prefix}:${localName}` : localName;
11311
11143
  }
11312
11144
 
11145
+ const BINARY_OPERATORS = new Map([
11146
+ ['&&', BinaryOperator.And],
11147
+ ['>', BinaryOperator.Bigger],
11148
+ ['>=', BinaryOperator.BiggerEquals],
11149
+ ['&', BinaryOperator.BitwiseAnd],
11150
+ ['/', BinaryOperator.Divide],
11151
+ ['==', BinaryOperator.Equals],
11152
+ ['===', BinaryOperator.Identical],
11153
+ ['<', BinaryOperator.Lower],
11154
+ ['<=', BinaryOperator.LowerEquals],
11155
+ ['-', BinaryOperator.Minus],
11156
+ ['%', BinaryOperator.Modulo],
11157
+ ['*', BinaryOperator.Multiply],
11158
+ ['!=', BinaryOperator.NotEquals],
11159
+ ['!==', BinaryOperator.NotIdentical],
11160
+ ['??', BinaryOperator.NullishCoalesce],
11161
+ ['||', BinaryOperator.Or],
11162
+ ['+', BinaryOperator.Plus],
11163
+ ]);
11164
+ const NAMESPACES = new Map([['svg', Namespace.SVG], ['math', Namespace.Math]]);
11165
+ function namespaceForKey(namespacePrefixKey) {
11166
+ if (namespacePrefixKey === null) {
11167
+ return Namespace.HTML;
11168
+ }
11169
+ return NAMESPACES.get(namespacePrefixKey) ?? Namespace.HTML;
11170
+ }
11171
+ function keyForNamespace(namespace) {
11172
+ for (const [k, n] of NAMESPACES.entries()) {
11173
+ if (n === namespace) {
11174
+ return k;
11175
+ }
11176
+ }
11177
+ return null; // No namespace prefix for HTML
11178
+ }
11179
+ function prefixWithNamespace(strippedTag, namespace) {
11180
+ if (namespace === Namespace.HTML) {
11181
+ return strippedTag;
11182
+ }
11183
+ return `:${keyForNamespace(namespace)}:${strippedTag}`;
11184
+ }
11185
+ function literalOrArrayLiteral(value) {
11186
+ if (Array.isArray(value)) {
11187
+ return literalArr(value.map(literalOrArrayLiteral));
11188
+ }
11189
+ return literal(value, INFERRED_TYPE);
11190
+ }
11191
+
11313
11192
  /**
11314
11193
  * Converts the semantic attributes of element-like operations (elements, templates) into constant
11315
11194
  * array expressions, and lifts them into the overall component `consts`.
11316
11195
  */
11317
11196
  function phaseConstCollection(job) {
11318
- if (job instanceof ComponentCompilationJob) {
11319
- // Serialize the extracted messages into the const array.
11320
- const messageConstIndices = {};
11321
- for (const unit of job.units) {
11322
- for (const op of unit.create) {
11323
- if (op.kind === OpKind.ExtractedMessage) {
11324
- messageConstIndices[op.owner] = job.addConst(op.expression, op.statements);
11325
- OpList.remove(op);
11326
- }
11327
- }
11328
- }
11329
- // Assign const index to i18n ops that messages were extracted from.
11330
- for (const unit of job.units) {
11331
- for (const op of unit.create) {
11332
- if (op.kind === OpKind.I18nStart && messageConstIndices[op.xref] !== undefined) {
11333
- op.messageIndex = messageConstIndices[op.xref];
11334
- }
11335
- }
11336
- }
11337
- }
11338
11197
  // Collect all extracted attributes.
11339
- const elementAttributes = new Map();
11198
+ const allElementAttributes = new Map();
11340
11199
  for (const unit of job.units) {
11341
11200
  for (const op of unit.create) {
11342
11201
  if (op.kind === OpKind.ExtractedAttribute) {
11343
- const attributes = elementAttributes.get(op.target) || new ElementAttributes();
11344
- elementAttributes.set(op.target, attributes);
11202
+ const attributes = allElementAttributes.get(op.target) || new ElementAttributes();
11203
+ allElementAttributes.set(op.target, attributes);
11345
11204
  attributes.add(op.bindingKind, op.name, op.expression);
11346
11205
  OpList.remove(op);
11347
11206
  }
@@ -11351,9 +11210,8 @@ function phaseConstCollection(job) {
11351
11210
  if (job instanceof ComponentCompilationJob) {
11352
11211
  for (const unit of job.units) {
11353
11212
  for (const op of unit.create) {
11354
- if (op.kind === OpKind.Element || op.kind === OpKind.ElementStart ||
11355
- op.kind === OpKind.Template) {
11356
- const attributes = elementAttributes.get(op.xref);
11213
+ if (isElementOrContainerOp(op)) {
11214
+ const attributes = allElementAttributes.get(op.xref);
11357
11215
  if (attributes !== undefined) {
11358
11216
  const attrArray = serializeAttributes(attributes);
11359
11217
  if (attrArray.entries.length > 0) {
@@ -11367,7 +11225,7 @@ function phaseConstCollection(job) {
11367
11225
  else if (job instanceof HostBindingCompilationJob) {
11368
11226
  // TODO: If the host binding case further diverges, we may want to split it into its own
11369
11227
  // phase.
11370
- for (const [xref, attributes] of elementAttributes.entries()) {
11228
+ for (const [xref, attributes] of allElementAttributes.entries()) {
11371
11229
  if (xref !== job.root.xref) {
11372
11230
  throw new Error(`An attribute would be const collected into the host binding's template function, but is not associated with the root xref.`);
11373
11231
  }
@@ -11414,6 +11272,15 @@ class ElementAttributes {
11414
11272
  return;
11415
11273
  }
11416
11274
  this.known.add(name);
11275
+ if (name === 'ngProjectAs') {
11276
+ if (value === null || !(value instanceof LiteralExpr) || (value.value == null) ||
11277
+ (typeof value.value?.toString() !== 'string')) {
11278
+ throw Error('ngProjectAs must have a string literal value');
11279
+ }
11280
+ this.projectAs = value.value.toString();
11281
+ // TODO: TemplateDefinitionBuilder allows `ngProjectAs` to also be assigned as a literal
11282
+ // attribute. Is this sane?
11283
+ }
11417
11284
  const array = this.arrayFor(kind);
11418
11285
  array.push(...getAttributeNameLiterals$1(name));
11419
11286
  if (kind === BindingKind.Attribute || kind === BindingKind.StyleProperty) {
@@ -11449,7 +11316,10 @@ function getAttributeNameLiterals$1(name) {
11449
11316
  function serializeAttributes({ attributes, bindings, classes, i18n, projectAs, styles, template }) {
11450
11317
  const attrArray = [...attributes];
11451
11318
  if (projectAs !== null) {
11452
- attrArray.push(literal(5 /* core.AttributeMarker.ProjectAs */), literal(projectAs));
11319
+ // Parse the attribute value into a CssSelectorList. Note that we only take the
11320
+ // first selector, because we don't support multiple selectors in ngProjectAs.
11321
+ const parsedR3Selector = parseSelectorToR3Selector(projectAs)[0];
11322
+ attrArray.push(literal(5 /* core.AttributeMarker.ProjectAs */), literalOrArrayLiteral(parsedR3Selector));
11453
11323
  }
11454
11324
  if (classes.length > 0) {
11455
11325
  attrArray.push(literal(1 /* core.AttributeMarker.Classes */), ...classes);
@@ -18057,7 +17927,7 @@ class _TreeBuilder {
18057
17927
  // This is unlikely to happen, but we have an assertion just in case.
18058
17928
  if (parent instanceof BlockGroup) {
18059
17929
  this.errors.push(TreeError.create(null, startSpan, 'Text cannot be placed directly inside of a block group.'));
18060
- return null;
17930
+ return;
18061
17931
  }
18062
17932
  if (parent != null && parent.children.length === 0 &&
18063
17933
  this.getTagDefinition(parent.name).ignoreFirstLf) {
@@ -19094,47 +18964,6 @@ function hyphenate(value) {
19094
18964
  .toLowerCase();
19095
18965
  }
19096
18966
 
19097
- const BINARY_OPERATORS = new Map([
19098
- ['&&', BinaryOperator.And],
19099
- ['>', BinaryOperator.Bigger],
19100
- ['>=', BinaryOperator.BiggerEquals],
19101
- ['&', BinaryOperator.BitwiseAnd],
19102
- ['/', BinaryOperator.Divide],
19103
- ['==', BinaryOperator.Equals],
19104
- ['===', BinaryOperator.Identical],
19105
- ['<', BinaryOperator.Lower],
19106
- ['<=', BinaryOperator.LowerEquals],
19107
- ['-', BinaryOperator.Minus],
19108
- ['%', BinaryOperator.Modulo],
19109
- ['*', BinaryOperator.Multiply],
19110
- ['!=', BinaryOperator.NotEquals],
19111
- ['!==', BinaryOperator.NotIdentical],
19112
- ['??', BinaryOperator.NullishCoalesce],
19113
- ['||', BinaryOperator.Or],
19114
- ['+', BinaryOperator.Plus],
19115
- ]);
19116
- const NAMESPACES = new Map([['svg', Namespace.SVG], ['math', Namespace.Math]]);
19117
- function namespaceForKey(namespacePrefixKey) {
19118
- if (namespacePrefixKey === null) {
19119
- return Namespace.HTML;
19120
- }
19121
- return NAMESPACES.get(namespacePrefixKey) ?? Namespace.HTML;
19122
- }
19123
- function keyForNamespace(namespace) {
19124
- for (const [k, n] of NAMESPACES.entries()) {
19125
- if (n === namespace) {
19126
- return k;
19127
- }
19128
- }
19129
- return null; // No namespace prefix for HTML
19130
- }
19131
- function prefixWithNamespace(strippedTag, namespace) {
19132
- if (namespace === Namespace.HTML) {
19133
- return strippedTag;
19134
- }
19135
- return `:${keyForNamespace(namespace)}:${strippedTag}`;
19136
- }
19137
-
19138
18967
  /**
19139
18968
  * Generate names for functions and variables across all views.
19140
18969
  *
@@ -19310,6 +19139,7 @@ function mergeNextContextsInOps(ops) {
19310
19139
  tryToMerge = false;
19311
19140
  break;
19312
19141
  }
19142
+ return;
19313
19143
  });
19314
19144
  }
19315
19145
  }
@@ -19367,7 +19197,7 @@ function phaseNoListenersOnTemplates(job) {
19367
19197
  /**
19368
19198
  * Looks up an element in the given map by xref ID.
19369
19199
  */
19370
- function lookupElement(elements, xref) {
19200
+ function lookupElement$1(elements, xref) {
19371
19201
  const el = elements.get(xref);
19372
19202
  if (el === undefined) {
19373
19203
  throw new Error('All attributes should have an element-like target.');
@@ -19396,7 +19226,7 @@ function phaseNonbindable(job) {
19396
19226
  OpList.insertAfter(createDisableBindingsOp(op.xref), op);
19397
19227
  }
19398
19228
  if ((op.kind === OpKind.ElementEnd || op.kind === OpKind.ContainerEnd) &&
19399
- lookupElement(elements, op.xref).nonBindable) {
19229
+ lookupElement$1(elements, op.xref).nonBindable) {
19400
19230
  OpList.insertBefore(createEnableBindingsOp(op.xref), op);
19401
19231
  }
19402
19232
  }
@@ -19734,8 +19564,11 @@ function elementContainerEnd() {
19734
19564
  }
19735
19565
  function template(slot, templateFnRef, decls, vars, tag, constIndex, sourceSpan) {
19736
19566
  const args = [literal(slot), templateFnRef, literal(decls), literal(vars)];
19737
- if (tag != null && constIndex != null) {
19738
- args.push(literal(tag), literal(constIndex));
19567
+ if (tag !== null) {
19568
+ args.push(literal(tag));
19569
+ if (constIndex !== null) {
19570
+ args.push(literal(constIndex));
19571
+ }
19739
19572
  }
19740
19573
  return call(Identifiers.templateCreate, args, sourceSpan);
19741
19574
  }
@@ -19805,6 +19638,19 @@ function text(slot, initialValue, sourceSpan) {
19805
19638
  }
19806
19639
  return call(Identifiers.text, args, sourceSpan);
19807
19640
  }
19641
+ function projectionDef(def) {
19642
+ return call(Identifiers.projectionDef, def ? [def] : [], null);
19643
+ }
19644
+ function projection(slot, projectionSlotIndex, attributes) {
19645
+ const args = [literal(slot)];
19646
+ if (projectionSlotIndex !== 0 || attributes !== null) {
19647
+ args.push(literal(projectionSlotIndex));
19648
+ if (attributes != null) {
19649
+ args.push(literal(attributes));
19650
+ }
19651
+ }
19652
+ return call(Identifiers.projection, args, null);
19653
+ }
19808
19654
  function i18nStart(slot, constIndex) {
19809
19655
  return call(Identifiers.i18nStart, [literal(slot), literal(constIndex)], null);
19810
19656
  }
@@ -20195,7 +20041,7 @@ function reifyCreateOperations(unit, ops) {
20195
20041
  throw new Error(`AssertionError: must be compiling a component`);
20196
20042
  }
20197
20043
  const childView = unit.job.views.get(op.xref);
20198
- OpList.replace(op, template(op.slot, variable(childView.fnName), childView.decls, childView.vars, op.tag, op.attributes, op.sourceSpan));
20044
+ OpList.replace(op, template(op.slot, variable(childView.fnName), childView.decls, childView.vars, op.controlFlow ? null : op.tag, op.attributes, op.sourceSpan));
20199
20045
  break;
20200
20046
  case OpKind.DisableBindings:
20201
20047
  OpList.replace(op, disableBindings());
@@ -20232,6 +20078,15 @@ function reifyCreateOperations(unit, ops) {
20232
20078
  break;
20233
20079
  }
20234
20080
  break;
20081
+ case OpKind.ProjectionDef:
20082
+ OpList.replace(op, projectionDef(op.def));
20083
+ break;
20084
+ case OpKind.Projection:
20085
+ if (op.slot === null) {
20086
+ throw new Error('No slot was assigned for project instruction');
20087
+ }
20088
+ OpList.replace(op, projection(op.slot, op.projectionSlotIndex, op.attributes));
20089
+ break;
20235
20090
  case OpKind.Statement:
20236
20091
  // Pass statement operations directly through.
20237
20092
  break;
@@ -21284,7 +21139,99 @@ function allowConservativeInlining(decl, target) {
21284
21139
  }
21285
21140
  }
21286
21141
 
21142
+ /**
21143
+ * Locate projection slots, populate the each component's `ngContentSelectors` literal field,
21144
+ * populate `project` arguments, and generate the required `projectionDef` instruction for the job's
21145
+ * root view.
21146
+ */
21147
+ function phaseGenerateProjectionDef(job) {
21148
+ // TODO: Why does TemplateDefinitionBuilder force a shared constant?
21149
+ const share = job.compatibility === CompatibilityMode.TemplateDefinitionBuilder;
21150
+ // Collect all selectors from this component, and its nested views. Also, assign each projection a
21151
+ // unique ascending projection slot index.
21152
+ const selectors = [];
21153
+ let projectionSlotIndex = 0;
21154
+ for (const unit of job.units) {
21155
+ for (const op of unit.create) {
21156
+ if (op.kind === OpKind.Projection) {
21157
+ selectors.push(op.selector);
21158
+ op.projectionSlotIndex = projectionSlotIndex++;
21159
+ }
21160
+ }
21161
+ }
21162
+ if (selectors.length > 0) {
21163
+ // Create the projectionDef array. If we only found a single wildcard selector, then we use the
21164
+ // default behavior with no arguments instead.
21165
+ let defExpr = null;
21166
+ if (selectors.length > 1 || selectors[0] !== '*') {
21167
+ const def = selectors.map(s => s === '*' ? s : parseSelectorToR3Selector(s));
21168
+ defExpr = job.pool.getConstLiteral(literalOrArrayLiteral(def), share);
21169
+ }
21170
+ // Create the ngContentSelectors constant.
21171
+ job.contentSelectors = job.pool.getConstLiteral(literalOrArrayLiteral(selectors), share);
21172
+ // The projection def instruction goes at the beginning of the root view, before any
21173
+ // `projection` instructions.
21174
+ job.root.create.prepend([createProjectionDefOp(defExpr)]);
21175
+ }
21176
+ }
21177
+
21178
+ /**
21179
+ * Lifts i18n properties into the consts array.
21180
+ */
21181
+ function phaseI18nConstCollection(job) {
21182
+ // Serialize the extracted messages into the const array.
21183
+ // TODO: Use `Map` instead of object.
21184
+ const messageConstIndices = {};
21185
+ for (const unit of job.units) {
21186
+ for (const op of unit.create) {
21187
+ if (op.kind === OpKind.ExtractedMessage) {
21188
+ messageConstIndices[op.owner] = job.addConst(op.expression, op.statements);
21189
+ OpList.remove(op);
21190
+ }
21191
+ }
21192
+ }
21193
+ // Assign const index to i18n ops that messages were extracted from.
21194
+ for (const unit of job.units) {
21195
+ for (const op of unit.create) {
21196
+ if (op.kind === OpKind.I18nStart && messageConstIndices[op.xref] !== undefined) {
21197
+ op.messageIndex = messageConstIndices[op.xref];
21198
+ }
21199
+ }
21200
+ }
21201
+ }
21202
+
21203
+ /**
21204
+ * Attributes of `ng-content` named 'select' are specifically removed, because they control which
21205
+ * content matches as a property of the `projection`, and are not a plain attribute.
21206
+ */
21207
+ function phaseRemoveContentSelectors(job) {
21208
+ for (const unit of job.units) {
21209
+ const elements = getElementsByXrefId(unit);
21210
+ for (const op of unit.update) {
21211
+ switch (op.kind) {
21212
+ case OpKind.Binding:
21213
+ const target = lookupElement(elements, op.target);
21214
+ if (op.name.toLowerCase() === 'select' && target.kind === OpKind.Projection) {
21215
+ OpList.remove(op);
21216
+ }
21217
+ continue;
21218
+ }
21219
+ }
21220
+ }
21221
+ }
21222
+ /**
21223
+ * Looks up an element in the given map by xref ID.
21224
+ */
21225
+ function lookupElement(elements, xref) {
21226
+ const el = elements.get(xref);
21227
+ if (el === undefined) {
21228
+ throw new Error('All attributes should have an element-like target.');
21229
+ }
21230
+ return el;
21231
+ }
21232
+
21287
21233
  const phases = [
21234
+ { kind: CompilationJobKind.Tmpl, fn: phaseRemoveContentSelectors },
21288
21235
  { kind: CompilationJobKind.Tmpl, fn: phaseGenerateI18nBlocks },
21289
21236
  { kind: CompilationJobKind.Tmpl, fn: phaseI18nTextExtraction },
21290
21237
  { kind: CompilationJobKind.Host, fn: phaseHostStylePropertyParsing },
@@ -21299,6 +21246,7 @@ const phases = [
21299
21246
  { kind: CompilationJobKind.Tmpl, fn: phasePipeCreation },
21300
21247
  { kind: CompilationJobKind.Tmpl, fn: phasePipeVariadic },
21301
21248
  { kind: CompilationJobKind.Both, fn: phasePureLiteralStructures },
21249
+ { kind: CompilationJobKind.Tmpl, fn: phaseGenerateProjectionDef },
21302
21250
  { kind: CompilationJobKind.Tmpl, fn: phaseGenerateVariables },
21303
21251
  { kind: CompilationJobKind.Tmpl, fn: phaseSaveRestoreView },
21304
21252
  { kind: CompilationJobKind.Tmpl, fn: phaseFindAnyCasts },
@@ -21313,6 +21261,7 @@ const phases = [
21313
21261
  { kind: CompilationJobKind.Tmpl, fn: phaseSlotAllocation },
21314
21262
  { kind: CompilationJobKind.Tmpl, fn: phaseResolveI18nPlaceholders },
21315
21263
  { kind: CompilationJobKind.Tmpl, fn: phaseI18nMessageExtraction },
21264
+ { kind: CompilationJobKind.Tmpl, fn: phaseI18nConstCollection },
21316
21265
  { kind: CompilationJobKind.Both, fn: phaseConstCollection },
21317
21266
  { kind: CompilationJobKind.Both, fn: phaseVarCounting },
21318
21267
  { kind: CompilationJobKind.Tmpl, fn: phaseGenerateAdvance },
@@ -21508,6 +21457,9 @@ function ingestNodes(unit, template) {
21508
21457
  else if (node instanceof Template) {
21509
21458
  ingestTemplate(unit, node);
21510
21459
  }
21460
+ else if (node instanceof Content) {
21461
+ ingestContent(unit, node);
21462
+ }
21511
21463
  else if (node instanceof Text$3) {
21512
21464
  ingestText(unit, node);
21513
21465
  }
@@ -21550,7 +21502,7 @@ function ingestTemplate(unit, tmpl) {
21550
21502
  [namespacePrefix, tagNameWithoutNamespace] = splitNsName(tmpl.tagName);
21551
21503
  }
21552
21504
  // TODO: validate the fallback tag name here.
21553
- const tplOp = createTemplateOp(childView.xref, tagNameWithoutNamespace ?? 'ng-template', namespaceForKey(namespacePrefix), tmpl.i18n, tmpl.startSourceSpan);
21505
+ const tplOp = createTemplateOp(childView.xref, tagNameWithoutNamespace ?? 'ng-template', namespaceForKey(namespacePrefix), false, tmpl.i18n, tmpl.startSourceSpan);
21554
21506
  unit.create.push(tplOp);
21555
21507
  ingestBindings(unit, tplOp, tmpl);
21556
21508
  ingestReferences(tplOp, tmpl);
@@ -21559,6 +21511,16 @@ function ingestTemplate(unit, tmpl) {
21559
21511
  childView.contextVariables.set(name, value);
21560
21512
  }
21561
21513
  }
21514
+ /**
21515
+ * Ingest a literal text node from the AST into the given `ViewCompilation`.
21516
+ */
21517
+ function ingestContent(unit, content) {
21518
+ const op = createProjectionOp(unit.job.allocateXrefId(), content.selector);
21519
+ for (const attr of content.attributes) {
21520
+ ingestBinding(unit, op.xref, attr.name, literal(attr.value), 1 /* e.BindingType.Attribute */, null, SecurityContext.NONE, attr.sourceSpan, true, false);
21521
+ }
21522
+ unit.create.push(op);
21523
+ }
21562
21524
  /**
21563
21525
  * Ingest a literal text node from the AST into the given `ViewCompilation`.
21564
21526
  */
@@ -21590,7 +21552,7 @@ function ingestSwitchBlock(unit, switchBlock) {
21590
21552
  const cView = unit.job.allocateView(unit.xref);
21591
21553
  if (!firstXref)
21592
21554
  firstXref = cView.xref;
21593
- unit.create.push(createTemplateOp(cView.xref, 'Case', Namespace.HTML, undefined, null));
21555
+ unit.create.push(createTemplateOp(cView.xref, 'Case', Namespace.HTML, true, undefined, null));
21594
21556
  const caseExpr = switchCase.expression ? convertAst(switchCase.expression, unit.job) : null;
21595
21557
  conditions.push([cView.xref, caseExpr]);
21596
21558
  ingestNodes(cView, switchCase.children);
@@ -23043,16 +23005,15 @@ function parseForLoopParameters(block, errors, bindingParser) {
23043
23005
  }
23044
23006
  const [, itemName, rawExpression] = match;
23045
23007
  const result = {
23046
- itemName,
23008
+ itemName: new Variable(itemName, '$implicit', expressionParam.sourceSpan, expressionParam.sourceSpan),
23047
23009
  trackBy: null,
23048
23010
  expression: parseBlockParameterToBinding(expressionParam, bindingParser, rawExpression),
23049
- context: null,
23011
+ context: {},
23050
23012
  };
23051
23013
  for (const param of secondaryParams) {
23052
23014
  const letMatch = param.expression.match(FOR_LOOP_LET_PATTERN);
23053
23015
  if (letMatch !== null) {
23054
- result.context = result.context || {};
23055
- parseLetParameter(param.sourceSpan, letMatch[1], result.context, errors);
23016
+ parseLetParameter(param.sourceSpan, letMatch[1], param.sourceSpan, result.context, errors);
23056
23017
  continue;
23057
23018
  }
23058
23019
  const trackMatch = param.expression.match(FOR_LOOP_TRACK_PATTERN);
@@ -23067,15 +23028,22 @@ function parseForLoopParameters(block, errors, bindingParser) {
23067
23028
  }
23068
23029
  errors.push(new ParseError(param.sourceSpan, `Unrecognized loop paramater "${param.expression}"`));
23069
23030
  }
23031
+ // Fill out any variables that haven't been defined explicitly.
23032
+ for (const variableName of ALLOWED_FOR_LOOP_LET_VARIABLES) {
23033
+ if (!result.context.hasOwnProperty(variableName)) {
23034
+ result.context[variableName] =
23035
+ new Variable(variableName, variableName, block.startSourceSpan, block.startSourceSpan);
23036
+ }
23037
+ }
23070
23038
  return result;
23071
23039
  }
23072
23040
  /** Parses the `let` parameter of a `for` loop block. */
23073
- function parseLetParameter(sourceSpan, expression, context, errors) {
23041
+ function parseLetParameter(sourceSpan, expression, span, context, errors) {
23074
23042
  const parts = expression.split(',');
23075
23043
  for (const part of parts) {
23076
23044
  const expressionParts = part.split('=');
23077
23045
  const name = expressionParts.length === 2 ? expressionParts[0].trim() : '';
23078
- const variableName = expressionParts.length === 2 ? expressionParts[1].trim() : '';
23046
+ const variableName = (expressionParts.length === 2 ? expressionParts[1].trim() : '');
23079
23047
  if (name.length === 0 || variableName.length === 0) {
23080
23048
  errors.push(new ParseError(sourceSpan, `Invalid for loop "let" parameter. Parameter should match the pattern "<name> = <variable name>"`));
23081
23049
  }
@@ -23086,7 +23054,7 @@ function parseLetParameter(sourceSpan, expression, context, errors) {
23086
23054
  errors.push(new ParseError(sourceSpan, `Duplicate "let" parameter variable "${variableName}"`));
23087
23055
  }
23088
23056
  else {
23089
- context[variableName] = name;
23057
+ context[variableName] = new Variable(name, variableName, span, span);
23090
23058
  }
23091
23059
  }
23092
23060
  }
@@ -23203,7 +23171,8 @@ function parseConditionalBlockParameters(block, errors, bindingParser) {
23203
23171
  errors.push(new ParseError(param.sourceSpan, 'Conditional can only have one "as" expression'));
23204
23172
  }
23205
23173
  else {
23206
- expressionAlias = aliasMatch[1].trim();
23174
+ const name = aliasMatch[1].trim();
23175
+ expressionAlias = new Variable(name, name, param.sourceSpan, param.sourceSpan);
23207
23176
  }
23208
23177
  }
23209
23178
  return { expression, expressionAlias };
@@ -23482,10 +23451,10 @@ function createTimerTrigger(parameters, sourceSpan) {
23482
23451
  return new TimerDeferredTrigger(delay, sourceSpan);
23483
23452
  }
23484
23453
  function createInteractionTrigger(parameters, sourceSpan) {
23485
- if (parameters.length > 1) {
23486
- throw new Error(`"${OnTriggerType.INTERACTION}" trigger can only have zero or one parameters`);
23454
+ if (parameters.length !== 1) {
23455
+ throw new Error(`"${OnTriggerType.INTERACTION}" trigger must have exactly one parameter`);
23487
23456
  }
23488
- return new InteractionDeferredTrigger(parameters[0] ?? null, sourceSpan);
23457
+ return new InteractionDeferredTrigger(parameters[0], sourceSpan);
23489
23458
  }
23490
23459
  function createImmediateTrigger(parameters, sourceSpan) {
23491
23460
  if (parameters.length > 0) {
@@ -23494,10 +23463,10 @@ function createImmediateTrigger(parameters, sourceSpan) {
23494
23463
  return new ImmediateDeferredTrigger(sourceSpan);
23495
23464
  }
23496
23465
  function createHoverTrigger(parameters, sourceSpan) {
23497
- if (parameters.length > 0) {
23498
- throw new Error(`"${OnTriggerType.HOVER}" trigger cannot have parameters`);
23466
+ if (parameters.length !== 1) {
23467
+ throw new Error(`"${OnTriggerType.HOVER}" trigger must have exactly one parameter`);
23499
23468
  }
23500
- return new HoverDeferredTrigger(sourceSpan);
23469
+ return new HoverDeferredTrigger(parameters[0], sourceSpan);
23501
23470
  }
23502
23471
  function createViewportTrigger(parameters, sourceSpan) {
23503
23472
  // TODO: the RFC has some more potential parameters for `viewport`.
@@ -25246,8 +25215,8 @@ class TemplateDefinitionBuilder {
25246
25215
  // If the branch has an alias, it'll be assigned directly to the container's context.
25247
25216
  // We define a variable referring directly to the context so that any nested usages can be
25248
25217
  // rewritten to refer to it.
25249
- const variables = expressionAlias ?
25250
- [new Variable(expressionAlias, DIRECT_CONTEXT_REFERENCE, sourceSpan, sourceSpan)] :
25218
+ const variables = expressionAlias !== null ?
25219
+ [new Variable(expressionAlias.name, DIRECT_CONTEXT_REFERENCE, expressionAlias.sourceSpan, expressionAlias.keySpan)] :
25251
25220
  undefined;
25252
25221
  return {
25253
25222
  index: this.createEmbeddedTemplateFn(null, children, '_Conditional', sourceSpan, variables),
@@ -25455,11 +25424,7 @@ class TemplateDefinitionBuilder {
25455
25424
  // Allocate one slot for the repeater metadata. The slots for the primary and empty block
25456
25425
  // are implicitly inferred by the runtime to index + 1 and index + 2.
25457
25426
  const blockIndex = this.allocateDataSlot();
25458
- const primaryData = this.prepareEmbeddedTemplateFn(block.children, '_For', [
25459
- new Variable(block.itemName, '$implicit', block.sourceSpan, block.sourceSpan),
25460
- new Variable(getLoopLocalName(block, '$index'), '$index', block.sourceSpan, block.sourceSpan),
25461
- new Variable(getLoopLocalName(block, '$count'), '$count', block.sourceSpan, block.sourceSpan),
25462
- ]);
25427
+ const primaryData = this.prepareEmbeddedTemplateFn(block.children, '_For', [block.item, block.contextVariables.$index, block.contextVariables.$count]);
25463
25428
  const emptyData = block.empty === null ?
25464
25429
  null :
25465
25430
  this.prepareEmbeddedTemplateFn(block.empty.children, '_ForEmpty');
@@ -25489,34 +25454,35 @@ class TemplateDefinitionBuilder {
25489
25454
  this.updateInstruction(block.sourceSpan, Identifiers.repeater, () => [literal(blockIndex), this.convertPropertyBinding(value)]);
25490
25455
  }
25491
25456
  registerComputedLoopVariables(block, bindingScope) {
25492
- const indexLocalName = getLoopLocalName(block, '$index');
25493
- const countLocalName = getLoopLocalName(block, '$count');
25457
+ const indexLocalName = block.contextVariables.$index.name;
25458
+ const countLocalName = block.contextVariables.$count.name;
25494
25459
  const level = bindingScope.bindingLevel;
25495
- bindingScope.set(level, getLoopLocalName(block, '$odd'), scope => scope.get(indexLocalName).modulo(literal(2)).notIdentical(literal(0)));
25496
- bindingScope.set(level, getLoopLocalName(block, '$even'), scope => scope.get(indexLocalName).modulo(literal(2)).identical(literal(0)));
25497
- bindingScope.set(level, getLoopLocalName(block, '$first'), scope => scope.get(indexLocalName).identical(literal(0)));
25498
- bindingScope.set(level, getLoopLocalName(block, '$last'), scope => scope.get(indexLocalName).identical(scope.get(countLocalName).minus(literal(1))));
25460
+ bindingScope.set(level, block.contextVariables.$odd.name, scope => scope.get(indexLocalName).modulo(literal(2)).notIdentical(literal(0)));
25461
+ bindingScope.set(level, block.contextVariables.$even.name, scope => scope.get(indexLocalName).modulo(literal(2)).identical(literal(0)));
25462
+ bindingScope.set(level, block.contextVariables.$first.name, scope => scope.get(indexLocalName).identical(literal(0)));
25463
+ bindingScope.set(level, block.contextVariables.$last.name, scope => scope.get(indexLocalName).identical(scope.get(countLocalName).minus(literal(1))));
25499
25464
  }
25500
25465
  optimizeTrackByFunction(block) {
25466
+ const indexLocalName = block.contextVariables.$index.name;
25467
+ const itemName = block.item.name;
25501
25468
  const ast = block.trackBy.ast;
25502
25469
  // Top-level access of `$index` uses the built in `repeaterTrackByIndex`.
25503
25470
  if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver &&
25504
- ast.name === getLoopLocalName(block, '$index')) {
25471
+ ast.name === indexLocalName) {
25505
25472
  return { expression: importExpr(Identifiers.repeaterTrackByIndex), usesComponentInstance: false };
25506
25473
  }
25507
25474
  // Top-level access of the item uses the built in `repeaterTrackByIdentity`.
25508
25475
  if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver &&
25509
- ast.name === block.itemName) {
25476
+ ast.name === itemName) {
25510
25477
  return { expression: importExpr(Identifiers.repeaterTrackByIdentity), usesComponentInstance: false };
25511
25478
  }
25512
25479
  // Top-level calls in the form of `fn($index, item)` can be passed in directly.
25513
25480
  if (ast instanceof Call && ast.receiver instanceof PropertyRead &&
25514
25481
  ast.receiver.receiver instanceof ImplicitReceiver && ast.args.length === 2) {
25515
25482
  const firstIsIndex = ast.args[0] instanceof PropertyRead &&
25516
- ast.args[0].receiver instanceof ImplicitReceiver &&
25517
- ast.args[0].name === getLoopLocalName(block, '$index');
25483
+ ast.args[0].receiver instanceof ImplicitReceiver && ast.args[0].name === indexLocalName;
25518
25484
  const secondIsItem = ast.args[1] instanceof PropertyRead &&
25519
- ast.args[1].receiver instanceof ImplicitReceiver && ast.args[1].name === block.itemName;
25485
+ ast.args[1].receiver instanceof ImplicitReceiver && ast.args[1].name === itemName;
25520
25486
  if (firstIsIndex && secondIsItem) {
25521
25487
  // If we're in the top-level component, we can access directly through `ctx`,
25522
25488
  // otherwise we have to get a hold of the component through `componentInstance()`.
@@ -25533,20 +25499,22 @@ class TemplateDefinitionBuilder {
25533
25499
  if (optimizedFn !== null) {
25534
25500
  return optimizedFn;
25535
25501
  }
25536
- // Referencing these requires access to the context which the tracking function
25537
- // might not have. `$index` is special because of backwards compatibility.
25538
- const bannedGlobals = new Set([
25539
- getLoopLocalName(block, '$count'), getLoopLocalName(block, '$first'),
25540
- getLoopLocalName(block, '$last'), getLoopLocalName(block, '$even'),
25541
- getLoopLocalName(block, '$odd')
25542
- ]);
25502
+ const contextVars = block.contextVariables;
25543
25503
  const scope = new TrackByBindingScope(this._bindingScope, {
25544
25504
  // Alias `$index` and the item name to `$index` and `$item` respectively.
25545
25505
  // This allows us to reuse pure functions that may have different item names,
25546
25506
  // but are otherwise identical.
25547
- [getLoopLocalName(block, '$index')]: '$index',
25548
- [block.itemName]: '$item',
25549
- }, bannedGlobals);
25507
+ [contextVars.$index.name]: '$index',
25508
+ [block.item.name]: '$item',
25509
+ // Accessing these variables in a tracking function will result in a template diagnostic.
25510
+ // We define them as globals so that their accesses are preserved verbatim instead of being
25511
+ // rewritten to the actual accesses.
25512
+ [contextVars.$count.name]: contextVars.$count.name,
25513
+ [contextVars.$first.name]: contextVars.$first.name,
25514
+ [contextVars.$last.name]: contextVars.$last.name,
25515
+ [contextVars.$even.name]: contextVars.$even.name,
25516
+ [contextVars.$odd.name]: contextVars.$odd.name,
25517
+ });
25550
25518
  const params = [new FnParam('$index'), new FnParam('$item')];
25551
25519
  const stmts = convertPureComponentScopeFunction(block.trackBy.ast, scope, variable(CONTEXT_NAME), 'track');
25552
25520
  const usesComponentInstance = scope.getComponentAccessCount() > 0;
@@ -25562,6 +25530,7 @@ class TemplateDefinitionBuilder {
25562
25530
  stmts[stmts.length - 1] = new ReturnStatement(lastStatement.expr);
25563
25531
  }
25564
25532
  }
25533
+ // This has to be a function expression, because `.bind` doesn't work on arrow functions.
25565
25534
  fn$1 = fn(params, stmts);
25566
25535
  }
25567
25536
  return {
@@ -26204,25 +26173,20 @@ class BindingScope {
26204
26173
  }
26205
26174
  /** Binding scope of a `track` function inside a `for` loop block. */
26206
26175
  class TrackByBindingScope extends BindingScope {
26207
- constructor(parentScope, globalAliases, bannedGlobals) {
26176
+ constructor(parentScope, globalAliases) {
26208
26177
  super(parentScope.bindingLevel + 1, parentScope);
26209
26178
  this.globalAliases = globalAliases;
26210
- this.bannedGlobals = bannedGlobals;
26211
26179
  this.componentAccessCount = 0;
26212
26180
  }
26213
26181
  get(name) {
26214
26182
  let current = this.parent;
26215
- // Verify that the expression isn't trying to access a variable from a parent scope.
26183
+ // Prevent accesses of template variables outside the `for` loop.
26216
26184
  while (current) {
26217
26185
  if (current.hasLocal(name)) {
26218
- this.forbiddenAccessError(name);
26186
+ return null;
26219
26187
  }
26220
26188
  current = current.parent;
26221
26189
  }
26222
- // If the variable is one of the banned globals, we have to throw.
26223
- if (this.bannedGlobals.has(name)) {
26224
- this.forbiddenAccessError(name);
26225
- }
26226
26190
  // Intercept any aliased globals.
26227
26191
  if (this.globalAliases[name]) {
26228
26192
  return variable(this.globalAliases[name]);
@@ -26235,11 +26199,6 @@ class TrackByBindingScope extends BindingScope {
26235
26199
  getComponentAccessCount() {
26236
26200
  return this.componentAccessCount;
26237
26201
  }
26238
- forbiddenAccessError(propertyName) {
26239
- // TODO(crisbeto): this should be done through template type checking once it is available.
26240
- throw new Error(`Accessing ${propertyName} inside of a track expression is not allowed. ` +
26241
- `Tracking expressions can only access the item, $index and properties on the containing component.`);
26242
- }
26243
26202
  }
26244
26203
  /**
26245
26204
  * Creates a `CssSelector` given a tag name and a map of attributes
@@ -26557,10 +26516,6 @@ function createClosureModeGuard() {
26557
26516
  .notIdentical(literal('undefined', STRING_TYPE))
26558
26517
  .and(variable(NG_I18N_CLOSURE_MODE));
26559
26518
  }
26560
- /** Determines the name that a built in loop context variable is available under. */
26561
- function getLoopLocalName(block, name) {
26562
- return block.contextVariables?.[name] || name;
26563
- }
26564
26519
 
26565
26520
  // This regex matches any binding names that contain the "attr." prefix, e.g. "attr.required"
26566
26521
  // If there is a match, the first matching group will contain the attribute name to bind.
@@ -26719,6 +26674,9 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
26719
26674
  transform(tpl, CompilationJobKind.Tmpl);
26720
26675
  // Finally we emit the template function:
26721
26676
  const templateFn = emitTemplateFn(tpl, constantPool);
26677
+ if (tpl.contentSelectors !== null) {
26678
+ definitionMap.set('ngContentSelectors', tpl.contentSelectors);
26679
+ }
26722
26680
  definitionMap.set('decls', literal(tpl.root.decls));
26723
26681
  definitionMap.set('vars', literal(tpl.root.vars));
26724
26682
  if (tpl.consts.length > 0) {
@@ -26967,11 +26925,11 @@ function createHostBindingsFunction(hostBindingsMetadata, typeSourceSpan, bindin
26967
26925
  // actually already handle these special attributes internally. Therefore, we just drop them
26968
26926
  // into the attributes map.
26969
26927
  if (hostBindingsMetadata.specialAttributes.styleAttr) {
26970
- hostBindingsMetadata.attributes.style =
26928
+ hostBindingsMetadata.attributes['style'] =
26971
26929
  literal(hostBindingsMetadata.specialAttributes.styleAttr);
26972
26930
  }
26973
26931
  if (hostBindingsMetadata.specialAttributes.classAttr) {
26974
- hostBindingsMetadata.attributes.class =
26932
+ hostBindingsMetadata.attributes['class'] =
26975
26933
  literal(hostBindingsMetadata.specialAttributes.classAttr);
26976
26934
  }
26977
26935
  const hostJob = ingestHostBinding({
@@ -27946,7 +27904,7 @@ function publishFacade(global) {
27946
27904
  * @description
27947
27905
  * Entry point for all public APIs of the compiler package.
27948
27906
  */
27949
- const VERSION = new Version('17.0.0-next.3');
27907
+ const VERSION = new Version('17.0.0-next.5');
27950
27908
 
27951
27909
  class CompilerConfig {
27952
27910
  constructor({ defaultEncapsulation = ViewEncapsulation.Emulated, useJit = true, missingTranslation = null, preserveWhitespaces, strictInjectionParameters } = {}) {
@@ -29408,7 +29366,7 @@ class R3TargetBinder {
29408
29366
  // scopes in the template and makes them available for later use.
29409
29367
  const scope = Scope.apply(target.template);
29410
29368
  // Use the `Scope` to extract the entities present at every level of the template.
29411
- const templateEntities = extractTemplateEntities(scope);
29369
+ const scopedNodeEntities = extractScopedNodeEntities(scope);
29412
29370
  // Next, perform directive matching on the template using the `DirectiveBinder`. This returns:
29413
29371
  // - directives: Map of nodes (elements & ng-templates) to the directives on them.
29414
29372
  // - bindings: Map of inputs, outputs, and attributes to the directive/element that claims
@@ -29418,7 +29376,7 @@ class R3TargetBinder {
29418
29376
  // Finally, run the TemplateBinder to bind references, variables, and other entities within the
29419
29377
  // template. This extracts all the metadata that doesn't depend on directive matching.
29420
29378
  const { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks } = TemplateBinder.applyWithScope(target.template, scope);
29421
- return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel, templateEntities, usedPipes, eagerPipes, deferBlocks);
29379
+ return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks);
29422
29380
  }
29423
29381
  }
29424
29382
  /**
@@ -29429,17 +29387,19 @@ class R3TargetBinder {
29429
29387
  * be analyzed and have their child `Scope`s available in `childScopes`.
29430
29388
  */
29431
29389
  class Scope {
29432
- constructor(parentScope, template) {
29390
+ constructor(parentScope, rootNode) {
29433
29391
  this.parentScope = parentScope;
29434
- this.template = template;
29392
+ this.rootNode = rootNode;
29435
29393
  /**
29436
29394
  * Named members of the `Scope`, such as `Reference`s or `Variable`s.
29437
29395
  */
29438
29396
  this.namedEntities = new Map();
29439
29397
  /**
29440
- * Child `Scope`s for immediately nested `Template`s.
29398
+ * Child `Scope`s for immediately nested `ScopedNode`s.
29441
29399
  */
29442
29400
  this.childScopes = new Map();
29401
+ this.isDeferred =
29402
+ parentScope !== null && parentScope.isDeferred ? true : rootNode instanceof DeferredBlock;
29443
29403
  }
29444
29404
  static newRootScope() {
29445
29405
  return new Scope(null, null);
@@ -29454,18 +29414,35 @@ class Scope {
29454
29414
  return scope;
29455
29415
  }
29456
29416
  /**
29457
- * Internal method to process the template and populate the `Scope`.
29417
+ * Internal method to process the scoped node and populate the `Scope`.
29458
29418
  */
29459
- ingest(template) {
29460
- if (template instanceof Template) {
29419
+ ingest(nodeOrNodes) {
29420
+ if (nodeOrNodes instanceof Template) {
29461
29421
  // Variables on an <ng-template> are defined in the inner scope.
29462
- template.variables.forEach(node => this.visitVariable(node));
29422
+ nodeOrNodes.variables.forEach(node => this.visitVariable(node));
29463
29423
  // Process the nodes of the template.
29464
- template.children.forEach(node => node.visit(this));
29424
+ nodeOrNodes.children.forEach(node => node.visit(this));
29425
+ }
29426
+ else if (nodeOrNodes instanceof IfBlockBranch) {
29427
+ if (nodeOrNodes.expressionAlias !== null) {
29428
+ this.visitVariable(nodeOrNodes.expressionAlias);
29429
+ }
29430
+ nodeOrNodes.children.forEach(node => node.visit(this));
29431
+ }
29432
+ else if (nodeOrNodes instanceof ForLoopBlock) {
29433
+ this.visitVariable(nodeOrNodes.item);
29434
+ Object.values(nodeOrNodes.contextVariables).forEach(v => this.visitVariable(v));
29435
+ nodeOrNodes.children.forEach(node => node.visit(this));
29436
+ }
29437
+ else if (nodeOrNodes instanceof SwitchBlockCase || nodeOrNodes instanceof ForLoopBlockEmpty ||
29438
+ nodeOrNodes instanceof DeferredBlock || nodeOrNodes instanceof DeferredBlockError ||
29439
+ nodeOrNodes instanceof DeferredBlockPlaceholder ||
29440
+ nodeOrNodes instanceof DeferredBlockLoading) {
29441
+ nodeOrNodes.children.forEach(node => node.visit(this));
29465
29442
  }
29466
29443
  else {
29467
29444
  // No overarching `Template` instance, so process the nodes directly.
29468
- template.forEach(node => node.visit(this));
29445
+ nodeOrNodes.forEach(node => node.visit(this));
29469
29446
  }
29470
29447
  }
29471
29448
  visitElement(element) {
@@ -29479,9 +29456,7 @@ class Scope {
29479
29456
  // processing the template's child scope.
29480
29457
  template.references.forEach(node => this.visitReference(node));
29481
29458
  // Next, create an inner scope and process the template within it.
29482
- const scope = new Scope(this, template);
29483
- scope.ingest(template);
29484
- this.childScopes.set(template, scope);
29459
+ this.ingestScopedNode(template);
29485
29460
  }
29486
29461
  visitVariable(variable) {
29487
29462
  // Declare the variable if it's not already.
@@ -29492,38 +29467,38 @@ class Scope {
29492
29467
  this.maybeDeclare(reference);
29493
29468
  }
29494
29469
  visitDeferredBlock(deferred) {
29495
- deferred.children.forEach(node => node.visit(this));
29470
+ this.ingestScopedNode(deferred);
29496
29471
  deferred.placeholder?.visit(this);
29497
29472
  deferred.loading?.visit(this);
29498
29473
  deferred.error?.visit(this);
29499
29474
  }
29500
29475
  visitDeferredBlockPlaceholder(block) {
29501
- block.children.forEach(node => node.visit(this));
29476
+ this.ingestScopedNode(block);
29502
29477
  }
29503
29478
  visitDeferredBlockError(block) {
29504
- block.children.forEach(node => node.visit(this));
29479
+ this.ingestScopedNode(block);
29505
29480
  }
29506
29481
  visitDeferredBlockLoading(block) {
29507
- block.children.forEach(node => node.visit(this));
29482
+ this.ingestScopedNode(block);
29508
29483
  }
29509
29484
  visitSwitchBlock(block) {
29510
29485
  block.cases.forEach(node => node.visit(this));
29511
29486
  }
29512
29487
  visitSwitchBlockCase(block) {
29513
- block.children.forEach(node => node.visit(this));
29488
+ this.ingestScopedNode(block);
29514
29489
  }
29515
29490
  visitForLoopBlock(block) {
29516
- block.children.forEach(node => node.visit(this));
29491
+ this.ingestScopedNode(block);
29517
29492
  block.empty?.visit(this);
29518
29493
  }
29519
29494
  visitForLoopBlockEmpty(block) {
29520
- block.children.forEach(node => node.visit(this));
29495
+ this.ingestScopedNode(block);
29521
29496
  }
29522
29497
  visitIfBlock(block) {
29523
29498
  block.branches.forEach(node => node.visit(this));
29524
29499
  }
29525
29500
  visitIfBlockBranch(block) {
29526
- block.children.forEach(node => node.visit(this));
29501
+ this.ingestScopedNode(block);
29527
29502
  }
29528
29503
  // Unused visitors.
29529
29504
  visitContent(content) { }
@@ -29560,17 +29535,22 @@ class Scope {
29560
29535
  }
29561
29536
  }
29562
29537
  /**
29563
- * Get the child scope for a `Template`.
29538
+ * Get the child scope for a `ScopedNode`.
29564
29539
  *
29565
29540
  * This should always be defined.
29566
29541
  */
29567
- getChildScope(template) {
29568
- const res = this.childScopes.get(template);
29542
+ getChildScope(node) {
29543
+ const res = this.childScopes.get(node);
29569
29544
  if (res === undefined) {
29570
- throw new Error(`Assertion error: child scope for ${template} not found`);
29545
+ throw new Error(`Assertion error: child scope for ${node} not found`);
29571
29546
  }
29572
29547
  return res;
29573
29548
  }
29549
+ ingestScopedNode(node) {
29550
+ const scope = new Scope(this, node);
29551
+ scope.ingest(node);
29552
+ this.childScopes.set(node, scope);
29553
+ }
29574
29554
  }
29575
29555
  /**
29576
29556
  * Processes a template and matches directives on nodes (elements and templates).
@@ -29703,6 +29683,8 @@ class DirectiveBinder {
29703
29683
  block.children.forEach(node => node.visit(this));
29704
29684
  }
29705
29685
  visitForLoopBlock(block) {
29686
+ block.item.visit(this);
29687
+ Object.values(block.contextVariables).forEach(v => v.visit(this));
29706
29688
  block.children.forEach(node => node.visit(this));
29707
29689
  block.empty?.visit(this);
29708
29690
  }
@@ -29713,6 +29695,7 @@ class DirectiveBinder {
29713
29695
  block.branches.forEach(node => node.visit(this));
29714
29696
  }
29715
29697
  visitIfBlockBranch(block) {
29698
+ block.expressionAlias?.visit(this);
29716
29699
  block.children.forEach(node => node.visit(this));
29717
29700
  }
29718
29701
  // Unused visitors.
@@ -29738,7 +29721,7 @@ class DirectiveBinder {
29738
29721
  * by overridden methods from that visitor.
29739
29722
  */
29740
29723
  class TemplateBinder extends RecursiveAstVisitor {
29741
- constructor(bindings, symbols, usedPipes, eagerPipes, deferBlocks, nestingLevel, scope, template, level) {
29724
+ constructor(bindings, symbols, usedPipes, eagerPipes, deferBlocks, nestingLevel, scope, rootNode, level) {
29742
29725
  super();
29743
29726
  this.bindings = bindings;
29744
29727
  this.symbols = symbols;
@@ -29747,10 +29730,8 @@ class TemplateBinder extends RecursiveAstVisitor {
29747
29730
  this.deferBlocks = deferBlocks;
29748
29731
  this.nestingLevel = nestingLevel;
29749
29732
  this.scope = scope;
29750
- this.template = template;
29733
+ this.rootNode = rootNode;
29751
29734
  this.level = level;
29752
- // Indicates whether we are visiting elements within a {#defer} block
29753
- this.isInDeferBlock = false;
29754
29735
  // Save a bit of processing time by constructing this closure in advance.
29755
29736
  this.visitNode = (node) => node.visit(this);
29756
29737
  }
@@ -29790,18 +29771,39 @@ class TemplateBinder extends RecursiveAstVisitor {
29790
29771
  binder.ingest(nodes);
29791
29772
  return { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks };
29792
29773
  }
29793
- ingest(template) {
29794
- if (template instanceof Template) {
29774
+ ingest(nodeOrNodes) {
29775
+ if (nodeOrNodes instanceof Template) {
29795
29776
  // For <ng-template>s, process only variables and child nodes. Inputs, outputs, templateAttrs,
29796
29777
  // and references were all processed in the scope of the containing template.
29797
- template.variables.forEach(this.visitNode);
29798
- template.children.forEach(this.visitNode);
29778
+ nodeOrNodes.variables.forEach(this.visitNode);
29779
+ nodeOrNodes.children.forEach(this.visitNode);
29799
29780
  // Set the nesting level.
29800
- this.nestingLevel.set(template, this.level);
29781
+ this.nestingLevel.set(nodeOrNodes, this.level);
29782
+ }
29783
+ else if (nodeOrNodes instanceof IfBlockBranch) {
29784
+ if (nodeOrNodes.expressionAlias !== null) {
29785
+ this.visitNode(nodeOrNodes.expressionAlias);
29786
+ }
29787
+ nodeOrNodes.children.forEach(this.visitNode);
29788
+ this.nestingLevel.set(nodeOrNodes, this.level);
29789
+ }
29790
+ else if (nodeOrNodes instanceof ForLoopBlock) {
29791
+ this.visitNode(nodeOrNodes.item);
29792
+ Object.values(nodeOrNodes.contextVariables).forEach(v => this.visitNode(v));
29793
+ nodeOrNodes.trackBy.visit(this);
29794
+ nodeOrNodes.children.forEach(this.visitNode);
29795
+ this.nestingLevel.set(nodeOrNodes, this.level);
29796
+ }
29797
+ else if (nodeOrNodes instanceof SwitchBlockCase || nodeOrNodes instanceof ForLoopBlockEmpty ||
29798
+ nodeOrNodes instanceof DeferredBlock || nodeOrNodes instanceof DeferredBlockError ||
29799
+ nodeOrNodes instanceof DeferredBlockPlaceholder ||
29800
+ nodeOrNodes instanceof DeferredBlockLoading) {
29801
+ nodeOrNodes.children.forEach(node => node.visit(this));
29802
+ this.nestingLevel.set(nodeOrNodes, this.level);
29801
29803
  }
29802
29804
  else {
29803
29805
  // Visit each node from the top-level template.
29804
- template.forEach(this.visitNode);
29806
+ nodeOrNodes.forEach(this.visitNode);
29805
29807
  }
29806
29808
  }
29807
29809
  visitElement(element) {
@@ -29809,29 +29811,27 @@ class TemplateBinder extends RecursiveAstVisitor {
29809
29811
  element.inputs.forEach(this.visitNode);
29810
29812
  element.outputs.forEach(this.visitNode);
29811
29813
  element.children.forEach(this.visitNode);
29814
+ element.references.forEach(this.visitNode);
29812
29815
  }
29813
29816
  visitTemplate(template) {
29814
29817
  // First, visit inputs, outputs and template attributes of the template node.
29815
29818
  template.inputs.forEach(this.visitNode);
29816
29819
  template.outputs.forEach(this.visitNode);
29817
29820
  template.templateAttrs.forEach(this.visitNode);
29818
- // References are also evaluated in the outer context.
29819
29821
  template.references.forEach(this.visitNode);
29820
- // Next, recurse into the template using its scope, and bumping the nesting level up by one.
29821
- const childScope = this.scope.getChildScope(template);
29822
- const binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.eagerPipes, this.deferBlocks, this.nestingLevel, childScope, template, this.level + 1);
29823
- binder.ingest(template);
29822
+ // Next, recurse into the template.
29823
+ this.ingestScopedNode(template);
29824
29824
  }
29825
29825
  visitVariable(variable) {
29826
29826
  // Register the `Variable` as a symbol in the current `Template`.
29827
- if (this.template !== null) {
29828
- this.symbols.set(variable, this.template);
29827
+ if (this.rootNode !== null) {
29828
+ this.symbols.set(variable, this.rootNode);
29829
29829
  }
29830
29830
  }
29831
29831
  visitReference(reference) {
29832
29832
  // Register the `Reference` as a symbol in the current `Template`.
29833
- if (this.template !== null) {
29834
- this.symbols.set(reference, this.template);
29833
+ if (this.rootNode !== null) {
29834
+ this.symbols.set(reference, this.rootNode);
29835
29835
  }
29836
29836
  }
29837
29837
  // Unused template visitors
@@ -29851,10 +29851,7 @@ class TemplateBinder extends RecursiveAstVisitor {
29851
29851
  }
29852
29852
  visitDeferredBlock(deferred) {
29853
29853
  this.deferBlocks.add(deferred);
29854
- const wasInDeferBlock = this.isInDeferBlock;
29855
- this.isInDeferBlock = true;
29856
- deferred.children.forEach(this.visitNode);
29857
- this.isInDeferBlock = wasInDeferBlock;
29854
+ this.ingestScopedNode(deferred);
29858
29855
  deferred.placeholder && this.visitNode(deferred.placeholder);
29859
29856
  deferred.loading && this.visitNode(deferred.loading);
29860
29857
  deferred.error && this.visitNode(deferred.error);
@@ -29865,13 +29862,13 @@ class TemplateBinder extends RecursiveAstVisitor {
29865
29862
  }
29866
29863
  }
29867
29864
  visitDeferredBlockPlaceholder(block) {
29868
- block.children.forEach(this.visitNode);
29865
+ this.ingestScopedNode(block);
29869
29866
  }
29870
29867
  visitDeferredBlockError(block) {
29871
- block.children.forEach(this.visitNode);
29868
+ this.ingestScopedNode(block);
29872
29869
  }
29873
29870
  visitDeferredBlockLoading(block) {
29874
- block.children.forEach(this.visitNode);
29871
+ this.ingestScopedNode(block);
29875
29872
  }
29876
29873
  visitSwitchBlock(block) {
29877
29874
  block.expression.visit(this);
@@ -29879,29 +29876,29 @@ class TemplateBinder extends RecursiveAstVisitor {
29879
29876
  }
29880
29877
  visitSwitchBlockCase(block) {
29881
29878
  block.expression?.visit(this);
29882
- block.children.forEach(this.visitNode);
29879
+ this.ingestScopedNode(block);
29883
29880
  }
29884
29881
  visitForLoopBlock(block) {
29885
29882
  block.expression.visit(this);
29886
- block.children.forEach(this.visitNode);
29883
+ this.ingestScopedNode(block);
29887
29884
  block.empty?.visit(this);
29888
29885
  }
29889
29886
  visitForLoopBlockEmpty(block) {
29890
- block.children.forEach(this.visitNode);
29887
+ this.ingestScopedNode(block);
29891
29888
  }
29892
29889
  visitIfBlock(block) {
29893
29890
  block.branches.forEach(node => node.visit(this));
29894
29891
  }
29895
29892
  visitIfBlockBranch(block) {
29896
29893
  block.expression?.visit(this);
29897
- block.children.forEach(node => node.visit(this));
29894
+ this.ingestScopedNode(block);
29898
29895
  }
29899
29896
  visitBoundText(text) {
29900
29897
  text.value.visit(this);
29901
29898
  }
29902
29899
  visitPipe(ast, context) {
29903
29900
  this.usedPipes.add(ast.name);
29904
- if (!this.isInDeferBlock) {
29901
+ if (!this.scope.isDeferred) {
29905
29902
  this.eagerPipes.add(ast.name);
29906
29903
  }
29907
29904
  return super.visitPipe(ast, context);
@@ -29909,18 +29906,23 @@ class TemplateBinder extends RecursiveAstVisitor {
29909
29906
  // These five types of AST expressions can refer to expression roots, which could be variables
29910
29907
  // or references in the current scope.
29911
29908
  visitPropertyRead(ast, context) {
29912
- this.maybeMap(context, ast, ast.name);
29909
+ this.maybeMap(ast, ast.name);
29913
29910
  return super.visitPropertyRead(ast, context);
29914
29911
  }
29915
29912
  visitSafePropertyRead(ast, context) {
29916
- this.maybeMap(context, ast, ast.name);
29913
+ this.maybeMap(ast, ast.name);
29917
29914
  return super.visitSafePropertyRead(ast, context);
29918
29915
  }
29919
29916
  visitPropertyWrite(ast, context) {
29920
- this.maybeMap(context, ast, ast.name);
29917
+ this.maybeMap(ast, ast.name);
29921
29918
  return super.visitPropertyWrite(ast, context);
29922
29919
  }
29923
- maybeMap(scope, ast, name) {
29920
+ ingestScopedNode(node) {
29921
+ const childScope = this.scope.getChildScope(node);
29922
+ const binder = new TemplateBinder(this.bindings, this.symbols, this.usedPipes, this.eagerPipes, this.deferBlocks, this.nestingLevel, childScope, node, this.level + 1);
29923
+ binder.ingest(node);
29924
+ }
29925
+ maybeMap(ast, name) {
29924
29926
  // If the receiver of the expression isn't the `ImplicitReceiver`, this isn't the root of an
29925
29927
  // `AST` expression that maps to a `Variable` or `Reference`.
29926
29928
  if (!(ast.receiver instanceof ImplicitReceiver)) {
@@ -29940,7 +29942,7 @@ class TemplateBinder extends RecursiveAstVisitor {
29940
29942
  * See `BoundTarget` for documentation on the individual methods.
29941
29943
  */
29942
29944
  class R3BoundTarget {
29943
- constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel, templateEntities, usedPipes, eagerPipes, deferredBlocks) {
29945
+ constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferredBlocks) {
29944
29946
  this.target = target;
29945
29947
  this.directives = directives;
29946
29948
  this.eagerDirectives = eagerDirectives;
@@ -29949,13 +29951,13 @@ class R3BoundTarget {
29949
29951
  this.exprTargets = exprTargets;
29950
29952
  this.symbols = symbols;
29951
29953
  this.nestingLevel = nestingLevel;
29952
- this.templateEntities = templateEntities;
29954
+ this.scopedNodeEntities = scopedNodeEntities;
29953
29955
  this.usedPipes = usedPipes;
29954
29956
  this.eagerPipes = eagerPipes;
29955
29957
  this.deferredBlocks = deferredBlocks;
29956
29958
  }
29957
- getEntitiesInTemplateScope(template) {
29958
- return this.templateEntities.get(template) ?? new Set();
29959
+ getEntitiesInScope(node) {
29960
+ return this.scopedNodeEntities.get(node) ?? new Set();
29959
29961
  }
29960
29962
  getDirectivesOfNode(node) {
29961
29963
  return this.directives.get(node) || null;
@@ -29969,11 +29971,11 @@ class R3BoundTarget {
29969
29971
  getExpressionTarget(expr) {
29970
29972
  return this.exprTargets.get(expr) || null;
29971
29973
  }
29972
- getTemplateOfSymbol(symbol) {
29974
+ getDefinitionNodeOfSymbol(symbol) {
29973
29975
  return this.symbols.get(symbol) || null;
29974
29976
  }
29975
- getNestingLevel(template) {
29976
- return this.nestingLevel.get(template) || 0;
29977
+ getNestingLevel(node) {
29978
+ return this.nestingLevel.get(node) || 0;
29977
29979
  }
29978
29980
  getUsedDirectives() {
29979
29981
  const set = new Set();
@@ -29993,23 +29995,79 @@ class R3BoundTarget {
29993
29995
  getDeferBlocks() {
29994
29996
  return Array.from(this.deferredBlocks);
29995
29997
  }
29998
+ getDeferredTriggerTarget(block, trigger) {
29999
+ // Only triggers that refer to DOM nodes can be resolved.
30000
+ if (!(trigger instanceof InteractionDeferredTrigger) &&
30001
+ !(trigger instanceof ViewportDeferredTrigger) &&
30002
+ !(trigger instanceof HoverDeferredTrigger)) {
30003
+ return null;
30004
+ }
30005
+ const name = trigger.reference;
30006
+ // TODO(crisbeto): account for `viewport` trigger without a `reference`.
30007
+ if (name === null) {
30008
+ return null;
30009
+ }
30010
+ const outsideRef = this.findEntityInScope(block, name);
30011
+ // First try to resolve the target in the scope of the main deferred block. Note that we
30012
+ // skip triggers defined inside the main block itself, because they might not exist yet.
30013
+ if (outsideRef instanceof Reference && this.getDefinitionNodeOfSymbol(outsideRef) !== block) {
30014
+ const target = this.getReferenceTarget(outsideRef);
30015
+ if (target !== null) {
30016
+ return this.referenceTargetToElement(target);
30017
+ }
30018
+ }
30019
+ // If the trigger couldn't be found in the main block, check the
30020
+ // placeholder block which is shown before the main block has loaded.
30021
+ if (block.placeholder !== null) {
30022
+ const refInPlaceholder = this.findEntityInScope(block.placeholder, name);
30023
+ const targetInPlaceholder = refInPlaceholder instanceof Reference ? this.getReferenceTarget(refInPlaceholder) : null;
30024
+ if (targetInPlaceholder !== null) {
30025
+ return this.referenceTargetToElement(targetInPlaceholder);
30026
+ }
30027
+ }
30028
+ return null;
30029
+ }
30030
+ /**
30031
+ * Finds an entity with a specific name in a scope.
30032
+ * @param rootNode Root node of the scope.
30033
+ * @param name Name of the entity.
30034
+ */
30035
+ findEntityInScope(rootNode, name) {
30036
+ const entities = this.getEntitiesInScope(rootNode);
30037
+ for (const entitity of entities) {
30038
+ if (entitity.name === name) {
30039
+ return entitity;
30040
+ }
30041
+ }
30042
+ return null;
30043
+ }
30044
+ /** Coerces a `ReferenceTarget` to an `Element`, if possible. */
30045
+ referenceTargetToElement(target) {
30046
+ if (target instanceof Element$1) {
30047
+ return target;
30048
+ }
30049
+ if (target instanceof Template) {
30050
+ return null;
30051
+ }
30052
+ return this.referenceTargetToElement(target.node);
30053
+ }
29996
30054
  }
29997
- function extractTemplateEntities(rootScope) {
30055
+ function extractScopedNodeEntities(rootScope) {
29998
30056
  const entityMap = new Map();
29999
30057
  function extractScopeEntities(scope) {
30000
- if (entityMap.has(scope.template)) {
30001
- return entityMap.get(scope.template);
30058
+ if (entityMap.has(scope.rootNode)) {
30059
+ return entityMap.get(scope.rootNode);
30002
30060
  }
30003
30061
  const currentEntities = scope.namedEntities;
30004
- let templateEntities;
30062
+ let entities;
30005
30063
  if (scope.parentScope !== null) {
30006
- templateEntities = new Map([...extractScopeEntities(scope.parentScope), ...currentEntities]);
30064
+ entities = new Map([...extractScopeEntities(scope.parentScope), ...currentEntities]);
30007
30065
  }
30008
30066
  else {
30009
- templateEntities = new Map(currentEntities);
30067
+ entities = new Map(currentEntities);
30010
30068
  }
30011
- entityMap.set(scope.template, templateEntities);
30012
- return templateEntities;
30069
+ entityMap.set(scope.rootNode, entities);
30070
+ return entities;
30013
30071
  }
30014
30072
  const scopesToProcess = [rootScope];
30015
30073
  while (scopesToProcess.length > 0) {
@@ -30104,7 +30162,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$6 = '12.0.0';
30104
30162
  function compileDeclareClassMetadata(metadata) {
30105
30163
  const definitionMap = new DefinitionMap();
30106
30164
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
30107
- definitionMap.set('version', literal('17.0.0-next.3'));
30165
+ definitionMap.set('version', literal('17.0.0-next.5'));
30108
30166
  definitionMap.set('ngImport', importExpr(Identifiers.core));
30109
30167
  definitionMap.set('type', metadata.type);
30110
30168
  definitionMap.set('decorators', metadata.decorators);
@@ -30212,7 +30270,7 @@ function createDirectiveDefinitionMap(meta) {
30212
30270
  // in 16.1 is actually used.
30213
30271
  const minVersion = hasTransformFunctions ? MINIMUM_PARTIAL_LINKER_VERSION$5 : '14.0.0';
30214
30272
  definitionMap.set('minVersion', literal(minVersion));
30215
- definitionMap.set('version', literal('17.0.0-next.3'));
30273
+ definitionMap.set('version', literal('17.0.0-next.5'));
30216
30274
  // e.g. `type: MyDirective`
30217
30275
  definitionMap.set('type', meta.type.value);
30218
30276
  if (meta.isStandalone) {
@@ -30443,7 +30501,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
30443
30501
  function compileDeclareFactoryFunction(meta) {
30444
30502
  const definitionMap = new DefinitionMap();
30445
30503
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
30446
- definitionMap.set('version', literal('17.0.0-next.3'));
30504
+ definitionMap.set('version', literal('17.0.0-next.5'));
30447
30505
  definitionMap.set('ngImport', importExpr(Identifiers.core));
30448
30506
  definitionMap.set('type', meta.type.value);
30449
30507
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -30478,7 +30536,7 @@ function compileDeclareInjectableFromMetadata(meta) {
30478
30536
  function createInjectableDefinitionMap(meta) {
30479
30537
  const definitionMap = new DefinitionMap();
30480
30538
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
30481
- definitionMap.set('version', literal('17.0.0-next.3'));
30539
+ definitionMap.set('version', literal('17.0.0-next.5'));
30482
30540
  definitionMap.set('ngImport', importExpr(Identifiers.core));
30483
30541
  definitionMap.set('type', meta.type.value);
30484
30542
  // Only generate providedIn property if it has a non-null value
@@ -30529,7 +30587,7 @@ function compileDeclareInjectorFromMetadata(meta) {
30529
30587
  function createInjectorDefinitionMap(meta) {
30530
30588
  const definitionMap = new DefinitionMap();
30531
30589
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
30532
- definitionMap.set('version', literal('17.0.0-next.3'));
30590
+ definitionMap.set('version', literal('17.0.0-next.5'));
30533
30591
  definitionMap.set('ngImport', importExpr(Identifiers.core));
30534
30592
  definitionMap.set('type', meta.type.value);
30535
30593
  definitionMap.set('providers', meta.providers);
@@ -30562,7 +30620,7 @@ function createNgModuleDefinitionMap(meta) {
30562
30620
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
30563
30621
  }
30564
30622
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
30565
- definitionMap.set('version', literal('17.0.0-next.3'));
30623
+ definitionMap.set('version', literal('17.0.0-next.5'));
30566
30624
  definitionMap.set('ngImport', importExpr(Identifiers.core));
30567
30625
  definitionMap.set('type', meta.type.value);
30568
30626
  // We only generate the keys in the metadata if the arrays contain values.
@@ -30613,7 +30671,7 @@ function compileDeclarePipeFromMetadata(meta) {
30613
30671
  function createPipeDefinitionMap(meta) {
30614
30672
  const definitionMap = new DefinitionMap();
30615
30673
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
30616
- definitionMap.set('version', literal('17.0.0-next.3'));
30674
+ definitionMap.set('version', literal('17.0.0-next.5'));
30617
30675
  definitionMap.set('ngImport', importExpr(Identifiers.core));
30618
30676
  // e.g. `type: MyPipe`
30619
30677
  definitionMap.set('type', meta.type.value);