fix(compiler_cli): normalize used directives

- e.g. needed for content projection.

Closes #8677
This commit is contained in:
Tobias Bosch 2016-05-16 12:06:21 -07:00
parent 50c9bed630
commit ff36b0384a
3 changed files with 54 additions and 13 deletions

View File

@ -0,0 +1,15 @@
import {Component} from '@angular/core';
@Component({
selector: 'comp-with-proj',
template: '<ng-content></ng-content>'
})
export class CompWithProjection {
}
@Component({
selector: 'main',
template: '<comp-with-proj><span greeting="Hello world!"></span></comp-with-proj>',
directives: [CompWithProjection]
})
export class MainComp {}

View File

@ -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 = <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!');
});
});

View File

@ -68,11 +68,16 @@ export class CodeGenerator {
const normalize = (metadata: compiler.CompileDirectiveMetadata) => { const normalize = (metadata: compiler.CompileDirectiveMetadata) => {
const directiveType = metadata.type.runtime; const directiveType = metadata.type.runtime;
const directives = this.resolver.getViewDirectivesMetadata(directiveType); const directives = this.resolver.getViewDirectivesMetadata(directiveType);
return Promise.all(directives.map(d => this.compiler.normalizeDirectiveMetadata(d)))
.then(normalizedDirectives => {
const pipes = this.resolver.getViewPipesMetadata(directiveType); const pipes = this.resolver.getViewPipesMetadata(directiveType);
return new compiler.NormalizedComponentWithViewDirectives(metadata, directives, pipes); return new compiler.NormalizedComponentWithViewDirectives(metadata,
normalizedDirectives, pipes);
});
}; };
return Promise.all(metadatas.map(normalize))
return this.compiler.compileTemplates(metadatas.map(normalize)); .then(normalizedCompWithDirectives =>
this.compiler.compileTemplates(normalizedCompWithDirectives));
} }
private readComponents(absSourcePath: string) { private readComponents(absSourcePath: string) {
@ -131,13 +136,13 @@ export class CodeGenerator {
codegen(): Promise<any> { codegen(): Promise<any> {
Parse5DomAdapter.makeCurrent(); Parse5DomAdapter.makeCurrent();
let stylesheetPromises: Promise<any>[] = [];
const generateOneFile = (absSourcePath: string) => const generateOneFile = (absSourcePath: string) =>
Promise.all(this.readComponents(absSourcePath)) Promise.all(this.readComponents(absSourcePath))
.then((metadatas: compiler.CompileDirectiveMetadata[]) => { .then((metadatas: compiler.CompileDirectiveMetadata[]) => {
if (!metadatas || !metadatas.length) { if (!metadatas || !metadatas.length) {
return; return;
} }
let stylesheetPromises: Promise<any>[] = [];
metadatas.forEach((metadata) => { metadatas.forEach((metadata) => {
let stylesheetPaths = metadata && metadata.template && metadata.template.styleUrls; let stylesheetPaths = metadata && metadata.template && metadata.template.styleUrls;
if (stylesheetPaths) { if (stylesheetPaths) {
@ -147,18 +152,22 @@ export class CodeGenerator {
}); });
} }
}); });
const generated = this.generateSource(metadatas); return this.generateSource(metadatas);
})
.then(generated => {
if (generated) {
const sourceFile = this.program.getSourceFile(absSourcePath); const sourceFile = this.program.getSourceFile(absSourcePath);
const emitPath = this.calculateEmitPath(generated.moduleUrl); const emitPath = this.calculateEmitPath(generated.moduleUrl);
this.host.writeFile(emitPath, PREAMBLE + generated.source, false, () => {}, this.host.writeFile(emitPath, PREAMBLE + generated.source, false, () => {},
[sourceFile]); [sourceFile]);
return Promise.all(stylesheetPromises); }
}) })
.catch((e) => { console.error(e.stack); }); .catch((e) => { console.error(e.stack); });
return Promise.all(this.program.getSourceFiles() var compPromises = this.program.getSourceFiles()
.map(sf => sf.fileName) .map(sf => sf.fileName)
.filter(f => !GENERATED_FILES.test(f)) .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, static create(ngOptions: AngularCompilerOptions, program: ts.Program, options: ts.CompilerOptions,