@angular-eslint/bundled-angular-compiler 17.2.1-alpha.4 → 17.2.1-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +463 -215
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * @license Angular v17.0.8
4
+ * @license Angular v17.1.0
5
5
  * (c) 2010-2022 Google LLC. https://angular.io/
6
6
  * License: MIT
7
7
  */
@@ -411,6 +411,13 @@ exports.ChangeDetectionStrategy = void 0;
411
411
  ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
412
412
  ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
413
413
  })(exports.ChangeDetectionStrategy || (exports.ChangeDetectionStrategy = {}));
414
+ /** Flags describing an input for a directive. */
415
+ var InputFlags;
416
+ (function (InputFlags) {
417
+ InputFlags[InputFlags["None"] = 0] = "None";
418
+ InputFlags[InputFlags["SignalBased"] = 1] = "SignalBased";
419
+ InputFlags[InputFlags["HasDecoratorInputTransform"] = 2] = "HasDecoratorInputTransform";
420
+ })(InputFlags || (InputFlags = {}));
414
421
  const CUSTOM_ELEMENTS_SCHEMA = {
415
422
  name: 'custom-elements'
416
423
  };
@@ -474,6 +481,7 @@ var core = /*#__PURE__*/Object.freeze({
474
481
  emitDistinctChangesOnlyDefaultValue: emitDistinctChangesOnlyDefaultValue,
475
482
  get ViewEncapsulation () { return exports.ViewEncapsulation; },
476
483
  get ChangeDetectionStrategy () { return exports.ChangeDetectionStrategy; },
484
+ get InputFlags () { return InputFlags; },
477
485
  CUSTOM_ELEMENTS_SCHEMA: CUSTOM_ELEMENTS_SCHEMA,
478
486
  NO_ERRORS_SCHEMA: NO_ERRORS_SCHEMA,
479
487
  Type: Type$1,
@@ -892,12 +900,13 @@ exports.BinaryOperator = void 0;
892
900
  BinaryOperator[BinaryOperator["Modulo"] = 8] = "Modulo";
893
901
  BinaryOperator[BinaryOperator["And"] = 9] = "And";
894
902
  BinaryOperator[BinaryOperator["Or"] = 10] = "Or";
895
- BinaryOperator[BinaryOperator["BitwiseAnd"] = 11] = "BitwiseAnd";
896
- BinaryOperator[BinaryOperator["Lower"] = 12] = "Lower";
897
- BinaryOperator[BinaryOperator["LowerEquals"] = 13] = "LowerEquals";
898
- BinaryOperator[BinaryOperator["Bigger"] = 14] = "Bigger";
899
- BinaryOperator[BinaryOperator["BiggerEquals"] = 15] = "BiggerEquals";
900
- BinaryOperator[BinaryOperator["NullishCoalesce"] = 16] = "NullishCoalesce";
903
+ BinaryOperator[BinaryOperator["BitwiseOr"] = 11] = "BitwiseOr";
904
+ BinaryOperator[BinaryOperator["BitwiseAnd"] = 12] = "BitwiseAnd";
905
+ BinaryOperator[BinaryOperator["Lower"] = 13] = "Lower";
906
+ BinaryOperator[BinaryOperator["LowerEquals"] = 14] = "LowerEquals";
907
+ BinaryOperator[BinaryOperator["Bigger"] = 15] = "Bigger";
908
+ BinaryOperator[BinaryOperator["BiggerEquals"] = 16] = "BiggerEquals";
909
+ BinaryOperator[BinaryOperator["NullishCoalesce"] = 17] = "NullishCoalesce";
901
910
  })(exports.BinaryOperator || (exports.BinaryOperator = {}));
902
911
  function nullSafeIsEquivalent(base, other) {
903
912
  if (base == null || other == null) {
@@ -970,6 +979,9 @@ class Expression {
970
979
  and(rhs, sourceSpan) {
971
980
  return new BinaryOperatorExpr(exports.BinaryOperator.And, this, rhs, null, sourceSpan);
972
981
  }
982
+ bitwiseOr(rhs, sourceSpan, parens = true) {
983
+ return new BinaryOperatorExpr(exports.BinaryOperator.BitwiseOr, this, rhs, null, sourceSpan, parens);
984
+ }
973
985
  bitwiseAnd(rhs, sourceSpan, parens = true) {
974
986
  return new BinaryOperatorExpr(exports.BinaryOperator.BitwiseAnd, this, rhs, null, sourceSpan, parens);
975
987
  }
@@ -2630,6 +2642,10 @@ class Identifiers {
2630
2642
  name: 'ɵɵgetInheritedFactory',
2631
2643
  moduleName: CORE,
2632
2644
  }; }
2645
+ static { this.InputFlags = {
2646
+ name: 'ɵɵInputFlags',
2647
+ moduleName: CORE,
2648
+ }; }
2633
2649
  // sanitization-related functions
2634
2650
  static { this.sanitizeHtml = { name: 'ɵɵsanitizeHtml', moduleName: CORE }; }
2635
2651
  static { this.sanitizeStyle = { name: 'ɵɵsanitizeStyle', moduleName: CORE }; }
@@ -2640,6 +2656,9 @@ class Identifiers {
2640
2656
  static { this.trustConstantHtml = { name: 'ɵɵtrustConstantHtml', moduleName: CORE }; }
2641
2657
  static { this.trustConstantResourceUrl = { name: 'ɵɵtrustConstantResourceUrl', moduleName: CORE }; }
2642
2658
  static { this.validateIframeAttribute = { name: 'ɵɵvalidateIframeAttribute', moduleName: CORE }; }
2659
+ // type-checking
2660
+ static { this.InputSignalBrandWriteType = { name: 'ɵINPUT_SIGNAL_BRAND_WRITE_TYPE', moduleName: CORE }; }
2661
+ static { this.UnwrapDirectiveSignalInputs = { name: 'ɵUnwrapDirectiveSignalInputs', moduleName: CORE }; }
2643
2662
  }
2644
2663
 
2645
2664
  const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
@@ -3257,6 +3276,9 @@ class AbstractEmitterVisitor {
3257
3276
  case exports.BinaryOperator.And:
3258
3277
  opStr = '&&';
3259
3278
  break;
3279
+ case exports.BinaryOperator.BitwiseOr:
3280
+ opStr = '|';
3281
+ break;
3260
3282
  case exports.BinaryOperator.BitwiseAnd:
3261
3283
  opStr = '&';
3262
3284
  break;
@@ -4955,7 +4977,13 @@ function asLiteral(value) {
4955
4977
  }
4956
4978
  return literal(value, INFERRED_TYPE);
4957
4979
  }
4958
- function conditionallyCreateDirectiveBindingLiteral(map, keepDeclared) {
4980
+ /**
4981
+ * Serializes inputs and outputs for `defineDirective` and `defineComponent`.
4982
+ *
4983
+ * This will attempt to generate optimized data structures to minimize memory or
4984
+ * file size of fully compiled applications.
4985
+ */
4986
+ function conditionallyCreateDirectiveBindingLiteral(map, forInputs) {
4959
4987
  const keys = Object.getOwnPropertyNames(map);
4960
4988
  if (keys.length === 0) {
4961
4989
  return null;
@@ -4977,12 +5005,28 @@ function conditionallyCreateDirectiveBindingLiteral(map, keepDeclared) {
4977
5005
  minifiedName = key;
4978
5006
  declaredName = value.classPropertyName;
4979
5007
  publicName = value.bindingPropertyName;
4980
- if (keepDeclared && (publicName !== declaredName || value.transformFunction != null)) {
4981
- const expressionKeys = [asLiteral(publicName), asLiteral(declaredName)];
4982
- if (value.transformFunction != null) {
4983
- expressionKeys.push(value.transformFunction);
5008
+ const differentDeclaringName = publicName !== declaredName;
5009
+ const hasDecoratorInputTransform = value.transformFunction !== null;
5010
+ // Build up input flags
5011
+ let flags = null;
5012
+ if (value.isSignal) {
5013
+ flags = bitwiseOrInputFlagsExpr(InputFlags.SignalBased, flags);
5014
+ }
5015
+ if (hasDecoratorInputTransform) {
5016
+ flags = bitwiseOrInputFlagsExpr(InputFlags.HasDecoratorInputTransform, flags);
5017
+ }
5018
+ // Inputs, compared to outputs, will track their declared name (for `ngOnChanges`), support
5019
+ // decorator input transform functions, or store flag information if there is any.
5020
+ if (forInputs && (differentDeclaringName || hasDecoratorInputTransform || flags !== null)) {
5021
+ const flagsExpr = flags ?? importExpr(Identifiers.InputFlags).prop(InputFlags[InputFlags.None]);
5022
+ const result = [flagsExpr, asLiteral(publicName)];
5023
+ if (differentDeclaringName || hasDecoratorInputTransform) {
5024
+ result.push(asLiteral(declaredName));
5025
+ if (hasDecoratorInputTransform) {
5026
+ result.push(value.transformFunction);
5027
+ }
4984
5028
  }
4985
- expressionValue = literalArr(expressionKeys);
5029
+ expressionValue = literalArr(result);
4986
5030
  }
4987
5031
  else {
4988
5032
  expressionValue = asLiteral(publicName);
@@ -4996,6 +5040,17 @@ function conditionallyCreateDirectiveBindingLiteral(map, keepDeclared) {
4996
5040
  };
4997
5041
  }));
4998
5042
  }
5043
+ /** Gets an output AST expression referencing the given flag. */
5044
+ function getInputFlagExpr(flag) {
5045
+ return importExpr(Identifiers.InputFlags).prop(InputFlags[flag]);
5046
+ }
5047
+ /** Combines a given input flag with an existing flag expression, if present. */
5048
+ function bitwiseOrInputFlagsExpr(flag, expr) {
5049
+ if (expr === null) {
5050
+ return getInputFlagExpr(flag);
5051
+ }
5052
+ return getInputFlagExpr(flag).bitwiseOr(expr);
5053
+ }
4999
5054
  /**
5000
5055
  * Remove trailing null nodes as they are implied.
5001
5056
  */
@@ -5281,10 +5336,10 @@ function createFactoryFunction(type) {
5281
5336
  }
5282
5337
 
5283
5338
  const UNUSABLE_INTERPOLATION_REGEXPS = [
5284
- /^\s*$/,
5285
- /[<>]/,
5286
- /^[{}]$/,
5287
- /&(#|[a-z])/i,
5339
+ /^\s*$/, // empty
5340
+ /[<>]/, // html tag
5341
+ /^[{}]$/, // i18n expansion
5342
+ /&(#|[a-z])/i, // character reference,
5288
5343
  /^\/\//, // comment
5289
5344
  ];
5290
5345
  function assertInterpolationSymbols(identifier, value) {
@@ -9209,16 +9264,6 @@ var DeferTriggerKind;
9209
9264
  DeferTriggerKind[DeferTriggerKind["Interaction"] = 4] = "Interaction";
9210
9265
  DeferTriggerKind[DeferTriggerKind["Viewport"] = 5] = "Viewport";
9211
9266
  })(DeferTriggerKind || (DeferTriggerKind = {}));
9212
- /**
9213
- * Repeaters implicitly define these derived variables, and child nodes may read them.
9214
- */
9215
- var DerivedRepeaterVarIdentity;
9216
- (function (DerivedRepeaterVarIdentity) {
9217
- DerivedRepeaterVarIdentity[DerivedRepeaterVarIdentity["First"] = 0] = "First";
9218
- DerivedRepeaterVarIdentity[DerivedRepeaterVarIdentity["Last"] = 1] = "Last";
9219
- DerivedRepeaterVarIdentity[DerivedRepeaterVarIdentity["Even"] = 2] = "Even";
9220
- DerivedRepeaterVarIdentity[DerivedRepeaterVarIdentity["Odd"] = 3] = "Odd";
9221
- })(DerivedRepeaterVarIdentity || (DerivedRepeaterVarIdentity = {}));
9222
9267
  /**
9223
9268
  * Kinds of i18n contexts. They can be created because of root i18n blocks, or ICUs.
9224
9269
  */
@@ -9419,10 +9464,11 @@ function createClassMapOp(xref, expression, sourceSpan) {
9419
9464
  /**
9420
9465
  * Create an `AttributeOp`.
9421
9466
  */
9422
- function createAttributeOp(target, name, expression, securityContext, isTextAttribute, isStructuralTemplateAttribute, templateKind, i18nMessage, sourceSpan) {
9467
+ function createAttributeOp(target, namespace, name, expression, securityContext, isTextAttribute, isStructuralTemplateAttribute, templateKind, i18nMessage, sourceSpan) {
9423
9468
  return {
9424
9469
  kind: OpKind.Attribute,
9425
9470
  target,
9471
+ namespace,
9426
9472
  name,
9427
9473
  expression,
9428
9474
  securityContext,
@@ -10044,26 +10090,6 @@ class SlotLiteralExpr extends ExpressionBase {
10044
10090
  }
10045
10091
  transformInternalExpressions() { }
10046
10092
  }
10047
- class DerivedRepeaterVarExpr extends ExpressionBase {
10048
- constructor(xref, identity) {
10049
- super();
10050
- this.xref = xref;
10051
- this.identity = identity;
10052
- this.kind = ExpressionKind.DerivedRepeaterVar;
10053
- }
10054
- transformInternalExpressions(transform, flags) { }
10055
- visitExpression(visitor, context) { }
10056
- isEquivalent(e) {
10057
- return e instanceof DerivedRepeaterVarExpr && e.identity === this.identity &&
10058
- e.xref === this.xref;
10059
- }
10060
- isConstant() {
10061
- return false;
10062
- }
10063
- clone() {
10064
- return new DerivedRepeaterVarExpr(this.xref, this.identity);
10065
- }
10066
- }
10067
10093
  class ConstCollectedExpr extends ExpressionBase {
10068
10094
  constructor(expr) {
10069
10095
  super();
@@ -10318,6 +10344,16 @@ function transformExpressionsInExpression(expr, transform, flags) {
10318
10344
  expr.template.expressions =
10319
10345
  expr.template.expressions.map(e => transformExpressionsInExpression(e, transform, flags));
10320
10346
  }
10347
+ else if (expr instanceof ArrowFunctionExpr) {
10348
+ if (Array.isArray(expr.body)) {
10349
+ for (let i = 0; i < expr.body.length; i++) {
10350
+ transformExpressionsInStatement(expr.body[i], transform, flags);
10351
+ }
10352
+ }
10353
+ else {
10354
+ expr.body = transformExpressionsInExpression(expr.body, transform, flags);
10355
+ }
10356
+ }
10321
10357
  else if (expr instanceof WrappedNodeExpr) ;
10322
10358
  else if (expr instanceof ReadVarExpr || expr instanceof ExternalExpr ||
10323
10359
  expr instanceof LiteralExpr) ;
@@ -10677,11 +10713,12 @@ function createProjectionDefOp(def) {
10677
10713
  /**
10678
10714
  * Create an `ExtractedAttributeOp`.
10679
10715
  */
10680
- function createExtractedAttributeOp(target, bindingKind, name, expression, i18nContext, i18nMessage, securityContext) {
10716
+ function createExtractedAttributeOp(target, bindingKind, namespace, name, expression, i18nContext, i18nMessage, securityContext) {
10681
10717
  return {
10682
10718
  kind: OpKind.ExtractedAttribute,
10683
10719
  target,
10684
10720
  bindingKind,
10721
+ namespace,
10685
10722
  name,
10686
10723
  expression,
10687
10724
  i18nContext,
@@ -10712,7 +10749,7 @@ function createI18nMessageOp(xref, i18nContext, i18nBlock, message, messagePlace
10712
10749
  /**
10713
10750
  * Create an `I18nStartOp`.
10714
10751
  */
10715
- function createI18nStartOp(xref, message, root) {
10752
+ function createI18nStartOp(xref, message, root, sourceSpan) {
10716
10753
  return {
10717
10754
  kind: OpKind.I18nStart,
10718
10755
  xref,
@@ -10722,6 +10759,7 @@ function createI18nStartOp(xref, message, root) {
10722
10759
  messageIndex: null,
10723
10760
  subTemplateIndex: null,
10724
10761
  context: null,
10762
+ sourceSpan,
10725
10763
  ...NEW_OP,
10726
10764
  ...TRAIT_CONSUMES_SLOT,
10727
10765
  };
@@ -10729,10 +10767,11 @@ function createI18nStartOp(xref, message, root) {
10729
10767
  /**
10730
10768
  * Create an `I18nEndOp`.
10731
10769
  */
10732
- function createI18nEndOp(xref) {
10770
+ function createI18nEndOp(xref, sourceSpan) {
10733
10771
  return {
10734
10772
  kind: OpKind.I18nEnd,
10735
10773
  xref,
10774
+ sourceSpan,
10736
10775
  ...NEW_OP,
10737
10776
  };
10738
10777
  }
@@ -11113,6 +11152,13 @@ function createOpXrefMap(unit) {
11113
11152
  continue;
11114
11153
  }
11115
11154
  map.set(op.xref, op);
11155
+ // TODO(dylhunn): `@for` loops with `@empty` blocks need to be special-cased here,
11156
+ // because the slot consumer trait currently only supports one slot per consumer and we
11157
+ // need two. This should be revisited when making the refactors mentioned in:
11158
+ // https://github.com/angular/angular/pull/53620#discussion_r1430918822
11159
+ if (op.kind === OpKind.RepeaterCreate && op.emptyView !== null) {
11160
+ map.set(op.emptyView, op);
11161
+ }
11116
11162
  }
11117
11163
  return map;
11118
11164
  }
@@ -11145,7 +11191,8 @@ function extractAttributes(job) {
11145
11191
  }
11146
11192
  OpList.insertBefore(
11147
11193
  // Deliberaly null i18nMessage value
11148
- createExtractedAttributeOp(op.target, bindingKind, op.name, /* expression */ null, /* i18nContext */ null,
11194
+ createExtractedAttributeOp(op.target, bindingKind, null, op.name, /* expression */ null,
11195
+ /* i18nContext */ null,
11149
11196
  /* i18nMessage */ null, op.securityContext), lookupElement$2(elements, op.target));
11150
11197
  }
11151
11198
  break;
@@ -11157,17 +11204,22 @@ function extractAttributes(job) {
11157
11204
  // mode.
11158
11205
  if (unit.job.compatibility === CompatibilityMode.TemplateDefinitionBuilder &&
11159
11206
  op.expression instanceof EmptyExpr) {
11160
- OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, op.name, /* expression */ null,
11207
+ OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.Property, null, op.name, /* expression */ null,
11161
11208
  /* i18nContext */ null,
11162
11209
  /* i18nMessage */ null, SecurityContext.STYLE), lookupElement$2(elements, op.target));
11163
11210
  }
11164
11211
  break;
11165
11212
  case OpKind.Listener:
11166
11213
  if (!op.isAnimationListener) {
11167
- const extractedAttributeOp = createExtractedAttributeOp(op.target, BindingKind.Property, op.name, /* expression */ null,
11214
+ const extractedAttributeOp = createExtractedAttributeOp(op.target, BindingKind.Property, null, op.name, /* expression */ null,
11168
11215
  /* i18nContext */ null,
11169
11216
  /* i18nMessage */ null, SecurityContext.NONE);
11170
11217
  if (job.kind === CompilationJobKind.Host) {
11218
+ if (job.compatibility) {
11219
+ // TemplateDefinitionBuilder does not extract listener bindings to the const array
11220
+ // (which is honestly pretty inconsistent).
11221
+ break;
11222
+ }
11171
11223
  // This attribute will apply to the enclosing host binding compilation unit, so order
11172
11224
  // doesn't matter.
11173
11225
  unit.create.push(extractedAttributeOp);
@@ -11205,7 +11257,7 @@ function extractAttributeOp(unit, op, elements) {
11205
11257
  extractable &&= op.isTextAttribute;
11206
11258
  }
11207
11259
  if (extractable) {
11208
- const extractedAttributeOp = createExtractedAttributeOp(op.target, op.isStructuralTemplateAttribute ? BindingKind.Template : BindingKind.Attribute, op.name, op.expression, op.i18nContext, op.i18nMessage, op.securityContext);
11260
+ const extractedAttributeOp = createExtractedAttributeOp(op.target, op.isStructuralTemplateAttribute ? BindingKind.Template : BindingKind.Attribute, op.namespace, op.name, op.expression, op.i18nContext, op.i18nMessage, op.securityContext);
11209
11261
  if (unit.job.kind === CompilationJobKind.Host) {
11210
11262
  // This attribute will apply to the enclosing host binding compilation unit, so order doesn't
11211
11263
  // matter.
@@ -11252,7 +11304,8 @@ function specializeBindings(job) {
11252
11304
  target.nonBindable = true;
11253
11305
  }
11254
11306
  else {
11255
- OpList.replace(op, createAttributeOp(op.target, op.name, op.expression, op.securityContext, op.isTextAttribute, op.isStructuralTemplateAttribute, op.templateKind, op.i18nMessage, op.sourceSpan));
11307
+ const [namespace, name] = splitNsName(op.name);
11308
+ OpList.replace(op, createAttributeOp(op.target, namespace, name, op.expression, op.securityContext, op.isTextAttribute, op.isStructuralTemplateAttribute, op.templateKind, op.i18nMessage, op.sourceSpan));
11256
11309
  }
11257
11310
  break;
11258
11311
  case BindingKind.Property:
@@ -11442,6 +11495,7 @@ new Map([
11442
11495
  ['&&', exports.BinaryOperator.And],
11443
11496
  ['>', exports.BinaryOperator.Bigger],
11444
11497
  ['>=', exports.BinaryOperator.BiggerEquals],
11498
+ ['|', exports.BinaryOperator.BitwiseOr],
11445
11499
  ['&', exports.BinaryOperator.BitwiseAnd],
11446
11500
  ['/', exports.BinaryOperator.Divide],
11447
11501
  ['==', exports.BinaryOperator.Equals],
@@ -11476,7 +11530,7 @@ function collectElementConsts(job) {
11476
11530
  if (op.kind === OpKind.ExtractedAttribute) {
11477
11531
  const attributes = allElementAttributes.get(op.target) || new ElementAttributes(job.compatibility);
11478
11532
  allElementAttributes.set(op.target, attributes);
11479
- attributes.add(op.bindingKind, op.name, op.expression, op.trustedValueFn);
11533
+ attributes.add(op.bindingKind, op.name, op.expression, op.namespace, op.trustedValueFn);
11480
11534
  OpList.remove(op);
11481
11535
  }
11482
11536
  }
@@ -11485,15 +11539,26 @@ function collectElementConsts(job) {
11485
11539
  if (job instanceof ComponentCompilationJob) {
11486
11540
  for (const unit of job.units) {
11487
11541
  for (const op of unit.create) {
11488
- if (isElementOrContainerOp(op)) {
11542
+ // TODO: Simplify and combine these cases.
11543
+ if (op.kind == OpKind.Projection) {
11489
11544
  const attributes = allElementAttributes.get(op.xref);
11490
11545
  if (attributes !== undefined) {
11491
11546
  const attrArray = serializeAttributes(attributes);
11492
11547
  if (attrArray.entries.length > 0) {
11493
- op.attributes = job.addConst(attrArray);
11548
+ op.attributes = attrArray;
11494
11549
  }
11495
11550
  }
11496
11551
  }
11552
+ else if (isElementOrContainerOp(op)) {
11553
+ op.attributes = getConstIndex(job, allElementAttributes, op.xref);
11554
+ // TODO(dylhunn): `@for` loops with `@empty` blocks need to be special-cased here,
11555
+ // because the slot consumer trait currently only supports one slot per consumer and we
11556
+ // need two. This should be revisited when making the refactors mentioned in:
11557
+ // https://github.com/angular/angular/pull/53620#discussion_r1430918822
11558
+ if (op.kind === OpKind.RepeaterCreate && op.emptyView !== null) {
11559
+ op.emptyAttributes = getConstIndex(job, allElementAttributes, op.emptyView);
11560
+ }
11561
+ }
11497
11562
  }
11498
11563
  }
11499
11564
  }
@@ -11511,6 +11576,16 @@ function collectElementConsts(job) {
11511
11576
  }
11512
11577
  }
11513
11578
  }
11579
+ function getConstIndex(job, allElementAttributes, xref) {
11580
+ const attributes = allElementAttributes.get(xref);
11581
+ if (attributes !== undefined) {
11582
+ const attrArray = serializeAttributes(attributes);
11583
+ if (attrArray.entries.length > 0) {
11584
+ return job.addConst(attrArray);
11585
+ }
11586
+ }
11587
+ return null;
11588
+ }
11514
11589
  /**
11515
11590
  * Shared instance of an empty array to avoid unnecessary array allocations.
11516
11591
  */
@@ -11552,7 +11627,7 @@ class ElementAttributes {
11552
11627
  nameToValue.add(name);
11553
11628
  return false;
11554
11629
  }
11555
- add(kind, name, value, trustedValueFn) {
11630
+ add(kind, name, value, namespace, trustedValueFn) {
11556
11631
  // TemplateDefinitionBuilder puts duplicate attribute, class, and style values into the consts
11557
11632
  // array. This seems inefficient, we can probably keep just the first one or the last value
11558
11633
  // (whichever actually gets applied when multiple values are listed for the same attribute).
@@ -11573,7 +11648,7 @@ class ElementAttributes {
11573
11648
  // attribute. Is this sane?
11574
11649
  }
11575
11650
  const array = this.arrayFor(kind);
11576
- array.push(...getAttributeNameLiterals$1(name));
11651
+ array.push(...getAttributeNameLiterals$1(namespace, name));
11577
11652
  if (kind === BindingKind.Attribute || kind === BindingKind.StyleProperty) {
11578
11653
  if (value === null) {
11579
11654
  throw Error('Attribute, i18n attribute, & style element attributes must have a value');
@@ -11599,13 +11674,10 @@ class ElementAttributes {
11599
11674
  /**
11600
11675
  * Gets an array of literal expressions representing the attribute's namespaced name.
11601
11676
  */
11602
- function getAttributeNameLiterals$1(name) {
11603
- const [attributeNamespace, attributeName] = splitNsName(name, false);
11604
- const nameLiteral = literal(attributeName);
11605
- if (attributeNamespace) {
11606
- return [
11607
- literal(0 /* core.AttributeMarker.NamespaceURI */), literal(attributeNamespace), nameLiteral
11608
- ];
11677
+ function getAttributeNameLiterals$1(namespace, name) {
11678
+ const nameLiteral = literal(name);
11679
+ if (namespace) {
11680
+ return [literal(0 /* core.AttributeMarker.NamespaceURI */), literal(namespace), nameLiteral];
11609
11681
  }
11610
11682
  return [nameLiteral];
11611
11683
  }
@@ -12655,7 +12727,7 @@ function parseHostStyleProperties(job) {
12655
12727
  if (op.name.startsWith(STYLE_DOT)) {
12656
12728
  op.bindingKind = BindingKind.StyleProperty;
12657
12729
  op.name = op.name.substring(STYLE_DOT.length);
12658
- if (isCssCustomProperty$1(op.name)) {
12730
+ if (!isCssCustomProperty$1(op.name)) {
12659
12731
  op.name = hyphenate$1(op.name);
12660
12732
  }
12661
12733
  const { property, suffix } = parseProperty$1(op.name);
@@ -20089,6 +20161,7 @@ function parse(value) {
20089
20161
  break;
20090
20162
  case 58 /* Char.Colon */:
20091
20163
  if (!currentProp && parenDepth === 0 && quote === 0 /* Char.QuoteNone */) {
20164
+ // TODO: Do not hyphenate CSS custom property names like: `--intentionallyCamelCase`
20092
20165
  currentProp = hyphenate(value.substring(propStart, i - 1).trim());
20093
20166
  valueStart = i;
20094
20167
  }
@@ -20163,7 +20236,7 @@ function addNamesToView(unit, baseName, state, compatibility) {
20163
20236
  op.handlerFnName = sanitizeIdentifier(op.handlerFnName);
20164
20237
  break;
20165
20238
  case OpKind.Variable:
20166
- varNames.set(op.xref, getVariableName(op.variable, state));
20239
+ varNames.set(op.xref, getVariableName(unit, op.variable, state));
20167
20240
  break;
20168
20241
  case OpKind.RepeaterCreate:
20169
20242
  if (!(unit instanceof ViewCompilationUnit)) {
@@ -20218,15 +20291,23 @@ function addNamesToView(unit, baseName, state, compatibility) {
20218
20291
  });
20219
20292
  }
20220
20293
  }
20221
- function getVariableName(variable, state) {
20294
+ function getVariableName(unit, variable, state) {
20222
20295
  if (variable.name === null) {
20223
20296
  switch (variable.kind) {
20224
20297
  case SemanticVariableKind.Context:
20225
20298
  variable.name = `ctx_r${state.index++}`;
20226
20299
  break;
20227
20300
  case SemanticVariableKind.Identifier:
20228
- // TODO: Prefix increment and `_r` for compatiblity only.
20229
- variable.name = `${variable.identifier}_r${++state.index}`;
20301
+ if (unit.job.compatibility === CompatibilityMode.TemplateDefinitionBuilder) {
20302
+ // TODO: Prefix increment and `_r` are for compatiblity with the old naming scheme.
20303
+ // This has the potential to cause collisions when `ctx` is the identifier, so we need a
20304
+ // special check for that as well.
20305
+ const compatPrefix = variable.identifier === 'ctx' ? 'i' : '';
20306
+ variable.name = `${variable.identifier}_${compatPrefix}r${++state.index}`;
20307
+ }
20308
+ else {
20309
+ variable.name = `${variable.identifier}_i${state.index++}`;
20310
+ }
20230
20311
  break;
20231
20312
  default:
20232
20313
  // TODO: Prefix increment for compatibility only.
@@ -20423,17 +20504,27 @@ const CREATE_ORDERING = [
20423
20504
  * op kinds.
20424
20505
  */
20425
20506
  const UPDATE_ORDERING = [
20426
- { test: kindWithInterpolationTest(OpKind.HostProperty, true) },
20427
- { test: kindWithInterpolationTest(OpKind.HostProperty, false) },
20428
20507
  { test: kindTest(OpKind.StyleMap), transform: keepLast },
20429
20508
  { test: kindTest(OpKind.ClassMap), transform: keepLast },
20430
20509
  { test: kindTest(OpKind.StyleProp) },
20431
20510
  { test: kindTest(OpKind.ClassProp) },
20432
- { test: kindWithInterpolationTest(OpKind.Property, true) },
20433
20511
  { test: kindWithInterpolationTest(OpKind.Attribute, true) },
20512
+ { test: kindWithInterpolationTest(OpKind.Property, true) },
20434
20513
  { test: kindWithInterpolationTest(OpKind.Property, false) },
20435
20514
  { test: kindWithInterpolationTest(OpKind.Attribute, false) },
20436
20515
  ];
20516
+ /**
20517
+ * Host bindings have their own update ordering.
20518
+ */
20519
+ const UPDATE_HOST_ORDERING = [
20520
+ { test: kindWithInterpolationTest(OpKind.HostProperty, true) },
20521
+ { test: kindWithInterpolationTest(OpKind.HostProperty, false) },
20522
+ { test: kindTest(OpKind.Attribute) },
20523
+ { test: kindTest(OpKind.StyleMap), transform: keepLast },
20524
+ { test: kindTest(OpKind.ClassMap), transform: keepLast },
20525
+ { test: kindTest(OpKind.StyleProp) },
20526
+ { test: kindTest(OpKind.ClassProp) },
20527
+ ];
20437
20528
  /**
20438
20529
  * The set of all op kinds we handle in the reordering phase.
20439
20530
  */
@@ -20454,7 +20545,8 @@ function orderOps(job) {
20454
20545
  // Create mode:
20455
20546
  orderWithin(unit.create, CREATE_ORDERING);
20456
20547
  // Update mode:
20457
- orderWithin(unit.update, UPDATE_ORDERING);
20548
+ const ordering = unit.job.kind === CompilationJobKind.Host ? UPDATE_HOST_ORDERING : UPDATE_ORDERING;
20549
+ orderWithin(unit.update, ordering);
20458
20550
  }
20459
20551
  }
20460
20552
  /**
@@ -20534,14 +20626,14 @@ function parseExtractedStyles(job) {
20534
20626
  if (op.name === 'style') {
20535
20627
  const parsedStyles = parse(op.expression.value);
20536
20628
  for (let i = 0; i < parsedStyles.length - 1; i += 2) {
20537
- OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.StyleProperty, parsedStyles[i], literal(parsedStyles[i + 1]), null, null, SecurityContext.STYLE), op);
20629
+ OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.StyleProperty, null, parsedStyles[i], literal(parsedStyles[i + 1]), null, null, SecurityContext.STYLE), op);
20538
20630
  }
20539
20631
  OpList.remove(op);
20540
20632
  }
20541
20633
  else if (op.name === 'class') {
20542
20634
  const parsedClasses = op.expression.value.trim().split(/\s+/g);
20543
20635
  for (const parsedClass of parsedClasses) {
20544
- OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.ClassName, parsedClass, null, null, null, SecurityContext.NONE), op);
20636
+ OpList.insertBefore(createExtractedAttributeOp(op.target, BindingKind.ClassName, null, parsedClass, null, null, null, SecurityContext.NONE), op);
20545
20637
  }
20546
20638
  OpList.remove(op);
20547
20639
  }
@@ -20565,15 +20657,6 @@ function removeContentSelectors(job) {
20565
20657
  OpList.remove(op);
20566
20658
  }
20567
20659
  break;
20568
- case OpKind.Projection:
20569
- // op.attributes is an array of [attr1-name, attr1-value, attr2-name, attr2-value, ...],
20570
- // find the "select" attribute and remove its name and corresponding value.
20571
- for (let i = op.attributes.length - 2; i >= 0; i -= 2) {
20572
- if (isSelectAttribute(op.attributes[i])) {
20573
- op.attributes.splice(i, 2);
20574
- }
20575
- }
20576
- break;
20577
20660
  }
20578
20661
  }
20579
20662
  }
@@ -20745,8 +20828,10 @@ function wrapTemplateWithI18n(unit, parentI18n) {
20745
20828
  // Only add i18n ops if they have not already been propagated to this template.
20746
20829
  if (unit.create.head.next?.kind !== OpKind.I18nStart) {
20747
20830
  const id = unit.job.allocateXrefId();
20748
- OpList.insertAfter(createI18nStartOp(id, parentI18n.message, parentI18n.root), unit.create.head);
20749
- OpList.insertBefore(createI18nEndOp(id), unit.create.tail);
20831
+ OpList.insertAfter(
20832
+ // Nested ng-template i18n start/end ops should not recieve source spans.
20833
+ createI18nStartOp(id, parentI18n.message, parentI18n.root, null), unit.create.head);
20834
+ OpList.insertBefore(createI18nEndOp(id, null), unit.create.tail);
20750
20835
  }
20751
20836
  }
20752
20837
 
@@ -20927,9 +21012,7 @@ function namespaceMath() {
20927
21012
  return call(Identifiers.namespaceMathML, [], null);
20928
21013
  }
20929
21014
  function advance(delta, sourceSpan) {
20930
- return call(Identifiers.advance, [
20931
- literal(delta),
20932
- ], sourceSpan);
21015
+ return call(Identifiers.advance, delta > 1 ? [literal(delta)] : [], sourceSpan);
20933
21016
  }
20934
21017
  function reference(slot) {
20935
21018
  return importExpr(Identifiers.reference).callFn([
@@ -21007,22 +21090,22 @@ function projectionDef(def) {
21007
21090
  }
21008
21091
  function projection(slot, projectionSlotIndex, attributes, sourceSpan) {
21009
21092
  const args = [literal(slot)];
21010
- if (projectionSlotIndex !== 0 || attributes.length > 0) {
21093
+ if (projectionSlotIndex !== 0 || attributes !== null) {
21011
21094
  args.push(literal(projectionSlotIndex));
21012
- if (attributes.length > 0) {
21013
- args.push(literalArr(attributes.map(attr => literal(attr))));
21095
+ if (attributes !== null) {
21096
+ args.push(attributes);
21014
21097
  }
21015
21098
  }
21016
21099
  return call(Identifiers.projection, args, sourceSpan);
21017
21100
  }
21018
- function i18nStart(slot, constIndex, subTemplateIndex) {
21101
+ function i18nStart(slot, constIndex, subTemplateIndex, sourceSpan) {
21019
21102
  const args = [literal(slot), literal(constIndex)];
21020
21103
  if (subTemplateIndex !== null) {
21021
21104
  args.push(literal(subTemplateIndex));
21022
21105
  }
21023
- return call(Identifiers.i18nStart, args, null);
21106
+ return call(Identifiers.i18nStart, args, sourceSpan);
21024
21107
  }
21025
- function repeaterCreate(slot, viewFnName, decls, vars, tag, constIndex, trackByFn, trackByUsesComponentInstance, emptyViewFnName, emptyDecls, emptyVars, sourceSpan) {
21108
+ function repeaterCreate(slot, viewFnName, decls, vars, tag, constIndex, trackByFn, trackByUsesComponentInstance, emptyViewFnName, emptyDecls, emptyVars, emptyTag, emptyConstIndex, sourceSpan) {
21026
21109
  const args = [
21027
21110
  literal(slot),
21028
21111
  variable(viewFnName),
@@ -21036,6 +21119,12 @@ function repeaterCreate(slot, viewFnName, decls, vars, tag, constIndex, trackByF
21036
21119
  args.push(literal(trackByUsesComponentInstance));
21037
21120
  if (emptyViewFnName !== null) {
21038
21121
  args.push(variable(emptyViewFnName), literal(emptyDecls), literal(emptyVars));
21122
+ if (emptyTag !== null || emptyConstIndex !== null) {
21123
+ args.push(literal(emptyTag));
21124
+ }
21125
+ if (emptyConstIndex !== null) {
21126
+ args.push(literal(emptyConstIndex));
21127
+ }
21039
21128
  }
21040
21129
  }
21041
21130
  return call(Identifiers.repeaterCreate, args, sourceSpan);
@@ -21046,15 +21135,15 @@ function repeater(collection, sourceSpan) {
21046
21135
  function deferWhen(prefetch, expr, sourceSpan) {
21047
21136
  return call(prefetch ? Identifiers.deferPrefetchWhen : Identifiers.deferWhen, [expr], sourceSpan);
21048
21137
  }
21049
- function i18n(slot, constIndex, subTemplateIndex) {
21138
+ function i18n(slot, constIndex, subTemplateIndex, sourceSpan) {
21050
21139
  const args = [literal(slot), literal(constIndex)];
21051
21140
  if (subTemplateIndex) {
21052
21141
  args.push(literal(subTemplateIndex));
21053
21142
  }
21054
- return call(Identifiers.i18n, args, null);
21143
+ return call(Identifiers.i18n, args, sourceSpan);
21055
21144
  }
21056
- function i18nEnd() {
21057
- return call(Identifiers.i18nEnd, [], null);
21145
+ function i18nEnd(endSourceSpan) {
21146
+ return call(Identifiers.i18nEnd, [], endSourceSpan);
21058
21147
  }
21059
21148
  function i18nAttributes(slot, i18nAttributesConfig) {
21060
21149
  const args = [literal(slot), literal(i18nAttributesConfig)];
@@ -21067,10 +21156,13 @@ function property(name, expression, sanitizer, sourceSpan) {
21067
21156
  }
21068
21157
  return call(Identifiers.property, args, sourceSpan);
21069
21158
  }
21070
- function attribute(name, expression, sanitizer) {
21159
+ function attribute(name, expression, sanitizer, namespace) {
21071
21160
  const args = [literal(name), expression];
21072
- if (sanitizer !== null) {
21073
- args.push(sanitizer);
21161
+ if (sanitizer !== null || namespace !== null) {
21162
+ args.push(sanitizer ?? literal(null));
21163
+ }
21164
+ if (namespace !== null) {
21165
+ args.push(literal(namespace));
21074
21166
  }
21075
21167
  return call(Identifiers.attribute, args, null);
21076
21168
  }
@@ -21440,13 +21532,13 @@ function reifyCreateOperations(unit, ops) {
21440
21532
  OpList.replace(op, elementContainerEnd());
21441
21533
  break;
21442
21534
  case OpKind.I18nStart:
21443
- OpList.replace(op, i18nStart(op.handle.slot, op.messageIndex, op.subTemplateIndex));
21535
+ OpList.replace(op, i18nStart(op.handle.slot, op.messageIndex, op.subTemplateIndex, op.sourceSpan));
21444
21536
  break;
21445
21537
  case OpKind.I18nEnd:
21446
- OpList.replace(op, i18nEnd());
21538
+ OpList.replace(op, i18nEnd(op.sourceSpan));
21447
21539
  break;
21448
21540
  case OpKind.I18n:
21449
- OpList.replace(op, i18n(op.handle.slot, op.messageIndex, op.subTemplateIndex));
21541
+ OpList.replace(op, i18n(op.handle.slot, op.messageIndex, op.subTemplateIndex, op.sourceSpan));
21450
21542
  break;
21451
21543
  case OpKind.I18nAttributes:
21452
21544
  if (op.i18nAttributesConfig === null) {
@@ -21564,7 +21656,7 @@ function reifyCreateOperations(unit, ops) {
21564
21656
  emptyDecls = emptyView.decls;
21565
21657
  emptyVars = emptyView.vars;
21566
21658
  }
21567
- OpList.replace(op, repeaterCreate(op.handle.slot, repeaterView.fnName, op.decls, op.vars, op.tag, op.attributes, op.trackByFn, op.usesComponentInstance, emptyViewFnName, emptyDecls, emptyVars, op.wholeSourceSpan));
21659
+ OpList.replace(op, repeaterCreate(op.handle.slot, repeaterView.fnName, op.decls, op.vars, op.tag, op.attributes, op.trackByFn, op.usesComponentInstance, emptyViewFnName, emptyDecls, emptyVars, op.emptyTag, op.emptyAttributes, op.wholeSourceSpan));
21568
21660
  break;
21569
21661
  case OpKind.Statement:
21570
21662
  // Pass statement operations directly through.
@@ -21630,7 +21722,7 @@ function reifyUpdateOperations(_unit, ops) {
21630
21722
  OpList.replace(op, attributeInterpolate(op.name, op.expression.strings, op.expression.expressions, op.sanitizer, op.sourceSpan));
21631
21723
  }
21632
21724
  else {
21633
- OpList.replace(op, attribute(op.name, op.expression, op.sanitizer));
21725
+ OpList.replace(op, attribute(op.name, op.expression, op.sanitizer, op.namespace));
21634
21726
  }
21635
21727
  break;
21636
21728
  case OpKind.HostProperty:
@@ -21819,42 +21911,6 @@ function removeUnusedI18nAttributesOps(job) {
21819
21911
  }
21820
21912
  }
21821
21913
 
21822
- /**
21823
- * Inside the body of a repeater, certain context variables (such as `$first`) are ambiently
21824
- * available. This phase finds those variable usages, and replaces them with the appropriate
21825
- * expression.
21826
- */
21827
- function generateRepeaterDerivedVars(job) {
21828
- const repeaters = new Map();
21829
- for (const unit of job.units) {
21830
- for (const op of unit.ops()) {
21831
- if (op.kind === OpKind.RepeaterCreate) {
21832
- repeaters.set(op.xref, op);
21833
- }
21834
- }
21835
- }
21836
- for (const unit of job.units) {
21837
- for (const op of unit.ops()) {
21838
- transformExpressionsInOp(op, expr => {
21839
- if (!(expr instanceof DerivedRepeaterVarExpr)) {
21840
- return expr;
21841
- }
21842
- const repeaterOp = repeaters.get(expr.xref);
21843
- switch (expr.identity) {
21844
- case DerivedRepeaterVarIdentity.First:
21845
- return new BinaryOperatorExpr(exports.BinaryOperator.Identical, new LexicalReadExpr(repeaterOp.varNames.$index), literal(0));
21846
- case DerivedRepeaterVarIdentity.Last:
21847
- return new BinaryOperatorExpr(exports.BinaryOperator.Identical, new LexicalReadExpr(repeaterOp.varNames.$index), new BinaryOperatorExpr(exports.BinaryOperator.Minus, new LexicalReadExpr(repeaterOp.varNames.$count), literal(1)));
21848
- case DerivedRepeaterVarIdentity.Even:
21849
- return new BinaryOperatorExpr(exports.BinaryOperator.Identical, new BinaryOperatorExpr(exports.BinaryOperator.Modulo, new LexicalReadExpr(repeaterOp.varNames.$index), literal(2)), literal(0));
21850
- case DerivedRepeaterVarIdentity.Odd:
21851
- return new BinaryOperatorExpr(exports.BinaryOperator.NotIdentical, new BinaryOperatorExpr(exports.BinaryOperator.Modulo, new LexicalReadExpr(repeaterOp.varNames.$index), literal(2)), literal(0));
21852
- }
21853
- }, VisitorContextFlag.None);
21854
- }
21855
- }
21856
- }
21857
-
21858
21914
  /**
21859
21915
  * Resolves `ir.ContextExpr` expressions (which represent embedded view or component contexts) to
21860
21916
  * either the `ctx` parameter to component functions (for the current view context) or to variables
@@ -22697,6 +22753,9 @@ function generateTrackFns(job) {
22697
22753
  // Find all component context reads.
22698
22754
  let usesComponentContext = false;
22699
22755
  op.track = transformExpressionsInExpression(op.track, expr => {
22756
+ if (expr instanceof PipeBindingExpr || expr instanceof PipeBindingVariadicExpr) {
22757
+ throw new Error(`Illegal State: Pipes are not allowed in this context`);
22758
+ }
22700
22759
  if (expr instanceof TrackContextExpr) {
22701
22760
  usesComponentContext = true;
22702
22761
  return variable('this');
@@ -23383,12 +23442,13 @@ function wrapI18nIcus(job) {
23383
23442
  case OpKind.IcuStart:
23384
23443
  if (currentI18nOp === null) {
23385
23444
  addedI18nId = job.allocateXrefId();
23386
- OpList.insertBefore(createI18nStartOp(addedI18nId, op.message), op);
23445
+ // ICU i18n start/end ops should not recieve source spans.
23446
+ OpList.insertBefore(createI18nStartOp(addedI18nId, op.message, undefined, null), op);
23387
23447
  }
23388
23448
  break;
23389
23449
  case OpKind.IcuEnd:
23390
23450
  if (addedI18nId !== null) {
23391
- OpList.insertAfter(createI18nEndOp(addedI18nId), op);
23451
+ OpList.insertAfter(createI18nEndOp(addedI18nId, null), op);
23392
23452
  addedI18nId = null;
23393
23453
  }
23394
23454
  break;
@@ -23435,7 +23495,6 @@ function wrapI18nIcus(job) {
23435
23495
  { kind: CompilationJobKind.Tmpl, fn: saveAndRestoreView },
23436
23496
  { kind: CompilationJobKind.Both, fn: deleteAnyCasts },
23437
23497
  { kind: CompilationJobKind.Both, fn: resolveDollarEvent },
23438
- { kind: CompilationJobKind.Tmpl, fn: generateRepeaterDerivedVars },
23439
23498
  { kind: CompilationJobKind.Tmpl, fn: generateTrackVariables },
23440
23499
  { kind: CompilationJobKind.Both, fn: resolveNames },
23441
23500
  { kind: CompilationJobKind.Tmpl, fn: resolveDeferTargetNames },
@@ -24972,8 +25031,8 @@ const TIME_PATTERN = /^\d+\.?\d*(ms|s)?$/;
24972
25031
  const SEPARATOR_PATTERN = /^\s$/;
24973
25032
  /** Pairs of characters that form syntax that is comma-delimited. */
24974
25033
  const COMMA_DELIMITED_SYNTAX = new Map([
24975
- [$LBRACE, $RBRACE],
24976
- [$LBRACKET, $RBRACKET],
25034
+ [$LBRACE, $RBRACE], // Object literals
25035
+ [$LBRACKET, $RBRACKET], // Array literals
24977
25036
  [$LPAREN, $RPAREN], // Function calls
24978
25037
  ]);
24979
25038
  /** Possible types of `on` triggers. */
@@ -26243,7 +26302,7 @@ class TemplateData {
26243
26302
  }
26244
26303
  }
26245
26304
  class TemplateDefinitionBuilder {
26246
- constructor(constantPool, parentBindingScope, level = 0, contextName, i18nContext, templateIndex, templateName, _namespace, relativeContextFilePath, i18nUseExternalIds, deferBlocks, elementLocations, _constants = createComponentDefConsts()) {
26305
+ constructor(constantPool, parentBindingScope, level = 0, contextName, i18nContext, templateIndex, templateName, _namespace, relativeContextFilePath, i18nUseExternalIds, deferBlocks, elementLocations, allDeferrableDepsFn, _constants = createComponentDefConsts()) {
26247
26306
  this.constantPool = constantPool;
26248
26307
  this.level = level;
26249
26308
  this.contextName = contextName;
@@ -26254,6 +26313,7 @@ class TemplateDefinitionBuilder {
26254
26313
  this.i18nUseExternalIds = i18nUseExternalIds;
26255
26314
  this.deferBlocks = deferBlocks;
26256
26315
  this.elementLocations = elementLocations;
26316
+ this.allDeferrableDepsFn = allDeferrableDepsFn;
26257
26317
  this._constants = _constants;
26258
26318
  this._dataIndex = 0;
26259
26319
  this._bindingContext = 0;
@@ -26908,7 +26968,7 @@ class TemplateDefinitionBuilder {
26908
26968
  const contextName = `${this.contextName}${contextNameSuffix}_${index}`;
26909
26969
  const name = `${contextName}_Template`;
26910
26970
  // Create the template function
26911
- const visitor = new TemplateDefinitionBuilder(this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, index, name, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds, this.deferBlocks, this.elementLocations, this._constants);
26971
+ const visitor = new TemplateDefinitionBuilder(this.constantPool, this._bindingScope, this.level + 1, contextName, this.i18n, index, name, this._namespace, this.fileBasedI18nSuffix, this.i18nUseExternalIds, this.deferBlocks, this.elementLocations, this.allDeferrableDepsFn, this._constants);
26912
26972
  // Nested templates must not be visited until after their parent templates have completed
26913
26973
  // processing, so they are queued here until after the initial pass. Otherwise, we wouldn't
26914
26974
  // be able to support bindings in nested templates to local refs that occur after the
@@ -27119,6 +27179,9 @@ class TemplateDefinitionBuilder {
27119
27179
  this.updateInstructionWithAdvance(containerIndex, block.branches[0].sourceSpan, Identifiers.conditional, paramsCallback);
27120
27180
  }
27121
27181
  visitSwitchBlock(block) {
27182
+ if (block.cases.length === 0) {
27183
+ return;
27184
+ }
27122
27185
  // We have to process the block in two steps: once here and again in the update instruction
27123
27186
  // callback in order to generate the correct expressions when pipes or pure functions are used.
27124
27187
  const caseData = block.cases.map(currentCase => {
@@ -27193,7 +27256,7 @@ class TemplateDefinitionBuilder {
27193
27256
  this.creationInstruction(deferred.sourceSpan, Identifiers.defer, trimTrailingNulls([
27194
27257
  literal(deferredIndex),
27195
27258
  literal(primaryTemplateIndex),
27196
- this.createDeferredDepsFunction(depsFnName, metadata),
27259
+ this.allDeferrableDepsFn ?? this.createDeferredDepsFunction(depsFnName, metadata),
27197
27260
  literal(loadingIndex),
27198
27261
  literal(placeholderIndex),
27199
27262
  literal(errorIndex),
@@ -27348,7 +27411,12 @@ class TemplateDefinitionBuilder {
27348
27411
  });
27349
27412
  const { expression: trackByExpression, usesComponentInstance: trackByUsesComponentInstance } = this.createTrackByFunction(block);
27350
27413
  let emptyData = null;
27414
+ let emptyTagName = null;
27415
+ let emptyAttrsExprs;
27351
27416
  if (block.empty !== null) {
27417
+ const emptyInferred = this.inferProjectionDataFromInsertionPoint(block.empty);
27418
+ emptyTagName = emptyInferred.tagName;
27419
+ emptyAttrsExprs = emptyInferred.attrsExprs;
27352
27420
  emptyData = this.prepareEmbeddedTemplateFn(block.empty.children, '_ForEmpty', undefined, block.empty.i18n);
27353
27421
  // Allocate an extra slot for the empty block tracking.
27354
27422
  this.allocateBindingSlots(null);
@@ -27366,13 +27434,13 @@ class TemplateDefinitionBuilder {
27366
27434
  trackByExpression,
27367
27435
  ];
27368
27436
  if (emptyData !== null) {
27369
- params.push(literal(trackByUsesComponentInstance), variable(emptyData.name), literal(emptyData.getConstCount()), literal(emptyData.getVarCount()));
27437
+ params.push(literal(trackByUsesComponentInstance), variable(emptyData.name), literal(emptyData.getConstCount()), literal(emptyData.getVarCount()), literal(emptyTagName), this.addAttrsToConsts(emptyAttrsExprs || null));
27370
27438
  }
27371
27439
  else if (trackByUsesComponentInstance) {
27372
27440
  // If the tracking function doesn't use the component instance, we can omit the flag.
27373
27441
  params.push(literal(trackByUsesComponentInstance));
27374
27442
  }
27375
- return params;
27443
+ return trimTrailingNulls(params);
27376
27444
  });
27377
27445
  // Note: the expression needs to be processed *after* the template,
27378
27446
  // otherwise pipes injecting some symbols won't work (see #52102).
@@ -27577,7 +27645,7 @@ class TemplateDefinitionBuilder {
27577
27645
  if (delta < 1) {
27578
27646
  throw new Error('advance instruction can only go forwards');
27579
27647
  }
27580
- this.instructionFn(this._updateCodeFns, span, Identifiers.advance, [literal(delta)]);
27648
+ this.instructionFn(this._updateCodeFns, span, Identifiers.advance, delta > 1 ? [literal(delta)] : []);
27581
27649
  this._currentIndex = nodeIndex;
27582
27650
  }
27583
27651
  }
@@ -28550,6 +28618,24 @@ function compileDirectiveFromMetadata(meta, constantPool, bindingParser) {
28550
28618
  const type = createDirectiveType(meta);
28551
28619
  return { expression, type, statements: [] };
28552
28620
  }
28621
+ /**
28622
+ * Creates an AST for a function that contains dynamic imports representing
28623
+ * deferrable dependencies.
28624
+ */
28625
+ function createDeferredDepsFunction(constantPool, name, deps) {
28626
+ // This defer block has deps for which we need to generate dynamic imports.
28627
+ const dependencyExp = [];
28628
+ for (const [symbolName, importPath] of deps) {
28629
+ // Callback function, e.g. `m () => m.MyCmp;`.
28630
+ const innerFn = arrowFn([new FnParam('m', DYNAMIC_TYPE)], variable('m').prop(symbolName));
28631
+ // Dynamic import, e.g. `import('./a').then(...)`.
28632
+ const importExpr = (new DynamicImportExpr(importPath)).prop('then').callFn([innerFn]);
28633
+ dependencyExp.push(importExpr);
28634
+ }
28635
+ const depsFnExpr = arrowFn([], literalArr(dependencyExp));
28636
+ constantPool.statements.push(depsFnExpr.toDeclStmt(name, exports.StmtModifier.Final));
28637
+ return variable(name);
28638
+ }
28553
28639
  /**
28554
28640
  * Compile a component for the render3 runtime as defined by the `R3ComponentMetadata`.
28555
28641
  */
@@ -28574,8 +28660,14 @@ function compileComponentFromMetadata(meta, constantPool, bindingParser) {
28574
28660
  {
28575
28661
  // This is the main path currently used in compilation, which compiles the template with the
28576
28662
  // legacy `TemplateDefinitionBuilder`.
28663
+ let allDeferrableDepsFn = null;
28664
+ if (meta.deferBlocks.size > 0 && meta.deferrableTypes.size > 0 &&
28665
+ meta.deferBlockDepsEmitMode === 1 /* DeferBlockDepsEmitMode.PerComponent */) {
28666
+ const fnName = `${templateTypeName}_DeferFn`;
28667
+ allDeferrableDepsFn = createDeferredDepsFunction(constantPool, fnName, meta.deferrableTypes);
28668
+ }
28577
28669
  const template = meta.template;
28578
- const templateBuilder = new TemplateDefinitionBuilder(constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, Identifiers.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.deferBlocks, new Map());
28670
+ const templateBuilder = new TemplateDefinitionBuilder(constantPool, BindingScope.createRootScope(), 0, templateTypeName, null, null, templateName, Identifiers.namespaceHTML, meta.relativeContextFilePath, meta.i18nUseExternalIds, meta.deferBlocks, new Map(), allDeferrableDepsFn);
28579
28671
  const templateFunctionExpression = templateBuilder.buildTemplateFunction(template.nodes, []);
28580
28672
  // We need to provide this so that dynamically generated components know what
28581
28673
  // projected content blocks to pass through to the component when it is
@@ -28788,14 +28880,16 @@ function createBaseDirectiveTypeParams(meta) {
28788
28880
  function getInputsTypeExpression(meta) {
28789
28881
  return literalMap(Object.keys(meta.inputs).map(key => {
28790
28882
  const value = meta.inputs[key];
28791
- return {
28792
- key,
28793
- value: literalMap([
28794
- { key: 'alias', value: literal(value.bindingPropertyName), quoted: true },
28795
- { key: 'required', value: literal(value.required), quoted: true }
28796
- ]),
28797
- quoted: true
28798
- };
28883
+ const values = [
28884
+ { key: 'alias', value: literal(value.bindingPropertyName), quoted: true },
28885
+ { key: 'required', value: literal(value.required), quoted: true },
28886
+ ];
28887
+ // TODO(legacy-partial-output-inputs): Consider always emitting this information,
28888
+ // or leaving it as is.
28889
+ if (value.isSignal) {
28890
+ values.push({ key: 'isSignal', value: literal(value.isSignal), quoted: true });
28891
+ }
28892
+ return { key, value: literalMap(values), quoted: true };
28799
28893
  }));
28800
28894
  }
28801
28895
  /**
@@ -29144,6 +29238,18 @@ function compileStyles(styles, selector, hostSelector) {
29144
29238
  return shadowCss.shimCssText(style, selector, hostSelector);
29145
29239
  });
29146
29240
  }
29241
+ /**
29242
+ * Encapsulates a CSS stylesheet with emulated view encapsulation.
29243
+ * This allows a stylesheet to be used with an Angular component that
29244
+ * is using the `ViewEncapsulation.Emulated` mode.
29245
+ *
29246
+ * @param style The content of a CSS stylesheet.
29247
+ * @returns The encapsulated content for the style.
29248
+ */
29249
+ function encapsulateStyle(style) {
29250
+ const shadowCss = new ShadowCss();
29251
+ return shadowCss.shimCssText(style, CONTENT_ATTR, HOST_ATTR);
29252
+ }
29147
29253
  function createHostDirectivesType(meta) {
29148
29254
  if (!meta.hostDirectives?.length) {
29149
29255
  return NONE_TYPE;
@@ -29239,7 +29345,7 @@ class R3TargetBinder {
29239
29345
  // Finally, run the TemplateBinder to bind references, variables, and other entities within the
29240
29346
  // template. This extracts all the metadata that doesn't depend on directive matching.
29241
29347
  const { expressions, symbols, nestingLevel, usedPipes, eagerPipes, deferBlocks } = TemplateBinder.applyWithScope(target.template, scope);
29242
- return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks);
29348
+ return new R3BoundTarget(target, directives, eagerDirectives, bindings, references, expressions, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferBlocks, scope);
29243
29349
  }
29244
29350
  }
29245
29351
  /**
@@ -29257,6 +29363,10 @@ class Scope {
29257
29363
  * Named members of the `Scope`, such as `Reference`s or `Variable`s.
29258
29364
  */
29259
29365
  this.namedEntities = new Map();
29366
+ /**
29367
+ * Set of elements that belong to this scope.
29368
+ */
29369
+ this.elementsInScope = new Set();
29260
29370
  /**
29261
29371
  * Child `Scope`s for immediately nested `ScopedNode`s.
29262
29372
  */
@@ -29313,6 +29423,7 @@ class Scope {
29313
29423
  element.references.forEach(node => this.visitReference(node));
29314
29424
  // Recurse into the `Element`'s children.
29315
29425
  element.children.forEach(node => node.visit(this));
29426
+ this.elementsInScope.add(element);
29316
29427
  }
29317
29428
  visitTemplate(template) {
29318
29429
  // References on a <ng-template> are defined in the outer scope, so capture them before
@@ -29806,7 +29917,7 @@ class TemplateBinder extends RecursiveAstVisitor {
29806
29917
  * See `BoundTarget` for documentation on the individual methods.
29807
29918
  */
29808
29919
  class R3BoundTarget {
29809
- constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferredBlocks) {
29920
+ constructor(target, directives, eagerDirectives, bindings, references, exprTargets, symbols, nestingLevel, scopedNodeEntities, usedPipes, eagerPipes, deferredBlocks, rootScope) {
29810
29921
  this.target = target;
29811
29922
  this.directives = directives;
29812
29923
  this.eagerDirectives = eagerDirectives;
@@ -29819,6 +29930,7 @@ class R3BoundTarget {
29819
29930
  this.usedPipes = usedPipes;
29820
29931
  this.eagerPipes = eagerPipes;
29821
29932
  this.deferredBlocks = deferredBlocks;
29933
+ this.rootScope = rootScope;
29822
29934
  }
29823
29935
  getEntitiesInScope(node) {
29824
29936
  return this.scopedNodeEntities.get(node) ?? new Set();
@@ -29908,6 +30020,15 @@ class R3BoundTarget {
29908
30020
  }
29909
30021
  return null;
29910
30022
  }
30023
+ isDeferred(element) {
30024
+ for (const deferBlock of this.deferredBlocks) {
30025
+ const scope = this.rootScope.childScopes.get(deferBlock);
30026
+ if (scope && scope.elementsInScope.has(element)) {
30027
+ return true;
30028
+ }
30029
+ }
30030
+ return false;
30031
+ }
29911
30032
  /**
29912
30033
  * Finds an entity with a specific name in a scope.
29913
30034
  * @param rootNode Root node of the scope.
@@ -30053,7 +30174,7 @@ class CompilerFacadeImpl {
30053
30174
  type: wrapReference(facade.type),
30054
30175
  bootstrap: facade.bootstrap.map(wrapReference),
30055
30176
  declarations: facade.declarations.map(wrapReference),
30056
- publicDeclarationTypes: null,
30177
+ publicDeclarationTypes: null, // only needed for types in AOT
30057
30178
  imports: facade.imports.map(wrapReference),
30058
30179
  includeImportTypes: true,
30059
30180
  exports: facade.exports.map(wrapReference),
@@ -30096,9 +30217,9 @@ class CompilerFacadeImpl {
30096
30217
  declarations: facade.declarations.map(convertDeclarationFacadeToMetadata),
30097
30218
  declarationListEmitMode: 0 /* DeclarationListEmitMode.Direct */,
30098
30219
  deferBlocks,
30099
- // TODO: leaving empty in JIT mode for now,
30100
- // to be implemented as one of the next steps.
30220
+ deferrableTypes: new Map(),
30101
30221
  deferrableDeclToImportDecl: new Map(),
30222
+ deferBlockDepsEmitMode: 0 /* DeferBlockDepsEmitMode.PerBlock */,
30102
30223
  styles: [...facade.styles, ...template.styles],
30103
30224
  encapsulation: facade.encapsulation,
30104
30225
  interpolation,
@@ -30209,6 +30330,10 @@ function convertDirectiveFacadeToMetadata(facade) {
30209
30330
  bindingPropertyName: ann.alias || field,
30210
30331
  classPropertyName: field,
30211
30332
  required: ann.required || false,
30333
+ // For JIT, decorators are used to declare signal inputs. That is because of
30334
+ // a technical limitation where it's not possible to statically reflect class
30335
+ // members of a directive/component at runtime before instantiating the class.
30336
+ isSignal: !!ann.isSignal,
30212
30337
  transformFunction: ann.transform != null ? new WrappedNodeExpr(ann.transform) : null,
30213
30338
  };
30214
30339
  }
@@ -30240,7 +30365,7 @@ function convertDeclareDirectiveFacadeToMetadata(declaration, typeSourceSpan) {
30240
30365
  type: wrapReference(declaration.type),
30241
30366
  typeSourceSpan,
30242
30367
  selector: declaration.selector ?? null,
30243
- inputs: declaration.inputs ? inputsMappingToInputMetadata(declaration.inputs) : {},
30368
+ inputs: declaration.inputs ? inputsPartialMetadataToInputMetadata(declaration.inputs) : {},
30244
30369
  outputs: declaration.outputs ?? {},
30245
30370
  host: convertHostDeclarationToMetadata(declaration.host),
30246
30371
  queries: (declaration.queries ?? []).map(convertQueryDeclarationToMetadata),
@@ -30330,9 +30455,9 @@ function convertDeclareComponentFacadeToMetadata(decl, typeSourceSpan, sourceMap
30330
30455
  null,
30331
30456
  animations: decl.animations !== undefined ? new WrappedNodeExpr(decl.animations) : null,
30332
30457
  deferBlocks,
30333
- // TODO: leaving empty in JIT mode for now,
30334
- // to be implemented as one of the next steps.
30458
+ deferrableTypes: new Map(),
30335
30459
  deferrableDeclToImportDecl: new Map(),
30460
+ deferBlockDepsEmitMode: 0 /* DeferBlockDepsEmitMode.PerBlock */,
30336
30461
  changeDetection: decl.changeDetection ?? exports.ChangeDetectionStrategy.Default,
30337
30462
  encapsulation: decl.encapsulation ?? exports.ViewEncapsulation.Emulated,
30338
30463
  interpolation,
@@ -30503,28 +30628,51 @@ function isInput(value) {
30503
30628
  function isOutput(value) {
30504
30629
  return value.ngMetadataName === 'Output';
30505
30630
  }
30506
- function inputsMappingToInputMetadata(inputs) {
30507
- return Object.keys(inputs).reduce((result, key) => {
30508
- const value = inputs[key];
30509
- if (typeof value === 'string') {
30510
- result[key] = {
30511
- bindingPropertyName: value,
30512
- classPropertyName: value,
30513
- transformFunction: null,
30514
- required: false,
30515
- };
30631
+ function inputsPartialMetadataToInputMetadata(inputs) {
30632
+ return Object.keys(inputs).reduce((result, minifiedClassName) => {
30633
+ const value = inputs[minifiedClassName];
30634
+ // Handle legacy partial input output.
30635
+ if (typeof value === 'string' || Array.isArray(value)) {
30636
+ result[minifiedClassName] = parseLegacyInputPartialOutput(value);
30516
30637
  }
30517
30638
  else {
30518
- result[key] = {
30519
- bindingPropertyName: value[0],
30520
- classPropertyName: value[1],
30521
- transformFunction: value[2] ? new WrappedNodeExpr(value[2]) : null,
30522
- required: false,
30639
+ result[minifiedClassName] = {
30640
+ bindingPropertyName: value.publicName,
30641
+ classPropertyName: minifiedClassName,
30642
+ transformFunction: value.transformFunction !== null ?
30643
+ new WrappedNodeExpr(value.transformFunction) :
30644
+ null,
30645
+ required: value.isRequired,
30646
+ isSignal: value.isSignal,
30523
30647
  };
30524
30648
  }
30525
30649
  return result;
30526
30650
  }, {});
30527
30651
  }
30652
+ /**
30653
+ * Parses the legacy input partial output. For more details see `partial/directive.ts`.
30654
+ * TODO(legacy-partial-output-inputs): Remove in v18.
30655
+ */
30656
+ function parseLegacyInputPartialOutput(value) {
30657
+ if (typeof value === 'string') {
30658
+ return {
30659
+ bindingPropertyName: value,
30660
+ classPropertyName: value,
30661
+ transformFunction: null,
30662
+ required: false,
30663
+ // legacy partial output does not capture signal inputs.
30664
+ isSignal: false,
30665
+ };
30666
+ }
30667
+ return {
30668
+ bindingPropertyName: value[0],
30669
+ classPropertyName: value[1],
30670
+ transformFunction: value[2] ? new WrappedNodeExpr(value[2]) : null,
30671
+ required: false,
30672
+ // legacy partial output does not capture signal inputs.
30673
+ isSignal: false,
30674
+ };
30675
+ }
30528
30676
  function parseInputsArray(values) {
30529
30677
  return values.reduce((results, value) => {
30530
30678
  if (typeof value === 'string') {
@@ -30533,6 +30681,8 @@ function parseInputsArray(values) {
30533
30681
  bindingPropertyName,
30534
30682
  classPropertyName,
30535
30683
  required: false,
30684
+ // Signal inputs not supported for the inputs array.
30685
+ isSignal: false,
30536
30686
  transformFunction: null,
30537
30687
  };
30538
30688
  }
@@ -30541,6 +30691,8 @@ function parseInputsArray(values) {
30541
30691
  bindingPropertyName: value.alias || value.name,
30542
30692
  classPropertyName: value.name,
30543
30693
  required: value.required || false,
30694
+ // Signal inputs not supported for the inputs array.
30695
+ isSignal: false,
30544
30696
  transformFunction: value.transform != null ? new WrappedNodeExpr(value.transform) : null,
30545
30697
  };
30546
30698
  }
@@ -30593,7 +30745,7 @@ function publishFacade(global) {
30593
30745
  * @description
30594
30746
  * Entry point for all public APIs of the compiler package.
30595
30747
  */
30596
- const VERSION = new Version('17.0.8');
30748
+ const VERSION = new Version('17.1.0');
30597
30749
 
30598
30750
  class CompilerConfig {
30599
30751
  constructor({ defaultEncapsulation = exports.ViewEncapsulation.Emulated, preserveWhitespaces, strictInjectionParameters } = {}) {
@@ -32088,7 +32240,7 @@ function compileClassMetadata(metadata) {
32088
32240
  * check to tree-shake away this code in production mode.
32089
32241
  */
32090
32242
  function compileComponentClassMetadata(metadata, deferrableTypes) {
32091
- if (deferrableTypes.size === 0) {
32243
+ if (deferrableTypes === null || deferrableTypes.size === 0) {
32092
32244
  // If there are no deferrable symbols - just generate a regular `setClassMetadata` call.
32093
32245
  return compileClassMetadata(metadata);
32094
32246
  }
@@ -32155,11 +32307,11 @@ function compileClassDebugInfo(debugInfo) {
32155
32307
  *
32156
32308
  * Do not include any prerelease in these versions as they are ignored.
32157
32309
  */
32158
- const MINIMUM_PARTIAL_LINKER_VERSION$6 = '12.0.0';
32310
+ const MINIMUM_PARTIAL_LINKER_VERSION$5 = '12.0.0';
32159
32311
  function compileDeclareClassMetadata(metadata) {
32160
32312
  const definitionMap = new DefinitionMap();
32161
- definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$6));
32162
- definitionMap.set('version', literal('17.0.8'));
32313
+ definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
32314
+ definitionMap.set('version', literal('17.1.0'));
32163
32315
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32164
32316
  definitionMap.set('type', metadata.type);
32165
32317
  definitionMap.set('decorators', metadata.decorators);
@@ -32238,14 +32390,6 @@ function compileDependency(dep) {
32238
32390
  return depMeta.toLiteralMap();
32239
32391
  }
32240
32392
 
32241
- /**
32242
- * Every time we make a breaking change to the declaration interface or partial-linker behavior, we
32243
- * must update this constant to prevent old partial-linkers from incorrectly processing the
32244
- * declaration.
32245
- *
32246
- * Do not include any prerelease in these versions as they are ignored.
32247
- */
32248
- const MINIMUM_PARTIAL_LINKER_VERSION$5 = '16.1.0';
32249
32393
  /**
32250
32394
  * Compile a directive declaration defined by the `R3DirectiveMetadata`.
32251
32395
  */
@@ -32261,13 +32405,9 @@ function compileDeclareDirectiveFromMetadata(meta) {
32261
32405
  */
32262
32406
  function createDirectiveDefinitionMap(meta) {
32263
32407
  const definitionMap = new DefinitionMap();
32264
- const hasTransformFunctions = Object.values(meta.inputs).some(input => input.transformFunction !== null);
32265
- // Note: in order to allow consuming Angular libraries that have been compiled with 16.1+ in
32266
- // Angular 16.0, we only force a minimum version of 16.1 if input transform feature as introduced
32267
- // in 16.1 is actually used.
32268
- const minVersion = hasTransformFunctions ? MINIMUM_PARTIAL_LINKER_VERSION$5 : '14.0.0';
32408
+ const minVersion = getMinimumVersionForPartialOutput(meta);
32269
32409
  definitionMap.set('minVersion', literal(minVersion));
32270
- definitionMap.set('version', literal('17.0.8'));
32410
+ definitionMap.set('version', literal('17.1.0'));
32271
32411
  // e.g. `type: MyDirective`
32272
32412
  definitionMap.set('type', meta.type.value);
32273
32413
  if (meta.isStandalone) {
@@ -32280,7 +32420,8 @@ function createDirectiveDefinitionMap(meta) {
32280
32420
  if (meta.selector !== null) {
32281
32421
  definitionMap.set('selector', literal(meta.selector));
32282
32422
  }
32283
- definitionMap.set('inputs', conditionallyCreateDirectiveBindingLiteral(meta.inputs, true));
32423
+ definitionMap.set('inputs', needsNewInputPartialOutput(meta) ? createInputsPartialMetadata(meta.inputs) :
32424
+ legacyInputsPartialMetadata(meta.inputs));
32284
32425
  definitionMap.set('outputs', conditionallyCreateDirectiveBindingLiteral(meta.outputs));
32285
32426
  definitionMap.set('host', compileHostMetadata(meta.host));
32286
32427
  definitionMap.set('providers', meta.providers);
@@ -32305,6 +32446,44 @@ function createDirectiveDefinitionMap(meta) {
32305
32446
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32306
32447
  return definitionMap;
32307
32448
  }
32449
+ /**
32450
+ * Determines the minimum linker version for the partial output
32451
+ * generated for this directive.
32452
+ *
32453
+ * Every time we make a breaking change to the declaration interface or partial-linker
32454
+ * behavior, we must update the minimum versions to prevent old partial-linkers from
32455
+ * incorrectly processing the declaration.
32456
+ *
32457
+ * NOTE: Do not include any prerelease in these versions as they are ignored.
32458
+ */
32459
+ function getMinimumVersionForPartialOutput(meta) {
32460
+ // We are starting with the oldest minimum version that can work for common
32461
+ // directive partial compilation output. As we discover usages of new features
32462
+ // that require a newer partial output emit, we bump the `minVersion`. Our goal
32463
+ // is to keep libraries as much compatible with older linker versions as possible.
32464
+ let minVersion = '14.0.0';
32465
+ // Note: in order to allow consuming Angular libraries that have been compiled with 16.1+ in
32466
+ // Angular 16.0, we only force a minimum version of 16.1 if input transform feature as introduced
32467
+ // in 16.1 is actually used.
32468
+ const hasDecoratorTransformFunctions = Object.values(meta.inputs).some(input => input.transformFunction !== null);
32469
+ if (hasDecoratorTransformFunctions) {
32470
+ minVersion = '16.1.0';
32471
+ }
32472
+ // If there are input flags and we need the new emit, use the actual minimum version,
32473
+ // where this was introduced. i.e. in 17.1.0
32474
+ // TODO(legacy-partial-output-inputs): Remove in v18.
32475
+ if (needsNewInputPartialOutput(meta)) {
32476
+ minVersion = '17.1.0';
32477
+ }
32478
+ return minVersion;
32479
+ }
32480
+ /**
32481
+ * Gets whether the given directive needs the new input partial output structure
32482
+ * that can hold additional metadata like `isRequired`, `isSignal` etc.
32483
+ */
32484
+ function needsNewInputPartialOutput(meta) {
32485
+ return Object.values(meta.inputs).some(input => input.isSignal);
32486
+ }
32308
32487
  /**
32309
32488
  * Compiles the metadata of a single query into its partial declaration form as declared
32310
32489
  * by `R3DeclareQueryMetadata`.
@@ -32375,6 +32554,74 @@ function createHostDirectives(hostDirectives) {
32375
32554
  // otherwise we can save some bytes by using a plain array, e.g. `[{directive: HostDir}]`.
32376
32555
  return literalArr(expressions);
32377
32556
  }
32557
+ /**
32558
+ * Generates partial output metadata for inputs of a directive.
32559
+ *
32560
+ * The generated structure is expected to match `R3DeclareDirectiveFacade['inputs']`.
32561
+ */
32562
+ function createInputsPartialMetadata(inputs) {
32563
+ const keys = Object.getOwnPropertyNames(inputs);
32564
+ if (keys.length === 0) {
32565
+ return null;
32566
+ }
32567
+ return literalMap(keys.map(declaredName => {
32568
+ const value = inputs[declaredName];
32569
+ return {
32570
+ key: declaredName,
32571
+ // put quotes around keys that contain potentially unsafe characters
32572
+ quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(declaredName),
32573
+ value: literalMap([
32574
+ { key: 'classPropertyName', quoted: false, value: asLiteral(value.classPropertyName) },
32575
+ { key: 'publicName', quoted: false, value: asLiteral(value.bindingPropertyName) },
32576
+ { key: 'isSignal', quoted: false, value: asLiteral(value.isSignal) },
32577
+ { key: 'isRequired', quoted: false, value: asLiteral(value.required) },
32578
+ { key: 'transformFunction', quoted: false, value: value.transformFunction ?? NULL_EXPR },
32579
+ ])
32580
+ };
32581
+ }));
32582
+ }
32583
+ /**
32584
+ * Pre v18 legacy partial output for inputs.
32585
+ *
32586
+ * Previously, inputs did not capture metadata like `isSignal` in the partial compilation output.
32587
+ * To enable capturing such metadata, we restructured how input metadata is communicated in the
32588
+ * partial output. This would make libraries incompatible with older Angular FW versions where the
32589
+ * linker would not know how to handle this new "format". For this reason, if we know this metadata
32590
+ * does not need to be captured- we fall back to the old format. This is what this function
32591
+ * generates.
32592
+ *
32593
+ * See:
32594
+ * https://github.com/angular/angular/blob/d4b423690210872b5c32a322a6090beda30b05a3/packages/core/src/compiler/compiler_facade_interface.ts#L197-L199
32595
+ */
32596
+ function legacyInputsPartialMetadata(inputs) {
32597
+ // TODO(legacy-partial-output-inputs): Remove function in v18.
32598
+ const keys = Object.getOwnPropertyNames(inputs);
32599
+ if (keys.length === 0) {
32600
+ return null;
32601
+ }
32602
+ return literalMap(keys.map(declaredName => {
32603
+ const value = inputs[declaredName];
32604
+ const publicName = value.bindingPropertyName;
32605
+ const differentDeclaringName = publicName !== declaredName;
32606
+ let result;
32607
+ if (differentDeclaringName || value.transformFunction !== null) {
32608
+ const values = [asLiteral(publicName), asLiteral(declaredName)];
32609
+ if (value.transformFunction !== null) {
32610
+ values.push(value.transformFunction);
32611
+ }
32612
+ result = literalArr(values);
32613
+ }
32614
+ else {
32615
+ result = asLiteral(publicName);
32616
+ }
32617
+ return {
32618
+ key: declaredName,
32619
+ // put quotes around keys that contain potentially unsafe characters
32620
+ quoted: UNSAFE_OBJECT_KEY_NAME_REGEXP.test(declaredName),
32621
+ value: result,
32622
+ };
32623
+ }));
32624
+ }
32378
32625
 
32379
32626
  /**
32380
32627
  * Compile a component declaration defined by the `R3ComponentMetadata`.
@@ -32541,7 +32788,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
32541
32788
  function compileDeclareFactoryFunction(meta) {
32542
32789
  const definitionMap = new DefinitionMap();
32543
32790
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
32544
- definitionMap.set('version', literal('17.0.8'));
32791
+ definitionMap.set('version', literal('17.1.0'));
32545
32792
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32546
32793
  definitionMap.set('type', meta.type.value);
32547
32794
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -32576,7 +32823,7 @@ function compileDeclareInjectableFromMetadata(meta) {
32576
32823
  function createInjectableDefinitionMap(meta) {
32577
32824
  const definitionMap = new DefinitionMap();
32578
32825
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
32579
- definitionMap.set('version', literal('17.0.8'));
32826
+ definitionMap.set('version', literal('17.1.0'));
32580
32827
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32581
32828
  definitionMap.set('type', meta.type.value);
32582
32829
  // Only generate providedIn property if it has a non-null value
@@ -32627,7 +32874,7 @@ function compileDeclareInjectorFromMetadata(meta) {
32627
32874
  function createInjectorDefinitionMap(meta) {
32628
32875
  const definitionMap = new DefinitionMap();
32629
32876
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
32630
- definitionMap.set('version', literal('17.0.8'));
32877
+ definitionMap.set('version', literal('17.1.0'));
32631
32878
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32632
32879
  definitionMap.set('type', meta.type.value);
32633
32880
  definitionMap.set('providers', meta.providers);
@@ -32660,7 +32907,7 @@ function createNgModuleDefinitionMap(meta) {
32660
32907
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
32661
32908
  }
32662
32909
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
32663
- definitionMap.set('version', literal('17.0.8'));
32910
+ definitionMap.set('version', literal('17.1.0'));
32664
32911
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32665
32912
  definitionMap.set('type', meta.type.value);
32666
32913
  // We only generate the keys in the metadata if the arrays contain values.
@@ -32711,7 +32958,7 @@ function compileDeclarePipeFromMetadata(meta) {
32711
32958
  function createPipeDefinitionMap(meta) {
32712
32959
  const definitionMap = new DefinitionMap();
32713
32960
  definitionMap.set('minVersion', literal(MINIMUM_PARTIAL_LINKER_VERSION));
32714
- definitionMap.set('version', literal('17.0.8'));
32961
+ definitionMap.set('version', literal('17.1.0'));
32715
32962
  definitionMap.set('ngImport', importExpr(Identifiers.core));
32716
32963
  // e.g. `type: MyPipe`
32717
32964
  definitionMap.set('type', meta.type.value);
@@ -32924,6 +33171,7 @@ exports.createInjectableType = createInjectableType;
32924
33171
  exports.createMayBeForwardRefExpression = createMayBeForwardRefExpression;
32925
33172
  exports.devOnlyGuardedExpression = devOnlyGuardedExpression;
32926
33173
  exports.emitDistinctChangesOnlyDefaultValue = emitDistinctChangesOnlyDefaultValue;
33174
+ exports.encapsulateStyle = encapsulateStyle;
32927
33175
  exports.getHtmlTagDefinition = getHtmlTagDefinition;
32928
33176
  exports.getNsPrefix = getNsPrefix;
32929
33177
  exports.getSafePropertyAccessString = getSafePropertyAccessString;