diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index efd45c5fb9053..6a918a9b21947 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -274,6 +274,7 @@ export function extractDirectiveMetadata( outputs: {...outputsFromMeta, ...outputsFromFields}, queries, viewQueries, selector, fullInheritance: !!(flags & HandlerFlags.FULL_INHERITANCE), type: new WrappedNodeExpr(clazz.name), + internalType: new WrappedNodeExpr(reflector.getInternalNameOfClass(clazz)), typeArgumentCount: reflector.getGenericArityOfClass(clazz) || 0, typeSourceSpan: EMPTY_SOURCE_SPAN, usesInheritance, exportAs, providers }; diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts index 36dd84b8360e2..50550a3ed0b98 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts @@ -81,6 +81,7 @@ export class InjectableDecoratorHandler implements const factoryRes = compileNgFactoryDefField({ name: meta.name, type: meta.type, + internalType: meta.internalType, typeArgumentCount: meta.typeArgumentCount, deps: analysis.ctorDeps, injectFn: Identifiers.inject, @@ -114,6 +115,7 @@ function extractInjectableMetadata( reflector: ReflectionHost): R3InjectableMetadata { const name = clazz.name.text; const type = new WrappedNodeExpr(clazz.name); + const internalType = new WrappedNodeExpr(reflector.getInternalNameOfClass(clazz)); const typeArgumentCount = reflector.getGenericArityOfClass(clazz) || 0; if (decorator.args === null) { throw new FatalDiagnosticError( @@ -125,6 +127,7 @@ function extractInjectableMetadata( name, type, typeArgumentCount, + internalType, providedIn: new LiteralExpr(null), }; } else if (decorator.args.length === 1) { @@ -159,6 +162,7 @@ function extractInjectableMetadata( name, type, typeArgumentCount, + internalType, providedIn, useValue: new WrappedNodeExpr(unwrapForwardRef(meta.get('useValue') !, reflector)), }; @@ -167,6 +171,7 @@ function extractInjectableMetadata( name, type, typeArgumentCount, + internalType, providedIn, useExisting: new WrappedNodeExpr(unwrapForwardRef(meta.get('useExisting') !, reflector)), }; @@ -175,6 +180,7 @@ function extractInjectableMetadata( name, type, typeArgumentCount, + internalType, providedIn, useClass: new WrappedNodeExpr(unwrapForwardRef(meta.get('useClass') !, reflector)), userDeps, @@ -186,11 +192,12 @@ function extractInjectableMetadata( name, type, typeArgumentCount, + internalType, providedIn, useFactory: factory, userDeps, }; } else { - return {name, type, typeArgumentCount, providedIn}; + return {name, type, typeArgumentCount, internalType, providedIn}; } } else { throw new FatalDiagnosticError( diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts index 4c82fec50639b..268e842b56d64 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/metadata.ts @@ -28,7 +28,7 @@ export function generateSetClassMetadataCall( if (!reflection.isClass(clazz)) { return null; } - const id = ts.updateIdentifier(clazz.name); + const id = ts.updateIdentifier(reflection.getAdjacentNameOfClass(clazz)); // Reflect over the class decorators. If none are present, or those that are aren't from // Angular, then return null. Otherwise, turn them into metadata. 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 e8e3f48af0a41..8df4671232e5f 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/ng_module.ts @@ -198,6 +198,8 @@ export class NgModuleDecoratorHandler implements DecoratorHandler { const name = clazz.name.text; const type = new WrappedNodeExpr(clazz.name); + const internalType = new WrappedNodeExpr(this.reflector.getInternalNameOfClass(clazz)); if (decorator.args === null) { throw new FatalDiagnosticError( ErrorCode.DECORATOR_NOT_CALLED, Decorator.nodeForError(decorator), @@ -97,6 +98,7 @@ export class PipeDecoratorHandler implements DecoratorHandler meta.type.ɵfac(t) + // () => type.ɵfac(t) factory: o.fn([new o.FnParam('t', o.DYNAMIC_TYPE)], [new o.ReturnStatement(type.callMethod( 'ɵfac', [o.variable('t')]))]) }; diff --git a/packages/compiler/src/jit_compiler_facade.ts b/packages/compiler/src/jit_compiler_facade.ts index 38ab7dba31e4f..877501c14f029 100644 --- a/packages/compiler/src/jit_compiler_facade.ts +++ b/packages/compiler/src/jit_compiler_facade.ts @@ -19,7 +19,7 @@ import {ParseError, ParseSourceSpan, r3JitTypeSourceSpan} from './parse_util'; import {R3DependencyMetadata, R3FactoryTarget, R3ResolvedDependencyType, compileFactoryFunction} from './render3/r3_factory'; import {R3JitReflector} from './render3/r3_jit'; import {R3InjectorMetadata, R3NgModuleMetadata, compileInjector, compileNgModule} from './render3/r3_module_compiler'; -import {compilePipeFromMetadata} from './render3/r3_pipe_compiler'; +import {R3PipeMetadata, compilePipeFromMetadata} from './render3/r3_pipe_compiler'; import {R3Reference} from './render3/util'; import {R3DirectiveMetadata, R3QueryMetadata} from './render3/view/api'; import {ParsedHostBindings, compileComponentFromMetadata, compileDirectiveFromMetadata, parseHostBindings, verifyHostBindings} from './render3/view/compiler'; @@ -37,9 +37,10 @@ export class CompilerFacadeImpl implements CompilerFacade { compilePipe(angularCoreEnv: CoreEnvironment, sourceMapUrl: string, facade: R3PipeMetadataFacade): any { - const metadata = { + const metadata: R3PipeMetadata = { name: facade.name, type: new WrappedNodeExpr(facade.type), + internalType: new WrappedNodeExpr(facade.type), typeArgumentCount: facade.typeArgumentCount, deps: convertR3DependencyMetadataArray(facade.deps), pipeName: facade.pipeName, @@ -55,6 +56,7 @@ export class CompilerFacadeImpl implements CompilerFacade { const {expression, statements} = compileInjectable({ name: facade.name, type: new WrappedNodeExpr(facade.type), + internalType: new WrappedNodeExpr(facade.type), typeArgumentCount: facade.typeArgumentCount, providedIn: computeProvidedIn(facade.providedIn), useClass: wrapExpression(facade, USE_CLASS), @@ -73,6 +75,7 @@ export class CompilerFacadeImpl implements CompilerFacade { const meta: R3InjectorMetadata = { name: facade.name, type: new WrappedNodeExpr(facade.type), + internalType: new WrappedNodeExpr(facade.type), deps: convertR3DependencyMetadataArray(facade.deps), providers: new WrappedNodeExpr(facade.providers), imports: facade.imports.map(i => new WrappedNodeExpr(i)), @@ -86,6 +89,8 @@ export class CompilerFacadeImpl implements CompilerFacade { facade: R3NgModuleMetadataFacade): any { const meta: R3NgModuleMetadata = { type: new WrappedNodeExpr(facade.type), + internalType: new WrappedNodeExpr(facade.type), + adjacentType: new WrappedNodeExpr(facade.type), bootstrap: facade.bootstrap.map(wrapReference), declarations: facade.declarations.map(wrapReference), imports: facade.imports.map(wrapReference), @@ -159,6 +164,7 @@ export class CompilerFacadeImpl implements CompilerFacade { const factoryRes = compileFactoryFunction({ name: meta.name, type: new WrappedNodeExpr(meta.type), + internalType: new WrappedNodeExpr(meta.type), typeArgumentCount: meta.typeArgumentCount, deps: convertR3DependencyMetadataArray(meta.deps), injectFn: meta.injectFn === 'directiveInject' ? Identifiers.directiveInject : @@ -247,6 +253,7 @@ function convertDirectiveFacadeToMetadata(facade: R3DirectiveMetadataFacade): R3 ...facade as R3DirectiveMetadataFacadeNoPropAndWhitespace, typeSourceSpan: facade.typeSourceSpan, type: new WrappedNodeExpr(facade.type), + internalType: new WrappedNodeExpr(facade.type), deps: convertR3DependencyMetadataArray(facade.deps), host: extractHostBindings(facade.propMetadata, facade.typeSourceSpan, facade.host), inputs: {...inputsFromMetadata, ...inputsFromType}, diff --git a/packages/compiler/src/render3/r3_factory.ts b/packages/compiler/src/render3/r3_factory.ts index 5e8027f5fe8e5..10d1edc7e7356 100644 --- a/packages/compiler/src/render3/r3_factory.ts +++ b/packages/compiler/src/render3/r3_factory.ts @@ -30,14 +30,19 @@ export interface R3ConstructorFactoryMetadata { name: string; /** - * An expression representing the function (or constructor) which will instantiate the requested - * type. - * - * This could be a reference to a constructor type, or to a user-defined factory function. The - * `useNew` property determines whether it will be called as a constructor or not. + * An expression representing the interface type being constructed. */ type: o.Expression; + /** + * An expression representing the constructor type, intended for use within a class definition + * itself. + * + * This can differ from the outer `type` if the class is being compiled by ngcc and is inside + * an IIFE structure that uses a different name internally. + */ + internalType: o.Expression; + /** Number of arguments for the `type`. */ typeArgumentCount: number; @@ -176,8 +181,9 @@ export function compileFactoryFunction(meta: R3FactoryMetadata): R3FactoryFn { // parameter provided by the user (t) if specified, or the current type if not. If there is a // delegated factory (which is used to create the current type) then this is only the type-to- // create parameter (t). - const typeForCtor = - !isDelegatedMetadata(meta) ? new o.BinaryOperatorExpr(o.BinaryOperator.Or, t, meta.type) : t; + const typeForCtor = !isDelegatedMetadata(meta) ? + new o.BinaryOperatorExpr(o.BinaryOperator.Or, t, meta.internalType) : + t; let ctorExpr: o.Expression|null = null; if (meta.deps !== null) { @@ -191,9 +197,8 @@ export function compileFactoryFunction(meta: R3FactoryMetadata): R3FactoryFn { const baseFactory = o.variable(`ɵ${meta.name}_BaseFactory`); const getInheritedFactory = o.importExpr(R3.getInheritedFactory); const baseFactoryStmt = - baseFactory.set(getInheritedFactory.callFn([meta.type])).toDeclStmt(o.INFERRED_TYPE, [ - o.StmtModifier.Exported, o.StmtModifier.Final - ]); + baseFactory.set(getInheritedFactory.callFn([meta.internalType])) + .toDeclStmt(o.INFERRED_TYPE, [o.StmtModifier.Exported, o.StmtModifier.Final]); statements.push(baseFactoryStmt); // There is no constructor, use the base class' factory to construct typeForCtor. @@ -220,7 +225,7 @@ export function compileFactoryFunction(meta: R3FactoryMetadata): R3FactoryFn { if (isDelegatedMetadata(meta) && meta.delegateType === R3FactoryDelegateType.Factory) { const delegateFactory = o.variable(`ɵ${meta.name}_BaseFactory`); const getFactoryOf = o.importExpr(R3.getFactoryOf); - if (meta.delegate.isEquivalent(meta.type)) { + if (meta.delegate.isEquivalent(meta.internalType)) { throw new Error(`Illegal state: compiling factory that delegates to itself`); } const delegateFactoryStmt = diff --git a/packages/compiler/src/render3/r3_module_compiler.ts b/packages/compiler/src/render3/r3_module_compiler.ts index ebe48a109a664..c571ca89e3ff4 100644 --- a/packages/compiler/src/render3/r3_module_compiler.ts +++ b/packages/compiler/src/render3/r3_module_compiler.ts @@ -31,6 +31,24 @@ export interface R3NgModuleMetadata { */ type: o.Expression; + /** + * An expression representing the module type being compiled, intended for use within a class + * definition itself. + * + * This can differ from the outer `type` if the class is being compiled by ngcc and is inside + * an IIFE structure that uses a different name internally. + */ + internalType: o.Expression; + + /** + * An expression intended for use by statements that are adjacent (i.e. tightly coupled) to but + * not internal to a class definition. + * + * This can differ from the outer `type` if the class is being compiled by ngcc and is inside + * an IIFE structure that uses a different name internally. + */ + adjacentType: o.Expression; + /** * An array of expressions representing the bootstrap components specified by the module. */ @@ -77,6 +95,7 @@ export interface R3NgModuleMetadata { */ export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef { const { + internalType, type: moduleType, bootstrap, declarations, @@ -90,7 +109,7 @@ export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef { const additionalStatements: o.Statement[] = []; const definitionMap = { - type: moduleType + type: internalType } as{ type: o.Expression, bootstrap: o.Expression, @@ -156,7 +175,7 @@ export function compileNgModule(meta: R3NgModuleMetadata): R3NgModuleDef { * symbols to become tree-shakeable. */ function generateSetNgModuleScopeCall(meta: R3NgModuleMetadata): o.Statement|null { - const {type: moduleType, declarations, imports, exports, containsForwardDecls} = meta; + const {adjacentType: moduleType, declarations, imports, exports, containsForwardDecls} = meta; const scopeMap = {} as{ declarations: o.Expression, @@ -198,6 +217,7 @@ export interface R3InjectorDef { export interface R3InjectorMetadata { name: string; type: o.Expression; + internalType: o.Expression; deps: R3DependencyMetadata[]|null; providers: o.Expression|null; imports: o.Expression[]; @@ -207,6 +227,7 @@ export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef { const result = compileFactoryFunction({ name: meta.name, type: meta.type, + internalType: meta.internalType, typeArgumentCount: 0, deps: meta.deps, injectFn: R3.inject, diff --git a/packages/compiler/src/render3/r3_pipe_compiler.ts b/packages/compiler/src/render3/r3_pipe_compiler.ts index c4551fa27e926..03bfab91e1683 100644 --- a/packages/compiler/src/render3/r3_pipe_compiler.ts +++ b/packages/compiler/src/render3/r3_pipe_compiler.ts @@ -27,6 +27,15 @@ export interface R3PipeMetadata { */ type: o.Expression; + /** + * An expression representing the pipe being compiled, intended for use within a class definition + * itself. + * + * This can differ from the outer `type` if the class is being compiled by ngcc and is inside an + * IIFE structure that uses a different name internally. + */ + internalType: o.Expression; + /** * Number of generic type parameters of the type itself. */ @@ -80,10 +89,12 @@ export function compilePipeFromRender2( return error(`Cannot resolve the name of ${pipe.type}`); } + const type = outputCtx.importExpr(pipe.type.reference); const metadata: R3PipeMetadata = { name, + type, + internalType: type, pipeName: pipe.name, - type: outputCtx.importExpr(pipe.type.reference), typeArgumentCount: 0, deps: dependenciesFromGlobalMetadata(pipe.type, outputCtx, reflector), pure: pipe.pure, diff --git a/packages/compiler/src/render3/view/api.ts b/packages/compiler/src/render3/view/api.ts index 57ae0eec1bce1..0372ede4b5be0 100644 --- a/packages/compiler/src/render3/view/api.ts +++ b/packages/compiler/src/render3/view/api.ts @@ -28,6 +28,15 @@ export interface R3DirectiveMetadata { */ type: o.Expression; + /** + * An expression representing a reference to the directive being compiled, intended for use within + * a class definition itself. + * + * This can differ from the outer `type` if the class is being compiled by ngcc and is inside + * an IIFE structure that uses a different name internally. + */ + internalType: o.Expression; + /** * Number of generic type parameters of the type itself. */ diff --git a/packages/compiler/src/render3/view/compiler.ts b/packages/compiler/src/render3/view/compiler.ts index bf8878ce40cc5..dc057c570215f 100644 --- a/packages/compiler/src/render3/view/compiler.ts +++ b/packages/compiler/src/render3/view/compiler.ts @@ -45,7 +45,7 @@ function baseDirectiveFields( const selectors = core.parseSelectorToR3Selector(meta.selector); // e.g. `type: MyDirective` - definitionMap.set('type', meta.type); + definitionMap.set('type', meta.internalType); // e.g. `selectors: [['', 'someDir', '']]` if (selectors.length > 0) {