diff --git a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts index ce1a5a154b..60ab38d4c8 100644 --- a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts @@ -14,7 +14,7 @@ import {ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecorato import {CycleAnalyzer, CycleHandlingStrategy, ImportGraph} from '../../../src/ngtsc/cycles'; import {isFatalDiagnosticError} from '../../../src/ngtsc/diagnostics'; import {absoluteFromSourceFile, LogicalFileSystem, ReadonlyFileSystem} from '../../../src/ngtsc/file_system'; -import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, NOOP_DEFAULT_IMPORT_RECORDER, PrivateExportAliasingHost, Reexport, ReferenceEmitter} from '../../../src/ngtsc/imports'; +import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, PrivateExportAliasingHost, Reexport, ReferenceEmitter} from '../../../src/ngtsc/imports'; import {SemanticSymbol} from '../../../src/ngtsc/incremental/semantic_graph'; import {CompoundMetadataReader, CompoundMetadataRegistry, DtsMetadataReader, InjectableClassRegistry, LocalMetadataRegistry, ResourceRegistry} from '../../../src/ngtsc/metadata'; import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator'; @@ -107,8 +107,8 @@ export class DecorationAnalyzer { /* i18nUseExternalIds */ true, this.bundle.enableI18nLegacyMessageIdFormat, /* usePoisonedData */ false, /* i18nNormalizeLineEndingsInICUs */ false, this.moduleResolver, this.cycleAnalyzer, - CycleHandlingStrategy.UseRemoteScoping, this.refEmitter, NOOP_DEFAULT_IMPORT_RECORDER, - NOOP_DEPENDENCY_TRACKER, this.injectableRegistry, + CycleHandlingStrategy.UseRemoteScoping, this.refEmitter, NOOP_DEPENDENCY_TRACKER, + this.injectableRegistry, /* semanticDepGraphUpdater */ null, !!this.compilerOptions.annotateForClosureCompiler, NOOP_PERF_RECORDER), @@ -116,7 +116,7 @@ export class DecorationAnalyzer { // clang-format off new DirectiveDecoratorHandler( this.reflectionHost, this.evaluator, this.fullRegistry, this.scopeRegistry, - this.fullMetaReader, NOOP_DEFAULT_IMPORT_RECORDER, this.injectableRegistry, this.isCore, + this.fullMetaReader, this.injectableRegistry, this.isCore, /* semanticDepGraphUpdater */ null, !!this.compilerOptions.annotateForClosureCompiler, // In ngcc we want to compile undecorated classes with Angular features. As of @@ -131,18 +131,17 @@ export class DecorationAnalyzer { // before injectable factories (so injectable factories can delegate to them) new PipeDecoratorHandler( this.reflectionHost, this.evaluator, this.metaRegistry, this.scopeRegistry, - NOOP_DEFAULT_IMPORT_RECORDER, this.injectableRegistry, this.isCore, NOOP_PERF_RECORDER), + this.injectableRegistry, this.isCore, NOOP_PERF_RECORDER), new InjectableDecoratorHandler( - this.reflectionHost, NOOP_DEFAULT_IMPORT_RECORDER, this.isCore, + this.reflectionHost, this.isCore, /* strictCtorDeps */ false, this.injectableRegistry, NOOP_PERF_RECORDER, /* errorOnDuplicateProv */ false), new NgModuleDecoratorHandler( this.reflectionHost, this.evaluator, this.fullMetaReader, this.fullRegistry, this.scopeRegistry, this.referencesRegistry, this.isCore, /* routeAnalyzer */ null, this.refEmitter, - /* factoryTracker */ null, NOOP_DEFAULT_IMPORT_RECORDER, - !!this.compilerOptions.annotateForClosureCompiler, this.injectableRegistry, - NOOP_PERF_RECORDER), + /* factoryTracker */ null, !!this.compilerOptions.annotateForClosureCompiler, + this.injectableRegistry, NOOP_PERF_RECORDER), ]; compiler = new NgccTraitCompiler(this.handlers, this.reflectionHost); migrations: Migration[] = [ diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts index 1f970328fd..ba723a1cd5 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts @@ -12,7 +12,7 @@ import * as ts from 'typescript'; import {Cycle, CycleAnalyzer, CycleHandlingStrategy} from '../../cycles'; import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics'; import {absoluteFrom, relative} from '../../file_system'; -import {DefaultImportRecorder, ImportedFile, ModuleResolver, Reference, ReferenceEmitter} from '../../imports'; +import {ImportedFile, ModuleResolver, Reference, ReferenceEmitter} from '../../imports'; import {DependencyTracker} from '../../incremental/api'; import {extractSemanticTypeParameters, isArrayEqual, isReferenceEqual, SemanticDepGraphUpdater, SemanticReference, SemanticSymbol} from '../../incremental/semantic_graph'; import {IndexingContext} from '../../indexer'; @@ -205,7 +205,6 @@ export class ComponentDecoratorHandler implements private i18nNormalizeLineEndingsInICUs: boolean|undefined, private moduleResolver: ModuleResolver, private cycleAnalyzer: CycleAnalyzer, private cycleHandlingStrategy: CycleHandlingStrategy, private refEmitter: ReferenceEmitter, - private defaultImportRecorder: DefaultImportRecorder, private depTracker: DependencyTracker|null, private injectableRegistry: InjectableClassRegistry, private semanticDepGraphUpdater: SemanticDepGraphUpdater|null, @@ -326,8 +325,8 @@ export class ComponentDecoratorHandler implements // @Component inherits @Directive, so begin by extracting the @Directive metadata and building // on it. const directiveResult = extractDirectiveMetadata( - node, decorator, this.reflector, this.evaluator, this.defaultImportRecorder, this.isCore, - flags, this.annotateForClosureCompiler, + node, decorator, this.reflector, this.evaluator, this.isCore, flags, + this.annotateForClosureCompiler, this.elementSchemaRegistry.getDefaultComponentElementName()); if (directiveResult === undefined) { // `extractDirectiveMetadata` returns undefined when the @Directive has `jit: true`. In this @@ -490,8 +489,7 @@ export class ComponentDecoratorHandler implements }, typeCheckMeta: extractDirectiveTypeCheckMeta(node, inputs, this.reflector), classMetadata: extractClassMetadata( - node, this.reflector, this.defaultImportRecorder, this.isCore, - this.annotateForClosureCompiler), + node, this.reflector, this.isCore, this.annotateForClosureCompiler), template, providersRequiringFactory, viewProvidersRequiringFactory, diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index 4c3e2369ac..3893ad0725 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -11,7 +11,7 @@ import {emitDistinctChangesOnlyDefaultValue} from '@angular/compiler/src/core'; import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {DefaultImportRecorder, Reference} from '../../imports'; +import {Reference} from '../../imports'; import {areTypeParametersEqual, extractSemanticTypeParameters, isArrayEqual, isSetEqual, isSymbolEqual, SemanticDepGraphUpdater, SemanticSymbol, SemanticTypeParameter} from '../../incremental/semantic_graph'; import {BindingPropertyName, ClassPropertyMapping, ClassPropertyName, DirectiveTypeCheckMeta, InjectableClassRegistry, MetadataReader, MetadataRegistry, TemplateGuardMeta} from '../../metadata'; import {extractDirectiveTypeCheckMeta} from '../../metadata/src/util'; @@ -177,9 +177,8 @@ export class DirectiveDecoratorHandler implements constructor( private reflector: ReflectionHost, private evaluator: PartialEvaluator, private metaRegistry: MetadataRegistry, private scopeRegistry: LocalModuleScopeRegistry, - private metaReader: MetadataReader, private defaultImportRecorder: DefaultImportRecorder, - private injectableRegistry: InjectableClassRegistry, private isCore: boolean, - private semanticDepGraphUpdater: SemanticDepGraphUpdater|null, + private metaReader: MetadataReader, private injectableRegistry: InjectableClassRegistry, + private isCore: boolean, private semanticDepGraphUpdater: SemanticDepGraphUpdater|null, private annotateForClosureCompiler: boolean, private compileUndecoratedClassesWithAngularFeatures: boolean, private perf: PerfRecorder) {} @@ -215,8 +214,8 @@ export class DirectiveDecoratorHandler implements this.perf.eventCount(PerfEvent.AnalyzeDirective); const directiveResult = extractDirectiveMetadata( - node, decorator, this.reflector, this.evaluator, this.defaultImportRecorder, this.isCore, - flags, this.annotateForClosureCompiler); + node, decorator, this.reflector, this.evaluator, this.isCore, flags, + this.annotateForClosureCompiler); if (directiveResult === undefined) { return {}; } @@ -234,8 +233,7 @@ export class DirectiveDecoratorHandler implements outputs: directiveResult.outputs, meta: analysis, classMetadata: extractClassMetadata( - node, this.reflector, this.defaultImportRecorder, this.isCore, - this.annotateForClosureCompiler), + node, this.reflector, this.isCore, this.annotateForClosureCompiler), baseClass: readBaseClass(node, this.reflector, this.evaluator), typeCheckMeta: extractDirectiveTypeCheckMeta(node, directiveResult.inputs, this.reflector), providersRequiringFactory, @@ -351,9 +349,8 @@ export class DirectiveDecoratorHandler implements */ export function extractDirectiveMetadata( clazz: ClassDeclaration, decorator: Readonly, reflector: ReflectionHost, - evaluator: PartialEvaluator, defaultImportRecorder: DefaultImportRecorder, isCore: boolean, - flags: HandlerFlags, annotateForClosureCompiler: boolean, - defaultSelector: string|null = null): { + evaluator: PartialEvaluator, isCore: boolean, flags: HandlerFlags, + annotateForClosureCompiler: boolean, defaultSelector: string|null = null): { decorator: Map, metadata: R3DirectiveMetadata, inputs: ClassPropertyMapping, @@ -473,7 +470,7 @@ export function extractDirectiveMetadata( exportAs = resolved.split(',').map(part => part.trim()); } - const rawCtorDeps = getConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore); + const rawCtorDeps = getConstructorDependencies(clazz, reflector, isCore); // Non-abstract directives (those with a selector) require valid constructor dependencies, whereas // abstract directives are allowed to have invalid dependencies, given that a subclass may call diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts index 734e2748ed..ee0ad85820 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts @@ -10,7 +10,6 @@ import {compileClassMetadata, CompileClassMetadataFn, compileDeclareClassMetadat import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {DefaultImportRecorder} from '../../imports'; import {InjectableClassRegistry} from '../../metadata'; import {PerfEvent, PerfRecorder} from '../../perf'; import {ClassDeclaration, Decorator, ReflectionHost, reflectObjectLiteral} from '../../reflection'; @@ -33,8 +32,7 @@ export interface InjectableHandlerData { export class InjectableDecoratorHandler implements DecoratorHandler { constructor( - private reflector: ReflectionHost, private defaultImportRecorder: DefaultImportRecorder, - private isCore: boolean, private strictCtorDeps: boolean, + private reflector: ReflectionHost, private isCore: boolean, private strictCtorDeps: boolean, private injectableRegistry: InjectableClassRegistry, private perf: PerfRecorder, /** * What to do if the injectable already contains a ɵprov property. @@ -74,10 +72,8 @@ export class InjectableDecoratorHandler implements analysis: { meta, ctorDeps: extractInjectableCtorDeps( - node, meta, decorator, this.reflector, this.defaultImportRecorder, this.isCore, - this.strictCtorDeps), - classMetadata: - extractClassMetadata(node, this.reflector, this.defaultImportRecorder, this.isCore), + node, meta, decorator, this.reflector, this.isCore, this.strictCtorDeps), + classMetadata: extractClassMetadata(node, this.reflector, this.isCore), // Avoid generating multiple factories if a class has // more Angular decorators, apart from Injectable. needsFactory: !decorators || @@ -232,8 +228,7 @@ function getProviderExpression( function extractInjectableCtorDeps( clazz: ClassDeclaration, meta: R3InjectableMetadata, decorator: Decorator, - reflector: ReflectionHost, defaultImportRecorder: DefaultImportRecorder, isCore: boolean, - strictCtorDeps: boolean) { + reflector: ReflectionHost, isCore: boolean, strictCtorDeps: boolean) { if (decorator.args === null) { throw new FatalDiagnosticError( ErrorCode.DECORATOR_NOT_CALLED, Decorator.nodeForError(decorator), @@ -252,15 +247,15 @@ function extractInjectableCtorDeps( // constructor signature does not work for DI then a factory definition (ɵfac) that throws is // generated. if (strictCtorDeps) { - ctorDeps = getValidConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore); + ctorDeps = getValidConstructorDependencies(clazz, reflector, isCore); } else { - ctorDeps = unwrapConstructorDependencies( - getConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore)); + ctorDeps = + unwrapConstructorDependencies(getConstructorDependencies(clazz, reflector, isCore)); } return ctorDeps; } else if (decorator.args.length === 1) { - const rawCtorDeps = getConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore); + const rawCtorDeps = getConstructorDependencies(clazz, reflector, isCore); if (strictCtorDeps && meta.useValue === undefined && meta.useExisting === undefined && meta.useClass === undefined && meta.useFactory === undefined) { diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts index aac4bbe4f0..223a0ed16f 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts @@ -9,7 +9,6 @@ import {Expression, FunctionExpr, LiteralArrayExpr, LiteralExpr, literalMap, R3ClassMetadata, ReturnStatement, WrappedNodeExpr} from '@angular/compiler'; import * as ts from 'typescript'; -import {DefaultImportRecorder} from '../../imports'; import {CtorParameter, DeclarationNode, Decorator, ReflectionHost, TypeValueReferenceKind} from '../../reflection'; import {valueReferenceToExpression, wrapFunctionExpressionsInParens} from './util'; @@ -23,8 +22,7 @@ import {valueReferenceToExpression, wrapFunctionExpressionsInParens} from './uti * as a `Statement` for inclusion along with the class. */ export function extractClassMetadata( - clazz: DeclarationNode, reflection: ReflectionHost, - defaultImportRecorder: DefaultImportRecorder, isCore: boolean, + clazz: DeclarationNode, reflection: ReflectionHost, isCore: boolean, annotateForClosureCompiler?: boolean): R3ClassMetadata|null { if (!reflection.isClass(clazz)) { return null; @@ -55,8 +53,7 @@ export function extractClassMetadata( let metaCtorParameters: Expression|null = null; const classCtorParameters = reflection.getConstructorParameters(clazz); if (classCtorParameters !== null) { - const ctorParameters = classCtorParameters.map( - param => ctorParameterToMetadata(param, defaultImportRecorder, isCore)); + const ctorParameters = classCtorParameters.map(param => ctorParameterToMetadata(param, isCore)); metaCtorParameters = new FunctionExpr([], [ new ReturnStatement(new LiteralArrayExpr(ctorParameters)), ]); @@ -93,13 +90,11 @@ export function extractClassMetadata( /** * Convert a reflected constructor parameter to metadata. */ -function ctorParameterToMetadata( - param: CtorParameter, defaultImportRecorder: DefaultImportRecorder, - isCore: boolean): Expression { +function ctorParameterToMetadata(param: CtorParameter, isCore: boolean): Expression { // Parameters sometimes have a type that can be referenced. If so, then use it, otherwise // its type is undefined. const type = param.typeValueReference.kind !== TypeValueReferenceKind.UNAVAILABLE ? - valueReferenceToExpression(param.typeValueReference, defaultImportRecorder) : + valueReferenceToExpression(param.typeValueReference) : new LiteralExpr(undefined); const mapEntries: {key: string, value: Expression, quoted: false}[] = [ diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts index 51e3c4ea7e..cb98a2fa78 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -10,7 +10,7 @@ import {compileClassMetadata, compileDeclareClassMetadata, compileDeclareInjecto import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics'; -import {DefaultImportRecorder, Reference, ReferenceEmitter} from '../../imports'; +import {Reference, ReferenceEmitter} from '../../imports'; import {isArrayEqual, isReferenceEqual, isSymbolEqual, SemanticReference, SemanticSymbol} from '../../incremental/semantic_graph'; import {InjectableClassRegistry, MetadataReader, MetadataRegistry} from '../../metadata'; import {PartialEvaluator, ResolvedValue} from '../../partial_evaluator'; @@ -130,9 +130,7 @@ export class NgModuleDecoratorHandler implements private scopeRegistry: LocalModuleScopeRegistry, private referencesRegistry: ReferencesRegistry, private isCore: boolean, private routeAnalyzer: NgModuleRouteAnalyzer|null, private refEmitter: ReferenceEmitter, - private factoryTracker: FactoryTracker|null, - private defaultImportRecorder: DefaultImportRecorder, - private annotateForClosureCompiler: boolean, + private factoryTracker: FactoryTracker|null, private annotateForClosureCompiler: boolean, private injectableRegistry: InjectableClassRegistry, private perf: PerfRecorder, private localeId?: string) {} @@ -350,8 +348,7 @@ export class NgModuleDecoratorHandler implements type, internalType, typeArgumentCount: 0, - deps: getValidConstructorDependencies( - node, this.reflector, this.defaultImportRecorder, this.isCore), + deps: getValidConstructorDependencies(node, this.reflector, this.isCore), target: FactoryTarget.NgModule, }; @@ -371,8 +368,7 @@ export class NgModuleDecoratorHandler implements resolveProvidersRequiringFactory(rawProviders, this.reflector, this.evaluator) : null, classMetadata: extractClassMetadata( - node, this.reflector, this.defaultImportRecorder, this.isCore, - this.annotateForClosureCompiler), + node, this.reflector, this.isCore, this.annotateForClosureCompiler), factorySymbolName: node.name.text, }, }; diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts index 691d563eb0..1dd0d4b961 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts @@ -10,7 +10,7 @@ import {compileClassMetadata, compileDeclareClassMetadata, compileDeclarePipeFro import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; -import {DefaultImportRecorder, Reference} from '../../imports'; +import {Reference} from '../../imports'; import {SemanticSymbol} from '../../incremental/semantic_graph'; import {InjectableClassRegistry, MetadataRegistry} from '../../metadata'; import {PartialEvaluator} from '../../partial_evaluator'; @@ -55,7 +55,6 @@ export class PipeDecoratorHandler implements constructor( private reflector: ReflectionHost, private evaluator: PartialEvaluator, private metaRegistry: MetadataRegistry, private scopeRegistry: LocalModuleScopeRegistry, - private defaultImportRecorder: DefaultImportRecorder, private injectableRegistry: InjectableClassRegistry, private isCore: boolean, private perf: PerfRecorder) {} @@ -131,12 +130,10 @@ export class PipeDecoratorHandler implements internalType, typeArgumentCount: this.reflector.getGenericArityOfClass(clazz) || 0, pipeName, - deps: getValidConstructorDependencies( - clazz, this.reflector, this.defaultImportRecorder, this.isCore), + deps: getValidConstructorDependencies(clazz, this.reflector, this.isCore), pure, }, - classMetadata: - extractClassMetadata(clazz, this.reflector, this.defaultImportRecorder, this.isCore), + classMetadata: extractClassMetadata(clazz, this.reflector, this.isCore), }, }; } diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts index 098b18391d..69d29dbd01 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts @@ -12,7 +12,8 @@ import {FactoryTarget} from '@angular/compiler/src/render3/partial/api'; import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics'; -import {DefaultImportRecorder, ImportFlags, Reference, ReferenceEmitter} from '../../imports'; +import {ImportFlags, Reference, ReferenceEmitter} from '../../imports'; +import {attachDefaultImportDeclaration} from '../../imports/src/default'; import {ForeignFunctionResolver, PartialEvaluator} from '../../partial_evaluator'; import {ClassDeclaration, CtorParameter, Decorator, Import, ImportedTypeValueReference, isNamedClassDeclaration, LocalTypeValueReference, ReflectionHost, TypeValueReference, TypeValueReferenceKind, UnavailableValue, ValueUnavailableKind} from '../../reflection'; import {DeclarationData} from '../../scope'; @@ -32,8 +33,7 @@ export interface ConstructorDepError { } export function getConstructorDependencies( - clazz: ClassDeclaration, reflector: ReflectionHost, - defaultImportRecorder: DefaultImportRecorder, isCore: boolean): ConstructorDeps|null { + clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean): ConstructorDeps|null { const deps: R3DependencyMetadata[] = []; const errors: ConstructorDepError[] = []; let ctorParams = reflector.getConstructorParameters(clazz); @@ -45,7 +45,7 @@ export function getConstructorDependencies( } } ctorParams.forEach((param, idx) => { - let token = valueReferenceToExpression(param.typeValueReference, defaultImportRecorder); + let token = valueReferenceToExpression(param.typeValueReference); let attributeNameType: Expression|null = null; let optional = false, self = false, skipSelf = false, host = false; @@ -115,22 +115,18 @@ export function getConstructorDependencies( * references are converted to an `ExternalExpr`. Note that this is only valid in the context of the * file in which the `TypeValueReference` originated. */ -export function valueReferenceToExpression( - valueRef: LocalTypeValueReference|ImportedTypeValueReference, - defaultImportRecorder: DefaultImportRecorder): Expression; -export function valueReferenceToExpression( - valueRef: TypeValueReference, defaultImportRecorder: DefaultImportRecorder): Expression|null; -export function valueReferenceToExpression( - valueRef: TypeValueReference, defaultImportRecorder: DefaultImportRecorder): Expression|null { +export function valueReferenceToExpression(valueRef: LocalTypeValueReference| + ImportedTypeValueReference): Expression; +export function valueReferenceToExpression(valueRef: TypeValueReference): Expression|null; +export function valueReferenceToExpression(valueRef: TypeValueReference): Expression|null { if (valueRef.kind === TypeValueReferenceKind.UNAVAILABLE) { return null; } else if (valueRef.kind === TypeValueReferenceKind.LOCAL) { - if (defaultImportRecorder !== null && valueRef.defaultImportStatement !== null && - ts.isIdentifier(valueRef.expression)) { - defaultImportRecorder.recordImportedIdentifier( - valueRef.expression, valueRef.defaultImportStatement); + const expr = new WrappedNodeExpr(valueRef.expression); + if (valueRef.defaultImportStatement !== null) { + attachDefaultImportDeclaration(expr, valueRef.defaultImportStatement); } - return new WrappedNodeExpr(valueRef.expression); + return expr; } else { let importExpr: Expression = new ExternalExpr({moduleName: valueRef.moduleName, name: valueRef.importedName}); @@ -163,10 +159,10 @@ export function unwrapConstructorDependencies(deps: ConstructorDeps|null): R3Dep } export function getValidConstructorDependencies( - clazz: ClassDeclaration, reflector: ReflectionHost, - defaultImportRecorder: DefaultImportRecorder, isCore: boolean): R3DependencyMetadata[]|null { + clazz: ClassDeclaration, reflector: ReflectionHost, isCore: boolean): R3DependencyMetadata[]| + null { return validateConstructorDependencies( - clazz, getConstructorDependencies(clazz, reflector, defaultImportRecorder, isCore)); + clazz, getConstructorDependencies(clazz, reflector, isCore)); } /** diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts index 63d33bd2c3..8fcfca7eb6 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/component_spec.ts @@ -13,7 +13,7 @@ import {CycleAnalyzer, CycleHandlingStrategy, ImportGraph} from '../../cycles'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; import {absoluteFrom} from '../../file_system'; import {runInEachFileSystem} from '../../file_system/testing'; -import {ModuleResolver, NOOP_DEFAULT_IMPORT_RECORDER, ReferenceEmitter} from '../../imports'; +import {ModuleResolver, ReferenceEmitter} from '../../imports'; import {CompoundMetadataReader, DtsMetadataReader, InjectableClassRegistry, LocalMetadataRegistry, ResourceRegistry} from '../../metadata'; import {PartialEvaluator} from '../../partial_evaluator'; import {NOOP_PERF_RECORDER} from '../../perf'; @@ -81,7 +81,6 @@ function setup(program: ts.Program, options: ts.CompilerOptions, host: ts.Compil cycleAnalyzer, CycleHandlingStrategy.UseRemoteScoping, refEmitter, - NOOP_DEFAULT_IMPORT_RECORDER, /* depTracker */ null, injectableRegistry, /* semanticDepGraphUpdater */ null, diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/directive_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/directive_spec.ts index 898a0a28eb..bfef378682 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/directive_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/directive_spec.ts @@ -10,7 +10,7 @@ import * as ts from 'typescript'; import {absoluteFrom} from '../../file_system'; import {runInEachFileSystem} from '../../file_system/testing'; -import {NOOP_DEFAULT_IMPORT_RECORDER, ReferenceEmitter} from '../../imports'; +import {ReferenceEmitter} from '../../imports'; import {DtsMetadataReader, InjectableClassRegistry, LocalMetadataRegistry} from '../../metadata'; import {PartialEvaluator} from '../../partial_evaluator'; import {NOOP_PERF_RECORDER} from '../../perf'; @@ -168,8 +168,8 @@ runInEachFileSystem(() => { null); const injectableRegistry = new InjectableClassRegistry(reflectionHost); const handler = new DirectiveDecoratorHandler( - reflectionHost, evaluator, scopeRegistry, scopeRegistry, metaReader, - NOOP_DEFAULT_IMPORT_RECORDER, injectableRegistry, /*isCore*/ false, + reflectionHost, evaluator, scopeRegistry, scopeRegistry, metaReader, injectableRegistry, + /*isCore*/ false, /*semanticDepGraphUpdater*/ null, /*annotateForClosureCompiler*/ false, /*detectUndecoratedClassesWithAngularFeatures*/ false, NOOP_PERF_RECORDER); diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/injectable_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/injectable_spec.ts index 293fd25533..901463b7e4 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/injectable_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/injectable_spec.ts @@ -8,7 +8,6 @@ import {ErrorCode, FatalDiagnosticError, ngErrorCode} from '../../diagnostics'; import {absoluteFrom} from '../../file_system'; import {runInEachFileSystem} from '../../file_system/testing'; -import {NOOP_DEFAULT_IMPORT_RECORDER} from '../../imports'; import {InjectableClassRegistry} from '../../metadata'; import {NOOP_PERF_RECORDER} from '../../perf'; import {isNamedClassDeclaration, TypeScriptReflectionHost} from '../../reflection'; @@ -70,7 +69,7 @@ function setupHandler(errorOnDuplicateProv: boolean) { const reflectionHost = new TypeScriptReflectionHost(checker); const injectableRegistry = new InjectableClassRegistry(reflectionHost); const handler = new InjectableDecoratorHandler( - reflectionHost, NOOP_DEFAULT_IMPORT_RECORDER, /* isCore */ false, + reflectionHost, /* isCore */ false, /* strictCtorDeps */ false, injectableRegistry, NOOP_PERF_RECORDER, errorOnDuplicateProv); const TestClass = getDeclaration(program, ENTRY_FILE, 'TestClass', isNamedClassDeclaration); const ɵprov = reflectionHost.getMembersOfClass(TestClass).find(member => member.name === 'ɵprov'); diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts index 569e81e731..180ccab12d 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/metadata_spec.ts @@ -10,7 +10,7 @@ import * as ts from 'typescript'; import {absoluteFrom, getSourceFileOrError} from '../../file_system'; import {runInEachFileSystem, TestFile} from '../../file_system/testing'; -import {NOOP_DEFAULT_IMPORT_RECORDER, NoopImportRewriter} from '../../imports'; +import {NoopImportRewriter} from '../../imports'; import {TypeScriptReflectionHost} from '../../reflection'; import {getDeclaration, makeProgram} from '../../testing'; import {ImportManager, translateStatement} from '../../translator'; @@ -128,7 +128,7 @@ runInEachFileSystem(() => { {target: ts.ScriptTarget.ES2015}); const host = new TypeScriptReflectionHost(program.getTypeChecker()); const target = getDeclaration(program, _('/index.ts'), 'Target', ts.isClassDeclaration); - const call = extractClassMetadata(target, host, NOOP_DEFAULT_IMPORT_RECORDER, false); + const call = extractClassMetadata(target, host, false); if (call === null) { return ''; } diff --git a/packages/compiler-cli/src/ngtsc/annotations/test/ng_module_spec.ts b/packages/compiler-cli/src/ngtsc/annotations/test/ng_module_spec.ts index 5e0387b1db..bd16ad693e 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/test/ng_module_spec.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/test/ng_module_spec.ts @@ -11,7 +11,7 @@ import * as ts from 'typescript'; import {absoluteFrom} from '../../file_system'; import {runInEachFileSystem} from '../../file_system/testing'; -import {LocalIdentifierStrategy, NOOP_DEFAULT_IMPORT_RECORDER, ReferenceEmitter} from '../../imports'; +import {LocalIdentifierStrategy, ReferenceEmitter} from '../../imports'; import {CompoundMetadataReader, DtsMetadataReader, InjectableClassRegistry, LocalMetadataRegistry} from '../../metadata'; import {PartialEvaluator} from '../../partial_evaluator'; import {NOOP_PERF_RECORDER} from '../../perf'; @@ -72,8 +72,7 @@ runInEachFileSystem(() => { const handler = new NgModuleDecoratorHandler( reflectionHost, evaluator, metaReader, metaRegistry, scopeRegistry, referencesRegistry, /* isCore */ false, /* routeAnalyzer */ null, refEmitter, /* factoryTracker */ null, - NOOP_DEFAULT_IMPORT_RECORDER, /* annotateForClosureCompiler */ false, injectableRegistry, - NOOP_PERF_RECORDER); + /* annotateForClosureCompiler */ false, injectableRegistry, NOOP_PERF_RECORDER); const TestModule = getDeclaration(program, _('/entry.ts'), 'TestModule', isNamedClassDeclaration); const detected = diff --git a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts index 8a0ae5b4b3..6a0ebb4a13 100644 --- a/packages/compiler-cli/src/ngtsc/core/src/compiler.ts +++ b/packages/compiler-cli/src/ngtsc/core/src/compiler.ts @@ -52,7 +52,6 @@ interface LazyCompilationState { routeAnalyzer: NgModuleRouteAnalyzer; dtsTransforms: DtsTransformRegistry; mwpScanner: ModuleWithProvidersScanner; - defaultImportTracker: DefaultImportTracker; aliasingHost: AliasingHost|null; refEmitter: ReferenceEmitter; templateTypeChecker: TemplateTypeChecker; @@ -613,13 +612,14 @@ export class NgCompiler { importRewriter = new NoopImportRewriter(); } + const defaultImportTracker = new DefaultImportTracker(); + const before = [ ivyTransformFactory( - compilation.traitCompiler, compilation.reflector, importRewriter, - compilation.defaultImportTracker, this.delegatingPerfRecorder, compilation.isCore, - this.closureCompilerEnabled), + compilation.traitCompiler, compilation.reflector, importRewriter, defaultImportTracker, + this.delegatingPerfRecorder, compilation.isCore, this.closureCompilerEnabled), aliasTransformFactory(compilation.traitCompiler.exportStatements), - compilation.defaultImportTracker.importPreservingTransformer(), + defaultImportTracker.importPreservingTransformer(), ]; const afterDeclarations: ts.TransformerFactory[] = []; @@ -971,7 +971,6 @@ export class NgCompiler { const isCore = isAngularCorePackage(this.inputProgram); - const defaultImportTracker = new DefaultImportTracker(); const resourceRegistry = new ResourceRegistry(); const compilationMode = @@ -993,16 +992,15 @@ export class NgCompiler { this.options.i18nUseExternalIds !== false, this.options.enableI18nLegacyMessageIdFormat !== false, this.usePoisonedData, this.options.i18nNormalizeLineEndingsInICUs, this.moduleResolver, this.cycleAnalyzer, - cycleHandlingStrategy, refEmitter, defaultImportTracker, this.incrementalDriver.depGraph, - injectableRegistry, semanticDepGraphUpdater, this.closureCompilerEnabled, - this.delegatingPerfRecorder), + cycleHandlingStrategy, refEmitter, this.incrementalDriver.depGraph, injectableRegistry, + semanticDepGraphUpdater, this.closureCompilerEnabled, this.delegatingPerfRecorder), // TODO(alxhub): understand why the cast here is necessary (something to do with `null` // not being assignable to `unknown` when wrapped in `Readonly`). // clang-format off new DirectiveDecoratorHandler( reflector, evaluator, metaRegistry, scopeRegistry, metaReader, - defaultImportTracker, injectableRegistry, isCore, semanticDepGraphUpdater, + injectableRegistry, isCore, semanticDepGraphUpdater, this.closureCompilerEnabled, compileUndecoratedClassesWithAngularFeatures, this.delegatingPerfRecorder, ) as Readonly>, @@ -1010,16 +1008,15 @@ export class NgCompiler { // Pipe handler must be before injectable handler in list so pipe factories are printed // before injectable factories (so injectable factories can delegate to them) new PipeDecoratorHandler( - reflector, evaluator, metaRegistry, scopeRegistry, defaultImportTracker, - injectableRegistry, isCore, this.delegatingPerfRecorder), + reflector, evaluator, metaRegistry, scopeRegistry, injectableRegistry, isCore, + this.delegatingPerfRecorder), new InjectableDecoratorHandler( - reflector, defaultImportTracker, isCore, this.options.strictInjectionParameters || false, - injectableRegistry, this.delegatingPerfRecorder), + reflector, isCore, this.options.strictInjectionParameters || false, injectableRegistry, + this.delegatingPerfRecorder), new NgModuleDecoratorHandler( reflector, evaluator, metaReader, metaRegistry, scopeRegistry, referencesRegistry, isCore, - routeAnalyzer, refEmitter, this.adapter.factoryTracker, defaultImportTracker, - this.closureCompilerEnabled, injectableRegistry, this.delegatingPerfRecorder, - this.options.i18nInLocale), + routeAnalyzer, refEmitter, this.adapter.factoryTracker, this.closureCompilerEnabled, + injectableRegistry, this.delegatingPerfRecorder, this.options.i18nInLocale), ]; const traitCompiler = new TraitCompiler( @@ -1051,7 +1048,6 @@ export class NgCompiler { mwpScanner, metaReader, typeCheckScopeRegistry, - defaultImportTracker, aliasingHost, refEmitter, templateTypeChecker, diff --git a/packages/compiler-cli/src/ngtsc/imports/README.md b/packages/compiler-cli/src/ngtsc/imports/README.md index 67b6c87e83..3112283847 100644 --- a/packages/compiler-cli/src/ngtsc/imports/README.md +++ b/packages/compiler-cli/src/ngtsc/imports/README.md @@ -167,8 +167,6 @@ It consists of two mechanisms: 1. A `DefaultImportTracker`, which records information about both default imports encountered in the program as well as usages of those imports added during compilation. -A `DefaultImportRecorder` interface is used to allow for a noop implementation in cases (like ngcc) where this tracking isn't necessary. - 2. A TypeScript transformer which processes default import statements and can preserve those which are actually used. This is accessed via `DefaultImportTracker.importPreservingTransformer`. diff --git a/packages/compiler-cli/src/ngtsc/imports/index.ts b/packages/compiler-cli/src/ngtsc/imports/index.ts index 8843ad1824..523bdffe6b 100644 --- a/packages/compiler-cli/src/ngtsc/imports/index.ts +++ b/packages/compiler-cli/src/ngtsc/imports/index.ts @@ -8,7 +8,7 @@ export {AliasingHost, AliasStrategy, PrivateExportAliasingHost, UnifiedModulesAliasingHost} from './src/alias'; export {ImportRewriter, NoopImportRewriter, R3SymbolsImportRewriter, validateAndRewriteCoreSymbol} from './src/core'; -export {DefaultImportRecorder, DefaultImportTracker, NOOP_DEFAULT_IMPORT_RECORDER} from './src/default'; +export {DefaultImportTracker} from './src/default'; export {AbsoluteModuleStrategy, EmittedReference, ImportedFile, ImportFlags, LocalIdentifierStrategy, LogicalProjectStrategy, ReferenceEmitStrategy, ReferenceEmitter, RelativePathStrategy, UnifiedModulesStrategy} from './src/emitter'; export {Reexport} from './src/reexport'; export {OwningModule, Reference} from './src/references'; diff --git a/packages/compiler-cli/src/ngtsc/imports/src/default.ts b/packages/compiler-cli/src/ngtsc/imports/src/default.ts index 23ff5be771..05bf46627e 100644 --- a/packages/compiler-cli/src/ngtsc/imports/src/default.ts +++ b/packages/compiler-cli/src/ngtsc/imports/src/default.ts @@ -6,52 +6,33 @@ * found in the LICENSE file at https://angular.io/license */ +import {WrappedNodeExpr} from '@angular/compiler'; import * as ts from 'typescript'; import {getSourceFile} from '../../util/src/typescript'; -/** - * Registers and records usages of `ts.Identifer`s that came from default import statements. - * - * See `DefaultImportTracker` for details. - */ -export interface DefaultImportRecorder { - /** - * Record an association between a `ts.Identifier` which might be emitted and the - * `ts.ImportDeclaration` from which it came. - * - * Alone, this method has no effect as the `ts.Identifier` might not be used in the output. - * The identifier must later be marked as used with `recordUsedIdentifier` in order for its - * import to be preserved. - */ - recordImportedIdentifier(id: ts.Identifier, decl: ts.ImportDeclaration): void; +const DefaultImportDeclaration = Symbol('DefaultImportDeclaration'); - /** - * Record the fact that the given `ts.Identifer` will be emitted, and thus its - * `ts.ImportDeclaration`, if it was a previously registered default import, must be preserved. - * - * This method can be called safely for any `ts.Identifer`, regardless of its origin. It will only - * have an effect if the identifier came from a `ts.ImportDeclaration` default import which was - * previously registered with `recordImportedIdentifier`. - */ - recordUsedIdentifier(id: ts.Identifier): void; +interface WithDefaultImportDeclaration { + [DefaultImportDeclaration]?: ts.ImportDeclaration; } /** - * An implementation of `DefaultImportRecorder` which does nothing. - * - * This is useful when default import tracking isn't required, such as when emitting .d.ts code - * or for ngcc. + * Attaches a default import declaration to `expr` to indicate the dependency of `expr` on the + * default import. */ -export const NOOP_DEFAULT_IMPORT_RECORDER: DefaultImportRecorder = { - recordImportedIdentifier: (id: ts.Identifier) => void{}, - recordUsedIdentifier: (id: ts.Identifier) => void{}, -}; +export function attachDefaultImportDeclaration( + expr: WrappedNodeExpr, importDecl: ts.ImportDeclaration): void { + (expr as WithDefaultImportDeclaration)[DefaultImportDeclaration] = importDecl; +} -const ImportDeclarationMapping = Symbol('ImportDeclarationMapping'); - -interface SourceFileWithImportDeclarationMapping extends ts.SourceFile { - [ImportDeclarationMapping]?: Map; +/** + * Obtains the default import declaration that `expr` depends on, or `null` if there is no such + * dependency. + */ +export function getDefaultImportDeclaration(expr: WrappedNodeExpr): ts.ImportDeclaration| + null { + return (expr as WithDefaultImportDeclaration)[DefaultImportDeclaration] ?? null; } /** @@ -84,45 +65,28 @@ interface SourceFileWithImportDeclarationMapping extends ts.SourceFile { * This problem does not exist for non-default imports as the compiler can easily insert * "import * as X" style imports for those, and the "X" identifier survives transformation. */ -export class DefaultImportTracker implements DefaultImportRecorder { +export class DefaultImportTracker { /** * A `Map` which tracks the `Set` of `ts.ImportDeclaration`s for default imports that were used in * a given `ts.SourceFile` and need to be preserved. */ private sourceFileToUsedImports = new Map>(); - recordImportedIdentifier(id: ts.Identifier, decl: ts.ImportDeclaration): void { - const sf = getSourceFile(id) as SourceFileWithImportDeclarationMapping; - if (sf[ImportDeclarationMapping] === undefined) { - sf[ImportDeclarationMapping] = new Map(); - } - sf[ImportDeclarationMapping]!.set(id, decl); - } - recordUsedIdentifier(id: ts.Identifier): void { - const sf = getSourceFile(id) as SourceFileWithImportDeclarationMapping; - const identifierToDeclaration = sf[ImportDeclarationMapping]; - if (identifierToDeclaration === undefined) { - // The identifier's source file has no registered default imports at all. - return; - } - if (!identifierToDeclaration.has(id)) { - // The identifier isn't from a registered default import. - return; - } - const decl = identifierToDeclaration.get(id)!; + recordUsedImport(importDecl: ts.ImportDeclaration): void { + const sf = getSourceFile(importDecl); // Add the default import declaration to the set of used import declarations for the file. if (!this.sourceFileToUsedImports.has(sf)) { this.sourceFileToUsedImports.set(sf, new Set()); } - this.sourceFileToUsedImports.get(sf)!.add(decl); + this.sourceFileToUsedImports.get(sf)!.add(importDecl); } /** * Get a `ts.TransformerFactory` which will preserve default imports that were previously marked * as used. * - * This transformer must run after any other transformers which call `recordUsedIdentifier`. + * This transformer must run after any other transformers which call `recordUsedImport`. */ importPreservingTransformer(): ts.TransformerFactory { return (context: ts.TransformationContext) => { diff --git a/packages/compiler-cli/src/ngtsc/imports/test/default_spec.ts b/packages/compiler-cli/src/ngtsc/imports/test/default_spec.ts index f07ea36462..307ecceda1 100644 --- a/packages/compiler-cli/src/ngtsc/imports/test/default_spec.ts +++ b/packages/compiler-cli/src/ngtsc/imports/test/default_spec.ts @@ -39,12 +39,10 @@ runInEachFileSystem(() => { module: ts.ModuleKind.ES2015, }); const fooClause = getDeclaration(program, _('/test.ts'), 'Foo', ts.isImportClause); - const fooId = fooClause.name!; const fooDecl = fooClause.parent; const tracker = new DefaultImportTracker(); - tracker.recordImportedIdentifier(fooId, fooDecl); - tracker.recordUsedIdentifier(fooId); + tracker.recordUsedImport(fooDecl); program.emit(undefined, undefined, undefined, undefined, { before: [tracker.importPreservingTransformer()], }); @@ -73,8 +71,7 @@ runInEachFileSystem(() => { const fooDecl = fooClause.parent; const tracker = new DefaultImportTracker(); - tracker.recordImportedIdentifier(fooId, fooDecl); - tracker.recordUsedIdentifier(fooId); + tracker.recordUsedImport(fooDecl); program.emit(undefined, undefined, undefined, undefined, { before: [ addReferenceTransformer(fooId), diff --git a/packages/compiler-cli/src/ngtsc/transform/src/transform.ts b/packages/compiler-cli/src/ngtsc/transform/src/transform.ts index c9a0d7bd10..7d29340e8f 100644 --- a/packages/compiler-cli/src/ngtsc/transform/src/transform.ts +++ b/packages/compiler-cli/src/ngtsc/transform/src/transform.ts @@ -9,10 +9,11 @@ import {ConstantPool} from '@angular/compiler'; import * as ts from 'typescript'; -import {DefaultImportRecorder, ImportRewriter} from '../../imports'; +import {DefaultImportTracker, ImportRewriter} from '../../imports'; +import {getDefaultImportDeclaration} from '../../imports/src/default'; import {PerfPhase, PerfRecorder} from '../../perf'; import {Decorator, ReflectionHost} from '../../reflection'; -import {ImportManager, RecordWrappedNodeExprFn, translateExpression, translateStatement, TranslatorOptions} from '../../translator'; +import {ImportManager, RecordWrappedNodeFn, translateExpression, translateStatement, TranslatorOptions} from '../../translator'; import {visit, VisitListEntryResult, Visitor} from '../../util/src/visitor'; import {CompileResult} from './api'; @@ -34,16 +35,16 @@ interface FileOverviewMeta { export function ivyTransformFactory( compilation: TraitCompiler, reflector: ReflectionHost, importRewriter: ImportRewriter, - defaultImportRecorder: DefaultImportRecorder, perf: PerfRecorder, isCore: boolean, + defaultImportTracker: DefaultImportTracker, perf: PerfRecorder, isCore: boolean, isClosureCompilerEnabled: boolean): ts.TransformerFactory { - const recordWrappedNodeExpr = createRecorderFn(defaultImportRecorder); + const recordWrappedNode = createRecorderFn(defaultImportTracker); return (context: ts.TransformationContext): ts.Transformer => { return (file: ts.SourceFile): ts.SourceFile => { return perf.inPhase( PerfPhase.Compile, () => transformIvySourceFile( compilation, context, reflector, importRewriter, file, isCore, - isClosureCompilerEnabled, recordWrappedNodeExpr)); + isClosureCompilerEnabled, recordWrappedNode)); }; }; } @@ -81,7 +82,7 @@ class IvyTransformationVisitor extends Visitor { private compilation: TraitCompiler, private classCompilationMap: Map, private reflector: ReflectionHost, private importManager: ImportManager, - private recordWrappedNodeExpr: RecordWrappedNodeExprFn, + private recordWrappedNodeExpr: RecordWrappedNodeFn, private isClosureCompilerEnabled: boolean, private isCore: boolean) { super(); } @@ -95,7 +96,7 @@ class IvyTransformationVisitor extends Visitor { } const translateOptions: TranslatorOptions = { - recordWrappedNodeExpr: this.recordWrappedNodeExpr, + recordWrappedNode: this.recordWrappedNodeExpr, annotateForClosureCompiler: this.isClosureCompilerEnabled, }; @@ -252,7 +253,7 @@ function transformIvySourceFile( compilation: TraitCompiler, context: ts.TransformationContext, reflector: ReflectionHost, importRewriter: ImportRewriter, file: ts.SourceFile, isCore: boolean, isClosureCompilerEnabled: boolean, - recordWrappedNodeExpr: RecordWrappedNodeExprFn): ts.SourceFile { + recordWrappedNode: RecordWrappedNodeFn): ts.SourceFile { const constantPool = new ConstantPool(isClosureCompilerEnabled); const importManager = new ImportManager(importRewriter); @@ -274,7 +275,7 @@ function transformIvySourceFile( // results obtained at Step 1. const transformationVisitor = new IvyTransformationVisitor( compilation, compilationVisitor.classCompilationMap, reflector, importManager, - recordWrappedNodeExpr, isClosureCompilerEnabled, isCore); + recordWrappedNode, isClosureCompilerEnabled, isCore); let sf = visit(file, transformationVisitor, context); // Generate the constant statements first, as they may involve adding additional imports @@ -282,7 +283,7 @@ function transformIvySourceFile( const downlevelTranslatedCode = getLocalizeCompileTarget(context) < ts.ScriptTarget.ES2015; const constants = constantPool.statements.map(stmt => translateStatement(stmt, importManager, { - recordWrappedNodeExpr, + recordWrappedNode, downlevelTaggedTemplates: downlevelTranslatedCode, downlevelVariableDeclarations: downlevelTranslatedCode, annotateForClosureCompiler: isClosureCompilerEnabled, @@ -370,11 +371,12 @@ function isFromAngularCore(decorator: Decorator): boolean { return decorator.import !== null && decorator.import.from === '@angular/core'; } -function createRecorderFn(defaultImportRecorder: DefaultImportRecorder): - RecordWrappedNodeExprFn { - return expr => { - if (ts.isIdentifier(expr)) { - defaultImportRecorder.recordUsedIdentifier(expr); +function createRecorderFn(defaultImportTracker: DefaultImportTracker): + RecordWrappedNodeFn { + return node => { + const importDecl = getDefaultImportDeclaration(node); + if (importDecl !== null) { + defaultImportTracker.recordUsedImport(importDecl); } }; } diff --git a/packages/compiler-cli/src/ngtsc/translator/index.ts b/packages/compiler-cli/src/ngtsc/translator/index.ts index b6300ba02a..7fa09856f8 100644 --- a/packages/compiler-cli/src/ngtsc/translator/index.ts +++ b/packages/compiler-cli/src/ngtsc/translator/index.ts @@ -10,7 +10,7 @@ export {AstFactory, BinaryOperator, LeadingComment, ObjectLiteralProperty, Sourc export {ImportGenerator, NamedImport} from './src/api/import_generator'; export {Context} from './src/context'; export {Import, ImportManager} from './src/import_manager'; -export {ExpressionTranslatorVisitor, RecordWrappedNodeExprFn, TranslatorOptions} from './src/translator'; +export {ExpressionTranslatorVisitor, RecordWrappedNodeFn, TranslatorOptions} from './src/translator'; export {translateType} from './src/type_translator'; export {attachComments, createTemplateMiddle, createTemplateTail, TypeScriptAstFactory} from './src/typescript_ast_factory'; export {translateExpression, translateStatement} from './src/typescript_translator'; diff --git a/packages/compiler-cli/src/ngtsc/translator/src/translator.ts b/packages/compiler-cli/src/ngtsc/translator/src/translator.ts index 1aea892ea3..81a6377abf 100644 --- a/packages/compiler-cli/src/ngtsc/translator/src/translator.ts +++ b/packages/compiler-cli/src/ngtsc/translator/src/translator.ts @@ -37,12 +37,12 @@ const BINARY_OPERATORS = new Map([ [o.BinaryOperator.NullishCoalesce, '??'], ]); -export type RecordWrappedNodeExprFn = (expr: TExpression) => void; +export type RecordWrappedNodeFn = (node: o.WrappedNodeExpr) => void; export interface TranslatorOptions { downlevelTaggedTemplates?: boolean; downlevelVariableDeclarations?: boolean; - recordWrappedNodeExpr?: RecordWrappedNodeExprFn; + recordWrappedNode?: RecordWrappedNodeFn; annotateForClosureCompiler?: boolean; } @@ -50,14 +50,14 @@ export class ExpressionTranslatorVisitor implements o.E o.StatementVisitor { private downlevelTaggedTemplates: boolean; private downlevelVariableDeclarations: boolean; - private recordWrappedNodeExpr: RecordWrappedNodeExprFn; + private recordWrappedNode: RecordWrappedNodeFn; constructor( private factory: AstFactory, private imports: ImportGenerator, options: TranslatorOptions) { this.downlevelTaggedTemplates = options.downlevelTaggedTemplates === true; this.downlevelVariableDeclarations = options.downlevelVariableDeclarations === true; - this.recordWrappedNodeExpr = options.recordWrappedNodeExpr || (() => {}); + this.recordWrappedNode = options.recordWrappedNode || (() => {}); } visitDeclareVarStmt(stmt: o.DeclareVarStmt, context: Context): TStatement { @@ -382,7 +382,7 @@ export class ExpressionTranslatorVisitor implements o.E } visitWrappedNodeExpr(ast: o.WrappedNodeExpr, _context: Context): any { - this.recordWrappedNodeExpr(ast.node); + this.recordWrappedNode(ast); return ast.node; }