@angular/compiler-cli 21.1.0-next.3 → 21.1.0-rc.0

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.
@@ -12,7 +12,7 @@ import {
12
12
  formatDiagnostics,
13
13
  performCompilation,
14
14
  readConfiguration
15
- } from "./chunk-ML6J2RBK.js";
15
+ } from "./chunk-G5W5AISR.js";
16
16
 
17
17
  // packages/compiler-cli/src/main.js
18
18
  import ts2 from "typescript";
@@ -87,7 +87,7 @@ import {
87
87
  toUnredirectedSourceFile,
88
88
  tryParseInitializerApi,
89
89
  untagAllTsFiles
90
- } from "./chunk-PUEBQK4X.js";
90
+ } from "./chunk-G2AK5XJW.js";
91
91
  import {
92
92
  LogicalFileSystem,
93
93
  absoluteFromSourceFile,
@@ -622,12 +622,15 @@ var DirectiveExtractor = class extends ClassExtractor {
622
622
  }
623
623
  /** Extract docs info for directives and components (including underlying class info). */
624
624
  extract() {
625
+ const selector = this.metadata.selector ?? "";
626
+ const aliases = extractAliasesFromSelector(selector);
625
627
  return {
626
628
  ...super.extract(),
627
629
  isStandalone: this.metadata.isStandalone,
628
- selector: this.metadata.selector ?? "",
630
+ selector,
629
631
  exportAs: this.metadata.exportAs ?? [],
630
- entryType: this.metadata.isComponent ? EntryType.Component : EntryType.Directive
632
+ entryType: this.metadata.isComponent ? EntryType.Component : EntryType.Directive,
633
+ ...aliases.length > 0 && { aliases }
631
634
  };
632
635
  }
633
636
  /** Extracts docs info for a directive property, including input/output metadata. */
@@ -717,6 +720,21 @@ function extractPipeSyntax(metadata, classDeclaration) {
717
720
  });
718
721
  return `{{ value_expression | ${metadata.name}${paramNames.length ? ":" + paramNames.join(":") : ""} }}`;
719
722
  }
723
+ function extractAliasesFromSelector(selector) {
724
+ if (!selector) {
725
+ return [];
726
+ }
727
+ const aliases = [];
728
+ const attributeRegex = /\[([^\]=]+)(?:=[^\]]+)?\]/g;
729
+ let match;
730
+ while ((match = attributeRegex.exec(selector)) !== null) {
731
+ const attributeName = match[1].trim();
732
+ if (attributeName) {
733
+ aliases.push(attributeName);
734
+ }
735
+ }
736
+ return aliases;
737
+ }
720
738
 
721
739
  // packages/compiler-cli/src/ngtsc/docs/src/constant_extractor.js
722
740
  import ts7 from "typescript";
@@ -1204,7 +1222,7 @@ var DocsExtractor = class {
1204
1222
  if (isAngularPrivateName(exportName)) {
1205
1223
  continue;
1206
1224
  }
1207
- const entry = this.extractDeclarations(exportName, declarations);
1225
+ const entry = this.extractDeclarations(declarations);
1208
1226
  if (entry && !isIgnoredDocEntry(entry)) {
1209
1227
  const realSourceFile = declarations[0].getSourceFile();
1210
1228
  const importedSymbols = getImportedSymbols(realSourceFile);
@@ -1233,7 +1251,7 @@ var DocsExtractor = class {
1233
1251
  * the same name. This is used to combine entries, e.g. for a type and a namespace that are
1234
1252
  * exported under the same name.
1235
1253
  */
1236
- extractDeclarations(exportName, nodes) {
1254
+ extractDeclarations(nodes) {
1237
1255
  const entries = nodes.map((node) => this.extractDeclaration(node));
1238
1256
  const decorator = entries.find((e) => e?.entryType === EntryType.Decorator);
1239
1257
  if (decorator) {
@@ -2138,7 +2156,7 @@ var IndexingContext = class {
2138
2156
  import { ParseSourceFile } from "@angular/compiler";
2139
2157
 
2140
2158
  // packages/compiler-cli/src/ngtsc/indexer/src/template.js
2141
- import { ASTWithSource, CombinedRecursiveAstVisitor, ImplicitReceiver, PropertyRead, TmplAstComponent, TmplAstDirective, TmplAstElement, TmplAstReference, TmplAstTemplate, TmplAstVariable, tmplAstVisitAll } from "@angular/compiler";
2159
+ import { ASTWithSource, CombinedRecursiveAstVisitor, ImplicitReceiver, PropertyRead, ThisReceiver, TmplAstComponent, TmplAstDirective, TmplAstElement, TmplAstReference, TmplAstTemplate, TmplAstVariable, tmplAstVisitAll } from "@angular/compiler";
2142
2160
  var TemplateVisitor = class extends CombinedRecursiveAstVisitor {
2143
2161
  boundTemplate;
2144
2162
  // Identifiers of interest found in the template.
@@ -2368,7 +2386,7 @@ var TemplateVisitor = class extends CombinedRecursiveAstVisitor {
2368
2386
  if (this.currentAstWithSource === null || this.currentAstWithSource.source === null) {
2369
2387
  return;
2370
2388
  }
2371
- if (!(ast.receiver instanceof ImplicitReceiver)) {
2389
+ if (!(ast.receiver instanceof ImplicitReceiver) && !(ast.receiver instanceof ThisReceiver)) {
2372
2390
  return;
2373
2391
  }
2374
2392
  const { absoluteOffset, source: expressionStr } = this.currentAstWithSource;
@@ -3664,7 +3682,7 @@ var SUPPORTED_DIAGNOSTIC_NAMES = /* @__PURE__ */ new Set([
3664
3682
  ]);
3665
3683
 
3666
3684
  // packages/compiler-cli/src/ngtsc/typecheck/template_semantics/src/template_semantics_checker.js
3667
- import { ASTWithSource as ASTWithSource5, ImplicitReceiver as ImplicitReceiver2, ParsedEventType as ParsedEventType2, PropertyRead as PropertyRead6, Binary as Binary3, RecursiveAstVisitor, TmplAstBoundEvent as TmplAstBoundEvent3, TmplAstLetDeclaration as TmplAstLetDeclaration2, TmplAstRecursiveVisitor, TmplAstVariable as TmplAstVariable2 } from "@angular/compiler";
3685
+ import { ASTWithSource as ASTWithSource5, ImplicitReceiver as ImplicitReceiver2, ParsedEventType as ParsedEventType2, PropertyRead as PropertyRead6, Binary as Binary3, RecursiveAstVisitor, TmplAstBoundEvent as TmplAstBoundEvent3, TmplAstLetDeclaration as TmplAstLetDeclaration2, TmplAstRecursiveVisitor, TmplAstVariable as TmplAstVariable2, ThisReceiver as ThisReceiver2 } from "@angular/compiler";
3668
3686
  import ts23 from "typescript";
3669
3687
  var TemplateSemanticsCheckerImpl = class {
3670
3688
  templateTypeChecker;
@@ -3716,7 +3734,7 @@ var ExpressionsSemanticsVisitor = class extends RecursiveAstVisitor {
3716
3734
  this.checkForIllegalWriteInTwoWayBinding(ast, context);
3717
3735
  }
3718
3736
  checkForIllegalWriteInEventBinding(ast, context) {
3719
- if (!(context instanceof TmplAstBoundEvent3) || !(ast.receiver instanceof ImplicitReceiver2)) {
3737
+ if (!this.shouldCheckForIllegalWrites(ast, context)) {
3720
3738
  return;
3721
3739
  }
3722
3740
  const target = this.templateTypeChecker.getExpressionTarget(ast, this.component);
@@ -3726,7 +3744,7 @@ var ExpressionsSemanticsVisitor = class extends RecursiveAstVisitor {
3726
3744
  }
3727
3745
  }
3728
3746
  checkForIllegalWriteInTwoWayBinding(ast, context) {
3729
- if (!(context instanceof TmplAstBoundEvent3) || context.type !== ParsedEventType2.TwoWay || !(ast.receiver instanceof ImplicitReceiver2) || ast !== unwrapAstWithSource(context.handler)) {
3747
+ if (!this.shouldCheckForIllegalWrites(ast, context) || context.type !== ParsedEventType2.TwoWay || ast !== unwrapAstWithSource(context.handler)) {
3730
3748
  return;
3731
3749
  }
3732
3750
  const target = this.templateTypeChecker.getExpressionTarget(ast, this.component);
@@ -3757,6 +3775,9 @@ var ExpressionsSemanticsVisitor = class extends RecursiveAstVisitor {
3757
3775
  }
3758
3776
  ]);
3759
3777
  }
3778
+ shouldCheckForIllegalWrites(ast, context) {
3779
+ return context instanceof TmplAstBoundEvent3 && (ast.receiver instanceof ImplicitReceiver2 || ast.receiver instanceof ThisReceiver2);
3780
+ }
3760
3781
  };
3761
3782
  function unwrapAstWithSource(ast) {
3762
3783
  return ast instanceof ASTWithSource5 ? ast.ast : ast;
@@ -214,10 +214,14 @@ var ExpressionTranslatorVisitor = class {
214
214
  }
215
215
  visitLiteralMapExpr(ast, context) {
216
216
  const properties = ast.entries.map((entry) => {
217
- return {
217
+ return entry instanceof o.LiteralMapPropertyAssignment ? {
218
+ kind: "property",
218
219
  propertyName: entry.key,
219
220
  quoted: entry.quoted,
220
221
  value: entry.value.visitExpression(this, context)
222
+ } : {
223
+ kind: "spread",
224
+ expression: entry.expression.visitExpression(this, context)
221
225
  };
222
226
  });
223
227
  return this.setSourceMapRange(this.factory.createObjectLiteral(properties), ast.sourceSpan);
@@ -228,6 +232,10 @@ var ExpressionTranslatorVisitor = class {
228
232
  visitTemplateLiteralElementExpr(ast, context) {
229
233
  throw new Error("Method not implemented");
230
234
  }
235
+ visitSpreadElementExpr(ast, context) {
236
+ const expression = ast.expression.visitExpression(this, context);
237
+ return this.setSourceMapRange(this.factory.createSpreadElement(expression), ast.sourceSpan);
238
+ }
231
239
  visitWrappedNodeExpr(ast, _context) {
232
240
  this.recordWrappedNode(ast);
233
241
  return ast.node;
@@ -5,7 +5,7 @@
5
5
  import {
6
6
  Context,
7
7
  ExpressionTranslatorVisitor
8
- } from "./chunk-LS5RJ5CS.js";
8
+ } from "./chunk-FROPOOFC.js";
9
9
  import {
10
10
  LogicalProjectPath,
11
11
  absoluteFrom,
@@ -4434,12 +4434,13 @@ var StaticInterpreter = class {
4434
4434
  return res;
4435
4435
  }
4436
4436
  visitTypeQuery(node, context) {
4437
- if (!ts16.isIdentifier(node.exprName)) {
4437
+ const exprName = ts16.isQualifiedName(node.exprName) ? node.exprName.right : node.exprName;
4438
+ if (!ts16.isIdentifier(exprName)) {
4438
4439
  return DynamicValue.fromUnknown(node);
4439
4440
  }
4440
- const decl = this.host.getDeclarationOfIdentifier(node.exprName);
4441
+ const decl = this.host.getDeclarationOfIdentifier(exprName);
4441
4442
  if (decl === null) {
4442
- return DynamicValue.fromUnknownIdentifier(node.exprName);
4443
+ return DynamicValue.fromUnknownIdentifier(exprName);
4443
4444
  }
4444
4445
  const declContext = { ...context, ...joinModuleContext(context, node, decl) };
4445
4446
  return this.visitDeclaration(decl.node, declContext);
@@ -5348,6 +5349,9 @@ var TypeTranslatorVisitor = class {
5348
5349
  }
5349
5350
  visitLiteralMapExpr(ast, context) {
5350
5351
  const entries = ast.entries.map((entry) => {
5352
+ if (entry instanceof o.LiteralMapSpreadAssignment) {
5353
+ throw new Error("Spread is not supported in this context");
5354
+ }
5351
5355
  const { key, quoted } = entry;
5352
5356
  const type = this.translateExpression(entry.value, context);
5353
5357
  return ts25.factory.createPropertySignature(
@@ -5396,6 +5400,10 @@ var TypeTranslatorVisitor = class {
5396
5400
  visitParenthesizedExpr(ast, context) {
5397
5401
  throw new Error("Method not implemented.");
5398
5402
  }
5403
+ visitSpreadElementExpr(ast, context) {
5404
+ const typeNode = this.translateExpression(ast.expression, context);
5405
+ return ts25.factory.createRestTypeNode(typeNode);
5406
+ }
5399
5407
  translateType(type, context) {
5400
5408
  const typeNode = type.visitType(this, context);
5401
5409
  if (!ts25.isTypeNode(typeNode)) {
@@ -5565,10 +5573,16 @@ var TypeScriptAstFactory = class {
5565
5573
  return ts26.factory.createNewExpression(expression, void 0, args);
5566
5574
  }
5567
5575
  createObjectLiteral(properties) {
5568
- return ts26.factory.createObjectLiteralExpression(properties.map((prop) => ts26.factory.createPropertyAssignment(prop.quoted ? ts26.factory.createStringLiteral(prop.propertyName) : ts26.factory.createIdentifier(prop.propertyName), prop.value)));
5576
+ return ts26.factory.createObjectLiteralExpression(properties.map((prop) => {
5577
+ if (prop.kind === "spread") {
5578
+ return ts26.factory.createSpreadAssignment(prop.expression);
5579
+ }
5580
+ return ts26.factory.createPropertyAssignment(prop.quoted ? ts26.factory.createStringLiteral(prop.propertyName) : ts26.factory.createIdentifier(prop.propertyName), prop.value);
5581
+ }));
5569
5582
  }
5570
5583
  createParenthesizedExpression = ts26.factory.createParenthesizedExpression;
5571
5584
  createPropertyAccess = ts26.factory.createPropertyAccessExpression;
5585
+ createSpreadElement = ts26.factory.createSpreadElement;
5572
5586
  createReturnStatement(expression) {
5573
5587
  return ts26.factory.createReturnStatement(expression ?? void 0);
5574
5588
  }
@@ -9595,7 +9609,7 @@ function parseTemplateDeclaration(node, decorator, component, containingFile, ev
9595
9609
  resolvedTemplateUrl: containingFile
9596
9610
  };
9597
9611
  } else {
9598
- throw new FatalDiagnosticError(ErrorCode.COMPONENT_MISSING_TEMPLATE, decorator.node, "component is missing a template");
9612
+ throw new FatalDiagnosticError(ErrorCode.COMPONENT_MISSING_TEMPLATE, decorator.node, "@Component is missing a template. Add either a `template` or `templateUrl`");
9599
9613
  }
9600
9614
  }
9601
9615
  function preloadAndParseTemplate(evaluator, resourceLoader, depTracker, preanalyzeTemplateCache, node, decorator, component, containingFile, defaultPreserveWhitespaces, options, compilationMode) {
@@ -11598,7 +11612,7 @@ function getTypeCheckId(clazz) {
11598
11612
  }
11599
11613
 
11600
11614
  // packages/compiler-cli/src/ngtsc/typecheck/src/completion.js
11601
- import { EmptyExpr, ImplicitReceiver, PropertyRead, SafePropertyRead, TmplAstLetDeclaration, TmplAstReference, TmplAstTextAttribute } from "@angular/compiler";
11615
+ import { EmptyExpr, ImplicitReceiver, PropertyRead, SafePropertyRead, ThisReceiver, TmplAstLetDeclaration, TmplAstReference, TmplAstTextAttribute } from "@angular/compiler";
11602
11616
  import ts51 from "typescript";
11603
11617
  var CompletionEngine = class {
11604
11618
  tcb;
@@ -11677,7 +11691,7 @@ var CompletionEngine = class {
11677
11691
  };
11678
11692
  }
11679
11693
  }
11680
- if (node instanceof PropertyRead && node.receiver instanceof ImplicitReceiver) {
11694
+ if (node instanceof PropertyRead && (node.receiver instanceof ImplicitReceiver || node.receiver instanceof ThisReceiver)) {
11681
11695
  const nodeLocation = findFirstMatchingNode(this.tcb, {
11682
11696
  filter: ts51.isPropertyAccessExpression,
11683
11697
  withSpan: node.sourceSpan
@@ -13082,7 +13096,7 @@ var TypeParameterEmitter = class {
13082
13096
  };
13083
13097
 
13084
13098
  // packages/compiler-cli/src/ngtsc/typecheck/src/host_bindings.js
13085
- import { BindingType, CssSelector as CssSelector2, makeBindingParser, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstHostElement, AbsoluteSourceSpan as AbsoluteSourceSpan2, ParseSpan, PropertyRead as PropertyRead2, ParsedEventType, Call, ThisReceiver, KeyedRead, LiteralPrimitive, RecursiveAstVisitor, ASTWithName, SafeCall, ImplicitReceiver as ImplicitReceiver2 } from "@angular/compiler";
13099
+ import { BindingType, CssSelector as CssSelector2, makeBindingParser, TmplAstBoundAttribute, TmplAstBoundEvent, TmplAstHostElement, AbsoluteSourceSpan as AbsoluteSourceSpan2, ParseSpan, PropertyRead as PropertyRead2, ParsedEventType, Call, ThisReceiver as ThisReceiver2, KeyedRead, LiteralPrimitive, RecursiveAstVisitor, ASTWithName, SafeCall, ImplicitReceiver as ImplicitReceiver2 } from "@angular/compiler";
13086
13100
  import ts54 from "typescript";
13087
13101
  var GUARD_COMMENT_TEXT = "hostBindingsBlockGuard";
13088
13102
  function createHostElement(type, selector, sourceNode, literal4, bindingDecorators, listenerDecorators) {
@@ -13180,7 +13194,7 @@ function createNodeFromBindingDecorator(decorator, bindings) {
13180
13194
  }
13181
13195
  const span = new ParseSpan(-1, -1);
13182
13196
  const propertyStart = property.getStart();
13183
- const receiver = new ThisReceiver(span, new AbsoluteSourceSpan2(propertyStart, propertyStart));
13197
+ const receiver = new ThisReceiver2(span, new AbsoluteSourceSpan2(propertyStart, propertyStart));
13184
13198
  const nameSpan = new AbsoluteSourceSpan2(propertyName.getStart(), propertyName.getEnd());
13185
13199
  const read = ts54.isIdentifier(propertyName) ? new PropertyRead2(span, nameSpan, nameSpan, receiver, propertyName.text) : new KeyedRead(span, nameSpan, receiver, new LiteralPrimitive(span, nameSpan, propertyName.text));
13186
13200
  const { attrName, type } = inferBoundAttribute(nameNode.text);
@@ -13198,7 +13212,7 @@ function createNodeFromListenerDecorator(decorator, parser, listeners) {
13198
13212
  const span = new ParseSpan(-1, -1);
13199
13213
  const argNodes = [];
13200
13214
  const methodStart = method.getStart();
13201
- const methodReceiver = new ThisReceiver(span, new AbsoluteSourceSpan2(methodStart, methodStart));
13215
+ const methodReceiver = new ThisReceiver2(span, new AbsoluteSourceSpan2(methodStart, methodStart));
13202
13216
  const nameSpan = new AbsoluteSourceSpan2(method.name.getStart(), method.name.getEnd());
13203
13217
  const receiver = ts54.isIdentifier(method.name) ? new PropertyRead2(span, nameSpan, nameSpan, methodReceiver, method.name.text) : new KeyedRead(span, nameSpan, methodReceiver, new LiteralPrimitive(span, nameSpan, method.name.text));
13204
13218
  if (args.length > 1 && ts54.isArrayLiteralExpression(args[1])) {
@@ -14125,7 +14139,7 @@ import { TmplAstBoundAttribute as TmplAstBoundAttribute3, TmplAstTemplate } from
14125
14139
  import ts65 from "typescript";
14126
14140
 
14127
14141
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/expression.js
14128
- import { Binary, BindingPipe, Call as Call3, ImplicitReceiver as ImplicitReceiver3, PropertyRead as PropertyRead4, R3Identifiers as R3Identifiers4, SafeCall as SafeCall2, SafePropertyRead as SafePropertyRead3, ThisReceiver as ThisReceiver2, TmplAstLetDeclaration as TmplAstLetDeclaration2 } from "@angular/compiler";
14142
+ import { Binary, BindingPipe, Call as Call3, ImplicitReceiver as ImplicitReceiver3, PropertyRead as PropertyRead4, R3Identifiers as R3Identifiers4, SafeCall as SafeCall2, SafePropertyRead as SafePropertyRead3, ThisReceiver as ThisReceiver3, TmplAstLetDeclaration as TmplAstLetDeclaration2 } from "@angular/compiler";
14129
14143
  import ts64 from "typescript";
14130
14144
 
14131
14145
  // packages/compiler-cli/src/ngtsc/typecheck/src/expression.js
@@ -14260,9 +14274,13 @@ var AstTranslator = class {
14260
14274
  return node;
14261
14275
  }
14262
14276
  visitLiteralMap(ast) {
14263
- const properties = ast.keys.map(({ key }, idx) => {
14277
+ const properties = ast.keys.map((key, idx) => {
14264
14278
  const value = this.translate(ast.values[idx]);
14265
- return ts63.factory.createPropertyAssignment(ts63.factory.createStringLiteral(key), value);
14279
+ if (key.kind === "property") {
14280
+ return ts63.factory.createPropertyAssignment(ts63.factory.createStringLiteral(key.key), value);
14281
+ } else {
14282
+ return ts63.factory.createSpreadAssignment(value);
14283
+ }
14266
14284
  });
14267
14285
  const literal4 = ts63.factory.createObjectLiteralExpression(properties, true);
14268
14286
  const node = this.config.strictLiteralTypes ? literal4 : tsCastToAny(literal4);
@@ -14418,6 +14436,12 @@ var AstTranslator = class {
14418
14436
  visitParenthesizedExpression(ast) {
14419
14437
  return ts63.factory.createParenthesizedExpression(this.translate(ast.expression));
14420
14438
  }
14439
+ visitSpreadElement(ast) {
14440
+ const expression = wrapForDiagnostics(this.translate(ast.expression));
14441
+ const node = ts63.factory.createSpreadElement(expression);
14442
+ addParseSpanInfo(node, ast.sourceSpan);
14443
+ return node;
14444
+ }
14421
14445
  convertToSafeCall(ast, expr, args) {
14422
14446
  if (this.config.strictSafeNavigationTypes) {
14423
14447
  const call = ts63.factory.createCallExpression(ts63.factory.createNonNullExpression(expr), void 0, args);
@@ -14441,40 +14465,40 @@ var VeSafeLhsInferenceBugDetector = class _VeSafeLhsInferenceBugDetector {
14441
14465
  visitBinary(ast) {
14442
14466
  return ast.left.visit(this) || ast.right.visit(this);
14443
14467
  }
14444
- visitChain(ast) {
14468
+ visitChain() {
14445
14469
  return false;
14446
14470
  }
14447
14471
  visitConditional(ast) {
14448
14472
  return ast.condition.visit(this) || ast.trueExp.visit(this) || ast.falseExp.visit(this);
14449
14473
  }
14450
- visitCall(ast) {
14474
+ visitCall() {
14451
14475
  return true;
14452
14476
  }
14453
- visitSafeCall(ast) {
14477
+ visitSafeCall() {
14454
14478
  return false;
14455
14479
  }
14456
- visitImplicitReceiver(ast) {
14480
+ visitImplicitReceiver() {
14457
14481
  return false;
14458
14482
  }
14459
- visitThisReceiver(ast) {
14483
+ visitThisReceiver() {
14460
14484
  return false;
14461
14485
  }
14462
14486
  visitInterpolation(ast) {
14463
14487
  return ast.expressions.some((exp) => exp.visit(this));
14464
14488
  }
14465
- visitKeyedRead(ast) {
14489
+ visitKeyedRead() {
14466
14490
  return false;
14467
14491
  }
14468
- visitLiteralArray(ast) {
14492
+ visitLiteralArray() {
14469
14493
  return true;
14470
14494
  }
14471
- visitLiteralMap(ast) {
14495
+ visitLiteralMap() {
14472
14496
  return true;
14473
14497
  }
14474
- visitLiteralPrimitive(ast) {
14498
+ visitLiteralPrimitive() {
14475
14499
  return false;
14476
14500
  }
14477
- visitPipe(ast) {
14501
+ visitPipe() {
14478
14502
  return true;
14479
14503
  }
14480
14504
  visitPrefixNot(ast) {
@@ -14489,30 +14513,33 @@ var VeSafeLhsInferenceBugDetector = class _VeSafeLhsInferenceBugDetector {
14489
14513
  visitNonNullAssert(ast) {
14490
14514
  return ast.expression.visit(this);
14491
14515
  }
14492
- visitPropertyRead(ast) {
14516
+ visitPropertyRead() {
14493
14517
  return false;
14494
14518
  }
14495
- visitSafePropertyRead(ast) {
14519
+ visitSafePropertyRead() {
14496
14520
  return false;
14497
14521
  }
14498
- visitSafeKeyedRead(ast) {
14522
+ visitSafeKeyedRead() {
14499
14523
  return false;
14500
14524
  }
14501
- visitTemplateLiteral(ast, context) {
14525
+ visitTemplateLiteral() {
14502
14526
  return false;
14503
14527
  }
14504
- visitTemplateLiteralElement(ast, context) {
14528
+ visitTemplateLiteralElement() {
14505
14529
  return false;
14506
14530
  }
14507
- visitTaggedTemplateLiteral(ast, context) {
14531
+ visitTaggedTemplateLiteral() {
14508
14532
  return false;
14509
14533
  }
14510
- visitParenthesizedExpression(ast, context) {
14534
+ visitParenthesizedExpression(ast) {
14511
14535
  return ast.expression.visit(this);
14512
14536
  }
14513
- visitRegularExpressionLiteral(ast, context) {
14537
+ visitRegularExpressionLiteral() {
14514
14538
  return false;
14515
14539
  }
14540
+ visitSpreadElement(ast) {
14541
+ return ast.expression.visit(this);
14542
+ }
14516
14543
  };
14517
14544
 
14518
14545
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/expression.js
@@ -14560,7 +14587,7 @@ var TcbExpressionTranslator = class {
14560
14587
  * context). This method assists in resolving those.
14561
14588
  */
14562
14589
  resolve(ast) {
14563
- if (ast instanceof PropertyRead4 && ast.receiver instanceof ImplicitReceiver3 && !(ast.receiver instanceof ThisReceiver2)) {
14590
+ if (ast instanceof PropertyRead4 && ast.receiver instanceof ImplicitReceiver3) {
14564
14591
  const target = this.tcb.boundTarget.getExpressionTarget(ast);
14565
14592
  const targetExpression = target === null ? null : this.getTargetNodeExpression(target, ast);
14566
14593
  if (target instanceof TmplAstLetDeclaration2 && !this.isValidLetDeclarationAccess(target, ast)) {
@@ -14570,7 +14597,7 @@ var TcbExpressionTranslator = class {
14570
14597
  }
14571
14598
  }
14572
14599
  return targetExpression;
14573
- } else if (ast instanceof Binary && Binary.isAssignmentOperation(ast.operation) && ast.left instanceof PropertyRead4 && ast.left.receiver instanceof ImplicitReceiver3) {
14600
+ } else if (ast instanceof Binary && Binary.isAssignmentOperation(ast.operation) && ast.left instanceof PropertyRead4 && (ast.left.receiver instanceof ImplicitReceiver3 || ast.left.receiver instanceof ThisReceiver3)) {
14574
14601
  const read = ast.left;
14575
14602
  const target = this.tcb.boundTarget.getExpressionTarget(read);
14576
14603
  if (target === null) {
@@ -14585,7 +14612,7 @@ var TcbExpressionTranslator = class {
14585
14612
  this.tcb.oobRecorder.illegalWriteToLetDeclaration(this.tcb.id, read, target);
14586
14613
  }
14587
14614
  return result;
14588
- } else if (ast instanceof ImplicitReceiver3) {
14615
+ } else if (ast instanceof ImplicitReceiver3 || ast instanceof ThisReceiver3) {
14589
14616
  return ts64.factory.createThis();
14590
14617
  } else if (ast instanceof BindingPipe) {
14591
14618
  const expr = this.translate(ast.exp);
@@ -14617,7 +14644,7 @@ var TcbExpressionTranslator = class {
14617
14644
  addParseSpanInfo(result, ast.sourceSpan);
14618
14645
  return result;
14619
14646
  } else if ((ast instanceof Call3 || ast instanceof SafeCall2) && (ast.receiver instanceof PropertyRead4 || ast.receiver instanceof SafePropertyRead3)) {
14620
- if (ast.receiver.receiver instanceof ImplicitReceiver3 && !(ast.receiver.receiver instanceof ThisReceiver2) && ast.receiver.name === "$any" && ast.args.length === 1) {
14647
+ if (ast.receiver.receiver instanceof ImplicitReceiver3 && ast.receiver.name === "$any" && ast.args.length === 1) {
14621
14648
  const expr = this.translate(ast.args[0]);
14622
14649
  const exprAsAny = ts64.factory.createAsExpression(expr, ts64.factory.createKeywordTypeNode(ts64.SyntaxKind.AnyKeyword));
14623
14650
  const result = ts64.factory.createParenthesizedExpression(exprAsAny);
@@ -15018,33 +15045,53 @@ var TcbSwitchOp = class extends TcbOp {
15018
15045
  }
15019
15046
  execute() {
15020
15047
  const switchExpression = tcbExpression(this.block.expression, this.tcb, this.scope);
15021
- const clauses = this.block.cases.map((current) => {
15048
+ const clauses = this.block.groups.flatMap((current) => {
15022
15049
  const checkBody = this.tcb.env.config.checkControlFlowBodies;
15023
15050
  const clauseScope = this.scope.createChildScope(this.scope, null, checkBody ? current.children : [], checkBody ? this.generateGuard(current, switchExpression) : null);
15024
15051
  const statements = [...clauseScope.render(), ts70.factory.createBreakStatement()];
15025
- return current.expression === null ? ts70.factory.createDefaultClause(statements) : ts70.factory.createCaseClause(tcbExpression(current.expression, this.tcb, clauseScope), statements);
15052
+ return current.cases.map((switchCase, index) => {
15053
+ const statementsForCase = index === current.cases.length - 1 ? statements : [];
15054
+ return switchCase.expression === null ? ts70.factory.createDefaultClause(statementsForCase) : ts70.factory.createCaseClause(tcbExpression(switchCase.expression, this.tcb, this.scope), statementsForCase);
15055
+ });
15026
15056
  });
15027
15057
  this.scope.addStatement(ts70.factory.createSwitchStatement(switchExpression, ts70.factory.createCaseBlock(clauses)));
15028
15058
  return null;
15029
15059
  }
15030
- generateGuard(node, switchValue) {
15031
- if (node.expression !== null) {
15032
- const expression = tcbExpression(node.expression, this.tcb, this.scope);
15033
- markIgnoreDiagnostics(expression);
15034
- return ts70.factory.createBinaryExpression(switchValue, ts70.SyntaxKind.EqualsEqualsEqualsToken, expression);
15060
+ generateGuard(group, switchValue) {
15061
+ const hasDefault = group.cases.some((c) => c.expression === null);
15062
+ if (!hasDefault) {
15063
+ let guard2 = null;
15064
+ for (const switchCase of group.cases) {
15065
+ if (switchCase.expression !== null) {
15066
+ const expression = tcbExpression(switchCase.expression, this.tcb, this.scope);
15067
+ markIgnoreDiagnostics(expression);
15068
+ const comparison = ts70.factory.createBinaryExpression(switchValue, ts70.SyntaxKind.EqualsEqualsEqualsToken, expression);
15069
+ if (guard2 === null) {
15070
+ guard2 = comparison;
15071
+ } else {
15072
+ guard2 = ts70.factory.createBinaryExpression(guard2, ts70.SyntaxKind.BarBarToken, comparison);
15073
+ }
15074
+ }
15075
+ }
15076
+ return guard2;
15035
15077
  }
15036
15078
  let guard = null;
15037
- for (const current of this.block.cases) {
15038
- if (current.expression === null) {
15079
+ for (const currentGroup of this.block.groups) {
15080
+ if (currentGroup === group) {
15039
15081
  continue;
15040
15082
  }
15041
- const expression = tcbExpression(current.expression, this.tcb, this.scope);
15042
- markIgnoreDiagnostics(expression);
15043
- const comparison = ts70.factory.createBinaryExpression(switchValue, ts70.SyntaxKind.ExclamationEqualsEqualsToken, expression);
15044
- if (guard === null) {
15045
- guard = comparison;
15046
- } else {
15047
- guard = ts70.factory.createBinaryExpression(guard, ts70.SyntaxKind.AmpersandAmpersandToken, comparison);
15083
+ for (const switchCase of currentGroup.cases) {
15084
+ if (switchCase.expression === null) {
15085
+ continue;
15086
+ }
15087
+ const expression = tcbExpression(switchCase.expression, this.tcb, this.scope);
15088
+ markIgnoreDiagnostics(expression);
15089
+ const comparison = ts70.factory.createBinaryExpression(switchValue, ts70.SyntaxKind.ExclamationEqualsEqualsToken, expression);
15090
+ if (guard === null) {
15091
+ guard = comparison;
15092
+ } else {
15093
+ guard = ts70.factory.createBinaryExpression(guard, ts70.SyntaxKind.AmpersandAmpersandToken, comparison);
15094
+ }
15048
15095
  }
15049
15096
  }
15050
15097
  return guard;
@@ -15052,7 +15099,7 @@ var TcbSwitchOp = class extends TcbOp {
15052
15099
  };
15053
15100
 
15054
15101
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/for_block.js
15055
- import { ImplicitReceiver as ImplicitReceiver4, PropertyRead as PropertyRead5, TmplAstVariable } from "@angular/compiler";
15102
+ import { ImplicitReceiver as ImplicitReceiver4, PropertyRead as PropertyRead5, ThisReceiver as ThisReceiver4, TmplAstVariable } from "@angular/compiler";
15056
15103
  import ts71 from "typescript";
15057
15104
  var TcbForOfOp = class extends TcbOp {
15058
15105
  tcb;
@@ -15100,7 +15147,7 @@ var TcbForLoopTrackTranslator = class extends TcbExpressionTranslator {
15100
15147
  }
15101
15148
  }
15102
15149
  resolve(ast) {
15103
- if (ast instanceof PropertyRead5 && ast.receiver instanceof ImplicitReceiver4) {
15150
+ if (ast instanceof PropertyRead5 && (ast.receiver instanceof ImplicitReceiver4 || ast.receiver instanceof ThisReceiver4)) {
15104
15151
  const target = this.tcb.boundTarget.getExpressionTarget(ast);
15105
15152
  if (target !== null && (!(target instanceof TmplAstVariable) || !this.allowedVariables.has(target))) {
15106
15153
  this.tcb.oobRecorder.illegalForLoopTrackAccess(this.tcb.id, this.block, ast);
@@ -15149,10 +15196,13 @@ var formControlInputFields = [
15149
15196
  // Should be kept in sync with the `FormUiControl` bindings,
15150
15197
  // defined in `packages/forms/signals/src/api/control.ts`.
15151
15198
  "errors",
15152
- "invalid",
15199
+ "dirty",
15153
15200
  "disabled",
15154
15201
  "disabledReasons",
15202
+ "hidden",
15203
+ "invalid",
15155
15204
  "name",
15205
+ "pending",
15156
15206
  "readonly",
15157
15207
  "touched",
15158
15208
  "max",
@@ -15200,7 +15250,7 @@ var TcbNativeFieldOp = class extends TcbOp {
15200
15250
  }
15201
15251
  execute() {
15202
15252
  const inputs = this.node instanceof TmplAstHostElement2 ? this.node.bindings : this.node.inputs;
15203
- const fieldBinding = inputs.find((input) => input.type === BindingType3.Property && input.name === "field") ?? null;
15253
+ const fieldBinding = inputs.find((input) => input.type === BindingType3.Property && (input.name === "field" || input.name === "formField")) ?? null;
15204
15254
  if (fieldBinding === null) {
15205
15255
  return null;
15206
15256
  }
@@ -15279,17 +15329,17 @@ var TcbNativeRadioButtonFieldOp = class extends TcbNativeFieldOp {
15279
15329
  return null;
15280
15330
  }
15281
15331
  };
15282
- function expandBoundAttributesForField(directive, node, customFieldType) {
15283
- const fieldBinding = node.inputs.find((input) => input.type === BindingType3.Property && input.name === "field");
15332
+ function expandBoundAttributesForField(directive, node, customFormControlType) {
15333
+ const fieldBinding = node.inputs.find((input) => input.type === BindingType3.Property && (input.name === "field" || input.name === "formField"));
15284
15334
  if (!fieldBinding) {
15285
15335
  return null;
15286
15336
  }
15287
15337
  let boundInputs = null;
15288
15338
  let primaryInput;
15289
- if (customFieldType === "value") {
15290
- primaryInput = getSyntheticFieldBoundInput(directive, "value", "value", fieldBinding, customFieldType);
15291
- } else if (customFieldType === "checkbox") {
15292
- primaryInput = getSyntheticFieldBoundInput(directive, "checked", "value", fieldBinding, customFieldType);
15339
+ if (customFormControlType === "value") {
15340
+ primaryInput = getSyntheticFieldBoundInput(directive, "value", "value", fieldBinding, customFormControlType);
15341
+ } else if (customFormControlType === "checkbox") {
15342
+ primaryInput = getSyntheticFieldBoundInput(directive, "checked", "value", fieldBinding, customFormControlType);
15293
15343
  } else {
15294
15344
  primaryInput = null;
15295
15345
  }
@@ -15298,7 +15348,7 @@ function expandBoundAttributesForField(directive, node, customFieldType) {
15298
15348
  boundInputs.push(primaryInput);
15299
15349
  }
15300
15350
  for (const name of formControlInputFields) {
15301
- const input = getSyntheticFieldBoundInput(directive, name, name, fieldBinding, customFieldType);
15351
+ const input = getSyntheticFieldBoundInput(directive, name, name, fieldBinding, customFormControlType);
15302
15352
  if (input !== null) {
15303
15353
  boundInputs ??= [];
15304
15354
  boundInputs.push(input);
@@ -15307,7 +15357,7 @@ function expandBoundAttributesForField(directive, node, customFieldType) {
15307
15357
  return boundInputs;
15308
15358
  }
15309
15359
  function isFieldDirective(meta) {
15310
- if (meta.name !== "Field") {
15360
+ if (meta.name !== "Field" && meta.name !== "FormField") {
15311
15361
  return false;
15312
15362
  }
15313
15363
  if (meta.ref.bestGuessOwningModule?.specifier === "@angular/forms/signals") {
@@ -15390,7 +15440,19 @@ function extractFieldValue(expression, tcb, scope) {
15390
15440
  return ts73.factory.createCallExpression(ts73.factory.createPropertyAccessExpression(innerCall, "value"), void 0, void 0);
15391
15441
  }
15392
15442
  function hasModelInput(name, meta) {
15393
- return !!meta.inputs.getByBindingPropertyName(name)?.some((v) => v.isSignal) && meta.outputs.hasBindingPropertyName(name + "Change");
15443
+ return meta.inputs.hasBindingPropertyName(name) && meta.outputs.hasBindingPropertyName(name + "Change");
15444
+ }
15445
+ function isFormControl(allDirectiveMatches) {
15446
+ let result = false;
15447
+ for (const match of allDirectiveMatches) {
15448
+ if (match.inputs.hasBindingPropertyName("field")) {
15449
+ if (!isFieldDirective(match)) {
15450
+ return false;
15451
+ }
15452
+ result = true;
15453
+ }
15454
+ }
15455
+ return result;
15394
15456
  }
15395
15457
 
15396
15458
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/bindings.js
@@ -15478,14 +15540,16 @@ var TcbDirectiveInputsOp = class extends TcbOp {
15478
15540
  scope;
15479
15541
  node;
15480
15542
  dir;
15481
- customControlType;
15482
- constructor(tcb, scope, node, dir, customControlType) {
15543
+ isFormControl;
15544
+ customFormControlType;
15545
+ constructor(tcb, scope, node, dir, isFormControl2 = false, customFormControlType) {
15483
15546
  super();
15484
15547
  this.tcb = tcb;
15485
15548
  this.scope = scope;
15486
15549
  this.node = node;
15487
15550
  this.dir = dir;
15488
- this.customControlType = customControlType;
15551
+ this.isFormControl = isFormControl2;
15552
+ this.customFormControlType = customFormControlType;
15489
15553
  }
15490
15554
  get optional() {
15491
15555
  return false;
@@ -15494,9 +15558,11 @@ var TcbDirectiveInputsOp = class extends TcbOp {
15494
15558
  let dirId = null;
15495
15559
  const seenRequiredInputs = /* @__PURE__ */ new Set();
15496
15560
  const boundAttrs = getBoundAttributes(this.dir, this.node);
15497
- if (this.customControlType !== null) {
15561
+ if (this.customFormControlType !== null) {
15498
15562
  checkUnsupportedFieldBindings(this.node, customFormControlBannedInputFields, this.tcb);
15499
- const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customControlType);
15563
+ }
15564
+ if (this.customFormControlType !== null || this.isFormControl) {
15565
+ const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customFormControlType);
15500
15566
  if (additionalBindings !== null) {
15501
15567
  boundAttrs.push(...additionalBindings);
15502
15568
  }
@@ -15698,7 +15764,7 @@ var TcbDomSchemaCheckerOp = class extends TcbOp {
15698
15764
  };
15699
15765
 
15700
15766
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/events.js
15701
- import { ImplicitReceiver as ImplicitReceiver5, ParsedEventType as ParsedEventType2, PropertyRead as PropertyRead7, ThisReceiver as ThisReceiver3, TmplAstElement as TmplAstElement6 } from "@angular/compiler";
15767
+ import { ImplicitReceiver as ImplicitReceiver5, ParsedEventType as ParsedEventType2, PropertyRead as PropertyRead7, TmplAstElement as TmplAstElement6 } from "@angular/compiler";
15702
15768
  import ts76 from "typescript";
15703
15769
  var EVENT_PARAMETER = "$event";
15704
15770
  function tcbEventHandlerExpression(ast, tcb, scope) {
@@ -15858,7 +15924,7 @@ var TcbUnclaimedOutputsOp = class extends TcbOp {
15858
15924
  };
15859
15925
  var TcbEventHandlerTranslator = class extends TcbExpressionTranslator {
15860
15926
  resolve(ast) {
15861
- if (ast instanceof PropertyRead7 && ast.receiver instanceof ImplicitReceiver5 && !(ast.receiver instanceof ThisReceiver3) && ast.name === EVENT_PARAMETER) {
15927
+ if (ast instanceof PropertyRead7 && ast.receiver instanceof ImplicitReceiver5 && ast.name === EVENT_PARAMETER) {
15862
15928
  const event = ts76.factory.createIdentifier(EVENT_PARAMETER);
15863
15929
  addParseSpanInfo(event, ast.nameSpan);
15864
15930
  return event;
@@ -15999,14 +16065,14 @@ var TcbDirectiveCtorOp = class extends TcbOp {
15999
16065
  scope;
16000
16066
  node;
16001
16067
  dir;
16002
- customControlType;
16003
- constructor(tcb, scope, node, dir, customControlType) {
16068
+ customFormControlType;
16069
+ constructor(tcb, scope, node, dir, customFormControlType) {
16004
16070
  super();
16005
16071
  this.tcb = tcb;
16006
16072
  this.scope = scope;
16007
16073
  this.node = node;
16008
16074
  this.dir = dir;
16009
- this.customControlType = customControlType;
16075
+ this.customFormControlType = customFormControlType;
16010
16076
  }
16011
16077
  get optional() {
16012
16078
  return true;
@@ -16022,8 +16088,8 @@ var TcbDirectiveCtorOp = class extends TcbOp {
16022
16088
  } else {
16023
16089
  span = this.node.startSourceSpan || this.node.sourceSpan;
16024
16090
  boundAttrs = getBoundAttributes(this.dir, this.node);
16025
- if (this.customControlType !== null) {
16026
- const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customControlType);
16091
+ if (this.customFormControlType !== null) {
16092
+ const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customFormControlType);
16027
16093
  if (additionalBindings !== null) {
16028
16094
  boundAttrs.push(...additionalBindings);
16029
16095
  }
@@ -16171,7 +16237,7 @@ var TcbControlFlowContentProjectionOp = class extends TcbOp {
16171
16237
  }
16172
16238
  }
16173
16239
  } else if (child instanceof TmplAstSwitchBlock) {
16174
- for (const current of child.cases) {
16240
+ for (const current of child.groups) {
16175
16241
  if (this.shouldCheck(current)) {
16176
16242
  result.push(current);
16177
16243
  }
@@ -16720,15 +16786,16 @@ var Scope = class _Scope {
16720
16786
  }
16721
16787
  }
16722
16788
  appendDirectiveInputs(dir, node, dirMap, allDirectiveMatches) {
16723
- const customFieldType = allDirectiveMatches.some(isFieldDirective) ? getCustomFieldDirectiveType(dir) : null;
16724
- const directiveOp = this.getDirectiveOp(dir, node, customFieldType);
16789
+ const nodeIsFormControl = isFormControl(allDirectiveMatches);
16790
+ const customFormControlType = nodeIsFormControl ? getCustomFieldDirectiveType(dir) : null;
16791
+ const directiveOp = this.getDirectiveOp(dir, node, customFormControlType);
16725
16792
  const dirIndex = this.opQueue.push(directiveOp) - 1;
16726
16793
  dirMap.set(dir, dirIndex);
16727
16794
  if (isNativeField(dir, node, allDirectiveMatches)) {
16728
16795
  const inputType = node.name === "input" && node.attributes.find((attr) => attr.name === "type")?.value || null;
16729
16796
  this.opQueue.push(inputType === "radio" ? new TcbNativeRadioButtonFieldOp(this.tcb, this, node) : new TcbNativeFieldOp(this.tcb, this, node, inputType));
16730
16797
  }
16731
- this.opQueue.push(new TcbDirectiveInputsOp(this.tcb, this, node, dir, customFieldType));
16798
+ this.opQueue.push(new TcbDirectiveInputsOp(this.tcb, this, node, dir, nodeIsFormControl, customFormControlType));
16732
16799
  }
16733
16800
  getDirectiveOp(dir, node, customFieldType) {
16734
16801
  const dirRef = dir.ref;
@@ -20482,8 +20549,12 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
20482
20549
  const diagnostics = [];
20483
20550
  for (let i = 0; i < imports.length; i++) {
20484
20551
  const ref = imports[i];
20552
+ let refExpr = expr;
20553
+ if (ts90.isArrayLiteralExpression(expr) && expr.elements.length === imports.length && !expr.elements.some(ts90.isSpreadAssignment)) {
20554
+ refExpr = expr.elements[i];
20555
+ }
20485
20556
  if (Array.isArray(ref)) {
20486
- const { imports: childImports, diagnostics: childDiagnostics } = validateAndFlattenComponentImports(ref, expr, isDeferred);
20557
+ const { imports: childImports, diagnostics: childDiagnostics } = validateAndFlattenComponentImports(ref, refExpr, isDeferred);
20487
20558
  flattened.push(...childImports);
20488
20559
  diagnostics.push(...childDiagnostics);
20489
20560
  } else if (ref instanceof Reference) {
@@ -20501,11 +20572,11 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
20501
20572
  } else {
20502
20573
  let diagnosticNode;
20503
20574
  let diagnosticValue;
20504
- if (ref instanceof DynamicValue) {
20575
+ if (ref instanceof DynamicValue && isWithinExpression(ref.node, expr)) {
20505
20576
  diagnosticNode = ref.node;
20506
20577
  diagnosticValue = ref;
20507
- } else if (ts90.isArrayLiteralExpression(expr) && expr.elements.length === imports.length && !expr.elements.some(ts90.isSpreadAssignment) && !imports.some(Array.isArray)) {
20508
- diagnosticNode = expr.elements[i];
20578
+ } else if (refExpr !== expr) {
20579
+ diagnosticNode = refExpr;
20509
20580
  diagnosticValue = ref;
20510
20581
  } else {
20511
20582
  diagnosticNode = expr;
@@ -20516,6 +20587,16 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
20516
20587
  }
20517
20588
  return { imports: flattened, diagnostics };
20518
20589
  }
20590
+ function isWithinExpression(node, expr) {
20591
+ let current = node;
20592
+ while (current !== void 0) {
20593
+ if (current === expr) {
20594
+ return true;
20595
+ }
20596
+ current = current.parent;
20597
+ }
20598
+ return false;
20599
+ }
20519
20600
  function isLikelyModuleWithProviders(value) {
20520
20601
  if (value instanceof SyntheticValue && isResolvedModuleWithProviders(value)) {
20521
20602
  return true;
@@ -8,7 +8,7 @@ import {
8
8
  TrackedIncrementalBuildStrategy,
9
9
  freshCompilationTicket,
10
10
  incrementalFromCompilerTicket
11
- } from "./chunk-6VDGFZBQ.js";
11
+ } from "./chunk-B43HGQHK.js";
12
12
  import {
13
13
  ActivePerfRecorder,
14
14
  OptimizeFor,
@@ -18,7 +18,7 @@ import {
18
18
  TsCreateProgramDriver,
19
19
  replaceTsWithNgInErrors,
20
20
  retagAllTsFiles
21
- } from "./chunk-PUEBQK4X.js";
21
+ } from "./chunk-G2AK5XJW.js";
22
22
  import {
23
23
  absoluteFrom,
24
24
  createFileSystemTsReadDirectoryFn,
@@ -8,7 +8,7 @@ import {
8
8
  import {
9
9
  Context,
10
10
  ExpressionTranslatorVisitor
11
- } from "./chunk-LS5RJ5CS.js";
11
+ } from "./chunk-FROPOOFC.js";
12
12
 
13
13
  // packages/compiler-cli/linker/src/fatal_linker_error.js
14
14
  var FatalLinkerError = class extends Error {
@@ -455,7 +455,7 @@ import { compileDirectiveFromMetadata, makeBindingParser, ParseLocation, ParseSo
455
455
  // packages/compiler-cli/linker/src/file_linker/partial_linkers/util.js
456
456
  import { createMayBeForwardRefExpression, outputAst as o2 } from "@angular/compiler";
457
457
  import semver from "semver";
458
- var PLACEHOLDER_VERSION = "21.1.0-next.3";
458
+ var PLACEHOLDER_VERSION = "21.1.0-rc.0";
459
459
  function wrapReference(wrapped) {
460
460
  return { value: wrapped, type: wrapped };
461
461
  }
package/bundles/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  isTsDiagnostic,
18
18
  performCompilation,
19
19
  readConfiguration
20
- } from "./chunk-ML6J2RBK.js";
20
+ } from "./chunk-G5W5AISR.js";
21
21
  import {
22
22
  ConsoleLogger,
23
23
  LogLevel
@@ -34,7 +34,7 @@ import {
34
34
  freshCompilationTicket,
35
35
  incrementalFromStateTicket,
36
36
  isDocEntryWithSourceInfo
37
- } from "./chunk-6VDGFZBQ.js";
37
+ } from "./chunk-B43HGQHK.js";
38
38
  import {
39
39
  ActivePerfRecorder,
40
40
  ErrorCode,
@@ -46,8 +46,8 @@ import {
46
46
  getInitializerApiJitTransform,
47
47
  isLocalCompilationDiagnostics,
48
48
  ngErrorCode
49
- } from "./chunk-PUEBQK4X.js";
50
- import "./chunk-LS5RJ5CS.js";
49
+ } from "./chunk-G2AK5XJW.js";
50
+ import "./chunk-FROPOOFC.js";
51
51
  import {
52
52
  InvalidFileSystem,
53
53
  LogicalFileSystem,
@@ -77,7 +77,7 @@ import "./chunk-G7GFT6BU.js";
77
77
 
78
78
  // packages/compiler-cli/src/version.js
79
79
  import { Version } from "@angular/compiler";
80
- var VERSION = new Version("21.1.0-next.3");
80
+ var VERSION = new Version("21.1.0-rc.0");
81
81
 
82
82
  // packages/compiler-cli/private/tooling.js
83
83
  var GLOBAL_DEFS_FOR_TERSER = {
@@ -8,13 +8,13 @@ import {
8
8
  LinkerEnvironment,
9
9
  assert,
10
10
  isFatalLinkerError
11
- } from "../../chunk-ZJZNLTWN.js";
11
+ } from "../../chunk-WEF4HIPN.js";
12
12
  import {
13
13
  ConsoleLogger,
14
14
  LogLevel
15
15
  } from "../../chunk-6HOSNZU5.js";
16
16
  import "../../chunk-HYJ2H3FU.js";
17
- import "../../chunk-LS5RJ5CS.js";
17
+ import "../../chunk-FROPOOFC.js";
18
18
  import {
19
19
  NodeJSFileSystem
20
20
  } from "../../chunk-XYYEESKY.js";
@@ -86,6 +86,9 @@ var BabelAstFactory = class {
86
86
  );
87
87
  }
88
88
  createExpressionStatement = t.expressionStatement;
89
+ createSpreadElement(expression) {
90
+ return t.spreadElement(expression);
91
+ }
89
92
  createFunctionDeclaration(functionName, parameters, body) {
90
93
  assert(body, t.isBlockStatement, "a block");
91
94
  return t.functionDeclaration(t.identifier(functionName), parameters.map((param) => t.identifier(param)), body);
@@ -126,9 +129,14 @@ var BabelAstFactory = class {
126
129
  throw new Error(`Invalid literal: ${value} (${typeof value})`);
127
130
  }
128
131
  }
129
- createNewExpression = t.newExpression;
132
+ createNewExpression(expression, args) {
133
+ return t.newExpression(expression, args);
134
+ }
130
135
  createObjectLiteral(properties) {
131
136
  return t.objectExpression(properties.map((prop) => {
137
+ if (prop.kind === "spread") {
138
+ return t.spreadElement(prop.expression);
139
+ }
132
140
  const key = prop.quoted ? t.stringLiteral(prop.propertyName) : t.identifier(prop.propertyName);
133
141
  return t.objectProperty(key, prop.value);
134
142
  }));
@@ -142,7 +150,9 @@ var BabelAstFactory = class {
142
150
  false
143
151
  );
144
152
  }
145
- createReturnStatement = t.returnStatement;
153
+ createReturnStatement(expression) {
154
+ return t.returnStatement(expression);
155
+ }
146
156
  createTaggedTemplate(tag, template) {
147
157
  return t.taggedTemplateExpression(tag, this.createTemplateLiteral(template));
148
158
  }
@@ -10,9 +10,9 @@ import {
10
10
  assert,
11
11
  isFatalLinkerError,
12
12
  needsLinking
13
- } from "../chunk-ZJZNLTWN.js";
13
+ } from "../chunk-WEF4HIPN.js";
14
14
  import "../chunk-HYJ2H3FU.js";
15
- import "../chunk-LS5RJ5CS.js";
15
+ import "../chunk-FROPOOFC.js";
16
16
  import "../chunk-G7GFT6BU.js";
17
17
  export {
18
18
  DEFAULT_LINKER_OPTIONS,
@@ -5,7 +5,7 @@
5
5
  import {
6
6
  DiagnosticCategoryLabel,
7
7
  NgCompiler
8
- } from "../chunk-6VDGFZBQ.js";
8
+ } from "../chunk-B43HGQHK.js";
9
9
  import {
10
10
  CompilationMode,
11
11
  DtsMetadataReader,
@@ -32,8 +32,8 @@ import {
32
32
  queryDecoratorNames,
33
33
  reflectObjectLiteral,
34
34
  unwrapExpression
35
- } from "../chunk-PUEBQK4X.js";
36
- import "../chunk-LS5RJ5CS.js";
35
+ } from "../chunk-G2AK5XJW.js";
36
+ import "../chunk-FROPOOFC.js";
37
37
  import {
38
38
  getFileSystem,
39
39
  isLocalRelativePath
@@ -6,8 +6,8 @@ import {
6
6
  ImportedSymbolsTracker,
7
7
  TypeScriptReflectionHost,
8
8
  getInitializerApiJitTransform
9
- } from "../chunk-PUEBQK4X.js";
10
- import "../chunk-LS5RJ5CS.js";
9
+ } from "../chunk-G2AK5XJW.js";
10
+ import "../chunk-FROPOOFC.js";
11
11
  import {
12
12
  InvalidFileSystem,
13
13
  absoluteFrom,
@@ -4,8 +4,8 @@
4
4
 
5
5
  import {
6
6
  angularJitApplicationTransform
7
- } from "../chunk-PUEBQK4X.js";
8
- import "../chunk-LS5RJ5CS.js";
7
+ } from "../chunk-G2AK5XJW.js";
8
+ import "../chunk-FROPOOFC.js";
9
9
  import "../chunk-JEXAXD23.js";
10
10
  import "../chunk-XYYEESKY.js";
11
11
  import "../chunk-G7GFT6BU.js";
@@ -6,13 +6,13 @@
6
6
  import {
7
7
  main,
8
8
  readCommandLineAndConfiguration
9
- } from "../../chunk-OPZT26MK.js";
9
+ } from "../../chunk-6LHOU42A.js";
10
10
  import {
11
11
  EmitFlags
12
- } from "../../chunk-ML6J2RBK.js";
13
- import "../../chunk-6VDGFZBQ.js";
14
- import "../../chunk-PUEBQK4X.js";
15
- import "../../chunk-LS5RJ5CS.js";
12
+ } from "../../chunk-G5W5AISR.js";
13
+ import "../../chunk-B43HGQHK.js";
14
+ import "../../chunk-G2AK5XJW.js";
15
+ import "../../chunk-FROPOOFC.js";
16
16
  import {
17
17
  setFileSystem
18
18
  } from "../../chunk-JEXAXD23.js";
@@ -5,11 +5,11 @@
5
5
 
6
6
  import {
7
7
  main
8
- } from "../../chunk-OPZT26MK.js";
9
- import "../../chunk-ML6J2RBK.js";
10
- import "../../chunk-6VDGFZBQ.js";
11
- import "../../chunk-PUEBQK4X.js";
12
- import "../../chunk-LS5RJ5CS.js";
8
+ } from "../../chunk-6LHOU42A.js";
9
+ import "../../chunk-G5W5AISR.js";
10
+ import "../../chunk-B43HGQHK.js";
11
+ import "../../chunk-G2AK5XJW.js";
12
+ import "../../chunk-FROPOOFC.js";
13
13
  import {
14
14
  setFileSystem
15
15
  } from "../../chunk-JEXAXD23.js";
@@ -10,7 +10,7 @@ import { AstFactory, BinaryOperator, LeadingComment, ObjectLiteralProperty, Sour
10
10
  /**
11
11
  * A Babel flavored implementation of the AstFactory.
12
12
  */
13
- export declare class BabelAstFactory implements AstFactory<t.Statement, t.Expression> {
13
+ export declare class BabelAstFactory implements AstFactory<t.Statement, t.Expression | t.SpreadElement> {
14
14
  /** The absolute path to the source file being compiled. */
15
15
  private sourceUrl;
16
16
  constructor(
@@ -21,10 +21,11 @@ export declare class BabelAstFactory implements AstFactory<t.Statement, t.Expres
21
21
  createAssignment(target: t.Expression, operator: BinaryOperator, value: t.Expression): t.Expression;
22
22
  createBinaryExpression(leftOperand: t.Expression, operator: BinaryOperator, rightOperand: t.Expression): t.Expression;
23
23
  createBlock: typeof t.blockStatement;
24
- createCallExpression(callee: t.Expression, args: t.Expression[], pure: boolean): t.Expression;
24
+ createCallExpression(callee: t.Expression, args: (t.Expression | t.SpreadElement)[], pure: boolean): t.Expression;
25
25
  createConditional: typeof t.conditionalExpression;
26
26
  createElementAccess(expression: t.Expression, element: t.Expression): t.Expression;
27
27
  createExpressionStatement: typeof t.expressionStatement;
28
+ createSpreadElement(expression: t.Expression): t.SpreadElement;
28
29
  createFunctionDeclaration(functionName: string, parameters: string[], body: t.Statement): t.Statement;
29
30
  createArrowFunctionExpression(parameters: string[], body: t.Statement | t.Expression): t.Expression;
30
31
  createFunctionExpression(functionName: string | null, parameters: string[], body: t.Statement): t.Expression;
@@ -32,11 +33,11 @@ export declare class BabelAstFactory implements AstFactory<t.Statement, t.Expres
32
33
  createIfStatement: typeof t.ifStatement;
33
34
  createDynamicImport(url: string | t.Expression): t.Expression;
34
35
  createLiteral(value: string | number | boolean | null | undefined): t.Expression;
35
- createNewExpression: typeof t.newExpression;
36
+ createNewExpression(expression: t.Expression, args: t.Expression[]): t.Expression;
36
37
  createObjectLiteral(properties: ObjectLiteralProperty<t.Expression>[]): t.Expression;
37
38
  createParenthesizedExpression: typeof t.parenthesizedExpression;
38
39
  createPropertyAccess(expression: t.Expression, propertyName: string): t.Expression;
39
- createReturnStatement: typeof t.returnStatement;
40
+ createReturnStatement(expression: t.Expression | null): t.Statement;
40
41
  createTaggedTemplate(tag: t.Expression, template: TemplateLiteral<t.Expression>): t.Expression;
41
42
  createTemplateLiteral(template: TemplateLiteral<t.Expression>): t.TemplateLiteral;
42
43
  createThrowStatement: typeof t.throwStatement;
@@ -45,5 +46,5 @@ export declare class BabelAstFactory implements AstFactory<t.Statement, t.Expres
45
46
  createUnaryExpression: typeof t.unaryExpression;
46
47
  createVariableDeclaration(variableName: string, initializer: t.Expression | null, type: VariableDeclarationType): t.Statement;
47
48
  createRegularExpressionLiteral(body: string, flags: string | null): t.Expression;
48
- setSourceMapRange<T extends t.Statement | t.Expression | t.TemplateElement>(node: T, sourceMapRange: SourceMapRange | null): T;
49
+ setSourceMapRange<T extends t.Statement | t.Expression | t.TemplateElement | t.SpreadElement>(node: T, sourceMapRange: SourceMapRange | null): T;
49
50
  }
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { MaybeForwardRefExpression, outputAst as o, R3DeclareDependencyMetadata, R3DependencyMetadata, R3Reference } from '@angular/compiler';
9
9
  import { AstObject, AstValue } from '../../ast/ast_value';
10
- export declare const PLACEHOLDER_VERSION = "21.1.0-next.3";
10
+ export declare const PLACEHOLDER_VERSION = "21.1.0-rc.0";
11
11
  export declare function wrapReference<TExpression>(wrapped: o.WrappedNodeExpr<TExpression>): R3Reference;
12
12
  /**
13
13
  * Parses the value of an enum from the AST value's symbol name.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@angular/compiler-cli",
3
- "version": "21.1.0-next.3",
3
+ "version": "21.1.0-rc.0",
4
4
  "description": "Angular - the compiler CLI for Node.js",
5
5
  "typings": "index.d.ts",
6
6
  "bin": {
@@ -43,7 +43,7 @@
43
43
  "typescript": "5.9.3"
44
44
  },
45
45
  "peerDependencies": {
46
- "@angular/compiler": "21.1.0-next.3",
46
+ "@angular/compiler": "21.1.0-rc.0",
47
47
  "typescript": ">=5.9 <6.0"
48
48
  },
49
49
  "peerDependenciesMeta": {
@@ -226,6 +226,12 @@ export interface AstFactory<TStatement, TExpression> {
226
226
  * @param flags Flags of the regex, if any.
227
227
  */
228
228
  createRegularExpressionLiteral(body: string, flags: string | null): TExpression;
229
+ /**
230
+ * Create a spread element, typically in an array or function call. E.g. `[...a]` or `fn(...b)`.
231
+ *
232
+ * @param target Expression of the spread element.
233
+ */
234
+ createSpreadElement(expression: TExpression): TExpression;
229
235
  /**
230
236
  * Attach a source map range to the given node.
231
237
  *
@@ -268,9 +274,11 @@ export interface SourceMapRange {
268
274
  end: SourceMapLocation;
269
275
  }
270
276
  /**
271
- * Information used by the `AstFactory` to create a property on an object literal expression.
277
+ * Information used by the `AstFactory` to create a property assignment
278
+ * on an object literal expression.
272
279
  */
273
- export interface ObjectLiteralProperty<TExpression> {
280
+ export interface ObjectLiteralAssignment<TExpression> {
281
+ kind: 'property';
274
282
  propertyName: string;
275
283
  value: TExpression;
276
284
  /**
@@ -278,6 +286,15 @@ export interface ObjectLiteralProperty<TExpression> {
278
286
  */
279
287
  quoted: boolean;
280
288
  }
289
+ /**
290
+ * Information used by the `AstFactory` to create a spread on an object literal expression.
291
+ */
292
+ export interface ObjectLiteralSpread<TExpression> {
293
+ kind: 'spread';
294
+ expression: TExpression;
295
+ }
296
+ /** Possible properties in an object literal. */
297
+ export type ObjectLiteralProperty<TExpression> = ObjectLiteralAssignment<TExpression> | ObjectLiteralSpread<TExpression>;
281
298
  /**
282
299
  * Information used by the `AstFactory` to create a template literal string (i.e. a back-ticked
283
300
  * string with interpolations).
@@ -56,6 +56,7 @@ export declare class ExpressionTranslatorVisitor<TFile, TStatement, TExpression>
56
56
  visitLiteralMapExpr(ast: o.LiteralMapExpr, context: Context): TExpression;
57
57
  visitCommaExpr(ast: o.CommaExpr, context: Context): never;
58
58
  visitTemplateLiteralElementExpr(ast: o.TemplateLiteralElementExpr, context: any): void;
59
+ visitSpreadElementExpr(ast: o.outputAst.SpreadElementExpr, context: any): TExpression;
59
60
  visitWrappedNodeExpr(ast: o.WrappedNodeExpr<any>, _context: Context): any;
60
61
  visitTypeofExpr(ast: o.TypeofExpr, context: Context): TExpression;
61
62
  visitVoidExpr(ast: o.VoidExpr, context: Context): TExpression;
@@ -37,6 +37,7 @@ export declare class TypeScriptAstFactory implements AstFactory<ts.Statement, ts
37
37
  createObjectLiteral(properties: ObjectLiteralProperty<ts.Expression>[]): ts.Expression;
38
38
  createParenthesizedExpression: (expression: ts.Expression) => ts.ParenthesizedExpression;
39
39
  createPropertyAccess: (expression: ts.Expression, name: string | ts.MemberName) => ts.PropertyAccessExpression;
40
+ createSpreadElement: (expression: ts.Expression) => ts.SpreadElement;
40
41
  createReturnStatement(expression: ts.Expression | null): ts.Statement;
41
42
  createTaggedTemplate(tag: ts.Expression, template: TemplateLiteral<ts.Expression>): ts.Expression;
42
43
  createTemplateLiteral(template: TemplateLiteral<ts.Expression>): ts.TemplateLiteral;
@@ -11,7 +11,7 @@ import { TcbOp } from './base';
11
11
  import { Context } from './context';
12
12
  import type { Scope } from './scope';
13
13
  import { TypeCheckableDirectiveMeta } from '../../api';
14
- import { CustomFieldType } from './signal_forms';
14
+ import { CustomFormControlType } from './signal_forms';
15
15
  /**
16
16
  * A `TcbOp` which constructs an instance of a directive with types inferred from its inputs. The
17
17
  * inputs themselves are not checked here; checking of inputs is achieved in `TcbDirectiveInputsOp`.
@@ -29,8 +29,8 @@ export declare class TcbDirectiveCtorOp extends TcbOp {
29
29
  private scope;
30
30
  private node;
31
31
  private dir;
32
- private customControlType;
33
- constructor(tcb: Context, scope: Scope, node: DirectiveOwner, dir: TypeCheckableDirectiveMeta, customControlType: CustomFieldType | null);
32
+ private customFormControlType;
33
+ constructor(tcb: Context, scope: Scope, node: DirectiveOwner, dir: TypeCheckableDirectiveMeta, customFormControlType: CustomFormControlType | null);
34
34
  get optional(): boolean;
35
35
  execute(): ts.Identifier;
36
36
  circularFallback(): TcbOp;
@@ -11,7 +11,7 @@ import type { Context } from './context';
11
11
  import type { Scope } from './scope';
12
12
  import { TypeCheckableDirectiveMeta } from '../../api';
13
13
  import { TcbOp } from './base';
14
- import { CustomFieldType } from './signal_forms';
14
+ import { CustomFormControlType } from './signal_forms';
15
15
  import { LocalSymbol } from './references';
16
16
  /**
17
17
  * Translates the given attribute binding to a `ts.Expression`.
@@ -28,8 +28,9 @@ export declare class TcbDirectiveInputsOp extends TcbOp {
28
28
  private scope;
29
29
  private node;
30
30
  private dir;
31
- private customControlType;
32
- constructor(tcb: Context, scope: Scope, node: TmplAstTemplate | TmplAstElement | TmplAstComponent | TmplAstDirective, dir: TypeCheckableDirectiveMeta, customControlType: CustomFieldType | null);
31
+ private isFormControl;
32
+ private customFormControlType;
33
+ constructor(tcb: Context, scope: Scope, node: TmplAstTemplate | TmplAstElement | TmplAstComponent | TmplAstDirective, dir: TypeCheckableDirectiveMeta, isFormControl: boolean | undefined, customFormControlType: CustomFormControlType | null);
33
34
  get optional(): boolean;
34
35
  execute(): null;
35
36
  private checkRequiredInputs;
@@ -6,13 +6,13 @@
6
6
  * found in the LICENSE file at https://angular.dev/license
7
7
  */
8
8
  import { DirectiveOwner, TmplAstComponent, TmplAstDirective, TmplAstElement, TmplAstNode, TmplAstTemplate } from '@angular/compiler';
9
+ import { TypeCheckableDirectiveMeta } from '../../api';
9
10
  import { TcbOp } from './base';
11
+ import { TcbBoundAttribute } from './bindings';
10
12
  import type { Context } from './context';
11
13
  import type { Scope } from './scope';
12
- import { TypeCheckableDirectiveMeta } from '../../api';
13
- import { TcbBoundAttribute } from './bindings';
14
- /** Possible types of custom field directives. */
15
- export type CustomFieldType = 'value' | 'checkbox';
14
+ /** Possible types of custom form control directives. */
15
+ export type CustomFormControlType = 'value' | 'checkbox';
16
16
  /** Names of input fields to which users aren't allowed to bind when using a `field` directive. */
17
17
  export declare const customFormControlBannedInputFields: Set<string>;
18
18
  /**
@@ -39,13 +39,20 @@ export declare class TcbNativeRadioButtonFieldOp extends TcbNativeFieldOp {
39
39
  execute(): null;
40
40
  }
41
41
  /** Expands the set of bound inputs with the ones from custom field directives. */
42
- export declare function expandBoundAttributesForField(directive: TypeCheckableDirectiveMeta, node: TmplAstTemplate | TmplAstElement | TmplAstComponent | TmplAstDirective, customFieldType: CustomFieldType): TcbBoundAttribute[] | null;
42
+ export declare function expandBoundAttributesForField(directive: TypeCheckableDirectiveMeta, node: TmplAstTemplate | TmplAstElement | TmplAstComponent | TmplAstDirective, customFormControlType: CustomFormControlType | null): TcbBoundAttribute[] | null;
43
43
  export declare function isFieldDirective(meta: TypeCheckableDirectiveMeta): boolean;
44
44
  /** Determines if a directive is a custom field and its type. */
45
- export declare function getCustomFieldDirectiveType(meta: TypeCheckableDirectiveMeta): CustomFieldType | null;
45
+ export declare function getCustomFieldDirectiveType(meta: TypeCheckableDirectiveMeta): CustomFormControlType | null;
46
46
  /** Determines if a directive usage is on a native field. */
47
47
  export declare function isNativeField(dir: TypeCheckableDirectiveMeta, node: TmplAstNode, allDirectiveMatches: TypeCheckableDirectiveMeta[]): node is TmplAstElement & {
48
48
  name: 'input' | 'select' | 'textarea';
49
49
  };
50
50
  /** Checks whether a node has bindings that aren't supported on fields. */
51
51
  export declare function checkUnsupportedFieldBindings(node: DirectiveOwner, unsupportedBindingFields: Set<string>, tcb: Context): void;
52
+ /**
53
+ * Determines whether a node is a form control based on its matching directives.
54
+ *
55
+ * A node is a form control if it has a matching `Field` directive, and no other directives match
56
+ * the `field` input.
57
+ */
58
+ export declare function isFormControl(allDirectiveMatches: TypeCheckableDirectiveMeta[]): boolean;