refactor(compiler): split compiler and core (#18683)
After this, neither @angular/compiler nor @angular/comnpiler-cli depend on @angular/core. This add a duplication of some interfaces and enums which is stored in @angular/compiler/src/core.ts BREAKING CHANGE: - `@angular/platform-server` now additionally depends on `@angular/platform-browser-dynamic` as a peer dependency. PR Close #18683
This commit is contained in:

committed by
Miško Hevery

parent
a0ca01d580
commit
0cc77b4a69
@ -6,11 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Compiler, ComponentFactory, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type, ɵConsole as Console, ɵgetComponentViewDefinitionFactory as getComponentViewDefinitionFactory, ɵstringify as stringify} from '@angular/core';
|
||||
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileStylesheetMetadata, CompileTypeSummary, ProviderMeta, ProxyClass, createHostComponentMeta, identifierName, ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata';
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, CompileProviderMetadata, CompileStylesheetMetadata, CompileTypeSummary, ProviderMeta, ProxyClass, createHostComponentMeta, identifierName, ngModuleJitUrl, sharedStylesheetJitUrl, templateJitUrl, templateSourceUrl} from '../compile_metadata';
|
||||
import {CompileReflector} from '../compile_reflector';
|
||||
import {CompilerConfig} from '../config';
|
||||
import {CompilerInjectable} from '../injectable';
|
||||
import {Type} from '../core';
|
||||
import {CompileMetadataResolver} from '../metadata_resolver';
|
||||
import {NgModuleCompiler} from '../ng_module_compiler';
|
||||
import * as ir from '../output/output_ast';
|
||||
@ -19,10 +18,13 @@ import {jitStatements} from '../output/output_jit';
|
||||
import {CompiledStylesheet, StyleCompiler} from '../style_compiler';
|
||||
import {SummaryResolver} from '../summary_resolver';
|
||||
import {TemplateParser} from '../template_parser/template_parser';
|
||||
import {OutputContext, SyncAsync} from '../util';
|
||||
import {Console, OutputContext, SyncAsync, stringify} from '../util';
|
||||
import {ViewCompiler} from '../view_compiler/view_compiler';
|
||||
|
||||
|
||||
export interface ModuleWithComponentFactories {
|
||||
ngModuleFactory: object;
|
||||
componentFactories: object[];
|
||||
}
|
||||
|
||||
/**
|
||||
* An internal module of the Angular compiler that begins with component types,
|
||||
@ -33,41 +35,38 @@ import {ViewCompiler} from '../view_compiler/view_compiler';
|
||||
* from a trusted source. Attacker-controlled data introduced by a template could expose your
|
||||
* application to XSS risks. For more detail, see the [Security Guide](http://g.co/ng/security).
|
||||
*/
|
||||
@CompilerInjectable()
|
||||
export class JitCompiler implements Compiler {
|
||||
private _compiledTemplateCache = new Map<Type<any>, CompiledTemplate>();
|
||||
private _compiledHostTemplateCache = new Map<Type<any>, CompiledTemplate>();
|
||||
private _compiledDirectiveWrapperCache = new Map<Type<any>, Type<any>>();
|
||||
private _compiledNgModuleCache = new Map<Type<any>, NgModuleFactory<any>>();
|
||||
export class JitCompiler {
|
||||
private _compiledTemplateCache = new Map<Type, CompiledTemplate>();
|
||||
private _compiledHostTemplateCache = new Map<Type, CompiledTemplate>();
|
||||
private _compiledDirectiveWrapperCache = new Map<Type, Type>();
|
||||
private _compiledNgModuleCache = new Map<Type, object>();
|
||||
private _sharedStylesheetCount = 0;
|
||||
|
||||
constructor(
|
||||
private _injector: Injector, private _metadataResolver: CompileMetadataResolver,
|
||||
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler,
|
||||
private _viewCompiler: ViewCompiler, private _ngModuleCompiler: NgModuleCompiler,
|
||||
private _summaryResolver: SummaryResolver<Type<any>>, private _compilerConfig: CompilerConfig,
|
||||
private _console: Console) {}
|
||||
private _metadataResolver: CompileMetadataResolver, private _templateParser: TemplateParser,
|
||||
private _styleCompiler: StyleCompiler, private _viewCompiler: ViewCompiler,
|
||||
private _ngModuleCompiler: NgModuleCompiler, private _summaryResolver: SummaryResolver<Type>,
|
||||
private _reflector: CompileReflector, private _compilerConfig: CompilerConfig,
|
||||
private _console: Console,
|
||||
private getExtraNgModuleProviders: (ngModule: any) => CompileProviderMetadata[]) {}
|
||||
|
||||
get injector(): Injector { return this._injector; }
|
||||
|
||||
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
compileModuleSync(moduleType: Type): object {
|
||||
return SyncAsync.assertSync(this._compileModuleAndComponents(moduleType, true));
|
||||
}
|
||||
|
||||
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
||||
compileModuleAsync(moduleType: Type): Promise<object> {
|
||||
return Promise.resolve(this._compileModuleAndComponents(moduleType, false));
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
||||
compileModuleAndAllComponentsSync(moduleType: Type): ModuleWithComponentFactories {
|
||||
return SyncAsync.assertSync(this._compileModuleAndAllComponents(moduleType, true));
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
||||
Promise<ModuleWithComponentFactories<T>> {
|
||||
compileModuleAndAllComponentsAsync(moduleType: Type): Promise<ModuleWithComponentFactories> {
|
||||
return Promise.resolve(this._compileModuleAndAllComponents(moduleType, false));
|
||||
}
|
||||
|
||||
getNgContentSelectors(component: Type<any>): string[] {
|
||||
getNgContentSelectors(component: Type): string[] {
|
||||
this._console.warn(
|
||||
'Compiler.getNgContentSelectors is deprecated. Use ComponentFactory.ngContentSelectors instead!');
|
||||
const template = this._compiledTemplateCache.get(component);
|
||||
@ -77,9 +76,9 @@ export class JitCompiler implements Compiler {
|
||||
return template.compMeta.template !.ngContentSelectors;
|
||||
}
|
||||
|
||||
getComponentFactory<T>(component: Type<T>): ComponentFactory<T> {
|
||||
getComponentFactory(component: Type): object {
|
||||
const summary = this._metadataResolver.getDirectiveSummary(component);
|
||||
return <ComponentFactory<T>>summary.componentFactory;
|
||||
return summary.componentFactory as object;
|
||||
}
|
||||
|
||||
loadAotSummaries(summaries: () => any[]) {
|
||||
@ -90,26 +89,28 @@ export class JitCompiler implements Compiler {
|
||||
});
|
||||
}
|
||||
|
||||
hasAotSummary(ref: Type<any>) { return !!this._summaryResolver.resolveSummary(ref); }
|
||||
hasAotSummary(ref: Type) { return !!this._summaryResolver.resolveSummary(ref); }
|
||||
|
||||
private _filterJitIdentifiers(ids: CompileIdentifierMetadata[]): any[] {
|
||||
return ids.map(mod => mod.reference).filter((ref) => !this.hasAotSummary(ref));
|
||||
}
|
||||
|
||||
private _compileModuleAndComponents<T>(moduleType: Type<T>, isSync: boolean):
|
||||
SyncAsync<NgModuleFactory<T>> {
|
||||
private _compileModuleAndComponents(moduleType: Type, isSync: boolean): SyncAsync<object> {
|
||||
return SyncAsync.then(this._loadModules(moduleType, isSync), () => {
|
||||
this._compileComponents(moduleType, null);
|
||||
return this._compileModule(moduleType);
|
||||
});
|
||||
}
|
||||
|
||||
private _compileModuleAndAllComponents<T>(moduleType: Type<T>, isSync: boolean):
|
||||
SyncAsync<ModuleWithComponentFactories<T>> {
|
||||
private _compileModuleAndAllComponents(moduleType: Type, isSync: boolean):
|
||||
SyncAsync<ModuleWithComponentFactories> {
|
||||
return SyncAsync.then(this._loadModules(moduleType, isSync), () => {
|
||||
const componentFactories: ComponentFactory<any>[] = [];
|
||||
const componentFactories: object[] = [];
|
||||
this._compileComponents(moduleType, componentFactories);
|
||||
return new ModuleWithComponentFactories(this._compileModule(moduleType), componentFactories);
|
||||
return {
|
||||
ngModuleFactory: this._compileModule(moduleType),
|
||||
componentFactories: componentFactories
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -134,22 +135,16 @@ export class JitCompiler implements Compiler {
|
||||
return SyncAsync.all(loading);
|
||||
}
|
||||
|
||||
private _compileModule<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
private _compileModule(moduleType: Type): object {
|
||||
let ngModuleFactory = this._compiledNgModuleCache.get(moduleType) !;
|
||||
if (!ngModuleFactory) {
|
||||
const moduleMeta = this._metadataResolver.getNgModuleMetadata(moduleType) !;
|
||||
// Always provide a bound Compiler
|
||||
const extraProviders = [this._metadataResolver.getProviderMetadata(new ProviderMeta(
|
||||
Compiler, {useFactory: () => new ModuleBoundCompiler(this, moduleMeta.type.reference)}))];
|
||||
const extraProviders = this.getExtraNgModuleProviders(moduleMeta.type.reference);
|
||||
const outputCtx = createOutputContext();
|
||||
const compileResult = this._ngModuleCompiler.compile(outputCtx, moduleMeta, extraProviders);
|
||||
if (!this._compilerConfig.useJit) {
|
||||
ngModuleFactory =
|
||||
interpretStatements(outputCtx.statements)[compileResult.ngModuleFactoryVar];
|
||||
} else {
|
||||
ngModuleFactory = jitStatements(
|
||||
ngModuleJitUrl(moduleMeta), outputCtx.statements, )[compileResult.ngModuleFactoryVar];
|
||||
}
|
||||
ngModuleFactory = this._interpretOrJit(
|
||||
ngModuleJitUrl(moduleMeta), outputCtx.statements)[compileResult.ngModuleFactoryVar];
|
||||
this._compiledNgModuleCache.set(moduleMeta.type.reference, ngModuleFactory);
|
||||
}
|
||||
return ngModuleFactory;
|
||||
@ -158,7 +153,7 @@ export class JitCompiler implements Compiler {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_compileComponents(mainModule: Type<any>, allComponentFactories: ComponentFactory<any>[]|null) {
|
||||
_compileComponents(mainModule: Type, allComponentFactories: object[]|null) {
|
||||
const ngModule = this._metadataResolver.getNgModuleMetadata(mainModule) !;
|
||||
const moduleByJitDirective = new Map<any, CompileNgModuleMetadata>();
|
||||
const templates = new Set<CompiledTemplate>();
|
||||
@ -175,7 +170,7 @@ export class JitCompiler implements Compiler {
|
||||
const template =
|
||||
this._createCompiledHostTemplate(dirMeta.type.reference, localModuleMeta);
|
||||
templates.add(template);
|
||||
allComponentFactories.push(<ComponentFactory<any>>dirMeta.componentFactory);
|
||||
allComponentFactories.push(dirMeta.componentFactory as object);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -203,7 +198,7 @@ export class JitCompiler implements Compiler {
|
||||
templates.forEach((template) => this._compileTemplate(template));
|
||||
}
|
||||
|
||||
clearCacheFor(type: Type<any>) {
|
||||
clearCacheFor(type: Type) {
|
||||
this._compiledNgModuleCache.delete(type);
|
||||
this._metadataResolver.clearCacheFor(type);
|
||||
this._compiledHostTemplateCache.delete(type);
|
||||
@ -220,7 +215,7 @@ export class JitCompiler implements Compiler {
|
||||
this._compiledNgModuleCache.clear();
|
||||
}
|
||||
|
||||
private _createCompiledHostTemplate(compType: Type<any>, ngModule: CompileNgModuleMetadata):
|
||||
private _createCompiledHostTemplate(compType: Type, ngModule: CompileNgModuleMetadata):
|
||||
CompiledTemplate {
|
||||
if (!ngModule) {
|
||||
throw new Error(
|
||||
@ -231,10 +226,9 @@ export class JitCompiler implements Compiler {
|
||||
const compMeta = this._metadataResolver.getDirectiveMetadata(compType);
|
||||
assertComponent(compMeta);
|
||||
|
||||
const componentFactory = <ComponentFactory<any>>compMeta.componentFactory;
|
||||
const hostClass = this._metadataResolver.getHostComponentType(compType);
|
||||
const hostMeta = createHostComponentMeta(
|
||||
hostClass, compMeta, <any>getComponentViewDefinitionFactory(componentFactory));
|
||||
hostClass, compMeta, (compMeta.componentFactory as any).viewDefFactory);
|
||||
compiledTemplate =
|
||||
new CompiledTemplate(true, compMeta.type, hostMeta, ngModule, [compMeta.type]);
|
||||
this._compiledHostTemplateCache.set(compType, compiledTemplate);
|
||||
@ -280,13 +274,8 @@ export class JitCompiler implements Compiler {
|
||||
const compileResult = this._viewCompiler.compileComponent(
|
||||
outputContext, compMeta, parsedTemplate, ir.variable(componentStylesheet.stylesVar),
|
||||
usedPipes);
|
||||
let evalResult: any;
|
||||
if (!this._compilerConfig.useJit) {
|
||||
evalResult = interpretStatements(outputContext.statements);
|
||||
} else {
|
||||
evalResult = jitStatements(
|
||||
templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements);
|
||||
}
|
||||
const evalResult = this._interpretOrJit(
|
||||
templateJitUrl(template.ngModule.type, template.compMeta), outputContext.statements);
|
||||
const viewClass = evalResult[compileResult.viewClassVar];
|
||||
const rendererType = evalResult[compileResult.rendererTypeVar];
|
||||
template.compiled(viewClass, rendererType);
|
||||
@ -306,12 +295,16 @@ export class JitCompiler implements Compiler {
|
||||
result: CompiledStylesheet,
|
||||
externalStylesheetsByModuleUrl: Map<string, CompiledStylesheet>): string[] {
|
||||
this._resolveStylesCompileResult(result, externalStylesheetsByModuleUrl);
|
||||
return this._interpretOrJit(
|
||||
sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++),
|
||||
result.outputCtx.statements)[result.stylesVar];
|
||||
}
|
||||
|
||||
private _interpretOrJit(sourceUrl: string, statements: ir.Statement[]): any {
|
||||
if (!this._compilerConfig.useJit) {
|
||||
return interpretStatements(result.outputCtx.statements)[result.stylesVar];
|
||||
return interpretStatements(statements, this._reflector);
|
||||
} else {
|
||||
return jitStatements(
|
||||
sharedStylesheetJitUrl(result.meta, this._sharedStylesheetCount++),
|
||||
result.outputCtx.statements)[result.stylesVar];
|
||||
return jitStatements(sourceUrl, statements, this._reflector, this._compilerConfig.jitDevMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -342,46 +335,6 @@ function assertComponent(meta: CompileDirectiveMetadata) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements `Compiler` by delegating to the JitCompiler using a known module.
|
||||
*/
|
||||
class ModuleBoundCompiler implements Compiler {
|
||||
constructor(private _delegate: JitCompiler, private _ngModule: Type<any>) {}
|
||||
|
||||
get _injector(): Injector { return this._delegate.injector; }
|
||||
|
||||
compileModuleSync<T>(moduleType: Type<T>): NgModuleFactory<T> {
|
||||
return this._delegate.compileModuleSync(moduleType);
|
||||
}
|
||||
|
||||
compileModuleAsync<T>(moduleType: Type<T>): Promise<NgModuleFactory<T>> {
|
||||
return this._delegate.compileModuleAsync(moduleType);
|
||||
}
|
||||
compileModuleAndAllComponentsSync<T>(moduleType: Type<T>): ModuleWithComponentFactories<T> {
|
||||
return this._delegate.compileModuleAndAllComponentsSync(moduleType);
|
||||
}
|
||||
|
||||
compileModuleAndAllComponentsAsync<T>(moduleType: Type<T>):
|
||||
Promise<ModuleWithComponentFactories<T>> {
|
||||
return this._delegate.compileModuleAndAllComponentsAsync(moduleType);
|
||||
}
|
||||
|
||||
getNgContentSelectors(component: Type<any>): string[] {
|
||||
return this._delegate.getNgContentSelectors(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all caches
|
||||
*/
|
||||
clearCache(): void { this._delegate.clearCache(); }
|
||||
|
||||
/**
|
||||
* Clears the cache for the given component/ngModule.
|
||||
*/
|
||||
clearCacheFor(type: Type<any>) { this._delegate.clearCacheFor(type); }
|
||||
}
|
||||
|
||||
|
||||
function flattenSummaries(fn: () => any[], out: CompileTypeSummary[] = []): CompileTypeSummary[] {
|
||||
fn().forEach((entry) => {
|
||||
if (typeof entry === 'function') {
|
||||
|
Reference in New Issue
Block a user