From 6f085f86106eb9422810ee2a91e1023d28a55234 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Mon, 6 Aug 2018 09:56:43 +0200 Subject: [PATCH] fix(ivy): add missing exportAs field to ngDirectiveDef (#25392) This commit includes the missing exportAs field from @Directive and propagates it into the ngDirectiveDef. PR Close #25392 --- .../src/ngtsc/annotations/src/directive.ts | 12 ++++++++++- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 20 +++++++++++++++++++ packages/compiler/src/render3/view/api.ts | 6 ++++++ .../compiler/src/render3/view/compiler.ts | 4 ++++ packages/core/src/render3/jit/directive.ts | 1 + 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index 5b8f39063d..2aebbf94a6 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -131,6 +131,16 @@ export function extractDirectiveMetadata( member => !member.isStatic && member.kind === ClassMemberKind.Method && member.name === 'ngOnChanges'); + // Parse exportAs. + let exportAs: string|null = null; + if (directive.has('exportAs')) { + const resolved = staticallyResolve(directive.get('exportAs') !, reflector, checker); + if (typeof resolved !== 'string') { + throw new Error(`exportAs must be a string`); + } + exportAs = resolved; + } + // Detect if the component inherits from another class const usesInheritance = clazz.heritageClauses !== undefined && clazz.heritageClauses.some(hc => hc.token === ts.SyntaxKind.ExtendsKeyword); @@ -144,7 +154,7 @@ export function extractDirectiveMetadata( outputs: {...outputsFromMeta, ...outputsFromFields}, queries, selector, type: new WrappedNodeExpr(clazz.name !), typeArgumentCount: (clazz.typeParameters || []).length, - typeSourceSpan: null !, usesInheritance, + typeSourceSpan: null !, usesInheritance, exportAs, }; return {decoratedElements, decorator: directive, metadata}; } diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index f963d35878..4d7a45ee1d 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -604,6 +604,26 @@ describe('ngtsc behavioral tests', () => { expect(jsContents).not.toMatch(/import \* as i[0-9] from ['"].\/test['"]/); }); + it('should generate exportAs declarations', () => { + writeConfig(); + write('test.ts', ` + import {Component, Directive} from '@angular/core'; + + @Directive({ + selector: '[test]', + exportAs: 'foo', + }) + class Dir {} + `); + + const exitCode = main(['-p', basePath], errorSpy); + expect(errorSpy).not.toHaveBeenCalled(); + expect(exitCode).toBe(0); + + const jsContents = getContents('test.js'); + expect(jsContents).toContain(`exportAs: "foo"`); + }); + it('should generate correct factory stubs for a test module', () => { writeConfig({'allowEmptyCodegenFiles': true}); diff --git a/packages/compiler/src/render3/view/api.ts b/packages/compiler/src/render3/view/api.ts index 6e45d13783..6ee53ee6d2 100644 --- a/packages/compiler/src/render3/view/api.ts +++ b/packages/compiler/src/render3/view/api.ts @@ -96,6 +96,12 @@ export interface R3DirectiveMetadata { * Whether or not the component or directive inherits from another class */ usesInheritance: boolean; + + /** + * Reference name under which to export the directive's type in a template, + * if any. + */ + exportAs: string|null; } /** diff --git a/packages/compiler/src/render3/view/compiler.ts b/packages/compiler/src/render3/view/compiler.ts index 0c1ec63a7c..611931dcdc 100644 --- a/packages/compiler/src/render3/view/compiler.ts +++ b/packages/compiler/src/render3/view/compiler.ts @@ -79,6 +79,9 @@ function baseDirectiveFields( if (features.length) { definitionMap.set('features', o.literalArr(features)); } + if (meta.exportAs !== null) { + definitionMap.set('exportAs', o.literal(meta.exportAs)); + } return {definitionMap, statements: result.statements}; } @@ -279,6 +282,7 @@ function directiveMetadataFromGlobalMetadata( inputs: directive.inputs, outputs: directive.outputs, usesInheritance: false, + exportAs: null, }; } diff --git a/packages/core/src/render3/jit/directive.ts b/packages/core/src/render3/jit/directive.ts index 21ba4ba1ba..2bc6cef0bb 100644 --- a/packages/core/src/render3/jit/directive.ts +++ b/packages/core/src/render3/jit/directive.ts @@ -168,6 +168,7 @@ function directiveMetadata(type: Type, metadata: Directive): R3DirectiveMet }, typeSourceSpan: null !, usesInheritance: !extendsDirectlyFromObject(type), + exportAs: metadata.exportAs || null, }; }