fix(compiler_cli): normalize used directives
- e.g. needed for content projection. Closes #8677
This commit is contained in:
parent
50c9bed630
commit
ff36b0384a
|
@ -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 {}
|
|
@ -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!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue