66 * found in the LICENSE file at https://angular.io/license
77 */
88
9- import { AnimationTriggerNames , BoundTarget , compileClassDebugInfo , compileComponentClassMetadata , compileComponentFromMetadata , compileDeclareClassMetadata , compileDeclareComponentFromMetadata , ConstantPool , CssSelector , DeclarationListEmitMode , DeclareComponentTemplateInfo , DEFAULT_INTERPOLATION_CONFIG , DeferBlockDepsEmitMode , DomElementSchemaRegistry , ExternalExpr , FactoryTarget , makeBindingParser , outputAst as o , R3ComponentMetadata , R3DeferMetadata , R3DirectiveDependencyMetadata , R3NgModuleDependencyMetadata , R3PipeDependencyMetadata , R3TargetBinder , R3TemplateDependency , R3TemplateDependencyKind , R3TemplateDependencyMetadata , SchemaMetadata , SelectorMatcher , TmplAstDeferredBlock , ViewEncapsulation } from '@angular/compiler' ;
9+ import { AnimationTriggerNames , BoundTarget , compileClassDebugInfo , compileComponentClassMetadata , compileComponentFromMetadata , compileDeclareClassMetadata , compileDeclareComponentFromMetadata , compileDeferResolverFunction , ConstantPool , CssSelector , DeclarationListEmitMode , DeclareComponentTemplateInfo , DEFAULT_INTERPOLATION_CONFIG , DeferBlockDepsEmitMode , DomElementSchemaRegistry , ExternalExpr , FactoryTarget , makeBindingParser , outputAst as o , R3ComponentDeferMetadata , R3ComponentMetadata , R3DeferPerComponentDependency , R3DirectiveDependencyMetadata , R3NgModuleDependencyMetadata , R3PipeDependencyMetadata , R3TargetBinder , R3TemplateDependency , R3TemplateDependencyKind , R3TemplateDependencyMetadata , SchemaMetadata , SelectorMatcher , TmplAstDeferredBlock , ViewEncapsulation } from '@angular/compiler' ;
1010import ts from 'typescript' ;
1111
1212import { Cycle , CycleAnalyzer , CycleHandlingStrategy } from '../../../cycles' ;
@@ -484,13 +484,13 @@ export class ComponentDecoratorHandler implements
484484 // (if it exists) and populate the `DeferredSymbolTracker` state. These operations are safe
485485 // for the local compilation mode, since they don't require accessing/resolving symbols
486486 // outside of the current source file.
487- let explicitlyDeferredTypes : Map < string , { importPath : string , isDefaultImport : boolean } > | null =
488- null ;
487+ let explicitlyDeferredTypes : R3DeferPerComponentDependency [ ] | null = null ;
489488 if ( metadata . isStandalone && rawDeferredImports !== null ) {
490489 const deferredTypes = this . collectExplicitlyDeferredSymbols ( rawDeferredImports ) ;
491490 for ( const [ deferredType , importDetails ] of deferredTypes ) {
492- explicitlyDeferredTypes ??= new Map ( ) ;
493- explicitlyDeferredTypes . set ( importDetails . name , {
491+ explicitlyDeferredTypes ??= [ ] ;
492+ explicitlyDeferredTypes . push ( {
493+ symbolName : importDetails . name ,
494494 importPath : importDetails . from ,
495495 isDefaultImport : isDefaultImport ( importDetails . node ) ,
496496 } ) ;
@@ -715,10 +715,10 @@ export class ComponentDecoratorHandler implements
715715 declarationListEmitMode : ( ! analysis . meta . isStandalone || analysis . rawImports !== null ) ?
716716 DeclarationListEmitMode . RuntimeResolved :
717717 DeclarationListEmitMode . Direct ,
718- deferBlockDependencies : this . locateDeferBlocksWithoutScope ( analysis . template ) ,
718+ deferPerBlockDependencies : this . locateDeferBlocksWithoutScope ( analysis . template ) ,
719719 deferBlockDepsEmitMode : DeferBlockDepsEmitMode . PerComponent ,
720720 deferrableDeclToImportDecl : new Map ( ) ,
721- deferrableTypes : analysis . explicitlyDeferredTypes ?? new Map ( ) ,
721+ deferPerComponentDependencies : analysis . explicitlyDeferredTypes ?? [ ] ,
722722 } ;
723723
724724 if ( this . localCompilationExtraImportsTracker === null ) {
@@ -731,10 +731,10 @@ export class ComponentDecoratorHandler implements
731731 data = {
732732 declarations : EMPTY_ARRAY ,
733733 declarationListEmitMode : DeclarationListEmitMode . Direct ,
734- deferBlockDependencies : new Map ( ) ,
734+ deferPerBlockDependencies : new Map ( ) ,
735735 deferBlockDepsEmitMode : DeferBlockDepsEmitMode . PerBlock ,
736736 deferrableDeclToImportDecl : new Map ( ) ,
737- deferrableTypes : new Map ( ) ,
737+ deferPerComponentDependencies : [ ] ,
738738 } ;
739739 }
740740
@@ -1032,7 +1032,7 @@ export class ComponentDecoratorHandler implements
10321032 } else {
10331033 // If there is no scope, we can still use the binder to retrieve *some* information about the
10341034 // deferred blocks.
1035- data . deferBlockDependencies = this . locateDeferBlocksWithoutScope ( metadata . template ) ;
1035+ data . deferPerBlockDependencies = this . locateDeferBlocksWithoutScope ( metadata . template ) ;
10361036 }
10371037
10381038 // Run diagnostics only in global mode.
@@ -1257,22 +1257,19 @@ export class ComponentDecoratorHandler implements
12571257 * the `@Component.imports` field and their usage in `@defer` blocks.
12581258 */
12591259 private collectDeferredSymbols ( resolution : Readonly < ComponentResolutionData > ) {
1260- const deferrableTypes = new Map < string , { importPath : string , isDefaultImport : boolean } > ( ) ;
1260+ const deferrableTypes : R3DeferPerComponentDependency [ ] = [ ] ;
12611261 // Go over all dependencies of all defer blocks and update the value of
12621262 // the `isDeferrable` flag and the `importPath` to reflect the current
12631263 // state after visiting all components during the `resolve` phase.
1264- for ( const [ _ , deps ] of resolution . deferBlockDependencies ) {
1264+ for ( const [ _ , deps ] of resolution . deferPerBlockDependencies ) {
12651265 for ( const deferBlockDep of deps ) {
12661266 const importDecl =
12671267 resolution . deferrableDeclToImportDecl . get ( deferBlockDep . declaration . node ) ?? null ;
12681268 if ( importDecl !== null && this . deferredSymbolTracker . canDefer ( importDecl ) ) {
12691269 deferBlockDep . isDeferrable = true ;
12701270 deferBlockDep . importPath = ( importDecl . moduleSpecifier as ts . StringLiteral ) . text ;
12711271 deferBlockDep . isDefaultImport = isDefaultImport ( importDecl ) ;
1272- deferrableTypes . set ( deferBlockDep . symbolName , {
1273- importPath : deferBlockDep . importPath ,
1274- isDefaultImport : deferBlockDep . isDefaultImport ,
1275- } ) ;
1272+ deferrableTypes . push ( deferBlockDep as R3DeferPerComponentDependency ) ;
12761273 }
12771274 }
12781275 }
@@ -1353,11 +1350,11 @@ export class ComponentDecoratorHandler implements
13531350 const usedPipes = new Set ( bound . getEagerlyUsedPipes ( ) ) ;
13541351 let deps : DeferredComponentDependency [ ] ;
13551352
1356- if ( resolutionData . deferBlockDependencies . has ( deferBlock ) ) {
1357- deps = resolutionData . deferBlockDependencies . get ( deferBlock ) ! ;
1353+ if ( resolutionData . deferPerBlockDependencies . has ( deferBlock ) ) {
1354+ deps = resolutionData . deferPerBlockDependencies . get ( deferBlock ) ! ;
13581355 } else {
13591356 deps = [ ] ;
1360- resolutionData . deferBlockDependencies . set ( deferBlock , deps ) ;
1357+ resolutionData . deferPerBlockDependencies . set ( deferBlock , deps ) ;
13611358 }
13621359
13631360 for ( const decl of Array . from ( deferrableDecls . values ( ) ) ) {
@@ -1479,68 +1476,39 @@ export class ComponentDecoratorHandler implements
14791476 }
14801477
14811478 private compileDeferBlocks ( resolution : Readonly < Partial < ComponentResolutionData > > ) :
1482- R3DeferMetadata {
1483- if ( resolution . deferBlockDepsEmitMode === DeferBlockDepsEmitMode . PerBlock ) {
1484- if ( ! resolution . deferBlockDependencies ) {
1479+ R3ComponentDeferMetadata {
1480+ const {
1481+ deferBlockDepsEmitMode : mode ,
1482+ deferPerBlockDependencies : perBlockDeps ,
1483+ deferPerComponentDependencies : perComponentDeps
1484+ } = resolution ;
1485+
1486+ if ( mode === DeferBlockDepsEmitMode . PerBlock ) {
1487+ if ( ! perBlockDeps ) {
14851488 throw new Error (
1486- 'Internal error: deferBlockDependencies must be present when compiling in PerBlock mode' ) ;
1489+ 'Internal error: deferPerBlockDependencies must be present when compiling in PerBlock mode' ) ;
14871490 }
14881491
14891492 const blocks = new Map < TmplAstDeferredBlock , o . ArrowFunctionExpr | null > ( ) ;
1490-
1491- for ( const [ block , dependencies ] of resolution . deferBlockDependencies ) {
1492- const depExpressions : o . Expression [ ] = [ ] ;
1493- for ( const dep of dependencies ) {
1494- if ( dep . isDeferrable ) {
1495- // Callback function, e.g. `m () => m.MyCmp;`.
1496- const innerFn = o . arrowFn (
1497- // Default imports are always accessed through the `default` property.
1498- [ new o . FnParam ( 'm' , o . DYNAMIC_TYPE ) ] ,
1499- o . variable ( 'm' ) . prop ( dep . isDefaultImport ? 'default' : dep . symbolName ) ) ;
1500-
1501- // Dynamic import, e.g. `import('./a').then(...)`.
1502- const importExpr =
1503- ( new o . DynamicImportExpr ( dep . importPath ! ) ) . prop ( 'then' ) . callFn ( [ innerFn ] ) ;
1504- depExpressions . push ( importExpr ) ;
1505- } else {
1506- // Non-deferrable symbol, just use a reference to the type. Note that it's important to
1507- // go through `typeReference`, rather than `symbolName` in order to preserve the
1508- // original reference within the source file.
1509- depExpressions . push ( dep . typeReference ) ;
1510- }
1511- }
1493+ for ( const [ block , dependencies ] of perBlockDeps ) {
15121494 blocks . set (
15131495 block ,
1514- depExpressions . length === 0 ? null : o . arrowFn ( [ ] , o . literalArr ( depExpressions ) ) ) ;
1496+ dependencies . length === 0 ? null : compileDeferResolverFunction ( { mode , dependencies } ) ) ;
15151497 }
15161498
1517- return { mode : DeferBlockDepsEmitMode . PerBlock , blocks} ;
1499+ return { mode, blocks} ;
15181500 }
15191501
1520- if ( resolution . deferBlockDepsEmitMode === DeferBlockDepsEmitMode . PerComponent ) {
1521- if ( ! resolution . deferBlockDependencies || ! resolution . deferrableTypes ) {
1502+ if ( mode === DeferBlockDepsEmitMode . PerComponent ) {
1503+ if ( ! perComponentDeps ) {
15221504 throw new Error (
1523- 'Internal error: deferBlockDependencies and deferrableTypes must be present in PerComponent mode' ) ;
1505+ 'Internal error: deferPerComponentDependencies must be present in PerComponent mode' ) ;
15241506 }
1525-
1526- // This defer block has deps for which we need to generate dynamic imports.
1527- const depExpressions : o . Expression [ ] = [ ] ;
1528-
1529- for ( const [ symbolName , { importPath, isDefaultImport} ] of resolution . deferrableTypes ) {
1530- // Callback function, e.g. `m () => m.MyCmp;`.
1531- const innerFn = o . arrowFn (
1532- [ new o . FnParam ( 'm' , o . DYNAMIC_TYPE ) ] ,
1533- o . variable ( 'm' ) . prop ( isDefaultImport ? 'default' : symbolName ) ) ;
1534-
1535- // Dynamic import, e.g. `import('./a').then(...)`.
1536- const importExpr = ( new o . DynamicImportExpr ( importPath ) ) . prop ( 'then' ) . callFn ( [ innerFn ] ) ;
1537- depExpressions . push ( importExpr ) ;
1538- }
1539-
15401507 return {
15411508 mode : DeferBlockDepsEmitMode . PerComponent ,
1542- dependenciesFn : depExpressions . length === 0 ? null :
1543- o . arrowFn ( [ ] , o . literalArr ( depExpressions ) )
1509+ dependenciesFn : perComponentDeps . length === 0 ?
1510+ null :
1511+ compileDeferResolverFunction ( { mode, dependencies : perComponentDeps } )
15441512 } ;
15451513 }
15461514
@@ -1586,10 +1554,9 @@ function extractPipes(dependencies: Array<PipeMeta|DirectiveMeta|NgModuleMeta>):
15861554 * in the `setClassMetadataAsync` call. Otherwise, an import declaration gets retained.
15871555 */
15881556function removeDeferrableTypesFromComponentDecorator (
1589- analysis : Readonly < ComponentAnalysisData > ,
1590- deferrableTypes : Map < string , { importPath : string , isDefaultImport : boolean } > ) {
1557+ analysis : Readonly < ComponentAnalysisData > , deferrableTypes : R3DeferPerComponentDependency [ ] ) {
15911558 if ( analysis . classMetadata ) {
1592- const deferrableSymbols = new Set ( deferrableTypes . keys ( ) ) ;
1559+ const deferrableSymbols = new Set ( deferrableTypes . map ( t => t . symbolName ) ) ;
15931560 const rewrittenDecoratorsNode = removeIdentifierReferences (
15941561 ( analysis . classMetadata . decorators as o . WrappedNodeExpr < ts . Node > ) . node , deferrableSymbols ) ;
15951562 analysis . classMetadata . decorators = new o . WrappedNodeExpr ( rewrittenDecoratorsNode ) ;
0 commit comments