@angular/core 20.0.0-next.7 → 20.0.0-next.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/{api.d-KjtSQajV.d.ts → api.d-B58KU5QT.d.ts} +25 -40
  2. package/chrome_dev_tools_performance.d-qv7drdAl.d.ts +1 -1
  3. package/{discovery.d-D6xf1HH-.d.ts → discovery.d-BCmtv8-u.d.ts} +21 -7
  4. package/event_dispatcher.d-DlbccpYq.d.ts +1 -1
  5. package/fesm2022/attribute-BWp59EjE.mjs +1 -1
  6. package/fesm2022/core.mjs +60 -159
  7. package/fesm2022/core.mjs.map +1 -1
  8. package/fesm2022/{debug_node-B3CixwNH.mjs → debug_node-sP8Ihhla.mjs} +191 -56
  9. package/fesm2022/debug_node-sP8Ihhla.mjs.map +1 -0
  10. package/fesm2022/primitives/di.mjs +1 -1
  11. package/fesm2022/primitives/event-dispatch.mjs +1 -1
  12. package/fesm2022/primitives/signals.mjs +4 -4
  13. package/fesm2022/{resource-DtpS_sTw.mjs → resource-aJC_NNLX.mjs} +29 -76
  14. package/fesm2022/resource-aJC_NNLX.mjs.map +1 -0
  15. package/fesm2022/{root_effect_scheduler-BK3l7wIO.mjs → root_effect_scheduler-C95A9imp.mjs} +25 -10
  16. package/fesm2022/root_effect_scheduler-C95A9imp.mjs.map +1 -0
  17. package/fesm2022/rxjs-interop.mjs +12 -7
  18. package/fesm2022/rxjs-interop.mjs.map +1 -1
  19. package/fesm2022/{signal-B6pMq7KS.mjs → signal-CVVPheSN.mjs} +13 -3
  20. package/fesm2022/{signal-B6pMq7KS.mjs.map → signal-CVVPheSN.mjs.map} +1 -1
  21. package/fesm2022/testing.mjs +40 -21
  22. package/fesm2022/testing.mjs.map +1 -1
  23. package/fesm2022/{untracked-Bz5WMeU1.mjs → untracked-BLZYODu2.mjs} +3 -3
  24. package/fesm2022/{untracked-Bz5WMeU1.mjs.map → untracked-BLZYODu2.mjs.map} +1 -1
  25. package/fesm2022/weak_ref-BaIq-pgY.mjs +1 -1
  26. package/graph.d-BcIOep_B.d.ts +1 -1
  27. package/index.d.ts +190 -127
  28. package/package.json +2 -2
  29. package/primitives/di/index.d.ts +1 -1
  30. package/primitives/event-dispatch/index.d.ts +1 -1
  31. package/primitives/signals/index.d.ts +3 -3
  32. package/rxjs-interop/index.d.ts +4 -4
  33. package/schematics/bundles/{apply_import_manager-DczRKpTm.js → apply_import_manager-CxaTw_Wy.js} +3 -3
  34. package/schematics/bundles/{change_tracker-CWLh-wes.js → change_tracker-CkPYZ_km.js} +3 -3
  35. package/schematics/bundles/{checker-_f5wM7PH.js → checker-Crz1jSZM.js} +389 -122
  36. package/schematics/bundles/cleanup-unused-imports.js +6 -6
  37. package/schematics/bundles/{compiler-BaCbbux6.js → compiler-B4MK7BP9.js} +193 -88
  38. package/schematics/bundles/compiler_host-CAfDJO3W.js +1 -1
  39. package/schematics/bundles/control-flow-migration.js +2 -2
  40. package/schematics/bundles/document-core.js +6 -6
  41. package/schematics/bundles/imports-CIX-JgAN.js +1 -1
  42. package/schematics/bundles/{index--W6S49uu.js → index-BbZ6cSR1.js} +6 -5
  43. package/schematics/bundles/{index-rsJ8I_hu.js → index-Bk_3geTg.js} +463 -327
  44. package/schematics/bundles/inject-flags.js +6 -6
  45. package/schematics/bundles/inject-migration.js +14 -11
  46. package/schematics/bundles/leading_space-D9nQ8UQC.js +1 -1
  47. package/schematics/bundles/{migrate_ts_type_references-C4D_SzJk.js → migrate_ts_type_references-D6T3FlkH.js} +7 -6
  48. package/schematics/bundles/ng_decorators-DznZ5jMl.js +1 -1
  49. package/schematics/bundles/nodes-B16H9JUd.js +1 -1
  50. package/schematics/bundles/output-migration.js +7 -7
  51. package/schematics/bundles/{project_paths-Ce0O2u-M.js → project_paths-CQ4-VKlW.js} +4 -4
  52. package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.js +1 -1
  53. package/schematics/bundles/property_name-BBwFuqMe.js +1 -1
  54. package/schematics/bundles/route-lazy-loading.js +4 -4
  55. package/schematics/bundles/self-closing-tags-migration.js +5 -5
  56. package/schematics/bundles/signal-input-migration.js +8 -8
  57. package/schematics/bundles/signal-queries-migration.js +8 -8
  58. package/schematics/bundles/signals.js +8 -8
  59. package/schematics/bundles/standalone-migration.js +5 -5
  60. package/schematics/bundles/symbol-VPWguRxr.js +1 -1
  61. package/schematics/bundles/test-bed-get.js +5 -5
  62. package/{signal.d-E0e5nW1p.d.ts → signal.d-D6VJ67xi.d.ts} +8 -2
  63. package/testing/index.d.ts +12 -9
  64. package/weak_ref.d-eGOEP9S1.d.ts +1 -1
  65. package/fesm2022/debug_node-B3CixwNH.mjs.map +0 -1
  66. package/fesm2022/resource-DtpS_sTw.mjs.map +0 -1
  67. package/fesm2022/root_effect_scheduler-BK3l7wIO.mjs.map +0 -1
@@ -1,15 +1,15 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.7
3
+ * @license Angular v20.0.0-next.9
4
4
  * (c) 2010-2025 Google LLC. https://angular.io/
5
5
  * License: MIT
6
6
  */
7
7
  'use strict';
8
8
 
9
- var compiler = require('./compiler-BaCbbux6.js');
9
+ var compiler = require('./compiler-B4MK7BP9.js');
10
10
  var ts = require('typescript');
11
11
  var p = require('path');
12
- var checker = require('./checker-_f5wM7PH.js');
12
+ var checker = require('./checker-Crz1jSZM.js');
13
13
  require('os');
14
14
 
15
15
  function _interopNamespaceDefault(e) {
@@ -892,7 +892,7 @@ const MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION = '18.0.0';
892
892
  function compileDeclareClassMetadata(metadata) {
893
893
  const definitionMap = new compiler.DefinitionMap();
894
894
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_VERSION$5));
895
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
895
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
896
896
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
897
897
  definitionMap.set('type', metadata.type);
898
898
  definitionMap.set('decorators', metadata.decorators);
@@ -910,7 +910,7 @@ function compileComponentDeclareClassMetadata(metadata, dependencies) {
910
910
  callbackReturnDefinitionMap.set('ctorParameters', metadata.ctorParameters ?? compiler.literal(null));
911
911
  callbackReturnDefinitionMap.set('propDecorators', metadata.propDecorators ?? compiler.literal(null));
912
912
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_DEFER_SUPPORT_VERSION));
913
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
913
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
914
914
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
915
915
  definitionMap.set('type', metadata.type);
916
916
  definitionMap.set('resolveDeferredDeps', compileComponentMetadataAsyncResolver(dependencies));
@@ -1005,7 +1005,7 @@ function createDirectiveDefinitionMap(meta) {
1005
1005
  const definitionMap = new compiler.DefinitionMap();
1006
1006
  const minVersion = getMinimumVersionForPartialOutput(meta);
1007
1007
  definitionMap.set('minVersion', compiler.literal(minVersion));
1008
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
1008
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
1009
1009
  // e.g. `type: MyDirective`
1010
1010
  definitionMap.set('type', meta.type.value);
1011
1011
  if (meta.isStandalone !== undefined) {
@@ -1421,7 +1421,7 @@ const MINIMUM_PARTIAL_LINKER_VERSION$4 = '12.0.0';
1421
1421
  function compileDeclareFactoryFunction(meta) {
1422
1422
  const definitionMap = new compiler.DefinitionMap();
1423
1423
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_VERSION$4));
1424
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
1424
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
1425
1425
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
1426
1426
  definitionMap.set('type', meta.type.value);
1427
1427
  definitionMap.set('deps', compileDependencies(meta.deps));
@@ -1456,7 +1456,7 @@ function compileDeclareInjectableFromMetadata(meta) {
1456
1456
  function createInjectableDefinitionMap(meta) {
1457
1457
  const definitionMap = new compiler.DefinitionMap();
1458
1458
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_VERSION$3));
1459
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
1459
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
1460
1460
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
1461
1461
  definitionMap.set('type', meta.type.value);
1462
1462
  // Only generate providedIn property if it has a non-null value
@@ -1507,7 +1507,7 @@ function compileDeclareInjectorFromMetadata(meta) {
1507
1507
  function createInjectorDefinitionMap(meta) {
1508
1508
  const definitionMap = new compiler.DefinitionMap();
1509
1509
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_VERSION$2));
1510
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
1510
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
1511
1511
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
1512
1512
  definitionMap.set('type', meta.type.value);
1513
1513
  definitionMap.set('providers', meta.providers);
@@ -1540,7 +1540,7 @@ function createNgModuleDefinitionMap(meta) {
1540
1540
  throw new Error('Invalid path! Local compilation mode should not get into the partial compilation path');
1541
1541
  }
1542
1542
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_VERSION$1));
1543
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
1543
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
1544
1544
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
1545
1545
  definitionMap.set('type', meta.type.value);
1546
1546
  // We only generate the keys in the metadata if the arrays contain values.
@@ -1591,7 +1591,7 @@ function compileDeclarePipeFromMetadata(meta) {
1591
1591
  function createPipeDefinitionMap(meta) {
1592
1592
  const definitionMap = new compiler.DefinitionMap();
1593
1593
  definitionMap.set('minVersion', compiler.literal(MINIMUM_PARTIAL_LINKER_VERSION));
1594
- definitionMap.set('version', compiler.literal('20.0.0-next.7'));
1594
+ definitionMap.set('version', compiler.literal('20.0.0-next.9'));
1595
1595
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
1596
1596
  // e.g. `type: MyPipe`
1597
1597
  definitionMap.set('type', meta.type.value);
@@ -2582,6 +2582,7 @@ class DtsMetadataReader {
2582
2582
  name,
2583
2583
  nameExpr: null,
2584
2584
  isStandalone,
2585
+ isPure: null, // The DTS has no idea about that
2585
2586
  decorator: null,
2586
2587
  isExplicitlyDeferred: false,
2587
2588
  };
@@ -7916,6 +7917,7 @@ function parseExtractedTemplate(template, sourceStr, sourceParseRange, escapedSt
7916
7917
  escapedString,
7917
7918
  enableBlockSyntax: options.enableBlockSyntax,
7918
7919
  enableLetSyntax: options.enableLetSyntax,
7920
+ enableSelectorless: options.enableSelectorless,
7919
7921
  };
7920
7922
  const parsedTemplate = compiler.parseTemplate(sourceStr, sourceMapUrl ?? '', {
7921
7923
  ...commonParseOptions,
@@ -8879,7 +8881,8 @@ class ComponentDecoratorHandler {
8879
8881
  enableHmr;
8880
8882
  implicitStandaloneValue;
8881
8883
  typeCheckHostBindings;
8882
- constructor(reflector, evaluator, metaRegistry, metaReader, scopeReader, compilerHost, scopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, strictCtorDeps, resourceLoader, rootDirs, defaultPreserveWhitespaces, i18nUseExternalIds, enableI18nLegacyMessageIdFormat, usePoisonedData, i18nNormalizeLineEndingsInICUs, moduleResolver, cycleAnalyzer, cycleHandlingStrategy, refEmitter, referencesRegistry, depTracker, injectableRegistry, semanticDepGraphUpdater, annotateForClosureCompiler, perf, hostDirectivesResolver, importTracker, includeClassMetadata, compilationMode, deferredSymbolTracker, forbidOrphanRendering, enableBlockSyntax, enableLetSyntax, externalRuntimeStyles, localCompilationExtraImportsTracker, jitDeclarationRegistry, i18nPreserveSignificantWhitespace, strictStandalone, enableHmr, implicitStandaloneValue, typeCheckHostBindings) {
8884
+ enableSelectorless;
8885
+ constructor(reflector, evaluator, metaRegistry, metaReader, scopeReader, compilerHost, scopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, strictCtorDeps, resourceLoader, rootDirs, defaultPreserveWhitespaces, i18nUseExternalIds, enableI18nLegacyMessageIdFormat, usePoisonedData, i18nNormalizeLineEndingsInICUs, moduleResolver, cycleAnalyzer, cycleHandlingStrategy, refEmitter, referencesRegistry, depTracker, injectableRegistry, semanticDepGraphUpdater, annotateForClosureCompiler, perf, hostDirectivesResolver, importTracker, includeClassMetadata, compilationMode, deferredSymbolTracker, forbidOrphanRendering, enableBlockSyntax, enableLetSyntax, externalRuntimeStyles, localCompilationExtraImportsTracker, jitDeclarationRegistry, i18nPreserveSignificantWhitespace, strictStandalone, enableHmr, implicitStandaloneValue, typeCheckHostBindings, enableSelectorless) {
8883
8886
  this.reflector = reflector;
8884
8887
  this.evaluator = evaluator;
8885
8888
  this.metaRegistry = metaRegistry;
@@ -8924,12 +8927,14 @@ class ComponentDecoratorHandler {
8924
8927
  this.enableHmr = enableHmr;
8925
8928
  this.implicitStandaloneValue = implicitStandaloneValue;
8926
8929
  this.typeCheckHostBindings = typeCheckHostBindings;
8930
+ this.enableSelectorless = enableSelectorless;
8927
8931
  this.extractTemplateOptions = {
8928
8932
  enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
8929
8933
  i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs,
8930
8934
  usePoisonedData: this.usePoisonedData,
8931
8935
  enableBlockSyntax: this.enableBlockSyntax,
8932
8936
  enableLetSyntax: this.enableLetSyntax,
8937
+ enableSelectorless: this.enableSelectorless,
8933
8938
  preserveSignificantWhitespace: this.i18nPreserveSignificantWhitespace,
8934
8939
  };
8935
8940
  // Dependencies can't be deferred during HMR, because the HMR update module can't have
@@ -9198,6 +9203,7 @@ class ComponentDecoratorHandler {
9198
9203
  usePoisonedData: this.usePoisonedData,
9199
9204
  enableBlockSyntax: this.enableBlockSyntax,
9200
9205
  enableLetSyntax: this.enableLetSyntax,
9206
+ enableSelectorless: this.enableSelectorless,
9201
9207
  preserveSignificantWhitespace: this.i18nPreserveSignificantWhitespace,
9202
9208
  }, this.compilationMode);
9203
9209
  if (this.compilationMode === checker.CompilationMode.LOCAL &&
@@ -9471,6 +9477,7 @@ class ComponentDecoratorHandler {
9471
9477
  }
9472
9478
  }
9473
9479
  }
9480
+ // TODO(crisbeto): implement for selectorless.
9474
9481
  const binder = new compiler.R3TargetBinder(matcher);
9475
9482
  const boundTemplate = binder.bind({ template: analysis.template.diagNodes });
9476
9483
  context.addComponent({
@@ -9493,6 +9500,7 @@ class ComponentDecoratorHandler {
9493
9500
  // Don't type-check components that had errors in their scopes, unless requested.
9494
9501
  return;
9495
9502
  }
9503
+ // TODO(crisbeto): implement for selectorless.
9496
9504
  const binder = new compiler.R3TargetBinder(scope.matcher);
9497
9505
  const templateContext = {
9498
9506
  nodes: meta.template.diagNodes,
@@ -9577,168 +9585,16 @@ class ComponentDecoratorHandler {
9577
9585
  return {};
9578
9586
  }
9579
9587
  const scope = this.scopeReader.getScopeForComponent(node);
9580
- if (scope !== null) {
9581
- // Replace the empty components and directives from the analyze() step with a fully expanded
9582
- // scope. This is possible now because during resolve() the whole compilation unit has been
9583
- // fully analyzed.
9584
- //
9585
- // First it needs to be determined if actually importing the directives/pipes used in the
9586
- // template would create a cycle. Currently ngtsc refuses to generate cycles, so an option
9587
- // known as "remote scoping" is used if a cycle would be created. In remote scoping, the
9588
- // module file sets the directives/pipes on the ɵcmp of the component, without
9589
- // requiring new imports (but also in a way that breaks tree shaking).
9590
- //
9591
- // Determining this is challenging, because the TemplateDefinitionBuilder is responsible for
9592
- // matching directives and pipes in the template; however, that doesn't run until the actual
9593
- // compile() step. It's not possible to run template compilation sooner as it requires the
9594
- // ConstantPool for the overall file being compiled (which isn't available until the
9595
- // transform step).
9596
- //
9597
- // Instead, directives/pipes are matched independently here, using the R3TargetBinder. This
9598
- // is an alternative implementation of template matching which is used for template
9599
- // type-checking and will eventually replace matching in the TemplateDefinitionBuilder.
9600
- const isModuleScope = scope.kind === checker.ComponentScopeKind.NgModule;
9601
- // Dependencies coming from the regular `imports` field.
9602
- const dependencies = isModuleScope ? scope.compilation.dependencies : scope.dependencies;
9603
- // Dependencies from the `@Component.deferredImports` field.
9604
- const explicitlyDeferredDependencies = getExplicitlyDeferredDeps(scope);
9605
- // Mark the component is an NgModule-based component with its NgModule in a different file
9606
- // then mark this file for extra import generation
9607
- if (isModuleScope && context.fileName !== checker.getSourceFile(scope.ngModule).fileName) {
9608
- this.localCompilationExtraImportsTracker?.markFileForExtraImportGeneration(context);
9609
- }
9610
- // Make sure that `@Component.imports` and `@Component.deferredImports` do not have
9611
- // the same dependencies.
9612
- if (metadata.isStandalone &&
9613
- analysis.rawDeferredImports !== null &&
9614
- explicitlyDeferredDependencies.length > 0) {
9615
- const diagnostic = validateNoImportOverlap(dependencies, explicitlyDeferredDependencies, analysis.rawDeferredImports);
9616
- if (diagnostic !== null) {
9617
- diagnostics.push(diagnostic);
9618
- }
9619
- }
9620
- // Set up the R3TargetBinder.
9621
- const binder = createTargetBinder(dependencies);
9622
- let allDependencies = dependencies;
9623
- let deferBlockBinder = binder;
9624
- // If there are any explicitly deferred dependencies (via `@Component.deferredImports`),
9625
- // re-compute the list of dependencies and create a new binder for defer blocks. This
9626
- // is because we have deferred dependencies that are not in the standard imports list
9627
- // and need to be referenced later when determining what dependencies need to be in a
9628
- // defer function / instruction call. Otherwise they end up treated as a standard
9629
- // import, which is wrong.
9630
- if (explicitlyDeferredDependencies.length > 0) {
9631
- allDependencies = [...explicitlyDeferredDependencies, ...dependencies];
9632
- deferBlockBinder = createTargetBinder(allDependencies);
9633
- }
9634
- // Set up the pipes map that is later used to determine which dependencies are used in
9635
- // the template.
9636
- const pipes = extractPipes(allDependencies);
9637
- // Next, the component template AST is bound using the R3TargetBinder. This produces a
9638
- // BoundTarget, which is similar to a ts.TypeChecker.
9639
- const bound = binder.bind({ template: metadata.template.nodes });
9640
- // Find all defer blocks used in the template and for each block
9641
- // bind its own scope.
9642
- const deferBlocks = new Map();
9643
- for (const deferBlock of bound.getDeferBlocks()) {
9644
- deferBlocks.set(deferBlock, deferBlockBinder.bind({ template: deferBlock.children }));
9645
- }
9646
- // Register all Directives and Pipes used at the top level (outside
9647
- // of any defer blocks), which would be eagerly referenced.
9648
- const eagerlyUsed = new Set();
9649
- if (this.enableHmr) {
9650
- // In HMR we need to preserve all the dependencies, because they have to remain consistent
9651
- // with the initially-generated code no matter what the template looks like.
9652
- for (const dep of dependencies) {
9653
- if (dep.ref.node !== node) {
9654
- eagerlyUsed.add(dep.ref.node);
9655
- }
9656
- else {
9657
- const used = bound.getEagerlyUsedDirectives();
9658
- if (used.some((current) => current.ref.node === node)) {
9659
- eagerlyUsed.add(node);
9660
- }
9661
- }
9662
- }
9663
- }
9664
- else {
9665
- for (const dir of bound.getEagerlyUsedDirectives()) {
9666
- eagerlyUsed.add(dir.ref.node);
9667
- }
9668
- for (const name of bound.getEagerlyUsedPipes()) {
9669
- if (!pipes.has(name)) {
9670
- continue;
9671
- }
9672
- eagerlyUsed.add(pipes.get(name).ref.node);
9673
- }
9674
- }
9675
- // Set of Directives and Pipes used across the entire template,
9676
- // including all defer blocks.
9677
- const wholeTemplateUsed = new Set(eagerlyUsed);
9678
- for (const bound of deferBlocks.values()) {
9679
- for (const dir of bound.getUsedDirectives()) {
9680
- wholeTemplateUsed.add(dir.ref.node);
9681
- }
9682
- for (const name of bound.getUsedPipes()) {
9683
- if (!pipes.has(name)) {
9684
- continue;
9685
- }
9686
- wholeTemplateUsed.add(pipes.get(name).ref.node);
9687
- }
9688
- }
9689
- const declarations = new Map();
9690
- // Transform the dependencies list, filtering out unused dependencies.
9691
- for (const dep of allDependencies) {
9692
- // Only emit references to each dependency once.
9693
- if (declarations.has(dep.ref.node)) {
9694
- continue;
9695
- }
9696
- switch (dep.kind) {
9697
- case checker.MetaKind.Directive:
9698
- if (!wholeTemplateUsed.has(dep.ref.node) || dep.matchSource !== checker.MatchSource.Selector) {
9699
- continue;
9700
- }
9701
- const dirType = this.refEmitter.emit(dep.ref, context);
9702
- checker.assertSuccessfulReferenceEmit(dirType, node.name, dep.isComponent ? 'component' : 'directive');
9703
- declarations.set(dep.ref.node, {
9704
- kind: compiler.R3TemplateDependencyKind.Directive,
9705
- ref: dep.ref,
9706
- type: dirType.expression,
9707
- importedFile: dirType.importedFile,
9708
- selector: dep.selector,
9709
- inputs: dep.inputs.propertyNames,
9710
- outputs: dep.outputs.propertyNames,
9711
- exportAs: dep.exportAs,
9712
- isComponent: dep.isComponent,
9713
- });
9714
- break;
9715
- case checker.MetaKind.Pipe:
9716
- if (!wholeTemplateUsed.has(dep.ref.node)) {
9717
- continue;
9718
- }
9719
- const pipeType = this.refEmitter.emit(dep.ref, context);
9720
- checker.assertSuccessfulReferenceEmit(pipeType, node.name, 'pipe');
9721
- declarations.set(dep.ref.node, {
9722
- kind: compiler.R3TemplateDependencyKind.Pipe,
9723
- type: pipeType.expression,
9724
- name: dep.name,
9725
- ref: dep.ref,
9726
- importedFile: pipeType.importedFile,
9727
- });
9728
- break;
9729
- case checker.MetaKind.NgModule:
9730
- const ngModuleType = this.refEmitter.emit(dep.ref, context);
9731
- checker.assertSuccessfulReferenceEmit(ngModuleType, node.name, 'NgModule');
9732
- declarations.set(dep.ref.node, {
9733
- kind: compiler.R3TemplateDependencyKind.NgModule,
9734
- type: ngModuleType.expression,
9735
- importedFile: ngModuleType.importedFile,
9736
- });
9737
- break;
9738
- }
9739
- }
9740
- const getSemanticReference = (decl) => this.semanticDepGraphUpdater.getSemanticReference(decl.ref.node, decl.type);
9588
+ if (scope === null) {
9589
+ // If there is no scope, we can still use the binder to retrieve *some* information about the
9590
+ // deferred blocks.
9591
+ data.deferPerBlockDependencies = this.locateDeferBlocksWithoutScope(metadata.template);
9592
+ }
9593
+ else {
9594
+ const { eagerlyUsed, deferBlocks, allDependencies, wholeTemplateUsed } = this.resolveComponentDependencies(node, context, analysis, scope, metadata, diagnostics);
9595
+ const declarations = this.componentDependenciesToDeclarations(node, context, allDependencies, wholeTemplateUsed);
9741
9596
  if (this.semanticDepGraphUpdater !== null) {
9597
+ const getSemanticReference = (decl) => this.semanticDepGraphUpdater.getSemanticReference(decl.ref.node, decl.type);
9742
9598
  symbol.usedDirectives = Array.from(declarations.values())
9743
9599
  .filter(isUsedDirective)
9744
9600
  .map(getSemanticReference);
@@ -9746,142 +9602,17 @@ class ComponentDecoratorHandler {
9746
9602
  .filter(isUsedPipe)
9747
9603
  .map(getSemanticReference);
9748
9604
  }
9749
- const eagerDeclarations = Array.from(declarations.values()).filter((decl) => decl.kind === compiler.R3TemplateDependencyKind.NgModule || eagerlyUsed.has(decl.ref.node));
9750
9605
  // Process information related to defer blocks
9751
9606
  if (this.compilationMode !== checker.CompilationMode.LOCAL) {
9752
9607
  this.resolveDeferBlocks(node, deferBlocks, declarations, data, analysis, eagerlyUsed);
9753
9608
  }
9754
- const cyclesFromDirectives = new Map();
9755
- const cyclesFromPipes = new Map();
9756
- // Scan through the directives/pipes actually used in the template and check whether any
9757
- // import which needs to be generated would create a cycle. This check is skipped for
9758
- // standalone components as the dependencies of a standalone component have already been
9759
- // imported directly by the user, so Angular won't introduce any imports that aren't already
9760
- // in the user's program.
9761
- if (!metadata.isStandalone) {
9762
- for (const usedDep of eagerDeclarations) {
9763
- const cycle = this._checkForCyclicImport(usedDep.importedFile, usedDep.type, context);
9764
- if (cycle !== null) {
9765
- switch (usedDep.kind) {
9766
- case compiler.R3TemplateDependencyKind.Directive:
9767
- cyclesFromDirectives.set(usedDep, cycle);
9768
- break;
9769
- case compiler.R3TemplateDependencyKind.Pipe:
9770
- cyclesFromPipes.set(usedDep, cycle);
9771
- break;
9772
- }
9773
- }
9774
- }
9775
- }
9776
- // Check whether any usages of standalone components in imports requires the dependencies
9777
- // array to be wrapped in a closure. This check is technically a heuristic as there's no
9778
- // direct way to check whether a `Reference` came from a `forwardRef`. Instead, we check if
9779
- // the reference is `synthetic`, implying it came from _any_ foreign function resolver,
9780
- // including the `forwardRef` resolver.
9781
- const standaloneImportMayBeForwardDeclared = analysis.resolvedImports !== null && analysis.resolvedImports.some((ref) => ref.synthetic);
9782
- const cycleDetected = cyclesFromDirectives.size !== 0 || cyclesFromPipes.size !== 0;
9783
- if (!cycleDetected) {
9784
- // No cycle was detected. Record the imports that need to be created in the cycle detector
9785
- // so that future cyclic import checks consider their production.
9786
- for (const { type, importedFile } of eagerDeclarations) {
9787
- this.maybeRecordSyntheticImport(importedFile, type, context);
9788
- }
9789
- // Check whether the dependencies arrays in ɵcmp need to be wrapped in a closure.
9790
- // This is required if any dependency reference is to a declaration in the same file
9791
- // but declared after this component.
9792
- const declarationIsForwardDeclared = eagerDeclarations.some((decl) => checker.isExpressionForwardReference(decl.type, node.name, context));
9793
- if (this.compilationMode !== checker.CompilationMode.LOCAL &&
9794
- (declarationIsForwardDeclared || standaloneImportMayBeForwardDeclared)) {
9795
- data.declarationListEmitMode = 1 /* DeclarationListEmitMode.Closure */;
9796
- }
9797
- data.declarations = eagerDeclarations;
9798
- // Register extra local imports.
9799
- if (this.compilationMode === checker.CompilationMode.LOCAL &&
9800
- this.localCompilationExtraImportsTracker !== null) {
9801
- // In global compilation mode `eagerDeclarations` contains "all" the component
9802
- // dependencies, whose import statements will be added to the file. In local compilation
9803
- // mode `eagerDeclarations` only includes the "local" dependencies, meaning those that are
9804
- // declared inside this compilation unit.Here the import info of these local dependencies
9805
- // are added to the tracker so that we can generate extra imports representing these local
9806
- // dependencies. For non-local dependencies we use another technique of adding some
9807
- // best-guess extra imports globally to all files using
9808
- // `localCompilationExtraImportsTracker.addGlobalImportFromIdentifier`.
9809
- for (const { type } of eagerDeclarations) {
9810
- if (type instanceof compiler.ExternalExpr && type.value.moduleName) {
9811
- this.localCompilationExtraImportsTracker.addImportForFile(context, type.value.moduleName);
9812
- }
9813
- }
9814
- }
9815
- }
9816
- else {
9817
- if (this.cycleHandlingStrategy === 0 /* CycleHandlingStrategy.UseRemoteScoping */) {
9818
- // Declaring the directiveDefs/pipeDefs arrays directly would require imports that would
9819
- // create a cycle. Instead, mark this component as requiring remote scoping, so that the
9820
- // NgModule file will take care of setting the directives for the component.
9821
- this.scopeRegistry.setComponentRemoteScope(node, eagerDeclarations.filter(isUsedDirective).map((dir) => dir.ref), eagerDeclarations.filter(isUsedPipe).map((pipe) => pipe.ref));
9822
- symbol.isRemotelyScoped = true;
9823
- // If a semantic graph is being tracked, record the fact that this component is remotely
9824
- // scoped with the declaring NgModule symbol as the NgModule's emit becomes dependent on
9825
- // the directive/pipe usages of this component.
9826
- if (this.semanticDepGraphUpdater !== null &&
9827
- scope.kind === checker.ComponentScopeKind.NgModule &&
9828
- scope.ngModule !== null) {
9829
- const moduleSymbol = this.semanticDepGraphUpdater.getSymbol(scope.ngModule);
9830
- if (!(moduleSymbol instanceof NgModuleSymbol)) {
9831
- throw new Error(`AssertionError: Expected ${scope.ngModule.name} to be an NgModuleSymbol.`);
9832
- }
9833
- moduleSymbol.addRemotelyScopedComponent(symbol, symbol.usedDirectives, symbol.usedPipes);
9834
- }
9835
- }
9836
- else {
9837
- // We are not able to handle this cycle so throw an error.
9838
- const relatedMessages = [];
9839
- for (const [dir, cycle] of cyclesFromDirectives) {
9840
- relatedMessages.push(makeCyclicImportInfo(dir.ref, dir.isComponent ? 'component' : 'directive', cycle));
9841
- }
9842
- for (const [pipe, cycle] of cyclesFromPipes) {
9843
- relatedMessages.push(makeCyclicImportInfo(pipe.ref, 'pipe', cycle));
9844
- }
9845
- throw new checker.FatalDiagnosticError(checker.ErrorCode.IMPORT_CYCLE_DETECTED, node, 'One or more import cycles would need to be created to compile this component, ' +
9846
- 'which is not supported by the current compiler configuration.', relatedMessages);
9847
- }
9848
- }
9849
- }
9850
- else {
9851
- // If there is no scope, we can still use the binder to retrieve *some* information about the
9852
- // deferred blocks.
9853
- data.deferPerBlockDependencies = this.locateDeferBlocksWithoutScope(metadata.template);
9609
+ this.handleDependencyCycles(node, context, scope, data, analysis, metadata, declarations, eagerlyUsed, symbol);
9854
9610
  }
9855
9611
  // Run diagnostics only in global mode.
9856
9612
  if (this.compilationMode !== checker.CompilationMode.LOCAL) {
9857
- // Validate `@Component.imports` and `@Component.deferredImports` fields.
9858
- if (analysis.resolvedImports !== null && analysis.rawImports !== null) {
9859
- const importDiagnostics = validateStandaloneImports(analysis.resolvedImports, analysis.rawImports, this.metaReader, this.scopeReader, false /* isDeferredImport */);
9860
- diagnostics.push(...importDiagnostics);
9861
- }
9862
- if (analysis.resolvedDeferredImports !== null && analysis.rawDeferredImports !== null) {
9863
- const importDiagnostics = validateStandaloneImports(analysis.resolvedDeferredImports, analysis.rawDeferredImports, this.metaReader, this.scopeReader, true /* isDeferredImport */);
9864
- diagnostics.push(...importDiagnostics);
9865
- }
9866
- if (analysis.providersRequiringFactory !== null &&
9867
- analysis.meta.providers instanceof compiler.WrappedNodeExpr) {
9868
- const providerDiagnostics = checker.getProviderDiagnostics(analysis.providersRequiringFactory, analysis.meta.providers.node, this.injectableRegistry);
9869
- diagnostics.push(...providerDiagnostics);
9870
- }
9871
- if (analysis.viewProvidersRequiringFactory !== null &&
9872
- analysis.meta.viewProviders instanceof compiler.WrappedNodeExpr) {
9873
- const viewProviderDiagnostics = checker.getProviderDiagnostics(analysis.viewProvidersRequiringFactory, analysis.meta.viewProviders.node, this.injectableRegistry);
9874
- diagnostics.push(...viewProviderDiagnostics);
9875
- }
9876
- const directiveDiagnostics = checker.getDirectiveDiagnostics(node, this.injectableRegistry, this.evaluator, this.reflector, this.scopeRegistry, this.strictCtorDeps, 'Component');
9877
- if (directiveDiagnostics !== null) {
9878
- diagnostics.push(...directiveDiagnostics);
9879
- }
9880
- const hostDirectivesDiagnostics = analysis.hostDirectives && analysis.rawHostDirectives
9881
- ? checker.validateHostDirectives(analysis.rawHostDirectives, analysis.hostDirectives, this.metaReader)
9882
- : null;
9883
- if (hostDirectivesDiagnostics !== null) {
9884
- diagnostics.push(...hostDirectivesDiagnostics);
9613
+ const nonLocalDiagnostics = this.getNonLocalDiagnostics(node, analysis);
9614
+ if (nonLocalDiagnostics !== null) {
9615
+ diagnostics.push(...nonLocalDiagnostics);
9885
9616
  }
9886
9617
  }
9887
9618
  if (diagnostics.length > 0) {
@@ -10056,13 +9787,328 @@ class ComponentDecoratorHandler {
10056
9787
  ? null
10057
9788
  : getHmrUpdateDeclaration(res, pool.statements, hmrMeta, node);
10058
9789
  }
9790
+ /**
9791
+ * Determines the dependencies of a component and
9792
+ * categorizes them based on how they were introduced.
9793
+ */
9794
+ resolveComponentDependencies(node, context, analysis, scope, metadata, diagnostics) {
9795
+ // Replace the empty components and directives from the analyze() step with a fully expanded
9796
+ // scope. This is possible now because during resolve() the whole compilation unit has been
9797
+ // fully analyzed.
9798
+ //
9799
+ // First it needs to be determined if actually importing the directives/pipes used in the
9800
+ // template would create a cycle. Currently ngtsc refuses to generate cycles, so an option
9801
+ // known as "remote scoping" is used if a cycle would be created. In remote scoping, the
9802
+ // module file sets the directives/pipes on the ɵcmp of the component, without
9803
+ // requiring new imports (but also in a way that breaks tree shaking).
9804
+ //
9805
+ // Determining this is challenging, because the TemplateDefinitionBuilder is responsible for
9806
+ // matching directives and pipes in the template; however, that doesn't run until the actual
9807
+ // compile() step. It's not possible to run template compilation sooner as it requires the
9808
+ // ConstantPool for the overall file being compiled (which isn't available until the
9809
+ // transform step).
9810
+ //
9811
+ // Instead, directives/pipes are matched independently here, using the R3TargetBinder. This
9812
+ // is an alternative implementation of template matching which is used for template
9813
+ // type-checking and will eventually replace matching in the TemplateDefinitionBuilder.
9814
+ const isModuleScope = scope.kind === checker.ComponentScopeKind.NgModule;
9815
+ // Dependencies coming from the regular `imports` field.
9816
+ const dependencies = isModuleScope ? scope.compilation.dependencies : scope.dependencies;
9817
+ // Dependencies from the `@Component.deferredImports` field.
9818
+ const explicitlyDeferredDependencies = getExplicitlyDeferredDeps(scope);
9819
+ // Mark the component is an NgModule-based component with its NgModule in a different file
9820
+ // then mark this file for extra import generation
9821
+ if (isModuleScope && context.fileName !== checker.getSourceFile(scope.ngModule).fileName) {
9822
+ this.localCompilationExtraImportsTracker?.markFileForExtraImportGeneration(context);
9823
+ }
9824
+ // Make sure that `@Component.imports` and `@Component.deferredImports` do not have
9825
+ // the same dependencies.
9826
+ if (metadata.isStandalone &&
9827
+ analysis.rawDeferredImports !== null &&
9828
+ explicitlyDeferredDependencies.length > 0) {
9829
+ const diagnostic = validateNoImportOverlap(dependencies, explicitlyDeferredDependencies, analysis.rawDeferredImports);
9830
+ if (diagnostic !== null) {
9831
+ diagnostics.push(diagnostic);
9832
+ }
9833
+ }
9834
+ // Set up the R3TargetBinder.
9835
+ const binder = createTargetBinder(dependencies);
9836
+ let allDependencies = dependencies;
9837
+ let deferBlockBinder = binder;
9838
+ // If there are any explicitly deferred dependencies (via `@Component.deferredImports`),
9839
+ // re-compute the list of dependencies and create a new binder for defer blocks. This
9840
+ // is because we have deferred dependencies that are not in the standard imports list
9841
+ // and need to be referenced later when determining what dependencies need to be in a
9842
+ // defer function / instruction call. Otherwise they end up treated as a standard
9843
+ // import, which is wrong.
9844
+ if (explicitlyDeferredDependencies.length > 0) {
9845
+ allDependencies = [...explicitlyDeferredDependencies, ...dependencies];
9846
+ deferBlockBinder = createTargetBinder(allDependencies);
9847
+ }
9848
+ // Set up the pipes map that is later used to determine which dependencies are used in
9849
+ // the template.
9850
+ const pipes = extractPipes(allDependencies);
9851
+ // Next, the component template AST is bound using the R3TargetBinder. This produces a
9852
+ // BoundTarget, which is similar to a ts.TypeChecker.
9853
+ const bound = binder.bind({ template: metadata.template.nodes });
9854
+ // Find all defer blocks used in the template and for each block
9855
+ // bind its own scope.
9856
+ const deferBlocks = new Map();
9857
+ for (const deferBlock of bound.getDeferBlocks()) {
9858
+ deferBlocks.set(deferBlock, deferBlockBinder.bind({ template: deferBlock.children }));
9859
+ }
9860
+ // Register all Directives and Pipes used at the top level (outside
9861
+ // of any defer blocks), which would be eagerly referenced.
9862
+ const eagerlyUsed = new Set();
9863
+ if (this.enableHmr) {
9864
+ // In HMR we need to preserve all the dependencies, because they have to remain consistent
9865
+ // with the initially-generated code no matter what the template looks like.
9866
+ for (const dep of dependencies) {
9867
+ if (dep.ref.node !== node) {
9868
+ eagerlyUsed.add(dep.ref.node);
9869
+ }
9870
+ else {
9871
+ const used = bound.getEagerlyUsedDirectives();
9872
+ if (used.some((current) => current.ref.node === node)) {
9873
+ eagerlyUsed.add(node);
9874
+ }
9875
+ }
9876
+ }
9877
+ }
9878
+ else {
9879
+ for (const dir of bound.getEagerlyUsedDirectives()) {
9880
+ eagerlyUsed.add(dir.ref.node);
9881
+ }
9882
+ for (const name of bound.getEagerlyUsedPipes()) {
9883
+ if (pipes.has(name)) {
9884
+ eagerlyUsed.add(pipes.get(name).ref.node);
9885
+ }
9886
+ }
9887
+ }
9888
+ // Set of Directives and Pipes used across the entire template,
9889
+ // including all defer blocks.
9890
+ const wholeTemplateUsed = new Set(eagerlyUsed);
9891
+ for (const bound of deferBlocks.values()) {
9892
+ for (const dir of bound.getUsedDirectives()) {
9893
+ wholeTemplateUsed.add(dir.ref.node);
9894
+ }
9895
+ for (const name of bound.getUsedPipes()) {
9896
+ if (!pipes.has(name)) {
9897
+ continue;
9898
+ }
9899
+ wholeTemplateUsed.add(pipes.get(name).ref.node);
9900
+ }
9901
+ }
9902
+ return { allDependencies, eagerlyUsed, wholeTemplateUsed, deferBlocks };
9903
+ }
9904
+ /**
9905
+ * Converts component dependencies into declarations by
9906
+ * resolving their metadata and deduplicating them.
9907
+ */
9908
+ componentDependenciesToDeclarations(node, context, allDependencies, wholeTemplateUsed) {
9909
+ const declarations = new Map();
9910
+ // Transform the dependencies list, filtering out unused dependencies.
9911
+ for (const dep of allDependencies) {
9912
+ // Only emit references to each dependency once.
9913
+ if (declarations.has(dep.ref.node)) {
9914
+ continue;
9915
+ }
9916
+ switch (dep.kind) {
9917
+ case checker.MetaKind.Directive:
9918
+ if (!wholeTemplateUsed.has(dep.ref.node) || dep.matchSource !== checker.MatchSource.Selector) {
9919
+ continue;
9920
+ }
9921
+ const dirType = this.refEmitter.emit(dep.ref, context);
9922
+ checker.assertSuccessfulReferenceEmit(dirType, node.name, dep.isComponent ? 'component' : 'directive');
9923
+ declarations.set(dep.ref.node, {
9924
+ kind: compiler.R3TemplateDependencyKind.Directive,
9925
+ ref: dep.ref,
9926
+ type: dirType.expression,
9927
+ importedFile: dirType.importedFile,
9928
+ selector: dep.selector,
9929
+ inputs: dep.inputs.propertyNames,
9930
+ outputs: dep.outputs.propertyNames,
9931
+ exportAs: dep.exportAs,
9932
+ isComponent: dep.isComponent,
9933
+ });
9934
+ break;
9935
+ case checker.MetaKind.Pipe:
9936
+ if (!wholeTemplateUsed.has(dep.ref.node)) {
9937
+ continue;
9938
+ }
9939
+ const pipeType = this.refEmitter.emit(dep.ref, context);
9940
+ checker.assertSuccessfulReferenceEmit(pipeType, node.name, 'pipe');
9941
+ declarations.set(dep.ref.node, {
9942
+ kind: compiler.R3TemplateDependencyKind.Pipe,
9943
+ type: pipeType.expression,
9944
+ name: dep.name,
9945
+ ref: dep.ref,
9946
+ importedFile: pipeType.importedFile,
9947
+ });
9948
+ break;
9949
+ case checker.MetaKind.NgModule:
9950
+ const ngModuleType = this.refEmitter.emit(dep.ref, context);
9951
+ checker.assertSuccessfulReferenceEmit(ngModuleType, node.name, 'NgModule');
9952
+ declarations.set(dep.ref.node, {
9953
+ kind: compiler.R3TemplateDependencyKind.NgModule,
9954
+ type: ngModuleType.expression,
9955
+ importedFile: ngModuleType.importedFile,
9956
+ });
9957
+ break;
9958
+ }
9959
+ }
9960
+ return declarations;
9961
+ }
9962
+ /** Handles any cycles in the dependencies of a component. */
9963
+ handleDependencyCycles(node, context, scope, data, analysis, metadata, declarations, eagerlyUsed, symbol) {
9964
+ const eagerDeclarations = Array.from(declarations.values()).filter((decl) => {
9965
+ return decl.kind === compiler.R3TemplateDependencyKind.NgModule || eagerlyUsed.has(decl.ref.node);
9966
+ });
9967
+ const cyclesFromDirectives = new Map();
9968
+ const cyclesFromPipes = new Map();
9969
+ // Scan through the directives/pipes actually used in the template and check whether any
9970
+ // import which needs to be generated would create a cycle. This check is skipped for
9971
+ // standalone components as the dependencies of a standalone component have already been
9972
+ // imported directly by the user, so Angular won't introduce any imports that aren't already
9973
+ // in the user's program.
9974
+ if (!metadata.isStandalone) {
9975
+ for (const usedDep of eagerDeclarations) {
9976
+ const cycle = this._checkForCyclicImport(usedDep.importedFile, usedDep.type, context);
9977
+ if (cycle !== null) {
9978
+ switch (usedDep.kind) {
9979
+ case compiler.R3TemplateDependencyKind.Directive:
9980
+ cyclesFromDirectives.set(usedDep, cycle);
9981
+ break;
9982
+ case compiler.R3TemplateDependencyKind.Pipe:
9983
+ cyclesFromPipes.set(usedDep, cycle);
9984
+ break;
9985
+ }
9986
+ }
9987
+ }
9988
+ }
9989
+ // Check whether any usages of standalone components in imports requires the dependencies
9990
+ // array to be wrapped in a closure. This check is technically a heuristic as there's no
9991
+ // direct way to check whether a `Reference` came from a `forwardRef`. Instead, we check if
9992
+ // the reference is `synthetic`, implying it came from _any_ foreign function resolver,
9993
+ // including the `forwardRef` resolver.
9994
+ const standaloneImportMayBeForwardDeclared = analysis.resolvedImports !== null && analysis.resolvedImports.some((ref) => ref.synthetic);
9995
+ const cycleDetected = cyclesFromDirectives.size !== 0 || cyclesFromPipes.size !== 0;
9996
+ if (!cycleDetected) {
9997
+ // No cycle was detected. Record the imports that need to be created in the cycle detector
9998
+ // so that future cyclic import checks consider their production.
9999
+ for (const { type, importedFile } of eagerDeclarations) {
10000
+ this.maybeRecordSyntheticImport(importedFile, type, context);
10001
+ }
10002
+ // Check whether the dependencies arrays in ɵcmp need to be wrapped in a closure.
10003
+ // This is required if any dependency reference is to a declaration in the same file
10004
+ // but declared after this component.
10005
+ const declarationIsForwardDeclared = eagerDeclarations.some((decl) => checker.isExpressionForwardReference(decl.type, node.name, context));
10006
+ if (this.compilationMode !== checker.CompilationMode.LOCAL &&
10007
+ (declarationIsForwardDeclared || standaloneImportMayBeForwardDeclared)) {
10008
+ data.declarationListEmitMode = 1 /* DeclarationListEmitMode.Closure */;
10009
+ }
10010
+ data.declarations = eagerDeclarations;
10011
+ // Register extra local imports.
10012
+ if (this.compilationMode === checker.CompilationMode.LOCAL &&
10013
+ this.localCompilationExtraImportsTracker !== null) {
10014
+ // In global compilation mode `eagerDeclarations` contains "all" the component
10015
+ // dependencies, whose import statements will be added to the file. In local compilation
10016
+ // mode `eagerDeclarations` only includes the "local" dependencies, meaning those that are
10017
+ // declared inside this compilation unit.Here the import info of these local dependencies
10018
+ // are added to the tracker so that we can generate extra imports representing these local
10019
+ // dependencies. For non-local dependencies we use another technique of adding some
10020
+ // best-guess extra imports globally to all files using
10021
+ // `localCompilationExtraImportsTracker.addGlobalImportFromIdentifier`.
10022
+ for (const { type } of eagerDeclarations) {
10023
+ if (type instanceof compiler.ExternalExpr && type.value.moduleName) {
10024
+ this.localCompilationExtraImportsTracker.addImportForFile(context, type.value.moduleName);
10025
+ }
10026
+ }
10027
+ }
10028
+ }
10029
+ else if (this.cycleHandlingStrategy === 0 /* CycleHandlingStrategy.UseRemoteScoping */) {
10030
+ // Declaring the directiveDefs/pipeDefs arrays directly would require imports that would
10031
+ // create a cycle. Instead, mark this component as requiring remote scoping, so that the
10032
+ // NgModule file will take care of setting the directives for the component.
10033
+ this.scopeRegistry.setComponentRemoteScope(node, eagerDeclarations.filter(isUsedDirective).map((dir) => dir.ref), eagerDeclarations.filter(isUsedPipe).map((pipe) => pipe.ref));
10034
+ symbol.isRemotelyScoped = true;
10035
+ // If a semantic graph is being tracked, record the fact that this component is remotely
10036
+ // scoped with the declaring NgModule symbol as the NgModule's emit becomes dependent on
10037
+ // the directive/pipe usages of this component.
10038
+ if (this.semanticDepGraphUpdater !== null &&
10039
+ scope.kind === checker.ComponentScopeKind.NgModule &&
10040
+ scope.ngModule !== null) {
10041
+ const moduleSymbol = this.semanticDepGraphUpdater.getSymbol(scope.ngModule);
10042
+ if (!(moduleSymbol instanceof NgModuleSymbol)) {
10043
+ throw new Error(`AssertionError: Expected ${scope.ngModule.name} to be an NgModuleSymbol.`);
10044
+ }
10045
+ moduleSymbol.addRemotelyScopedComponent(symbol, symbol.usedDirectives, symbol.usedPipes);
10046
+ }
10047
+ }
10048
+ else {
10049
+ // We are not able to handle this cycle so throw an error.
10050
+ const relatedMessages = [];
10051
+ for (const [dir, cycle] of cyclesFromDirectives) {
10052
+ relatedMessages.push(makeCyclicImportInfo(dir.ref, dir.isComponent ? 'component' : 'directive', cycle));
10053
+ }
10054
+ for (const [pipe, cycle] of cyclesFromPipes) {
10055
+ relatedMessages.push(makeCyclicImportInfo(pipe.ref, 'pipe', cycle));
10056
+ }
10057
+ throw new checker.FatalDiagnosticError(checker.ErrorCode.IMPORT_CYCLE_DETECTED, node, 'One or more import cycles would need to be created to compile this component, ' +
10058
+ 'which is not supported by the current compiler configuration.', relatedMessages);
10059
+ }
10060
+ }
10061
+ /** Produces diagnostics that require more than local information. */
10062
+ getNonLocalDiagnostics(node, analysis) {
10063
+ // We shouldn't be able to hit this, but add an assertion just in case the call site changes.
10064
+ if (this.compilationMode === checker.CompilationMode.LOCAL) {
10065
+ throw new Error('Method cannot be called in local compilation mode.');
10066
+ }
10067
+ let diagnostics = null;
10068
+ // Validate `@Component.imports` and `@Component.deferredImports` fields.
10069
+ if (analysis.resolvedImports !== null && analysis.rawImports !== null) {
10070
+ const importDiagnostics = validateStandaloneImports(analysis.resolvedImports, analysis.rawImports, this.metaReader, this.scopeReader, false /* isDeferredImport */);
10071
+ diagnostics ??= [];
10072
+ diagnostics.push(...importDiagnostics);
10073
+ }
10074
+ if (analysis.resolvedDeferredImports !== null && analysis.rawDeferredImports !== null) {
10075
+ const importDiagnostics = validateStandaloneImports(analysis.resolvedDeferredImports, analysis.rawDeferredImports, this.metaReader, this.scopeReader, true /* isDeferredImport */);
10076
+ diagnostics ??= [];
10077
+ diagnostics.push(...importDiagnostics);
10078
+ }
10079
+ if (analysis.providersRequiringFactory !== null &&
10080
+ analysis.meta.providers instanceof compiler.WrappedNodeExpr) {
10081
+ const providerDiagnostics = checker.getProviderDiagnostics(analysis.providersRequiringFactory, analysis.meta.providers.node, this.injectableRegistry);
10082
+ diagnostics ??= [];
10083
+ diagnostics.push(...providerDiagnostics);
10084
+ }
10085
+ if (analysis.viewProvidersRequiringFactory !== null &&
10086
+ analysis.meta.viewProviders instanceof compiler.WrappedNodeExpr) {
10087
+ const viewProviderDiagnostics = checker.getProviderDiagnostics(analysis.viewProvidersRequiringFactory, analysis.meta.viewProviders.node, this.injectableRegistry);
10088
+ diagnostics ??= [];
10089
+ diagnostics.push(...viewProviderDiagnostics);
10090
+ }
10091
+ const directiveDiagnostics = checker.getDirectiveDiagnostics(node, this.injectableRegistry, this.evaluator, this.reflector, this.scopeRegistry, this.strictCtorDeps, 'Component');
10092
+ if (directiveDiagnostics !== null) {
10093
+ diagnostics ??= [];
10094
+ diagnostics.push(...directiveDiagnostics);
10095
+ }
10096
+ const hostDirectivesDiagnostics = analysis.hostDirectives && analysis.rawHostDirectives
10097
+ ? checker.validateHostDirectives(analysis.rawHostDirectives, analysis.hostDirectives, this.metaReader)
10098
+ : null;
10099
+ if (hostDirectivesDiagnostics !== null) {
10100
+ diagnostics ??= [];
10101
+ diagnostics.push(...hostDirectivesDiagnostics);
10102
+ }
10103
+ return diagnostics;
10104
+ }
10059
10105
  /**
10060
10106
  * Locates defer blocks in case scope information is not available.
10061
10107
  * For example, this happens in the local compilation mode.
10062
10108
  */
10063
10109
  locateDeferBlocksWithoutScope(template) {
10064
10110
  const deferBlocks = new Map();
10065
- const directivelessBinder = new compiler.R3TargetBinder(new compiler.SelectorMatcher());
10111
+ const directivelessBinder = new compiler.R3TargetBinder(null);
10066
10112
  const bound = directivelessBinder.bind({ template: template.nodes });
10067
10113
  const deferredBlocks = bound.getDeferBlocks();
10068
10114
  for (const block of deferredBlocks) {
@@ -10295,6 +10341,7 @@ function createTargetBinder(dependencies) {
10295
10341
  matcher.addSelectables(compiler.CssSelector.parse(dep.selector), [dep]);
10296
10342
  }
10297
10343
  }
10344
+ // TODO(crisbeto): implement for selectorless.
10298
10345
  return new compiler.R3TargetBinder(matcher);
10299
10346
  }
10300
10347
  /**
@@ -10821,6 +10868,7 @@ class PipeDecoratorHandler {
10821
10868
  isStandalone: analysis.meta.isStandalone,
10822
10869
  decorator: analysis.decorator,
10823
10870
  isExplicitlyDeferred: false,
10871
+ isPure: analysis.meta.pure,
10824
10872
  });
10825
10873
  this.injectableRegistry.registerInjectable(node, {
10826
10874
  ctorDeps: analysis.meta.deps,
@@ -10870,7 +10918,7 @@ class PipeDecoratorHandler {
10870
10918
  * @description
10871
10919
  * Entry point for all public APIs of the compiler-cli package.
10872
10920
  */
10873
- new compiler.Version('20.0.0-next.7');
10921
+ new compiler.Version('20.0.0-next.9');
10874
10922
 
10875
10923
  /**
10876
10924
  * Whether a given decorator should be treated as an Angular decorator.
@@ -12159,11 +12207,7 @@ class FunctionExtractor {
12159
12207
  // TODO: is there any real situation in which the signature would not be available here?
12160
12208
  // Is void a better type?
12161
12209
  const signature = this.typeChecker.getSignatureFromDeclaration(this.exportDeclaration);
12162
- const returnType = signature
12163
- ? this.typeChecker.typeToString(this.typeChecker.getReturnTypeOfSignature(signature), undefined,
12164
- // This ensures that e.g. `T | undefined` is not reduced to `T`.
12165
- ts.TypeFormatFlags.NoTypeReduction | ts.TypeFormatFlags.NoTruncation)
12166
- : 'unknown';
12210
+ const returnType = signature ? extractReturnType(signature, this.typeChecker) : 'unknown';
12167
12211
  const implementation = findImplementationOfFunction(this.exportDeclaration, this.typeChecker) ??
12168
12212
  this.exportDeclaration;
12169
12213
  const type = this.typeChecker.getTypeAtLocation(this.exportDeclaration);
@@ -12247,11 +12291,18 @@ function extractCallSignatures(name, typeChecker, type) {
12247
12291
  jsdocTags: extractJsDocTags(decl),
12248
12292
  params: extractAllParams(decl.parameters, typeChecker),
12249
12293
  rawComment: extractRawJsDoc(decl),
12250
- returnType: typeChecker.typeToString(typeChecker.getReturnTypeOfSignature(signature), undefined,
12251
- // This ensures that e.g. `T | undefined` is not reduced to `T`.
12252
- ts.TypeFormatFlags.NoTypeReduction | ts.TypeFormatFlags.NoTruncation),
12294
+ returnType: extractReturnType(signature, typeChecker),
12253
12295
  }));
12254
12296
  }
12297
+ function extractReturnType(signature, typeChecker) {
12298
+ // Handling Type Predicates
12299
+ if (signature?.declaration?.type && ts.isTypePredicateNode(signature.declaration.type)) {
12300
+ return signature.declaration.type.getText();
12301
+ }
12302
+ return typeChecker.typeToString(typeChecker.getReturnTypeOfSignature(signature), undefined,
12303
+ // This ensures that e.g. `T | undefined` is not reduced to `T`.
12304
+ ts.TypeFormatFlags.NoTypeReduction | ts.TypeFormatFlags.NoTruncation);
12305
+ }
12255
12306
  /** Finds the implementation of the given function declaration overload signature. */
12256
12307
  function findImplementationOfFunction(node, typeChecker) {
12257
12308
  if (node.body !== undefined || node.name === undefined) {
@@ -12331,7 +12382,8 @@ class ClassExtractor {
12331
12382
  else if (ts.isAccessor(memberDeclaration)) {
12332
12383
  return this.extractGetterSetter(memberDeclaration);
12333
12384
  }
12334
- else if (ts.isConstructorDeclaration(memberDeclaration)) {
12385
+ else if (ts.isConstructorDeclaration(memberDeclaration) &&
12386
+ memberDeclaration.parameters.length > 0) {
12335
12387
  return this.extractConstructor(memberDeclaration);
12336
12388
  }
12337
12389
  // We only expect methods, properties, and accessors. If we encounter something else,
@@ -12633,6 +12685,8 @@ class PipeExtractor extends ClassExtractor {
12633
12685
  pipeName: this.metadata.name,
12634
12686
  entryType: EntryType.Pipe,
12635
12687
  isStandalone: this.metadata.isStandalone,
12688
+ usage: extractPipeSyntax(this.metadata, this.declaration),
12689
+ isPure: this.metadata.isPure,
12636
12690
  };
12637
12691
  }
12638
12692
  }
@@ -12678,6 +12732,21 @@ function extractInterface(declaration, typeChecker) {
12678
12732
  const extractor = new ClassExtractor(declaration, typeChecker);
12679
12733
  return extractor.extract();
12680
12734
  }
12735
+ function extractPipeSyntax(metadata, classDeclaration) {
12736
+ const transformParams = classDeclaration.members.find((member) => {
12737
+ return (ts.isMethodDeclaration(member) &&
12738
+ member.name &&
12739
+ ts.isIdentifier(member.name) &&
12740
+ member.name.getText() === 'transform');
12741
+ });
12742
+ let paramNames = transformParams.parameters
12743
+ // value is the first argument, it's already referenced before the pipe
12744
+ .slice(1)
12745
+ .map((param) => {
12746
+ return param.name.getText();
12747
+ });
12748
+ return `{{ value_expression | ${metadata.name}${paramNames.length ? ':' + paramNames.join(':') : ''} }}`;
12749
+ }
12681
12750
 
12682
12751
  /** Name of the tag indicating that an object literal should be shown as an enum in docs. */
12683
12752
  const LITERAL_AS_ENUM_TAG = 'object-literal-as-enum';
@@ -14183,6 +14252,9 @@ let TemplateVisitor$1 = class TemplateVisitor extends compiler.RecursiveVisitor
14183
14252
  }
14184
14253
  /** Creates an identifier for a template element or template node. */
14185
14254
  elementOrTemplateToIdentifier(node) {
14255
+ if (node instanceof compiler.Component || node instanceof compiler.Directive) {
14256
+ throw new Error('TODO');
14257
+ }
14186
14258
  // If this node has already been seen, return the cached result.
14187
14259
  if (this.elementAndTemplateIdentifierCache.has(node)) {
14188
14260
  return this.elementAndTemplateIdentifierCache.get(node);
@@ -14260,7 +14332,10 @@ let TemplateVisitor$1 = class TemplateVisitor extends compiler.RecursiveVisitor
14260
14332
  if (refTarget) {
14261
14333
  let node = null;
14262
14334
  let directive = null;
14263
- if (refTarget instanceof compiler.Element || refTarget instanceof compiler.Template) {
14335
+ if (refTarget instanceof compiler.Element ||
14336
+ refTarget instanceof compiler.Template ||
14337
+ refTarget instanceof compiler.Component ||
14338
+ refTarget instanceof compiler.Directive) {
14264
14339
  node = this.elementOrTemplateToIdentifier(refTarget);
14265
14340
  }
14266
14341
  else {
@@ -14869,7 +14944,10 @@ function isSignalSymbol(symbol) {
14869
14944
  const fileName = decl.getSourceFile().fileName;
14870
14945
  return ((ts.isInterfaceDeclaration(decl) || ts.isTypeAliasDeclaration(decl)) &&
14871
14946
  SIGNAL_FNS.has(decl.name.text) &&
14872
- (fileName.includes('@angular/core') || fileName.includes('angular2/rc/packages/core')));
14947
+ (fileName.includes('@angular/core') ||
14948
+ fileName.includes('angular2/rc/packages/core') ||
14949
+ fileName.includes('bin/packages/core')) // for local usage in some tests
14950
+ );
14873
14951
  }));
14874
14952
  }
14875
14953
 
@@ -15120,7 +15198,7 @@ function buildDiagnosticForSignal(ctx, node, component) {
15120
15198
  }
15121
15199
  return [];
15122
15200
  }
15123
- const factory$c = {
15201
+ const factory$d = {
15124
15202
  code: checker.ErrorCode.INTERPOLATED_SIGNAL_NOT_INVOKED,
15125
15203
  name: checker.ExtendedTemplateDiagnosticName.INTERPOLATED_SIGNAL_NOT_INVOKED,
15126
15204
  create: () => new InterpolatedSignalCheck(),
@@ -15146,7 +15224,7 @@ class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
15146
15224
  return [diagnostic];
15147
15225
  }
15148
15226
  }
15149
- const factory$b = {
15227
+ const factory$c = {
15150
15228
  code: checker.ErrorCode.INVALID_BANANA_IN_BOX,
15151
15229
  name: checker.ExtendedTemplateDiagnosticName.INVALID_BANANA_IN_BOX,
15152
15230
  create: () => new InvalidBananaInBoxCheck(),
@@ -15161,7 +15239,7 @@ const factory$b = {
15161
15239
  * are used as structural directives and a warning would be generated. Once the
15162
15240
  * `CommonModule` is included, the `ngSwitch` would also be covered.
15163
15241
  */
15164
- const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
15242
+ const KNOWN_CONTROL_FLOW_DIRECTIVES$1 = new Map([
15165
15243
  ['ngIf', { directive: 'NgIf', builtIn: '@if' }],
15166
15244
  ['ngFor', { directive: 'NgFor', builtIn: '@for' }],
15167
15245
  ['ngSwitchCase', { directive: 'NgSwitchCase', builtIn: '@switch with @case' }],
@@ -15189,7 +15267,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
15189
15267
  visitNode(ctx, component, node) {
15190
15268
  if (!(node instanceof compiler.Template))
15191
15269
  return [];
15192
- const controlFlowAttr = node.templateAttrs.find((attr) => KNOWN_CONTROL_FLOW_DIRECTIVES.has(attr.name));
15270
+ const controlFlowAttr = node.templateAttrs.find((attr) => KNOWN_CONTROL_FLOW_DIRECTIVES$1.has(attr.name));
15193
15271
  if (!controlFlowAttr)
15194
15272
  return [];
15195
15273
  const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
@@ -15197,7 +15275,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
15197
15275
  return [];
15198
15276
  }
15199
15277
  const sourceSpan = controlFlowAttr.keySpan || controlFlowAttr.sourceSpan;
15200
- const directiveAndBuiltIn = KNOWN_CONTROL_FLOW_DIRECTIVES.get(controlFlowAttr.name);
15278
+ const directiveAndBuiltIn = KNOWN_CONTROL_FLOW_DIRECTIVES$1.get(controlFlowAttr.name);
15201
15279
  const errorMessage = `The \`*${controlFlowAttr.name}\` directive was used in the template, ` +
15202
15280
  `but neither the \`${directiveAndBuiltIn?.directive}\` directive nor the \`CommonModule\` was imported. ` +
15203
15281
  `Use Angular's built-in control flow ${directiveAndBuiltIn?.builtIn} or ` +
@@ -15207,7 +15285,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
15207
15285
  return [diagnostic];
15208
15286
  }
15209
15287
  }
15210
- const factory$a = {
15288
+ const factory$b = {
15211
15289
  code: checker.ErrorCode.MISSING_CONTROL_FLOW_DIRECTIVE,
15212
15290
  name: checker.ExtendedTemplateDiagnosticName.MISSING_CONTROL_FLOW_DIRECTIVE,
15213
15291
  create: (options) => {
@@ -15240,12 +15318,67 @@ class MissingNgForOfLetCheck extends TemplateCheckWithVisitor {
15240
15318
  return [diagnostic];
15241
15319
  }
15242
15320
  }
15243
- const factory$9 = {
15321
+ const factory$a = {
15244
15322
  code: checker.ErrorCode.MISSING_NGFOROF_LET,
15245
15323
  name: checker.ExtendedTemplateDiagnosticName.MISSING_NGFOROF_LET,
15246
15324
  create: () => new MissingNgForOfLetCheck(),
15247
15325
  };
15248
15326
 
15327
+ /**
15328
+ * The list of known control flow directives present in the `CommonModule`.
15329
+ *
15330
+ * If these control flow directives are missing they will be reported by a separate diagnostic.
15331
+ */
15332
+ const KNOWN_CONTROL_FLOW_DIRECTIVES = new Set([
15333
+ 'ngIf',
15334
+ 'ngFor',
15335
+ 'ngForOf',
15336
+ 'ngForTrackBy',
15337
+ 'ngSwitchCase',
15338
+ 'ngSwitchDefault',
15339
+ ]);
15340
+ /**
15341
+ * Ensures that there are no structural directives (something like *select or *featureFlag)
15342
+ * used in a template of a *standalone* component without importing the directive. Returns
15343
+ * diagnostics in case such a directive is detected.
15344
+ *
15345
+ * Note: this check only handles the cases when structural directive syntax is used (e.g. `*featureFlag`).
15346
+ * Regular binding syntax (e.g. `[featureFlag]`) is handled separately in type checker and treated as a
15347
+ * hard error instead of a warning.
15348
+ */
15349
+ class MissingStructuralDirectiveCheck extends TemplateCheckWithVisitor {
15350
+ code = checker.ErrorCode.MISSING_STRUCTURAL_DIRECTIVE;
15351
+ run(ctx, component, template) {
15352
+ const componentMetadata = ctx.templateTypeChecker.getDirectiveMetadata(component);
15353
+ // Avoid running this check for non-standalone components.
15354
+ if (!componentMetadata || !componentMetadata.isStandalone) {
15355
+ return [];
15356
+ }
15357
+ return super.run(ctx, component, template);
15358
+ }
15359
+ visitNode(ctx, component, node) {
15360
+ if (!(node instanceof compiler.Template))
15361
+ return [];
15362
+ const customStructuralDirective = node.templateAttrs.find((attr) => !KNOWN_CONTROL_FLOW_DIRECTIVES.has(attr.name));
15363
+ if (!customStructuralDirective)
15364
+ return [];
15365
+ const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
15366
+ if (symbol?.directives.length) {
15367
+ return [];
15368
+ }
15369
+ const sourceSpan = customStructuralDirective.keySpan || customStructuralDirective.sourceSpan;
15370
+ const errorMessage = `A structural directive \`${customStructuralDirective.name}\` was used in the template ` +
15371
+ `without a corresponding import in the component. ` +
15372
+ `Make sure that the directive is included in the \`@Component.imports\` array of this component.`;
15373
+ return [ctx.makeTemplateDiagnostic(sourceSpan, errorMessage)];
15374
+ }
15375
+ }
15376
+ const factory$9 = {
15377
+ code: checker.ErrorCode.MISSING_STRUCTURAL_DIRECTIVE,
15378
+ name: checker.ExtendedTemplateDiagnosticName.MISSING_STRUCTURAL_DIRECTIVE,
15379
+ create: () => new MissingStructuralDirectiveCheck(),
15380
+ };
15381
+
15249
15382
  /**
15250
15383
  * Ensures the left side of a nullish coalescing operation is nullable.
15251
15384
  * Returns diagnostics for the cases where the operator is useless.
@@ -15719,14 +15852,15 @@ function assertNever(value) {
15719
15852
  }
15720
15853
 
15721
15854
  const ALL_DIAGNOSTIC_FACTORIES = [
15722
- factory$b,
15855
+ factory$c,
15723
15856
  factory$8,
15724
15857
  factory$7,
15725
- factory$a,
15858
+ factory$b,
15726
15859
  factory$4,
15860
+ factory$a,
15727
15861
  factory$9,
15728
15862
  factory$5,
15729
- factory$c,
15863
+ factory$d,
15730
15864
  factory$3,
15731
15865
  factory$1,
15732
15866
  factory$6,
@@ -18779,7 +18913,7 @@ var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
18779
18913
  * @param minVersion Minimum required version for the feature.
18780
18914
  */
18781
18915
  function coreVersionSupportsFeature(coreVersion, minVersion) {
18782
- // A version of `20.0.0-next.7` usually means that core is at head so it supports
18916
+ // A version of `20.0.0-next.9` usually means that core is at head so it supports
18783
18917
  // all features. Use string interpolation prevent the placeholder from being replaced
18784
18918
  // with the current version during build time.
18785
18919
  if (coreVersion === `0.0.0-${'PLACEHOLDER'}`) {
@@ -18894,6 +19028,7 @@ class NgCompiler {
18894
19028
  angularCoreVersion;
18895
19029
  enableHmr;
18896
19030
  implicitStandaloneValue;
19031
+ enableSelectorless;
18897
19032
  /**
18898
19033
  * `NgCompiler` can be reused for multiple compilations (for resource-only changes), and each
18899
19034
  * new compilation uses a fresh `PerfRecorder`. Thus, classes created with a lifespan of the
@@ -18938,6 +19073,7 @@ class NgCompiler {
18938
19073
  // TODO(crisbeto): remove this flag and base `enableBlockSyntax` on the `angularCoreVersion`.
18939
19074
  this.enableBlockSyntax = options['_enableBlockSyntax'] ?? true;
18940
19075
  this.enableLetSyntax = options['_enableLetSyntax'] ?? true;
19076
+ this.enableSelectorless = options['_enableSelectorless'] ?? false;
18941
19077
  // Standalone by default is enabled since v19. We need to toggle it here,
18942
19078
  // because the language service extension may be running with the latest
18943
19079
  // version of the compiler against an older version of Angular.
@@ -19718,7 +19854,7 @@ class NgCompiler {
19718
19854
  const jitDeclarationRegistry = new JitDeclarationRegistry();
19719
19855
  // Set up the IvyCompilation, which manages state for the Ivy transformer.
19720
19856
  const handlers = [
19721
- new ComponentDecoratorHandler(reflector, evaluator, metaRegistry, metaReader, scopeReader, this.adapter, ngModuleScopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, strictCtorDeps, this.resourceManager, this.adapter.rootDirs, this.options.preserveWhitespaces || false, this.options.i18nUseExternalIds !== false, this.options.enableI18nLegacyMessageIdFormat !== false, this.usePoisonedData, this.options.i18nNormalizeLineEndingsInICUs === true, this.moduleResolver, this.cycleAnalyzer, cycleHandlingStrategy, refEmitter, referencesRegistry, this.incrementalCompilation.depGraph, injectableRegistry, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder, hostDirectivesResolver, importTracker, supportTestBed, compilationMode, deferredSymbolsTracker, !!this.options.forbidOrphanComponents, this.enableBlockSyntax, this.enableLetSyntax, externalRuntimeStyles, localCompilationExtraImportsTracker, jitDeclarationRegistry, this.options.i18nPreserveWhitespaceForLegacyExtraction ?? true, !!this.options.strictStandalone, this.enableHmr, this.implicitStandaloneValue, typeCheckHostBindings),
19857
+ new ComponentDecoratorHandler(reflector, evaluator, metaRegistry, metaReader, scopeReader, this.adapter, ngModuleScopeRegistry, typeCheckScopeRegistry, resourceRegistry, isCore, strictCtorDeps, this.resourceManager, this.adapter.rootDirs, this.options.preserveWhitespaces || false, this.options.i18nUseExternalIds !== false, this.options.enableI18nLegacyMessageIdFormat !== false, this.usePoisonedData, this.options.i18nNormalizeLineEndingsInICUs === true, this.moduleResolver, this.cycleAnalyzer, cycleHandlingStrategy, refEmitter, referencesRegistry, this.incrementalCompilation.depGraph, injectableRegistry, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder, hostDirectivesResolver, importTracker, supportTestBed, compilationMode, deferredSymbolsTracker, !!this.options.forbidOrphanComponents, this.enableBlockSyntax, this.enableLetSyntax, externalRuntimeStyles, localCompilationExtraImportsTracker, jitDeclarationRegistry, this.options.i18nPreserveWhitespaceForLegacyExtraction ?? true, !!this.options.strictStandalone, this.enableHmr, this.implicitStandaloneValue, typeCheckHostBindings, this.enableSelectorless),
19722
19858
  // TODO(alxhub): understand why the cast here is necessary (something to do with `null`
19723
19859
  // not being assignable to `unknown` when wrapped in `Readonly`).
19724
19860
  new DirectiveDecoratorHandler(reflector, evaluator, metaRegistry, ngModuleScopeRegistry, metaReader, injectableRegistry, refEmitter, referencesRegistry, isCore, strictCtorDeps, semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder, importTracker, supportTestBed, typeCheckScopeRegistry, compilationMode, jitDeclarationRegistry, resourceRegistry, !!this.options.strictStandalone, this.implicitStandaloneValue, this.usePoisonedData, typeCheckHostBindings),