@angular/compiler-cli 21.1.0-next.4 → 21.1.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.
@@ -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,
@@ -227,9 +227,14 @@ var COMPILER_ERRORS_WITH_GUIDES = /* @__PURE__ */ new Set([
227
227
 
228
228
  // packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.js
229
229
  import { VERSION } from "@angular/compiler";
230
+ var DOC_PAGE_BASE_URL = (() => {
231
+ const full = VERSION.full;
232
+ const isPreRelease = full.includes("-next") || full.includes("-rc") || full === "21.1.0";
233
+ const prefix = isPreRelease ? "next" : `v${VERSION.major}`;
234
+ return `https://${prefix}.angular.dev`;
235
+ })();
230
236
  var ERROR_DETAILS_PAGE_BASE_URL = (() => {
231
- const versionSubDomain = VERSION.major !== "0" ? `v${VERSION.major}.` : "";
232
- return `https://${versionSubDomain}angular.dev/errors`;
237
+ return `${DOC_PAGE_BASE_URL}/errors`;
233
238
  })();
234
239
 
235
240
  // packages/compiler-cli/src/ngtsc/diagnostics/src/extended_template_diagnostic_name.js
@@ -4434,12 +4439,13 @@ var StaticInterpreter = class {
4434
4439
  return res;
4435
4440
  }
4436
4441
  visitTypeQuery(node, context) {
4437
- if (!ts16.isIdentifier(node.exprName)) {
4442
+ const exprName = ts16.isQualifiedName(node.exprName) ? node.exprName.right : node.exprName;
4443
+ if (!ts16.isIdentifier(exprName)) {
4438
4444
  return DynamicValue.fromUnknown(node);
4439
4445
  }
4440
- const decl = this.host.getDeclarationOfIdentifier(node.exprName);
4446
+ const decl = this.host.getDeclarationOfIdentifier(exprName);
4441
4447
  if (decl === null) {
4442
- return DynamicValue.fromUnknownIdentifier(node.exprName);
4448
+ return DynamicValue.fromUnknownIdentifier(exprName);
4443
4449
  }
4444
4450
  const declContext = { ...context, ...joinModuleContext(context, node, decl) };
4445
4451
  return this.visitDeclaration(decl.node, declContext);
@@ -5348,6 +5354,9 @@ var TypeTranslatorVisitor = class {
5348
5354
  }
5349
5355
  visitLiteralMapExpr(ast, context) {
5350
5356
  const entries = ast.entries.map((entry) => {
5357
+ if (entry instanceof o.LiteralMapSpreadAssignment) {
5358
+ throw new Error("Spread is not supported in this context");
5359
+ }
5351
5360
  const { key, quoted } = entry;
5352
5361
  const type = this.translateExpression(entry.value, context);
5353
5362
  return ts25.factory.createPropertySignature(
@@ -5396,6 +5405,10 @@ var TypeTranslatorVisitor = class {
5396
5405
  visitParenthesizedExpr(ast, context) {
5397
5406
  throw new Error("Method not implemented.");
5398
5407
  }
5408
+ visitSpreadElementExpr(ast, context) {
5409
+ const typeNode = this.translateExpression(ast.expression, context);
5410
+ return ts25.factory.createRestTypeNode(typeNode);
5411
+ }
5399
5412
  translateType(type, context) {
5400
5413
  const typeNode = type.visitType(this, context);
5401
5414
  if (!ts25.isTypeNode(typeNode)) {
@@ -5565,10 +5578,16 @@ var TypeScriptAstFactory = class {
5565
5578
  return ts26.factory.createNewExpression(expression, void 0, args);
5566
5579
  }
5567
5580
  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)));
5581
+ return ts26.factory.createObjectLiteralExpression(properties.map((prop) => {
5582
+ if (prop.kind === "spread") {
5583
+ return ts26.factory.createSpreadAssignment(prop.expression);
5584
+ }
5585
+ return ts26.factory.createPropertyAssignment(prop.quoted ? ts26.factory.createStringLiteral(prop.propertyName) : ts26.factory.createIdentifier(prop.propertyName), prop.value);
5586
+ }));
5569
5587
  }
5570
5588
  createParenthesizedExpression = ts26.factory.createParenthesizedExpression;
5571
5589
  createPropertyAccess = ts26.factory.createPropertyAccessExpression;
5590
+ createSpreadElement = ts26.factory.createSpreadElement;
5572
5591
  createReturnStatement(expression) {
5573
5592
  return ts26.factory.createReturnStatement(expression ?? void 0);
5574
5593
  }
@@ -9595,7 +9614,7 @@ function parseTemplateDeclaration(node, decorator, component, containingFile, ev
9595
9614
  resolvedTemplateUrl: containingFile
9596
9615
  };
9597
9616
  } else {
9598
- throw new FatalDiagnosticError(ErrorCode.COMPONENT_MISSING_TEMPLATE, decorator.node, "component is missing a template");
9617
+ throw new FatalDiagnosticError(ErrorCode.COMPONENT_MISSING_TEMPLATE, decorator.node, "@Component is missing a template. Add either a `template` or `templateUrl`");
9599
9618
  }
9600
9619
  }
9601
9620
  function preloadAndParseTemplate(evaluator, resourceLoader, depTracker, preanalyzeTemplateCache, node, decorator, component, containingFile, defaultPreserveWhitespaces, options, compilationMode) {
@@ -11598,7 +11617,7 @@ function getTypeCheckId(clazz) {
11598
11617
  }
11599
11618
 
11600
11619
  // packages/compiler-cli/src/ngtsc/typecheck/src/completion.js
11601
- import { EmptyExpr, ImplicitReceiver, PropertyRead, SafePropertyRead, TmplAstLetDeclaration, TmplAstReference, TmplAstTextAttribute } from "@angular/compiler";
11620
+ import { EmptyExpr, ImplicitReceiver, PropertyRead, SafePropertyRead, ThisReceiver, TmplAstLetDeclaration, TmplAstReference, TmplAstTextAttribute } from "@angular/compiler";
11602
11621
  import ts51 from "typescript";
11603
11622
  var CompletionEngine = class {
11604
11623
  tcb;
@@ -11677,7 +11696,7 @@ var CompletionEngine = class {
11677
11696
  };
11678
11697
  }
11679
11698
  }
11680
- if (node instanceof PropertyRead && node.receiver instanceof ImplicitReceiver) {
11699
+ if (node instanceof PropertyRead && (node.receiver instanceof ImplicitReceiver || node.receiver instanceof ThisReceiver)) {
11681
11700
  const nodeLocation = findFirstMatchingNode(this.tcb, {
11682
11701
  filter: ts51.isPropertyAccessExpression,
11683
11702
  withSpan: node.sourceSpan
@@ -13082,7 +13101,7 @@ var TypeParameterEmitter = class {
13082
13101
  };
13083
13102
 
13084
13103
  // 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";
13104
+ 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
13105
  import ts54 from "typescript";
13087
13106
  var GUARD_COMMENT_TEXT = "hostBindingsBlockGuard";
13088
13107
  function createHostElement(type, selector, sourceNode, literal4, bindingDecorators, listenerDecorators) {
@@ -13180,7 +13199,7 @@ function createNodeFromBindingDecorator(decorator, bindings) {
13180
13199
  }
13181
13200
  const span = new ParseSpan(-1, -1);
13182
13201
  const propertyStart = property.getStart();
13183
- const receiver = new ThisReceiver(span, new AbsoluteSourceSpan2(propertyStart, propertyStart));
13202
+ const receiver = new ThisReceiver2(span, new AbsoluteSourceSpan2(propertyStart, propertyStart));
13184
13203
  const nameSpan = new AbsoluteSourceSpan2(propertyName.getStart(), propertyName.getEnd());
13185
13204
  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
13205
  const { attrName, type } = inferBoundAttribute(nameNode.text);
@@ -13198,7 +13217,7 @@ function createNodeFromListenerDecorator(decorator, parser, listeners) {
13198
13217
  const span = new ParseSpan(-1, -1);
13199
13218
  const argNodes = [];
13200
13219
  const methodStart = method.getStart();
13201
- const methodReceiver = new ThisReceiver(span, new AbsoluteSourceSpan2(methodStart, methodStart));
13220
+ const methodReceiver = new ThisReceiver2(span, new AbsoluteSourceSpan2(methodStart, methodStart));
13202
13221
  const nameSpan = new AbsoluteSourceSpan2(method.name.getStart(), method.name.getEnd());
13203
13222
  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
13223
  if (args.length > 1 && ts54.isArrayLiteralExpression(args[1])) {
@@ -13683,7 +13702,7 @@ var Environment = class extends ReferenceEmitEnvironment {
13683
13702
  };
13684
13703
 
13685
13704
  // packages/compiler-cli/src/ngtsc/typecheck/src/oob.js
13686
- import { AbsoluteSourceSpan as AbsoluteSourceSpan3, TmplAstBoundAttribute as TmplAstBoundAttribute2, TmplAstBoundEvent as TmplAstBoundEvent2, TmplAstComponent, TmplAstDirective, TmplAstElement, ParseSourceSpan as ParseSourceSpan2, BindingType as BindingType2 } from "@angular/compiler";
13705
+ import { AbsoluteSourceSpan as AbsoluteSourceSpan3, BindingType as BindingType2, ParseSourceSpan as ParseSourceSpan2, TmplAstBoundAttribute as TmplAstBoundAttribute2, TmplAstBoundEvent as TmplAstBoundEvent2, TmplAstComponent, TmplAstDirective, TmplAstElement } from "@angular/compiler";
13687
13706
  import ts58 from "typescript";
13688
13707
  var OutOfBandDiagnosticRecorderImpl = class {
13689
13708
  resolver;
@@ -13818,7 +13837,7 @@ Consider enabling the 'strictTemplates' option in your tsconfig.json for better
13818
13837
  splitTwoWayBinding(id, input, output, inputConsumer, outputConsumer) {
13819
13838
  const mapping = this.resolver.getTemplateSourceMapping(id);
13820
13839
  const errorMsg = `The property and event halves of the two-way binding '${input.name}' are not bound to the same target.
13821
- Find more at https://angular.dev/guide/templates/two-way-binding#how-two-way-binding-works`;
13840
+ Find more at ${DOC_PAGE_BASE_URL}/guide/templates/two-way-binding`;
13822
13841
  const relatedMessages = [];
13823
13842
  relatedMessages.push({
13824
13843
  text: `The property half of the binding is to the '${inputConsumer.name.text}' component.`,
@@ -13958,9 +13977,9 @@ Deferred blocks can only access triggers in same view, a parent embedded view or
13958
13977
  } else {
13959
13978
  name = node.name;
13960
13979
  }
13961
- message = `Binding to '${name}' is not allowed on nodes using the '[field]' directive`;
13980
+ message = `Binding to '${name}' is not allowed on nodes using the '[formField]' directive`;
13962
13981
  } else {
13963
- message = `Setting the '${node.name}' attribute is not allowed on nodes using the '[field]' directive`;
13982
+ message = `Setting the '${node.name}' attribute is not allowed on nodes using the '[formField]' directive`;
13964
13983
  }
13965
13984
  this._diagnostics.push(makeTemplateDiagnostic(id, this.resolver.getTemplateSourceMapping(id), node.sourceSpan, ts58.DiagnosticCategory.Error, ngErrorCode(ErrorCode.FORM_FIELD_UNSUPPORTED_BINDING), message));
13966
13985
  }
@@ -14125,7 +14144,7 @@ import { TmplAstBoundAttribute as TmplAstBoundAttribute3, TmplAstTemplate } from
14125
14144
  import ts65 from "typescript";
14126
14145
 
14127
14146
  // 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";
14147
+ 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
14148
  import ts64 from "typescript";
14130
14149
 
14131
14150
  // packages/compiler-cli/src/ngtsc/typecheck/src/expression.js
@@ -14260,9 +14279,13 @@ var AstTranslator = class {
14260
14279
  return node;
14261
14280
  }
14262
14281
  visitLiteralMap(ast) {
14263
- const properties = ast.keys.map(({ key }, idx) => {
14282
+ const properties = ast.keys.map((key, idx) => {
14264
14283
  const value = this.translate(ast.values[idx]);
14265
- return ts63.factory.createPropertyAssignment(ts63.factory.createStringLiteral(key), value);
14284
+ if (key.kind === "property") {
14285
+ return ts63.factory.createPropertyAssignment(ts63.factory.createStringLiteral(key.key), value);
14286
+ } else {
14287
+ return ts63.factory.createSpreadAssignment(value);
14288
+ }
14266
14289
  });
14267
14290
  const literal4 = ts63.factory.createObjectLiteralExpression(properties, true);
14268
14291
  const node = this.config.strictLiteralTypes ? literal4 : tsCastToAny(literal4);
@@ -14418,6 +14441,12 @@ var AstTranslator = class {
14418
14441
  visitParenthesizedExpression(ast) {
14419
14442
  return ts63.factory.createParenthesizedExpression(this.translate(ast.expression));
14420
14443
  }
14444
+ visitSpreadElement(ast) {
14445
+ const expression = wrapForDiagnostics(this.translate(ast.expression));
14446
+ const node = ts63.factory.createSpreadElement(expression);
14447
+ addParseSpanInfo(node, ast.sourceSpan);
14448
+ return node;
14449
+ }
14421
14450
  convertToSafeCall(ast, expr, args) {
14422
14451
  if (this.config.strictSafeNavigationTypes) {
14423
14452
  const call = ts63.factory.createCallExpression(ts63.factory.createNonNullExpression(expr), void 0, args);
@@ -14441,40 +14470,40 @@ var VeSafeLhsInferenceBugDetector = class _VeSafeLhsInferenceBugDetector {
14441
14470
  visitBinary(ast) {
14442
14471
  return ast.left.visit(this) || ast.right.visit(this);
14443
14472
  }
14444
- visitChain(ast) {
14473
+ visitChain() {
14445
14474
  return false;
14446
14475
  }
14447
14476
  visitConditional(ast) {
14448
14477
  return ast.condition.visit(this) || ast.trueExp.visit(this) || ast.falseExp.visit(this);
14449
14478
  }
14450
- visitCall(ast) {
14479
+ visitCall() {
14451
14480
  return true;
14452
14481
  }
14453
- visitSafeCall(ast) {
14482
+ visitSafeCall() {
14454
14483
  return false;
14455
14484
  }
14456
- visitImplicitReceiver(ast) {
14485
+ visitImplicitReceiver() {
14457
14486
  return false;
14458
14487
  }
14459
- visitThisReceiver(ast) {
14488
+ visitThisReceiver() {
14460
14489
  return false;
14461
14490
  }
14462
14491
  visitInterpolation(ast) {
14463
14492
  return ast.expressions.some((exp) => exp.visit(this));
14464
14493
  }
14465
- visitKeyedRead(ast) {
14494
+ visitKeyedRead() {
14466
14495
  return false;
14467
14496
  }
14468
- visitLiteralArray(ast) {
14497
+ visitLiteralArray() {
14469
14498
  return true;
14470
14499
  }
14471
- visitLiteralMap(ast) {
14500
+ visitLiteralMap() {
14472
14501
  return true;
14473
14502
  }
14474
- visitLiteralPrimitive(ast) {
14503
+ visitLiteralPrimitive() {
14475
14504
  return false;
14476
14505
  }
14477
- visitPipe(ast) {
14506
+ visitPipe() {
14478
14507
  return true;
14479
14508
  }
14480
14509
  visitPrefixNot(ast) {
@@ -14489,30 +14518,33 @@ var VeSafeLhsInferenceBugDetector = class _VeSafeLhsInferenceBugDetector {
14489
14518
  visitNonNullAssert(ast) {
14490
14519
  return ast.expression.visit(this);
14491
14520
  }
14492
- visitPropertyRead(ast) {
14521
+ visitPropertyRead() {
14493
14522
  return false;
14494
14523
  }
14495
- visitSafePropertyRead(ast) {
14524
+ visitSafePropertyRead() {
14496
14525
  return false;
14497
14526
  }
14498
- visitSafeKeyedRead(ast) {
14527
+ visitSafeKeyedRead() {
14499
14528
  return false;
14500
14529
  }
14501
- visitTemplateLiteral(ast, context) {
14530
+ visitTemplateLiteral() {
14502
14531
  return false;
14503
14532
  }
14504
- visitTemplateLiteralElement(ast, context) {
14533
+ visitTemplateLiteralElement() {
14505
14534
  return false;
14506
14535
  }
14507
- visitTaggedTemplateLiteral(ast, context) {
14536
+ visitTaggedTemplateLiteral() {
14508
14537
  return false;
14509
14538
  }
14510
- visitParenthesizedExpression(ast, context) {
14539
+ visitParenthesizedExpression(ast) {
14511
14540
  return ast.expression.visit(this);
14512
14541
  }
14513
- visitRegularExpressionLiteral(ast, context) {
14542
+ visitRegularExpressionLiteral() {
14514
14543
  return false;
14515
14544
  }
14545
+ visitSpreadElement(ast) {
14546
+ return ast.expression.visit(this);
14547
+ }
14516
14548
  };
14517
14549
 
14518
14550
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/expression.js
@@ -14560,7 +14592,7 @@ var TcbExpressionTranslator = class {
14560
14592
  * context). This method assists in resolving those.
14561
14593
  */
14562
14594
  resolve(ast) {
14563
- if (ast instanceof PropertyRead4 && ast.receiver instanceof ImplicitReceiver3 && !(ast.receiver instanceof ThisReceiver2)) {
14595
+ if (ast instanceof PropertyRead4 && ast.receiver instanceof ImplicitReceiver3) {
14564
14596
  const target = this.tcb.boundTarget.getExpressionTarget(ast);
14565
14597
  const targetExpression = target === null ? null : this.getTargetNodeExpression(target, ast);
14566
14598
  if (target instanceof TmplAstLetDeclaration2 && !this.isValidLetDeclarationAccess(target, ast)) {
@@ -14570,7 +14602,7 @@ var TcbExpressionTranslator = class {
14570
14602
  }
14571
14603
  }
14572
14604
  return targetExpression;
14573
- } else if (ast instanceof Binary && Binary.isAssignmentOperation(ast.operation) && ast.left instanceof PropertyRead4 && ast.left.receiver instanceof ImplicitReceiver3) {
14605
+ } else if (ast instanceof Binary && Binary.isAssignmentOperation(ast.operation) && ast.left instanceof PropertyRead4 && (ast.left.receiver instanceof ImplicitReceiver3 || ast.left.receiver instanceof ThisReceiver3)) {
14574
14606
  const read = ast.left;
14575
14607
  const target = this.tcb.boundTarget.getExpressionTarget(read);
14576
14608
  if (target === null) {
@@ -14585,7 +14617,7 @@ var TcbExpressionTranslator = class {
14585
14617
  this.tcb.oobRecorder.illegalWriteToLetDeclaration(this.tcb.id, read, target);
14586
14618
  }
14587
14619
  return result;
14588
- } else if (ast instanceof ImplicitReceiver3) {
14620
+ } else if (ast instanceof ImplicitReceiver3 || ast instanceof ThisReceiver3) {
14589
14621
  return ts64.factory.createThis();
14590
14622
  } else if (ast instanceof BindingPipe) {
14591
14623
  const expr = this.translate(ast.exp);
@@ -14617,7 +14649,7 @@ var TcbExpressionTranslator = class {
14617
14649
  addParseSpanInfo(result, ast.sourceSpan);
14618
14650
  return result;
14619
14651
  } 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) {
14652
+ if (ast.receiver.receiver instanceof ImplicitReceiver3 && ast.receiver.name === "$any" && ast.args.length === 1) {
14621
14653
  const expr = this.translate(ast.args[0]);
14622
14654
  const exprAsAny = ts64.factory.createAsExpression(expr, ts64.factory.createKeywordTypeNode(ts64.SyntaxKind.AnyKeyword));
14623
14655
  const result = ts64.factory.createParenthesizedExpression(exprAsAny);
@@ -15018,33 +15050,53 @@ var TcbSwitchOp = class extends TcbOp {
15018
15050
  }
15019
15051
  execute() {
15020
15052
  const switchExpression = tcbExpression(this.block.expression, this.tcb, this.scope);
15021
- const clauses = this.block.cases.map((current) => {
15053
+ const clauses = this.block.groups.flatMap((current) => {
15022
15054
  const checkBody = this.tcb.env.config.checkControlFlowBodies;
15023
15055
  const clauseScope = this.scope.createChildScope(this.scope, null, checkBody ? current.children : [], checkBody ? this.generateGuard(current, switchExpression) : null);
15024
15056
  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);
15057
+ return current.cases.map((switchCase, index) => {
15058
+ const statementsForCase = index === current.cases.length - 1 ? statements : [];
15059
+ return switchCase.expression === null ? ts70.factory.createDefaultClause(statementsForCase) : ts70.factory.createCaseClause(tcbExpression(switchCase.expression, this.tcb, this.scope), statementsForCase);
15060
+ });
15026
15061
  });
15027
15062
  this.scope.addStatement(ts70.factory.createSwitchStatement(switchExpression, ts70.factory.createCaseBlock(clauses)));
15028
15063
  return null;
15029
15064
  }
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);
15065
+ generateGuard(group, switchValue) {
15066
+ const hasDefault = group.cases.some((c) => c.expression === null);
15067
+ if (!hasDefault) {
15068
+ let guard2 = null;
15069
+ for (const switchCase of group.cases) {
15070
+ if (switchCase.expression !== null) {
15071
+ const expression = tcbExpression(switchCase.expression, this.tcb, this.scope);
15072
+ markIgnoreDiagnostics(expression);
15073
+ const comparison = ts70.factory.createBinaryExpression(switchValue, ts70.SyntaxKind.EqualsEqualsEqualsToken, expression);
15074
+ if (guard2 === null) {
15075
+ guard2 = comparison;
15076
+ } else {
15077
+ guard2 = ts70.factory.createBinaryExpression(guard2, ts70.SyntaxKind.BarBarToken, comparison);
15078
+ }
15079
+ }
15080
+ }
15081
+ return guard2;
15035
15082
  }
15036
15083
  let guard = null;
15037
- for (const current of this.block.cases) {
15038
- if (current.expression === null) {
15084
+ for (const currentGroup of this.block.groups) {
15085
+ if (currentGroup === group) {
15039
15086
  continue;
15040
15087
  }
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);
15088
+ for (const switchCase of currentGroup.cases) {
15089
+ if (switchCase.expression === null) {
15090
+ continue;
15091
+ }
15092
+ const expression = tcbExpression(switchCase.expression, this.tcb, this.scope);
15093
+ markIgnoreDiagnostics(expression);
15094
+ const comparison = ts70.factory.createBinaryExpression(switchValue, ts70.SyntaxKind.ExclamationEqualsEqualsToken, expression);
15095
+ if (guard === null) {
15096
+ guard = comparison;
15097
+ } else {
15098
+ guard = ts70.factory.createBinaryExpression(guard, ts70.SyntaxKind.AmpersandAmpersandToken, comparison);
15099
+ }
15048
15100
  }
15049
15101
  }
15050
15102
  return guard;
@@ -15052,7 +15104,7 @@ var TcbSwitchOp = class extends TcbOp {
15052
15104
  };
15053
15105
 
15054
15106
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/for_block.js
15055
- import { ImplicitReceiver as ImplicitReceiver4, PropertyRead as PropertyRead5, TmplAstVariable } from "@angular/compiler";
15107
+ import { ImplicitReceiver as ImplicitReceiver4, PropertyRead as PropertyRead5, ThisReceiver as ThisReceiver4, TmplAstVariable } from "@angular/compiler";
15056
15108
  import ts71 from "typescript";
15057
15109
  var TcbForOfOp = class extends TcbOp {
15058
15110
  tcb;
@@ -15100,7 +15152,7 @@ var TcbForLoopTrackTranslator = class extends TcbExpressionTranslator {
15100
15152
  }
15101
15153
  }
15102
15154
  resolve(ast) {
15103
- if (ast instanceof PropertyRead5 && ast.receiver instanceof ImplicitReceiver4) {
15155
+ if (ast instanceof PropertyRead5 && (ast.receiver instanceof ImplicitReceiver4 || ast.receiver instanceof ThisReceiver4)) {
15104
15156
  const target = this.tcb.boundTarget.getExpressionTarget(ast);
15105
15157
  if (target !== null && (!(target instanceof TmplAstVariable) || !this.allowedVariables.has(target))) {
15106
15158
  this.tcb.oobRecorder.illegalForLoopTrackAccess(this.tcb.id, this.block, ast);
@@ -15149,10 +15201,13 @@ var formControlInputFields = [
15149
15201
  // Should be kept in sync with the `FormUiControl` bindings,
15150
15202
  // defined in `packages/forms/signals/src/api/control.ts`.
15151
15203
  "errors",
15152
- "invalid",
15204
+ "dirty",
15153
15205
  "disabled",
15154
15206
  "disabledReasons",
15207
+ "hidden",
15208
+ "invalid",
15155
15209
  "name",
15210
+ "pending",
15156
15211
  "readonly",
15157
15212
  "touched",
15158
15213
  "max",
@@ -15200,7 +15255,7 @@ var TcbNativeFieldOp = class extends TcbOp {
15200
15255
  }
15201
15256
  execute() {
15202
15257
  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;
15258
+ const fieldBinding = inputs.find((input) => input.type === BindingType3.Property && input.name === "formField") ?? null;
15204
15259
  if (fieldBinding === null) {
15205
15260
  return null;
15206
15261
  }
@@ -15279,17 +15334,17 @@ var TcbNativeRadioButtonFieldOp = class extends TcbNativeFieldOp {
15279
15334
  return null;
15280
15335
  }
15281
15336
  };
15282
- function expandBoundAttributesForField(directive, node, customFieldType) {
15283
- const fieldBinding = node.inputs.find((input) => input.type === BindingType3.Property && input.name === "field");
15337
+ function expandBoundAttributesForField(directive, node, customFormControlType) {
15338
+ const fieldBinding = node.inputs.find((input) => input.type === BindingType3.Property && input.name === "formField");
15284
15339
  if (!fieldBinding) {
15285
15340
  return null;
15286
15341
  }
15287
15342
  let boundInputs = null;
15288
15343
  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);
15344
+ if (customFormControlType === "value") {
15345
+ primaryInput = getSyntheticFieldBoundInput(directive, "value", "value", fieldBinding, customFormControlType);
15346
+ } else if (customFormControlType === "checkbox") {
15347
+ primaryInput = getSyntheticFieldBoundInput(directive, "checked", "value", fieldBinding, customFormControlType);
15293
15348
  } else {
15294
15349
  primaryInput = null;
15295
15350
  }
@@ -15298,7 +15353,7 @@ function expandBoundAttributesForField(directive, node, customFieldType) {
15298
15353
  boundInputs.push(primaryInput);
15299
15354
  }
15300
15355
  for (const name of formControlInputFields) {
15301
- const input = getSyntheticFieldBoundInput(directive, name, name, fieldBinding, customFieldType);
15356
+ const input = getSyntheticFieldBoundInput(directive, name, name, fieldBinding, customFormControlType);
15302
15357
  if (input !== null) {
15303
15358
  boundInputs ??= [];
15304
15359
  boundInputs.push(input);
@@ -15307,7 +15362,7 @@ function expandBoundAttributesForField(directive, node, customFieldType) {
15307
15362
  return boundInputs;
15308
15363
  }
15309
15364
  function isFieldDirective(meta) {
15310
- if (meta.name !== "Field") {
15365
+ if (meta.name !== "FormField") {
15311
15366
  return false;
15312
15367
  }
15313
15368
  if (meta.ref.bestGuessOwningModule?.specifier === "@angular/forms/signals") {
@@ -15390,7 +15445,19 @@ function extractFieldValue(expression, tcb, scope) {
15390
15445
  return ts73.factory.createCallExpression(ts73.factory.createPropertyAccessExpression(innerCall, "value"), void 0, void 0);
15391
15446
  }
15392
15447
  function hasModelInput(name, meta) {
15393
- return !!meta.inputs.getByBindingPropertyName(name)?.some((v) => v.isSignal) && meta.outputs.hasBindingPropertyName(name + "Change");
15448
+ return meta.inputs.hasBindingPropertyName(name) && meta.outputs.hasBindingPropertyName(name + "Change");
15449
+ }
15450
+ function isFormControl(allDirectiveMatches) {
15451
+ let result = false;
15452
+ for (const match of allDirectiveMatches) {
15453
+ if (match.inputs.hasBindingPropertyName("formField")) {
15454
+ if (!isFieldDirective(match)) {
15455
+ return false;
15456
+ }
15457
+ result = true;
15458
+ }
15459
+ }
15460
+ return result;
15394
15461
  }
15395
15462
 
15396
15463
  // packages/compiler-cli/src/ngtsc/typecheck/src/ops/bindings.js
@@ -15478,14 +15545,16 @@ var TcbDirectiveInputsOp = class extends TcbOp {
15478
15545
  scope;
15479
15546
  node;
15480
15547
  dir;
15481
- customControlType;
15482
- constructor(tcb, scope, node, dir, customControlType) {
15548
+ isFormControl;
15549
+ customFormControlType;
15550
+ constructor(tcb, scope, node, dir, isFormControl2 = false, customFormControlType) {
15483
15551
  super();
15484
15552
  this.tcb = tcb;
15485
15553
  this.scope = scope;
15486
15554
  this.node = node;
15487
15555
  this.dir = dir;
15488
- this.customControlType = customControlType;
15556
+ this.isFormControl = isFormControl2;
15557
+ this.customFormControlType = customFormControlType;
15489
15558
  }
15490
15559
  get optional() {
15491
15560
  return false;
@@ -15494,9 +15563,11 @@ var TcbDirectiveInputsOp = class extends TcbOp {
15494
15563
  let dirId = null;
15495
15564
  const seenRequiredInputs = /* @__PURE__ */ new Set();
15496
15565
  const boundAttrs = getBoundAttributes(this.dir, this.node);
15497
- if (this.customControlType !== null) {
15566
+ if (this.customFormControlType !== null) {
15498
15567
  checkUnsupportedFieldBindings(this.node, customFormControlBannedInputFields, this.tcb);
15499
- const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customControlType);
15568
+ }
15569
+ if (this.customFormControlType !== null || this.isFormControl) {
15570
+ const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customFormControlType);
15500
15571
  if (additionalBindings !== null) {
15501
15572
  boundAttrs.push(...additionalBindings);
15502
15573
  }
@@ -15698,7 +15769,7 @@ var TcbDomSchemaCheckerOp = class extends TcbOp {
15698
15769
  };
15699
15770
 
15700
15771
  // 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";
15772
+ import { ImplicitReceiver as ImplicitReceiver5, ParsedEventType as ParsedEventType2, PropertyRead as PropertyRead7, TmplAstElement as TmplAstElement6 } from "@angular/compiler";
15702
15773
  import ts76 from "typescript";
15703
15774
  var EVENT_PARAMETER = "$event";
15704
15775
  function tcbEventHandlerExpression(ast, tcb, scope) {
@@ -15858,7 +15929,7 @@ var TcbUnclaimedOutputsOp = class extends TcbOp {
15858
15929
  };
15859
15930
  var TcbEventHandlerTranslator = class extends TcbExpressionTranslator {
15860
15931
  resolve(ast) {
15861
- if (ast instanceof PropertyRead7 && ast.receiver instanceof ImplicitReceiver5 && !(ast.receiver instanceof ThisReceiver3) && ast.name === EVENT_PARAMETER) {
15932
+ if (ast instanceof PropertyRead7 && ast.receiver instanceof ImplicitReceiver5 && ast.name === EVENT_PARAMETER) {
15862
15933
  const event = ts76.factory.createIdentifier(EVENT_PARAMETER);
15863
15934
  addParseSpanInfo(event, ast.nameSpan);
15864
15935
  return event;
@@ -15999,14 +16070,14 @@ var TcbDirectiveCtorOp = class extends TcbOp {
15999
16070
  scope;
16000
16071
  node;
16001
16072
  dir;
16002
- customControlType;
16003
- constructor(tcb, scope, node, dir, customControlType) {
16073
+ customFormControlType;
16074
+ constructor(tcb, scope, node, dir, customFormControlType) {
16004
16075
  super();
16005
16076
  this.tcb = tcb;
16006
16077
  this.scope = scope;
16007
16078
  this.node = node;
16008
16079
  this.dir = dir;
16009
- this.customControlType = customControlType;
16080
+ this.customFormControlType = customFormControlType;
16010
16081
  }
16011
16082
  get optional() {
16012
16083
  return true;
@@ -16022,8 +16093,8 @@ var TcbDirectiveCtorOp = class extends TcbOp {
16022
16093
  } else {
16023
16094
  span = this.node.startSourceSpan || this.node.sourceSpan;
16024
16095
  boundAttrs = getBoundAttributes(this.dir, this.node);
16025
- if (this.customControlType !== null) {
16026
- const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customControlType);
16096
+ if (this.customFormControlType !== null) {
16097
+ const additionalBindings = expandBoundAttributesForField(this.dir, this.node, this.customFormControlType);
16027
16098
  if (additionalBindings !== null) {
16028
16099
  boundAttrs.push(...additionalBindings);
16029
16100
  }
@@ -16171,7 +16242,7 @@ var TcbControlFlowContentProjectionOp = class extends TcbOp {
16171
16242
  }
16172
16243
  }
16173
16244
  } else if (child instanceof TmplAstSwitchBlock) {
16174
- for (const current of child.cases) {
16245
+ for (const current of child.groups) {
16175
16246
  if (this.shouldCheck(current)) {
16176
16247
  result.push(current);
16177
16248
  }
@@ -16720,15 +16791,16 @@ var Scope = class _Scope {
16720
16791
  }
16721
16792
  }
16722
16793
  appendDirectiveInputs(dir, node, dirMap, allDirectiveMatches) {
16723
- const customFieldType = allDirectiveMatches.some(isFieldDirective) ? getCustomFieldDirectiveType(dir) : null;
16724
- const directiveOp = this.getDirectiveOp(dir, node, customFieldType);
16794
+ const nodeIsFormControl = isFormControl(allDirectiveMatches);
16795
+ const customFormControlType = nodeIsFormControl ? getCustomFieldDirectiveType(dir) : null;
16796
+ const directiveOp = this.getDirectiveOp(dir, node, customFormControlType);
16725
16797
  const dirIndex = this.opQueue.push(directiveOp) - 1;
16726
16798
  dirMap.set(dir, dirIndex);
16727
16799
  if (isNativeField(dir, node, allDirectiveMatches)) {
16728
16800
  const inputType = node.name === "input" && node.attributes.find((attr) => attr.name === "type")?.value || null;
16729
16801
  this.opQueue.push(inputType === "radio" ? new TcbNativeRadioButtonFieldOp(this.tcb, this, node) : new TcbNativeFieldOp(this.tcb, this, node, inputType));
16730
16802
  }
16731
- this.opQueue.push(new TcbDirectiveInputsOp(this.tcb, this, node, dir, customFieldType));
16803
+ this.opQueue.push(new TcbDirectiveInputsOp(this.tcb, this, node, dir, nodeIsFormControl, customFormControlType));
16732
16804
  }
16733
16805
  getDirectiveOp(dir, node, customFieldType) {
16734
16806
  const dirRef = dir.ref;
@@ -20482,8 +20554,12 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
20482
20554
  const diagnostics = [];
20483
20555
  for (let i = 0; i < imports.length; i++) {
20484
20556
  const ref = imports[i];
20557
+ let refExpr = expr;
20558
+ if (ts90.isArrayLiteralExpression(expr) && expr.elements.length === imports.length && !expr.elements.some(ts90.isSpreadAssignment)) {
20559
+ refExpr = expr.elements[i];
20560
+ }
20485
20561
  if (Array.isArray(ref)) {
20486
- const { imports: childImports, diagnostics: childDiagnostics } = validateAndFlattenComponentImports(ref, expr, isDeferred);
20562
+ const { imports: childImports, diagnostics: childDiagnostics } = validateAndFlattenComponentImports(ref, refExpr, isDeferred);
20487
20563
  flattened.push(...childImports);
20488
20564
  diagnostics.push(...childDiagnostics);
20489
20565
  } else if (ref instanceof Reference) {
@@ -20501,11 +20577,11 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
20501
20577
  } else {
20502
20578
  let diagnosticNode;
20503
20579
  let diagnosticValue;
20504
- if (ref instanceof DynamicValue) {
20580
+ if (ref instanceof DynamicValue && isWithinExpression(ref.node, expr)) {
20505
20581
  diagnosticNode = ref.node;
20506
20582
  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];
20583
+ } else if (refExpr !== expr) {
20584
+ diagnosticNode = refExpr;
20509
20585
  diagnosticValue = ref;
20510
20586
  } else {
20511
20587
  diagnosticNode = expr;
@@ -20516,6 +20592,16 @@ function validateAndFlattenComponentImports(imports, expr, isDeferred) {
20516
20592
  }
20517
20593
  return { imports: flattened, diagnostics };
20518
20594
  }
20595
+ function isWithinExpression(node, expr) {
20596
+ let current = node;
20597
+ while (current !== void 0) {
20598
+ if (current === expr) {
20599
+ return true;
20600
+ }
20601
+ current = current.parent;
20602
+ }
20603
+ return false;
20604
+ }
20519
20605
  function isLikelyModuleWithProviders(value) {
20520
20606
  if (value instanceof SyntheticValue && isResolvedModuleWithProviders(value)) {
20521
20607
  return true;
@@ -22918,6 +23004,7 @@ export {
22918
23004
  makeDiagnostic,
22919
23005
  isFatalDiagnosticError,
22920
23006
  isLocalCompilationDiagnostics,
23007
+ DOC_PAGE_BASE_URL,
22921
23008
  ERROR_DETAILS_PAGE_BASE_URL,
22922
23009
  ExtendedTemplateDiagnosticName,
22923
23010
  isDtsPath,