@angular/core 20.0.0-next.8 → 20.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/{api.d-KjtSQajV.d.ts → api.d-CRxC7NlU.d.ts} +28 -43
  2. package/{chrome_dev_tools_performance.d-qv7drdAl.d.ts → chrome_dev_tools_performance.d-B0FzTuRf.d.ts} +7 -1
  3. package/{discovery.d-vJaEafe4.d.ts → discovery.d-CBxzK1ay.d.ts} +30 -6
  4. package/event_dispatcher.d-DlbccpYq.d.ts +1 -1
  5. package/fesm2022/attribute-BWp59EjE.mjs +1 -1
  6. package/fesm2022/core.mjs +80 -166
  7. package/fesm2022/core.mjs.map +1 -1
  8. package/fesm2022/{debug_node-DEfPCixm.mjs → debug_node-3mmnD06K.mjs} +138 -54
  9. package/fesm2022/debug_node-3mmnD06K.mjs.map +1 -0
  10. package/fesm2022/primitives/di.mjs +1 -1
  11. package/fesm2022/primitives/event-dispatch.mjs +2 -2
  12. package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
  13. package/fesm2022/primitives/signals.mjs +7 -5
  14. package/fesm2022/primitives/signals.mjs.map +1 -1
  15. package/fesm2022/{resource-DhKtse7l.mjs → resource-nrAenwIA.mjs} +31 -76
  16. package/fesm2022/resource-nrAenwIA.mjs.map +1 -0
  17. package/fesm2022/{root_effect_scheduler-BZMWiScf.mjs → root_effect_scheduler-B_EWGyLU.mjs} +20 -12
  18. package/fesm2022/root_effect_scheduler-B_EWGyLU.mjs.map +1 -0
  19. package/fesm2022/rxjs-interop.mjs +16 -11
  20. package/fesm2022/rxjs-interop.mjs.map +1 -1
  21. package/fesm2022/{signal-B6pMq7KS.mjs → signal-ePSl6jXn.mjs} +14 -4
  22. package/fesm2022/{signal-B6pMq7KS.mjs.map → signal-ePSl6jXn.mjs.map} +1 -1
  23. package/fesm2022/testing.mjs +61 -63
  24. package/fesm2022/testing.mjs.map +1 -1
  25. package/fesm2022/{untracked-Bz5WMeU1.mjs → untracked-2ouAFbCz.mjs} +4 -4
  26. package/fesm2022/untracked-2ouAFbCz.mjs.map +1 -0
  27. package/fesm2022/weak_ref-BaIq-pgY.mjs +1 -1
  28. package/graph.d-BcIOep_B.d.ts +1 -1
  29. package/index.d.ts +154 -136
  30. package/package.json +3 -3
  31. package/primitives/di/index.d.ts +1 -1
  32. package/primitives/event-dispatch/index.d.ts +1 -1
  33. package/primitives/signals/index.d.ts +3 -3
  34. package/rxjs-interop/index.d.ts +11 -11
  35. package/schematics/bundles/{apply_import_manager-CaG-_cEq.js → apply_import_manager-Coc7Hewu.js} +3 -3
  36. package/schematics/bundles/{change_tracker-ISzWfEHN.js → change_tracker-CDJPOAni.js} +3 -3
  37. package/schematics/bundles/{checker-DV96LHWz.js → checker-BAl7CJ0l.js} +386 -122
  38. package/schematics/bundles/cleanup-unused-imports.js +6 -6
  39. package/schematics/bundles/{compiler-BEZ6sUQS.js → compiler-BSv6JWRF.js} +58 -65
  40. package/schematics/bundles/compiler_host-CAfDJO3W.js +1 -1
  41. package/schematics/bundles/control-flow-migration.js +2 -2
  42. package/schematics/bundles/document-core.js +6 -6
  43. package/schematics/bundles/imports-CIX-JgAN.js +1 -1
  44. package/schematics/bundles/{index-6wv04ZFQ.js → index-CnKffIJ6.js} +6 -5
  45. package/schematics/bundles/{index-B1R5GL-k.js → index-CxuDmkeg.js} +421 -317
  46. package/schematics/bundles/inject-flags.js +6 -6
  47. package/schematics/bundles/inject-migration.js +4 -4
  48. package/schematics/bundles/leading_space-D9nQ8UQC.js +1 -1
  49. package/schematics/bundles/{migrate_ts_type_references-Dh9TZgTr.js → migrate_ts_type_references-DE1AlxIs.js} +6 -6
  50. package/schematics/bundles/ng_decorators-DznZ5jMl.js +1 -1
  51. package/schematics/bundles/nodes-B16H9JUd.js +1 -1
  52. package/schematics/bundles/output-migration.js +7 -7
  53. package/schematics/bundles/{project_paths-B-Nevd-p.js → project_paths-Bl-H7Vlb.js} +4 -4
  54. package/schematics/bundles/project_tsconfig_paths-CDVxT6Ov.js +1 -1
  55. package/schematics/bundles/property_name-BBwFuqMe.js +1 -1
  56. package/schematics/bundles/route-lazy-loading.js +4 -4
  57. package/schematics/bundles/self-closing-tags-migration.js +5 -5
  58. package/schematics/bundles/signal-input-migration.js +8 -8
  59. package/schematics/bundles/signal-queries-migration.js +8 -8
  60. package/schematics/bundles/signals.js +8 -8
  61. package/schematics/bundles/standalone-migration.js +5 -5
  62. package/schematics/bundles/symbol-VPWguRxr.js +1 -1
  63. package/schematics/bundles/test-bed-get.js +5 -5
  64. package/{signal.d-E0e5nW1p.d.ts → signal.d-D6VJ67xi.d.ts} +8 -2
  65. package/testing/index.d.ts +12 -24
  66. package/weak_ref.d-eGOEP9S1.d.ts +1 -1
  67. package/fesm2022/debug_node-DEfPCixm.mjs.map +0 -1
  68. package/fesm2022/resource-DhKtse7l.mjs.map +0 -1
  69. package/fesm2022/root_effect_scheduler-BZMWiScf.mjs.map +0 -1
  70. package/fesm2022/untracked-Bz5WMeU1.mjs.map +0 -1
@@ -1,15 +1,15 @@
1
1
  'use strict';
2
2
  /**
3
- * @license Angular v20.0.0-next.8
3
+ * @license Angular v20.0.0-rc.0
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-BEZ6sUQS.js');
9
+ var compiler = require('./compiler-BSv6JWRF.js');
10
10
  var ts = require('typescript');
11
11
  var p = require('path');
12
- var checker = require('./checker-DV96LHWz.js');
12
+ var checker = require('./checker-BAl7CJ0l.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.8'));
895
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
913
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
1008
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
1424
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
1459
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
1510
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
1543
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
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.8'));
1594
+ definitionMap.set('version', compiler.literal('20.0.0-rc.0'));
1595
1595
  definitionMap.set('ngImport', compiler.importExpr(compiler.Identifiers.core));
1596
1596
  // e.g. `type: MyPipe`
1597
1597
  definitionMap.set('type', meta.type.value);
@@ -7917,6 +7917,7 @@ function parseExtractedTemplate(template, sourceStr, sourceParseRange, escapedSt
7917
7917
  escapedString,
7918
7918
  enableBlockSyntax: options.enableBlockSyntax,
7919
7919
  enableLetSyntax: options.enableLetSyntax,
7920
+ enableSelectorless: options.enableSelectorless,
7920
7921
  };
7921
7922
  const parsedTemplate = compiler.parseTemplate(sourceStr, sourceMapUrl ?? '', {
7922
7923
  ...commonParseOptions,
@@ -8880,7 +8881,8 @@ class ComponentDecoratorHandler {
8880
8881
  enableHmr;
8881
8882
  implicitStandaloneValue;
8882
8883
  typeCheckHostBindings;
8883
- 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) {
8884
8886
  this.reflector = reflector;
8885
8887
  this.evaluator = evaluator;
8886
8888
  this.metaRegistry = metaRegistry;
@@ -8925,12 +8927,14 @@ class ComponentDecoratorHandler {
8925
8927
  this.enableHmr = enableHmr;
8926
8928
  this.implicitStandaloneValue = implicitStandaloneValue;
8927
8929
  this.typeCheckHostBindings = typeCheckHostBindings;
8930
+ this.enableSelectorless = enableSelectorless;
8928
8931
  this.extractTemplateOptions = {
8929
8932
  enableI18nLegacyMessageIdFormat: this.enableI18nLegacyMessageIdFormat,
8930
8933
  i18nNormalizeLineEndingsInICUs: this.i18nNormalizeLineEndingsInICUs,
8931
8934
  usePoisonedData: this.usePoisonedData,
8932
8935
  enableBlockSyntax: this.enableBlockSyntax,
8933
8936
  enableLetSyntax: this.enableLetSyntax,
8937
+ enableSelectorless: this.enableSelectorless,
8934
8938
  preserveSignificantWhitespace: this.i18nPreserveSignificantWhitespace,
8935
8939
  };
8936
8940
  // Dependencies can't be deferred during HMR, because the HMR update module can't have
@@ -9199,6 +9203,7 @@ class ComponentDecoratorHandler {
9199
9203
  usePoisonedData: this.usePoisonedData,
9200
9204
  enableBlockSyntax: this.enableBlockSyntax,
9201
9205
  enableLetSyntax: this.enableLetSyntax,
9206
+ enableSelectorless: this.enableSelectorless,
9202
9207
  preserveSignificantWhitespace: this.i18nPreserveSignificantWhitespace,
9203
9208
  }, this.compilationMode);
9204
9209
  if (this.compilationMode === checker.CompilationMode.LOCAL &&
@@ -9580,168 +9585,16 @@ class ComponentDecoratorHandler {
9580
9585
  return {};
9581
9586
  }
9582
9587
  const scope = this.scopeReader.getScopeForComponent(node);
9583
- if (scope !== null) {
9584
- // Replace the empty components and directives from the analyze() step with a fully expanded
9585
- // scope. This is possible now because during resolve() the whole compilation unit has been
9586
- // fully analyzed.
9587
- //
9588
- // First it needs to be determined if actually importing the directives/pipes used in the
9589
- // template would create a cycle. Currently ngtsc refuses to generate cycles, so an option
9590
- // known as "remote scoping" is used if a cycle would be created. In remote scoping, the
9591
- // module file sets the directives/pipes on the ɵcmp of the component, without
9592
- // requiring new imports (but also in a way that breaks tree shaking).
9593
- //
9594
- // Determining this is challenging, because the TemplateDefinitionBuilder is responsible for
9595
- // matching directives and pipes in the template; however, that doesn't run until the actual
9596
- // compile() step. It's not possible to run template compilation sooner as it requires the
9597
- // ConstantPool for the overall file being compiled (which isn't available until the
9598
- // transform step).
9599
- //
9600
- // Instead, directives/pipes are matched independently here, using the R3TargetBinder. This
9601
- // is an alternative implementation of template matching which is used for template
9602
- // type-checking and will eventually replace matching in the TemplateDefinitionBuilder.
9603
- const isModuleScope = scope.kind === checker.ComponentScopeKind.NgModule;
9604
- // Dependencies coming from the regular `imports` field.
9605
- const dependencies = isModuleScope ? scope.compilation.dependencies : scope.dependencies;
9606
- // Dependencies from the `@Component.deferredImports` field.
9607
- const explicitlyDeferredDependencies = getExplicitlyDeferredDeps(scope);
9608
- // Mark the component is an NgModule-based component with its NgModule in a different file
9609
- // then mark this file for extra import generation
9610
- if (isModuleScope && context.fileName !== checker.getSourceFile(scope.ngModule).fileName) {
9611
- this.localCompilationExtraImportsTracker?.markFileForExtraImportGeneration(context);
9612
- }
9613
- // Make sure that `@Component.imports` and `@Component.deferredImports` do not have
9614
- // the same dependencies.
9615
- if (metadata.isStandalone &&
9616
- analysis.rawDeferredImports !== null &&
9617
- explicitlyDeferredDependencies.length > 0) {
9618
- const diagnostic = validateNoImportOverlap(dependencies, explicitlyDeferredDependencies, analysis.rawDeferredImports);
9619
- if (diagnostic !== null) {
9620
- diagnostics.push(diagnostic);
9621
- }
9622
- }
9623
- // Set up the R3TargetBinder.
9624
- const binder = createTargetBinder(dependencies);
9625
- let allDependencies = dependencies;
9626
- let deferBlockBinder = binder;
9627
- // If there are any explicitly deferred dependencies (via `@Component.deferredImports`),
9628
- // re-compute the list of dependencies and create a new binder for defer blocks. This
9629
- // is because we have deferred dependencies that are not in the standard imports list
9630
- // and need to be referenced later when determining what dependencies need to be in a
9631
- // defer function / instruction call. Otherwise they end up treated as a standard
9632
- // import, which is wrong.
9633
- if (explicitlyDeferredDependencies.length > 0) {
9634
- allDependencies = [...explicitlyDeferredDependencies, ...dependencies];
9635
- deferBlockBinder = createTargetBinder(allDependencies);
9636
- }
9637
- // Set up the pipes map that is later used to determine which dependencies are used in
9638
- // the template.
9639
- const pipes = extractPipes(allDependencies);
9640
- // Next, the component template AST is bound using the R3TargetBinder. This produces a
9641
- // BoundTarget, which is similar to a ts.TypeChecker.
9642
- const bound = binder.bind({ template: metadata.template.nodes });
9643
- // Find all defer blocks used in the template and for each block
9644
- // bind its own scope.
9645
- const deferBlocks = new Map();
9646
- for (const deferBlock of bound.getDeferBlocks()) {
9647
- deferBlocks.set(deferBlock, deferBlockBinder.bind({ template: deferBlock.children }));
9648
- }
9649
- // Register all Directives and Pipes used at the top level (outside
9650
- // of any defer blocks), which would be eagerly referenced.
9651
- const eagerlyUsed = new Set();
9652
- if (this.enableHmr) {
9653
- // In HMR we need to preserve all the dependencies, because they have to remain consistent
9654
- // with the initially-generated code no matter what the template looks like.
9655
- for (const dep of dependencies) {
9656
- if (dep.ref.node !== node) {
9657
- eagerlyUsed.add(dep.ref.node);
9658
- }
9659
- else {
9660
- const used = bound.getEagerlyUsedDirectives();
9661
- if (used.some((current) => current.ref.node === node)) {
9662
- eagerlyUsed.add(node);
9663
- }
9664
- }
9665
- }
9666
- }
9667
- else {
9668
- for (const dir of bound.getEagerlyUsedDirectives()) {
9669
- eagerlyUsed.add(dir.ref.node);
9670
- }
9671
- for (const name of bound.getEagerlyUsedPipes()) {
9672
- if (!pipes.has(name)) {
9673
- continue;
9674
- }
9675
- eagerlyUsed.add(pipes.get(name).ref.node);
9676
- }
9677
- }
9678
- // Set of Directives and Pipes used across the entire template,
9679
- // including all defer blocks.
9680
- const wholeTemplateUsed = new Set(eagerlyUsed);
9681
- for (const bound of deferBlocks.values()) {
9682
- for (const dir of bound.getUsedDirectives()) {
9683
- wholeTemplateUsed.add(dir.ref.node);
9684
- }
9685
- for (const name of bound.getUsedPipes()) {
9686
- if (!pipes.has(name)) {
9687
- continue;
9688
- }
9689
- wholeTemplateUsed.add(pipes.get(name).ref.node);
9690
- }
9691
- }
9692
- const declarations = new Map();
9693
- // Transform the dependencies list, filtering out unused dependencies.
9694
- for (const dep of allDependencies) {
9695
- // Only emit references to each dependency once.
9696
- if (declarations.has(dep.ref.node)) {
9697
- continue;
9698
- }
9699
- switch (dep.kind) {
9700
- case checker.MetaKind.Directive:
9701
- if (!wholeTemplateUsed.has(dep.ref.node) || dep.matchSource !== checker.MatchSource.Selector) {
9702
- continue;
9703
- }
9704
- const dirType = this.refEmitter.emit(dep.ref, context);
9705
- checker.assertSuccessfulReferenceEmit(dirType, node.name, dep.isComponent ? 'component' : 'directive');
9706
- declarations.set(dep.ref.node, {
9707
- kind: compiler.R3TemplateDependencyKind.Directive,
9708
- ref: dep.ref,
9709
- type: dirType.expression,
9710
- importedFile: dirType.importedFile,
9711
- selector: dep.selector,
9712
- inputs: dep.inputs.propertyNames,
9713
- outputs: dep.outputs.propertyNames,
9714
- exportAs: dep.exportAs,
9715
- isComponent: dep.isComponent,
9716
- });
9717
- break;
9718
- case checker.MetaKind.Pipe:
9719
- if (!wholeTemplateUsed.has(dep.ref.node)) {
9720
- continue;
9721
- }
9722
- const pipeType = this.refEmitter.emit(dep.ref, context);
9723
- checker.assertSuccessfulReferenceEmit(pipeType, node.name, 'pipe');
9724
- declarations.set(dep.ref.node, {
9725
- kind: compiler.R3TemplateDependencyKind.Pipe,
9726
- type: pipeType.expression,
9727
- name: dep.name,
9728
- ref: dep.ref,
9729
- importedFile: pipeType.importedFile,
9730
- });
9731
- break;
9732
- case checker.MetaKind.NgModule:
9733
- const ngModuleType = this.refEmitter.emit(dep.ref, context);
9734
- checker.assertSuccessfulReferenceEmit(ngModuleType, node.name, 'NgModule');
9735
- declarations.set(dep.ref.node, {
9736
- kind: compiler.R3TemplateDependencyKind.NgModule,
9737
- type: ngModuleType.expression,
9738
- importedFile: ngModuleType.importedFile,
9739
- });
9740
- break;
9741
- }
9742
- }
9743
- 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);
9744
9596
  if (this.semanticDepGraphUpdater !== null) {
9597
+ const getSemanticReference = (decl) => this.semanticDepGraphUpdater.getSemanticReference(decl.ref.node, decl.type);
9745
9598
  symbol.usedDirectives = Array.from(declarations.values())
9746
9599
  .filter(isUsedDirective)
9747
9600
  .map(getSemanticReference);
@@ -9749,142 +9602,17 @@ class ComponentDecoratorHandler {
9749
9602
  .filter(isUsedPipe)
9750
9603
  .map(getSemanticReference);
9751
9604
  }
9752
- const eagerDeclarations = Array.from(declarations.values()).filter((decl) => decl.kind === compiler.R3TemplateDependencyKind.NgModule || eagerlyUsed.has(decl.ref.node));
9753
9605
  // Process information related to defer blocks
9754
9606
  if (this.compilationMode !== checker.CompilationMode.LOCAL) {
9755
9607
  this.resolveDeferBlocks(node, deferBlocks, declarations, data, analysis, eagerlyUsed);
9756
9608
  }
9757
- const cyclesFromDirectives = new Map();
9758
- const cyclesFromPipes = new Map();
9759
- // Scan through the directives/pipes actually used in the template and check whether any
9760
- // import which needs to be generated would create a cycle. This check is skipped for
9761
- // standalone components as the dependencies of a standalone component have already been
9762
- // imported directly by the user, so Angular won't introduce any imports that aren't already
9763
- // in the user's program.
9764
- if (!metadata.isStandalone) {
9765
- for (const usedDep of eagerDeclarations) {
9766
- const cycle = this._checkForCyclicImport(usedDep.importedFile, usedDep.type, context);
9767
- if (cycle !== null) {
9768
- switch (usedDep.kind) {
9769
- case compiler.R3TemplateDependencyKind.Directive:
9770
- cyclesFromDirectives.set(usedDep, cycle);
9771
- break;
9772
- case compiler.R3TemplateDependencyKind.Pipe:
9773
- cyclesFromPipes.set(usedDep, cycle);
9774
- break;
9775
- }
9776
- }
9777
- }
9778
- }
9779
- // Check whether any usages of standalone components in imports requires the dependencies
9780
- // array to be wrapped in a closure. This check is technically a heuristic as there's no
9781
- // direct way to check whether a `Reference` came from a `forwardRef`. Instead, we check if
9782
- // the reference is `synthetic`, implying it came from _any_ foreign function resolver,
9783
- // including the `forwardRef` resolver.
9784
- const standaloneImportMayBeForwardDeclared = analysis.resolvedImports !== null && analysis.resolvedImports.some((ref) => ref.synthetic);
9785
- const cycleDetected = cyclesFromDirectives.size !== 0 || cyclesFromPipes.size !== 0;
9786
- if (!cycleDetected) {
9787
- // No cycle was detected. Record the imports that need to be created in the cycle detector
9788
- // so that future cyclic import checks consider their production.
9789
- for (const { type, importedFile } of eagerDeclarations) {
9790
- this.maybeRecordSyntheticImport(importedFile, type, context);
9791
- }
9792
- // Check whether the dependencies arrays in ɵcmp need to be wrapped in a closure.
9793
- // This is required if any dependency reference is to a declaration in the same file
9794
- // but declared after this component.
9795
- const declarationIsForwardDeclared = eagerDeclarations.some((decl) => checker.isExpressionForwardReference(decl.type, node.name, context));
9796
- if (this.compilationMode !== checker.CompilationMode.LOCAL &&
9797
- (declarationIsForwardDeclared || standaloneImportMayBeForwardDeclared)) {
9798
- data.declarationListEmitMode = 1 /* DeclarationListEmitMode.Closure */;
9799
- }
9800
- data.declarations = eagerDeclarations;
9801
- // Register extra local imports.
9802
- if (this.compilationMode === checker.CompilationMode.LOCAL &&
9803
- this.localCompilationExtraImportsTracker !== null) {
9804
- // In global compilation mode `eagerDeclarations` contains "all" the component
9805
- // dependencies, whose import statements will be added to the file. In local compilation
9806
- // mode `eagerDeclarations` only includes the "local" dependencies, meaning those that are
9807
- // declared inside this compilation unit.Here the import info of these local dependencies
9808
- // are added to the tracker so that we can generate extra imports representing these local
9809
- // dependencies. For non-local dependencies we use another technique of adding some
9810
- // best-guess extra imports globally to all files using
9811
- // `localCompilationExtraImportsTracker.addGlobalImportFromIdentifier`.
9812
- for (const { type } of eagerDeclarations) {
9813
- if (type instanceof compiler.ExternalExpr && type.value.moduleName) {
9814
- this.localCompilationExtraImportsTracker.addImportForFile(context, type.value.moduleName);
9815
- }
9816
- }
9817
- }
9818
- }
9819
- else {
9820
- if (this.cycleHandlingStrategy === 0 /* CycleHandlingStrategy.UseRemoteScoping */) {
9821
- // Declaring the directiveDefs/pipeDefs arrays directly would require imports that would
9822
- // create a cycle. Instead, mark this component as requiring remote scoping, so that the
9823
- // NgModule file will take care of setting the directives for the component.
9824
- this.scopeRegistry.setComponentRemoteScope(node, eagerDeclarations.filter(isUsedDirective).map((dir) => dir.ref), eagerDeclarations.filter(isUsedPipe).map((pipe) => pipe.ref));
9825
- symbol.isRemotelyScoped = true;
9826
- // If a semantic graph is being tracked, record the fact that this component is remotely
9827
- // scoped with the declaring NgModule symbol as the NgModule's emit becomes dependent on
9828
- // the directive/pipe usages of this component.
9829
- if (this.semanticDepGraphUpdater !== null &&
9830
- scope.kind === checker.ComponentScopeKind.NgModule &&
9831
- scope.ngModule !== null) {
9832
- const moduleSymbol = this.semanticDepGraphUpdater.getSymbol(scope.ngModule);
9833
- if (!(moduleSymbol instanceof NgModuleSymbol)) {
9834
- throw new Error(`AssertionError: Expected ${scope.ngModule.name} to be an NgModuleSymbol.`);
9835
- }
9836
- moduleSymbol.addRemotelyScopedComponent(symbol, symbol.usedDirectives, symbol.usedPipes);
9837
- }
9838
- }
9839
- else {
9840
- // We are not able to handle this cycle so throw an error.
9841
- const relatedMessages = [];
9842
- for (const [dir, cycle] of cyclesFromDirectives) {
9843
- relatedMessages.push(makeCyclicImportInfo(dir.ref, dir.isComponent ? 'component' : 'directive', cycle));
9844
- }
9845
- for (const [pipe, cycle] of cyclesFromPipes) {
9846
- relatedMessages.push(makeCyclicImportInfo(pipe.ref, 'pipe', cycle));
9847
- }
9848
- throw new checker.FatalDiagnosticError(checker.ErrorCode.IMPORT_CYCLE_DETECTED, node, 'One or more import cycles would need to be created to compile this component, ' +
9849
- 'which is not supported by the current compiler configuration.', relatedMessages);
9850
- }
9851
- }
9852
- }
9853
- else {
9854
- // If there is no scope, we can still use the binder to retrieve *some* information about the
9855
- // deferred blocks.
9856
- data.deferPerBlockDependencies = this.locateDeferBlocksWithoutScope(metadata.template);
9609
+ this.handleDependencyCycles(node, context, scope, data, analysis, metadata, declarations, eagerlyUsed, symbol);
9857
9610
  }
9858
9611
  // Run diagnostics only in global mode.
9859
9612
  if (this.compilationMode !== checker.CompilationMode.LOCAL) {
9860
- // Validate `@Component.imports` and `@Component.deferredImports` fields.
9861
- if (analysis.resolvedImports !== null && analysis.rawImports !== null) {
9862
- const importDiagnostics = validateStandaloneImports(analysis.resolvedImports, analysis.rawImports, this.metaReader, this.scopeReader, false /* isDeferredImport */);
9863
- diagnostics.push(...importDiagnostics);
9864
- }
9865
- if (analysis.resolvedDeferredImports !== null && analysis.rawDeferredImports !== null) {
9866
- const importDiagnostics = validateStandaloneImports(analysis.resolvedDeferredImports, analysis.rawDeferredImports, this.metaReader, this.scopeReader, true /* isDeferredImport */);
9867
- diagnostics.push(...importDiagnostics);
9868
- }
9869
- if (analysis.providersRequiringFactory !== null &&
9870
- analysis.meta.providers instanceof compiler.WrappedNodeExpr) {
9871
- const providerDiagnostics = checker.getProviderDiagnostics(analysis.providersRequiringFactory, analysis.meta.providers.node, this.injectableRegistry);
9872
- diagnostics.push(...providerDiagnostics);
9873
- }
9874
- if (analysis.viewProvidersRequiringFactory !== null &&
9875
- analysis.meta.viewProviders instanceof compiler.WrappedNodeExpr) {
9876
- const viewProviderDiagnostics = checker.getProviderDiagnostics(analysis.viewProvidersRequiringFactory, analysis.meta.viewProviders.node, this.injectableRegistry);
9877
- diagnostics.push(...viewProviderDiagnostics);
9878
- }
9879
- const directiveDiagnostics = checker.getDirectiveDiagnostics(node, this.injectableRegistry, this.evaluator, this.reflector, this.scopeRegistry, this.strictCtorDeps, 'Component');
9880
- if (directiveDiagnostics !== null) {
9881
- diagnostics.push(...directiveDiagnostics);
9882
- }
9883
- const hostDirectivesDiagnostics = analysis.hostDirectives && analysis.rawHostDirectives
9884
- ? checker.validateHostDirectives(analysis.rawHostDirectives, analysis.hostDirectives, this.metaReader)
9885
- : null;
9886
- if (hostDirectivesDiagnostics !== null) {
9887
- diagnostics.push(...hostDirectivesDiagnostics);
9613
+ const nonLocalDiagnostics = this.getNonLocalDiagnostics(node, analysis);
9614
+ if (nonLocalDiagnostics !== null) {
9615
+ diagnostics.push(...nonLocalDiagnostics);
9888
9616
  }
9889
9617
  }
9890
9618
  if (diagnostics.length > 0) {
@@ -10059,13 +9787,328 @@ class ComponentDecoratorHandler {
10059
9787
  ? null
10060
9788
  : getHmrUpdateDeclaration(res, pool.statements, hmrMeta, node);
10061
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
+ }
10062
10105
  /**
10063
10106
  * Locates defer blocks in case scope information is not available.
10064
10107
  * For example, this happens in the local compilation mode.
10065
10108
  */
10066
10109
  locateDeferBlocksWithoutScope(template) {
10067
10110
  const deferBlocks = new Map();
10068
- const directivelessBinder = new compiler.R3TargetBinder(new compiler.SelectorMatcher());
10111
+ const directivelessBinder = new compiler.R3TargetBinder(null);
10069
10112
  const bound = directivelessBinder.bind({ template: template.nodes });
10070
10113
  const deferredBlocks = bound.getDeferBlocks();
10071
10114
  for (const block of deferredBlocks) {
@@ -10875,7 +10918,7 @@ class PipeDecoratorHandler {
10875
10918
  * @description
10876
10919
  * Entry point for all public APIs of the compiler-cli package.
10877
10920
  */
10878
- new compiler.Version('20.0.0-next.8');
10921
+ new compiler.Version('20.0.0-rc.0');
10879
10922
 
10880
10923
  /**
10881
10924
  * Whether a given decorator should be treated as an Angular decorator.
@@ -14901,7 +14944,10 @@ function isSignalSymbol(symbol) {
14901
14944
  const fileName = decl.getSourceFile().fileName;
14902
14945
  return ((ts.isInterfaceDeclaration(decl) || ts.isTypeAliasDeclaration(decl)) &&
14903
14946
  SIGNAL_FNS.has(decl.name.text) &&
14904
- (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
+ );
14905
14951
  }));
14906
14952
  }
14907
14953
 
@@ -15152,7 +15198,7 @@ function buildDiagnosticForSignal(ctx, node, component) {
15152
15198
  }
15153
15199
  return [];
15154
15200
  }
15155
- const factory$c = {
15201
+ const factory$d = {
15156
15202
  code: checker.ErrorCode.INTERPOLATED_SIGNAL_NOT_INVOKED,
15157
15203
  name: checker.ExtendedTemplateDiagnosticName.INTERPOLATED_SIGNAL_NOT_INVOKED,
15158
15204
  create: () => new InterpolatedSignalCheck(),
@@ -15178,7 +15224,7 @@ class InvalidBananaInBoxCheck extends TemplateCheckWithVisitor {
15178
15224
  return [diagnostic];
15179
15225
  }
15180
15226
  }
15181
- const factory$b = {
15227
+ const factory$c = {
15182
15228
  code: checker.ErrorCode.INVALID_BANANA_IN_BOX,
15183
15229
  name: checker.ExtendedTemplateDiagnosticName.INVALID_BANANA_IN_BOX,
15184
15230
  create: () => new InvalidBananaInBoxCheck(),
@@ -15193,7 +15239,7 @@ const factory$b = {
15193
15239
  * are used as structural directives and a warning would be generated. Once the
15194
15240
  * `CommonModule` is included, the `ngSwitch` would also be covered.
15195
15241
  */
15196
- const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([
15242
+ const KNOWN_CONTROL_FLOW_DIRECTIVES$1 = new Map([
15197
15243
  ['ngIf', { directive: 'NgIf', builtIn: '@if' }],
15198
15244
  ['ngFor', { directive: 'NgFor', builtIn: '@for' }],
15199
15245
  ['ngSwitchCase', { directive: 'NgSwitchCase', builtIn: '@switch with @case' }],
@@ -15221,7 +15267,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
15221
15267
  visitNode(ctx, component, node) {
15222
15268
  if (!(node instanceof compiler.Template))
15223
15269
  return [];
15224
- 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));
15225
15271
  if (!controlFlowAttr)
15226
15272
  return [];
15227
15273
  const symbol = ctx.templateTypeChecker.getSymbolOfNode(node, component);
@@ -15229,7 +15275,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
15229
15275
  return [];
15230
15276
  }
15231
15277
  const sourceSpan = controlFlowAttr.keySpan || controlFlowAttr.sourceSpan;
15232
- const directiveAndBuiltIn = KNOWN_CONTROL_FLOW_DIRECTIVES.get(controlFlowAttr.name);
15278
+ const directiveAndBuiltIn = KNOWN_CONTROL_FLOW_DIRECTIVES$1.get(controlFlowAttr.name);
15233
15279
  const errorMessage = `The \`*${controlFlowAttr.name}\` directive was used in the template, ` +
15234
15280
  `but neither the \`${directiveAndBuiltIn?.directive}\` directive nor the \`CommonModule\` was imported. ` +
15235
15281
  `Use Angular's built-in control flow ${directiveAndBuiltIn?.builtIn} or ` +
@@ -15239,7 +15285,7 @@ class MissingControlFlowDirectiveCheck extends TemplateCheckWithVisitor {
15239
15285
  return [diagnostic];
15240
15286
  }
15241
15287
  }
15242
- const factory$a = {
15288
+ const factory$b = {
15243
15289
  code: checker.ErrorCode.MISSING_CONTROL_FLOW_DIRECTIVE,
15244
15290
  name: checker.ExtendedTemplateDiagnosticName.MISSING_CONTROL_FLOW_DIRECTIVE,
15245
15291
  create: (options) => {
@@ -15272,12 +15318,67 @@ class MissingNgForOfLetCheck extends TemplateCheckWithVisitor {
15272
15318
  return [diagnostic];
15273
15319
  }
15274
15320
  }
15275
- const factory$9 = {
15321
+ const factory$a = {
15276
15322
  code: checker.ErrorCode.MISSING_NGFOROF_LET,
15277
15323
  name: checker.ExtendedTemplateDiagnosticName.MISSING_NGFOROF_LET,
15278
15324
  create: () => new MissingNgForOfLetCheck(),
15279
15325
  };
15280
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
+
15281
15382
  /**
15282
15383
  * Ensures the left side of a nullish coalescing operation is nullable.
15283
15384
  * Returns diagnostics for the cases where the operator is useless.
@@ -15751,14 +15852,15 @@ function assertNever(value) {
15751
15852
  }
15752
15853
 
15753
15854
  const ALL_DIAGNOSTIC_FACTORIES = [
15754
- factory$b,
15855
+ factory$c,
15755
15856
  factory$8,
15756
15857
  factory$7,
15757
- factory$a,
15858
+ factory$b,
15758
15859
  factory$4,
15860
+ factory$a,
15759
15861
  factory$9,
15760
15862
  factory$5,
15761
- factory$c,
15863
+ factory$d,
15762
15864
  factory$3,
15763
15865
  factory$1,
15764
15866
  factory$6,
@@ -18811,7 +18913,7 @@ var semver = /*@__PURE__*/getDefaultExportFromCjs(semverExports);
18811
18913
  * @param minVersion Minimum required version for the feature.
18812
18914
  */
18813
18915
  function coreVersionSupportsFeature(coreVersion, minVersion) {
18814
- // A version of `20.0.0-next.8` usually means that core is at head so it supports
18916
+ // A version of `20.0.0-rc.0` usually means that core is at head so it supports
18815
18917
  // all features. Use string interpolation prevent the placeholder from being replaced
18816
18918
  // with the current version during build time.
18817
18919
  if (coreVersion === `0.0.0-${'PLACEHOLDER'}`) {
@@ -18926,6 +19028,7 @@ class NgCompiler {
18926
19028
  angularCoreVersion;
18927
19029
  enableHmr;
18928
19030
  implicitStandaloneValue;
19031
+ enableSelectorless;
18929
19032
  /**
18930
19033
  * `NgCompiler` can be reused for multiple compilations (for resource-only changes), and each
18931
19034
  * new compilation uses a fresh `PerfRecorder`. Thus, classes created with a lifespan of the
@@ -18970,6 +19073,7 @@ class NgCompiler {
18970
19073
  // TODO(crisbeto): remove this flag and base `enableBlockSyntax` on the `angularCoreVersion`.
18971
19074
  this.enableBlockSyntax = options['_enableBlockSyntax'] ?? true;
18972
19075
  this.enableLetSyntax = options['_enableLetSyntax'] ?? true;
19076
+ this.enableSelectorless = options['_enableSelectorless'] ?? false;
18973
19077
  // Standalone by default is enabled since v19. We need to toggle it here,
18974
19078
  // because the language service extension may be running with the latest
18975
19079
  // version of the compiler against an older version of Angular.
@@ -19750,7 +19854,7 @@ class NgCompiler {
19750
19854
  const jitDeclarationRegistry = new JitDeclarationRegistry();
19751
19855
  // Set up the IvyCompilation, which manages state for the Ivy transformer.
19752
19856
  const handlers = [
19753
- 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),
19754
19858
  // TODO(alxhub): understand why the cast here is necessary (something to do with `null`
19755
19859
  // not being assignable to `unknown` when wrapped in `Readonly`).
19756
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),