From ff36b0384a33d415bf420543163d54b2fa5a45d5 Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Mon, 16 May 2016 12:06:21 -0700 Subject: [PATCH] fix(compiler_cli): normalize used directives - e.g. needed for content projection. Closes #8677 --- .../integrationtest/src/projection.ts | 15 ++++++++ .../integrationtest/test/projection_spec.ts | 17 +++++++++ modules/@angular/compiler_cli/src/codegen.ts | 35 ++++++++++++------- 3 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 modules/@angular/compiler_cli/integrationtest/src/projection.ts create mode 100644 modules/@angular/compiler_cli/integrationtest/test/projection_spec.ts diff --git a/modules/@angular/compiler_cli/integrationtest/src/projection.ts b/modules/@angular/compiler_cli/integrationtest/src/projection.ts new file mode 100644 index 0000000000..11febf20b5 --- /dev/null +++ b/modules/@angular/compiler_cli/integrationtest/src/projection.ts @@ -0,0 +1,15 @@ +import {Component} from '@angular/core'; + +@Component({ + selector: 'comp-with-proj', + template: '' +}) +export class CompWithProjection { +} + +@Component({ + selector: 'main', + template: '', + directives: [CompWithProjection] +}) +export class MainComp {} diff --git a/modules/@angular/compiler_cli/integrationtest/test/projection_spec.ts b/modules/@angular/compiler_cli/integrationtest/test/projection_spec.ts new file mode 100644 index 0000000000..5c34ad2212 --- /dev/null +++ b/modules/@angular/compiler_cli/integrationtest/test/projection_spec.ts @@ -0,0 +1,17 @@ +import {MainCompNgFactory} from '../src/projection.ngfactory'; +import {CompWithProjection} from '../src/projection'; +import {ReflectiveInjector, DebugElement, getDebugNode} from '@angular/core'; +import {browserPlatform, BROWSER_APP_STATIC_PROVIDERS, By} from '@angular/platform-browser'; + +describe("content projection", () => { + it("should support basic content projection", () => { + const appInjector = ReflectiveInjector.resolveAndCreate(BROWSER_APP_STATIC_PROVIDERS, + browserPlatform().injector); + var mainComp = MainCompNgFactory.create(appInjector); + + var debugElement = getDebugNode(mainComp.location.nativeElement); + var compWithProjection = debugElement.query(By.directive(CompWithProjection)); + expect(compWithProjection.children.length).toBe(1); + expect(compWithProjection.children[0].attributes['greeting']).toEqual('Hello world!'); + }); +}); diff --git a/modules/@angular/compiler_cli/src/codegen.ts b/modules/@angular/compiler_cli/src/codegen.ts index 546e473882..f5805f1e7f 100644 --- a/modules/@angular/compiler_cli/src/codegen.ts +++ b/modules/@angular/compiler_cli/src/codegen.ts @@ -68,11 +68,16 @@ export class CodeGenerator { const normalize = (metadata: compiler.CompileDirectiveMetadata) => { const directiveType = metadata.type.runtime; const directives = this.resolver.getViewDirectivesMetadata(directiveType); - const pipes = this.resolver.getViewPipesMetadata(directiveType); - return new compiler.NormalizedComponentWithViewDirectives(metadata, directives, pipes); + return Promise.all(directives.map(d => this.compiler.normalizeDirectiveMetadata(d))) + .then(normalizedDirectives => { + const pipes = this.resolver.getViewPipesMetadata(directiveType); + return new compiler.NormalizedComponentWithViewDirectives(metadata, + normalizedDirectives, pipes); + }); }; - - return this.compiler.compileTemplates(metadatas.map(normalize)); + return Promise.all(metadatas.map(normalize)) + .then(normalizedCompWithDirectives => + this.compiler.compileTemplates(normalizedCompWithDirectives)); } private readComponents(absSourcePath: string) { @@ -131,13 +136,13 @@ export class CodeGenerator { codegen(): Promise { Parse5DomAdapter.makeCurrent(); + let stylesheetPromises: Promise[] = []; const generateOneFile = (absSourcePath: string) => Promise.all(this.readComponents(absSourcePath)) .then((metadatas: compiler.CompileDirectiveMetadata[]) => { if (!metadatas || !metadatas.length) { return; } - let stylesheetPromises: Promise[] = []; metadatas.forEach((metadata) => { let stylesheetPaths = metadata && metadata.template && metadata.template.styleUrls; if (stylesheetPaths) { @@ -147,18 +152,22 @@ export class CodeGenerator { }); } }); - const generated = this.generateSource(metadatas); - const sourceFile = this.program.getSourceFile(absSourcePath); - const emitPath = this.calculateEmitPath(generated.moduleUrl); - this.host.writeFile(emitPath, PREAMBLE + generated.source, false, () => {}, - [sourceFile]); - return Promise.all(stylesheetPromises); + return this.generateSource(metadatas); + }) + .then(generated => { + if (generated) { + const sourceFile = this.program.getSourceFile(absSourcePath); + const emitPath = this.calculateEmitPath(generated.moduleUrl); + this.host.writeFile(emitPath, PREAMBLE + generated.source, false, () => {}, + [sourceFile]); + } }) .catch((e) => { console.error(e.stack); }); - return Promise.all(this.program.getSourceFiles() + var compPromises = this.program.getSourceFiles() .map(sf => sf.fileName) .filter(f => !GENERATED_FILES.test(f)) - .map(generateOneFile)); + .map(generateOneFile); + return Promise.all(stylesheetPromises.concat(compPromises)); } static create(ngOptions: AngularCompilerOptions, program: ts.Program, options: ts.CompilerOptions,