fix(compiler): include the summaries of reexported modules / directives / pipes (#13196)
Only if these are not part of the sources.
This commit is contained in:
parent
614a35d539
commit
75d1617b63
|
@ -72,9 +72,9 @@ export class AotCompiler {
|
||||||
|
|
||||||
// write summary files
|
// write summary files
|
||||||
const summaries: CompileTypeSummary[] = [
|
const summaries: CompileTypeSummary[] = [
|
||||||
...pipes.map(ref => this._metadataResolver.getPipeSummary(ref)),
|
...ngModules.map(ref => this._metadataResolver.getNgModuleSummary(ref)),
|
||||||
...directives.map(ref => this._metadataResolver.getDirectiveSummary(ref)),
|
...directives.map(ref => this._metadataResolver.getDirectiveSummary(ref)),
|
||||||
...ngModules.map(ref => this._metadataResolver.getNgModuleSummary(ref))
|
...pipes.map(ref => this._metadataResolver.getPipeSummary(ref))
|
||||||
];
|
];
|
||||||
generatedFiles.push(this._summaryResolver.serializeSummaries(srcFileUrl, summaries));
|
generatedFiles.push(this._summaryResolver.serializeSummaries(srcFileUrl, summaries));
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* Use of this source code is governed by an MIT-style license that can be
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {CompileIdentifierMetadata, CompileTypeMetadata, CompileTypeSummary, identifierModuleUrl, identifierName} from '../compile_metadata';
|
import {CompileDirectiveSummary, CompileIdentifierMetadata, CompileNgModuleSummary, CompilePipeSummary, CompileSummaryKind, CompileTypeMetadata, CompileTypeSummary, identifierModuleUrl, identifierName} from '../compile_metadata';
|
||||||
import {SummaryResolver} from '../summary_resolver';
|
import {SummaryResolver} from '../summary_resolver';
|
||||||
|
|
||||||
import {GeneratedFile} from './generated_file';
|
import {GeneratedFile} from './generated_file';
|
||||||
|
@ -35,7 +35,7 @@ export interface AotSummaryResolverOptions {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AotSummaryResolver implements SummaryResolver {
|
export class AotSummaryResolver implements SummaryResolver {
|
||||||
private summaryCache: {[srcFilePath: string]: CompileTypeSummary[]} = {};
|
private summaryCache: {[cacheKey: string]: CompileTypeSummary} = {};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private host: AotSummaryResolverHost, private staticReflector: StaticReflector,
|
private host: AotSummaryResolverHost, private staticReflector: StaticReflector,
|
||||||
|
@ -56,18 +56,32 @@ export class AotSummaryResolver implements SummaryResolver {
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
const allSummaries = summaries.slice();
|
||||||
|
summaries.forEach((summary) => {
|
||||||
|
if (summary.summaryKind === CompileSummaryKind.NgModule) {
|
||||||
|
const moduleMeta = <CompileNgModuleSummary>summary;
|
||||||
|
moduleMeta.exportedDirectives.concat(moduleMeta.exportedPipes).forEach((id) => {
|
||||||
|
if (!filterFileByPatterns(id.reference.filePath, this.options)) {
|
||||||
|
allSummaries.push(this.resolveSummary(id.reference));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return new GeneratedFile(
|
return new GeneratedFile(
|
||||||
srcFileUrl, summaryFileName(srcFileUrl), JSON.stringify(summaries, jsonReplacer));
|
srcFileUrl, summaryFileName(srcFileUrl), JSON.stringify(allSummaries, jsonReplacer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _cacheKey(symbol: StaticSymbol) { return `${symbol.filePath}|${symbol.name}`; }
|
||||||
|
|
||||||
resolveSummary(staticSymbol: StaticSymbol): any {
|
resolveSummary(staticSymbol: StaticSymbol): any {
|
||||||
const filePath = staticSymbol.filePath;
|
const filePath = staticSymbol.filePath;
|
||||||
const name = staticSymbol.name;
|
const name = staticSymbol.name;
|
||||||
|
const cacheKey = this._cacheKey(staticSymbol);
|
||||||
if (!filterFileByPatterns(filePath, this.options)) {
|
if (!filterFileByPatterns(filePath, this.options)) {
|
||||||
let summaries = this.summaryCache[filePath];
|
let summary = this.summaryCache[cacheKey];
|
||||||
const summaryFilePath = summaryFileName(filePath);
|
const summaryFilePath = summaryFileName(filePath);
|
||||||
if (!summaries) {
|
if (!summary) {
|
||||||
try {
|
try {
|
||||||
const jsonReviver = (key: string, value: any) => {
|
const jsonReviver = (key: string, value: any) => {
|
||||||
if (key === 'reference' && value && value['__symbolic__'] === 'symbol') {
|
if (key === 'reference' && value && value['__symbolic__'] === 'symbol') {
|
||||||
|
@ -81,19 +95,23 @@ export class AotSummaryResolver implements SummaryResolver {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
summaries = JSON.parse(this.host.loadSummary(summaryFilePath), jsonReviver);
|
const readSummaries: CompileTypeSummary[] =
|
||||||
|
JSON.parse(this.host.loadSummary(summaryFilePath), jsonReviver);
|
||||||
|
readSummaries.forEach((summary) => {
|
||||||
|
const filePath = summary.type.reference.filePath;
|
||||||
|
this.summaryCache[this._cacheKey(summary.type.reference)] = summary;
|
||||||
|
});
|
||||||
|
summary = this.summaryCache[cacheKey];
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Error loading summary file ${summaryFilePath}`);
|
console.error(`Error loading summary file ${summaryFilePath}`);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
this.summaryCache[filePath] = summaries;
|
|
||||||
}
|
}
|
||||||
const result = summaries.find((summary) => summary.type.reference === staticSymbol);
|
if (!summary) {
|
||||||
if (!result) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not find the symbol ${name} in the summary file ${summaryFilePath}!`);
|
`Could not find the symbol ${name} in the summary file ${summaryFilePath}!`);
|
||||||
}
|
}
|
||||||
return result;
|
return summary;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,14 +114,19 @@ export function identifierModuleUrl(compileIdentifier: CompileIdentifierMetadata
|
||||||
|
|
||||||
export interface CompileIdentifierMetadata { reference: any; }
|
export interface CompileIdentifierMetadata { reference: any; }
|
||||||
|
|
||||||
|
export enum CompileSummaryKind {
|
||||||
|
Template,
|
||||||
|
Pipe,
|
||||||
|
Directive,
|
||||||
|
NgModule
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A CompileSummary is the data needed to use a directive / pipe / module
|
* A CompileSummary is the data needed to use a directive / pipe / module
|
||||||
* in other modules / components. However, this data is not enough to compile
|
* in other modules / components. However, this data is not enough to compile
|
||||||
* the directive / module itself.
|
* the directive / module itself.
|
||||||
*/
|
*/
|
||||||
export interface CompileSummary {
|
export interface CompileSummary { summaryKind: CompileSummaryKind; }
|
||||||
isSummary: boolean /* TODO: `true` when we drop TS 1.8 support */;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CompileTypeSummary extends CompileSummary { type: CompileTypeMetadata; }
|
export interface CompileTypeSummary extends CompileSummary { type: CompileTypeMetadata; }
|
||||||
|
|
||||||
|
@ -206,7 +211,6 @@ export class CompileStylesheetMetadata {
|
||||||
* Summary Metadata regarding compilation of a template.
|
* Summary Metadata regarding compilation of a template.
|
||||||
*/
|
*/
|
||||||
export interface CompileTemplateSummary extends CompileSummary {
|
export interface CompileTemplateSummary extends CompileSummary {
|
||||||
isSummary: boolean /* TODO: `true` when we drop TS 1.8 support */;
|
|
||||||
animations: string[];
|
animations: string[];
|
||||||
ngContentSelectors: string[];
|
ngContentSelectors: string[];
|
||||||
encapsulation: ViewEncapsulation;
|
encapsulation: ViewEncapsulation;
|
||||||
|
@ -254,7 +258,7 @@ export class CompileTemplateMetadata {
|
||||||
|
|
||||||
toSummary(): CompileTemplateSummary {
|
toSummary(): CompileTemplateSummary {
|
||||||
return {
|
return {
|
||||||
isSummary: true,
|
summaryKind: CompileSummaryKind.Template,
|
||||||
animations: this.animations.map(anim => anim.name),
|
animations: this.animations.map(anim => anim.name),
|
||||||
ngContentSelectors: this.ngContentSelectors,
|
ngContentSelectors: this.ngContentSelectors,
|
||||||
encapsulation: this.encapsulation
|
encapsulation: this.encapsulation
|
||||||
|
@ -265,7 +269,6 @@ export class CompileTemplateMetadata {
|
||||||
// Note: This should only use interfaces as nested data types
|
// Note: This should only use interfaces as nested data types
|
||||||
// as we need to be able to serialize this from/to JSON!
|
// as we need to be able to serialize this from/to JSON!
|
||||||
export interface CompileDirectiveSummary extends CompileTypeSummary {
|
export interface CompileDirectiveSummary extends CompileTypeSummary {
|
||||||
isSummary: boolean /* TODO: `true` when we drop TS 1.8 support */;
|
|
||||||
type: CompileTypeMetadata;
|
type: CompileTypeMetadata;
|
||||||
isComponent: boolean;
|
isComponent: boolean;
|
||||||
selector: string;
|
selector: string;
|
||||||
|
@ -421,7 +424,7 @@ export class CompileDirectiveMetadata {
|
||||||
|
|
||||||
toSummary(): CompileDirectiveSummary {
|
toSummary(): CompileDirectiveSummary {
|
||||||
return {
|
return {
|
||||||
isSummary: true,
|
summaryKind: CompileSummaryKind.Directive,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
isComponent: this.isComponent,
|
isComponent: this.isComponent,
|
||||||
selector: this.selector,
|
selector: this.selector,
|
||||||
|
@ -473,7 +476,6 @@ export function createHostComponentMeta(
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CompilePipeSummary extends CompileTypeSummary {
|
export interface CompilePipeSummary extends CompileTypeSummary {
|
||||||
isSummary: boolean /* TODO: `true` when we drop TS 1.8 support */;
|
|
||||||
type: CompileTypeMetadata;
|
type: CompileTypeMetadata;
|
||||||
name: string;
|
name: string;
|
||||||
pure: boolean;
|
pure: boolean;
|
||||||
|
@ -495,19 +497,24 @@ export class CompilePipeMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
toSummary(): CompilePipeSummary {
|
toSummary(): CompilePipeSummary {
|
||||||
return {isSummary: true, type: this.type, name: this.name, pure: this.pure};
|
return {
|
||||||
|
summaryKind: CompileSummaryKind.Pipe,
|
||||||
|
type: this.type,
|
||||||
|
name: this.name,
|
||||||
|
pure: this.pure
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: This should only use interfaces as nested data types
|
// Note: This should only use interfaces as nested data types
|
||||||
// as we need to be able to serialize this from/to JSON!
|
// as we need to be able to serialize this from/to JSON!
|
||||||
export interface CompileNgModuleSummary extends CompileTypeSummary {
|
export interface CompileNgModuleSummary extends CompileTypeSummary {
|
||||||
isSummary: boolean /* TODO: `true` when we drop TS 1.8 support */;
|
|
||||||
type: CompileTypeMetadata;
|
type: CompileTypeMetadata;
|
||||||
|
|
||||||
|
// Note: This is transitive over the exported modules.
|
||||||
exportedDirectives: CompileIdentifierMetadata[];
|
exportedDirectives: CompileIdentifierMetadata[];
|
||||||
|
// Note: This is transitive over the exported modules.
|
||||||
exportedPipes: CompileIdentifierMetadata[];
|
exportedPipes: CompileIdentifierMetadata[];
|
||||||
exportedModules: CompileIdentifierMetadata[];
|
|
||||||
|
|
||||||
// Note: This is transitive.
|
// Note: This is transitive.
|
||||||
entryComponents: CompileIdentifierMetadata[];
|
entryComponents: CompileIdentifierMetadata[];
|
||||||
|
@ -573,29 +580,72 @@ export class CompileNgModuleMetadata {
|
||||||
|
|
||||||
toSummary(): CompileNgModuleSummary {
|
toSummary(): CompileNgModuleSummary {
|
||||||
return {
|
return {
|
||||||
isSummary: true,
|
summaryKind: CompileSummaryKind.NgModule,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
entryComponents: this.transitiveModule.entryComponents,
|
entryComponents: this.transitiveModule.entryComponents,
|
||||||
providers: this.transitiveModule.providers,
|
providers: this.transitiveModule.providers,
|
||||||
modules: this.transitiveModule.modules,
|
modules: this.transitiveModule.modules,
|
||||||
exportedDirectives: this.exportedDirectives,
|
exportedDirectives: this.transitiveModule.exportedDirectives,
|
||||||
exportedPipes: this.exportedPipes,
|
exportedPipes: this.transitiveModule.exportedPipes
|
||||||
exportedModules: this.exportedModules.map(m => m.type)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransitiveCompileNgModuleMetadata {
|
export class TransitiveCompileNgModuleMetadata {
|
||||||
directivesSet = new Set<any>();
|
directivesSet = new Set<any>();
|
||||||
|
directives: CompileIdentifierMetadata[] = [];
|
||||||
|
exportedDirectivesSet = new Set<any>();
|
||||||
|
exportedDirectives: CompileIdentifierMetadata[] = [];
|
||||||
pipesSet = new Set<any>();
|
pipesSet = new Set<any>();
|
||||||
|
pipes: CompileIdentifierMetadata[] = [];
|
||||||
|
exportedPipesSet = new Set<any>();
|
||||||
|
exportedPipes: CompileIdentifierMetadata[] = [];
|
||||||
|
modulesSet = new Set<any>();
|
||||||
|
modules: CompileTypeMetadata[] = [];
|
||||||
|
entryComponentsSet = new Set<any>();
|
||||||
|
entryComponents: CompileIdentifierMetadata[] = [];
|
||||||
|
|
||||||
constructor(
|
providers: {provider: CompileProviderMetadata, module: CompileIdentifierMetadata}[] = [];
|
||||||
public modules: CompileTypeMetadata[],
|
|
||||||
public providers: {provider: CompileProviderMetadata, module: CompileIdentifierMetadata}[],
|
addProvider(provider: CompileProviderMetadata, module: CompileIdentifierMetadata) {
|
||||||
public entryComponents: CompileIdentifierMetadata[],
|
this.providers.push({provider: provider, module: module});
|
||||||
public directives: CompileIdentifierMetadata[], public pipes: CompileIdentifierMetadata[]) {
|
}
|
||||||
directives.forEach(dir => this.directivesSet.add(dir.reference));
|
|
||||||
pipes.forEach(pipe => this.pipesSet.add(pipe.reference));
|
addDirective(id: CompileIdentifierMetadata) {
|
||||||
|
if (!this.directivesSet.has(id.reference)) {
|
||||||
|
this.directivesSet.add(id.reference);
|
||||||
|
this.directives.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addExportedDirective(id: CompileIdentifierMetadata) {
|
||||||
|
if (!this.exportedDirectivesSet.has(id.reference)) {
|
||||||
|
this.exportedDirectivesSet.add(id.reference);
|
||||||
|
this.exportedDirectives.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addPipe(id: CompileIdentifierMetadata) {
|
||||||
|
if (!this.pipesSet.has(id.reference)) {
|
||||||
|
this.pipesSet.add(id.reference);
|
||||||
|
this.pipes.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addExportedPipe(id: CompileIdentifierMetadata) {
|
||||||
|
if (!this.exportedPipesSet.has(id.reference)) {
|
||||||
|
this.exportedPipesSet.add(id.reference);
|
||||||
|
this.exportedPipes.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addModule(id: CompileTypeMetadata) {
|
||||||
|
if (!this.modulesSet.has(id.reference)) {
|
||||||
|
this.modulesSet.add(id.reference);
|
||||||
|
this.modules.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addEntryComponent(id: CompileIdentifierMetadata) {
|
||||||
|
if (!this.entryComponentsSet.has(id.reference)) {
|
||||||
|
this.entryComponentsSet.add(id.reference);
|
||||||
|
this.entryComponents.push(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,8 @@ import {MODULE_SUFFIX, SyncAsyncResult, ValueTransformer, visitValue} from './ut
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CompileMetadataResolver {
|
export class CompileMetadataResolver {
|
||||||
private _directiveCache = new Map<Type<any>, cpl.CompileDirectiveMetadata>();
|
private _directiveCache = new Map<Type<any>, cpl.CompileDirectiveMetadata>();
|
||||||
private _directiveSummaryCache = new Map<Type<any>, cpl.CompileDirectiveSummary>();
|
private _summaryCache = new Map<Type<any>, cpl.CompileTypeSummary>();
|
||||||
private _pipeCache = new Map<Type<any>, cpl.CompilePipeMetadata>();
|
private _pipeCache = new Map<Type<any>, cpl.CompilePipeMetadata>();
|
||||||
private _pipeSummaryCache = new Map<Type<any>, cpl.CompilePipeSummary>();
|
|
||||||
private _ngModuleSummaryCache = new Map<Type<any>, cpl.CompileNgModuleSummary>();
|
|
||||||
private _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>();
|
private _ngModuleCache = new Map<Type<any>, cpl.CompileNgModuleMetadata>();
|
||||||
private _ngModuleOfTypes = new Map<Type<any>, Type<any>>();
|
private _ngModuleOfTypes = new Map<Type<any>, Type<any>>();
|
||||||
|
|
||||||
|
@ -54,10 +52,8 @@ export class CompileMetadataResolver {
|
||||||
clearCacheFor(type: Type<any>) {
|
clearCacheFor(type: Type<any>) {
|
||||||
const dirMeta = this._directiveCache.get(type);
|
const dirMeta = this._directiveCache.get(type);
|
||||||
this._directiveCache.delete(type);
|
this._directiveCache.delete(type);
|
||||||
this._directiveSummaryCache.delete(type);
|
this._summaryCache.delete(type);
|
||||||
this._pipeCache.delete(type);
|
this._pipeCache.delete(type);
|
||||||
this._pipeSummaryCache.delete(type);
|
|
||||||
this._ngModuleSummaryCache.delete(type);
|
|
||||||
this._ngModuleOfTypes.delete(type);
|
this._ngModuleOfTypes.delete(type);
|
||||||
// Clear all of the NgModule as they contain transitive information!
|
// Clear all of the NgModule as they contain transitive information!
|
||||||
this._ngModuleCache.clear();
|
this._ngModuleCache.clear();
|
||||||
|
@ -68,12 +64,10 @@ export class CompileMetadataResolver {
|
||||||
|
|
||||||
clearCache() {
|
clearCache() {
|
||||||
this._directiveCache.clear();
|
this._directiveCache.clear();
|
||||||
this._directiveSummaryCache.clear();
|
this._summaryCache.clear();
|
||||||
this._pipeCache.clear();
|
this._pipeCache.clear();
|
||||||
this._pipeSummaryCache.clear();
|
|
||||||
this._ngModuleCache.clear();
|
this._ngModuleCache.clear();
|
||||||
this._ngModuleOfTypes.clear();
|
this._ngModuleOfTypes.clear();
|
||||||
this._ngModuleSummaryCache.clear();
|
|
||||||
this._directiveNormalizer.clearCache();
|
this._directiveNormalizer.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +125,15 @@ export class CompileMetadataResolver {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _loadSummary(type: any, kind: cpl.CompileSummaryKind): cpl.CompileTypeSummary {
|
||||||
|
let summary = this._summaryCache.get(type);
|
||||||
|
if (!summary) {
|
||||||
|
summary = this._summaryResolver.resolveSummary(type);
|
||||||
|
this._summaryCache.set(type, summary);
|
||||||
|
}
|
||||||
|
return summary && summary.summaryKind === kind ? summary : null;
|
||||||
|
}
|
||||||
|
|
||||||
private _loadDirectiveMetadata(directiveType: any, isSync: boolean): Promise<any> {
|
private _loadDirectiveMetadata(directiveType: any, isSync: boolean): Promise<any> {
|
||||||
if (this._directiveCache.has(directiveType)) {
|
if (this._directiveCache.has(directiveType)) {
|
||||||
return;
|
return;
|
||||||
|
@ -158,7 +161,7 @@ export class CompileMetadataResolver {
|
||||||
template: templateMetadata
|
template: templateMetadata
|
||||||
});
|
});
|
||||||
this._directiveCache.set(directiveType, normalizedDirMeta);
|
this._directiveCache.set(directiveType, normalizedDirMeta);
|
||||||
this._directiveSummaryCache.set(directiveType, normalizedDirMeta.toSummary());
|
this._summaryCache.set(directiveType, normalizedDirMeta.toSummary());
|
||||||
return normalizedDirMeta;
|
return normalizedDirMeta;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -293,16 +296,12 @@ export class CompileMetadataResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDirectiveSummary(dirType: any): cpl.CompileDirectiveSummary {
|
getDirectiveSummary(dirType: any): cpl.CompileDirectiveSummary {
|
||||||
let dirSummary = this._directiveSummaryCache.get(dirType);
|
const dirSummary =
|
||||||
|
<cpl.CompileDirectiveSummary>this._loadSummary(dirType, cpl.CompileSummaryKind.Directive);
|
||||||
if (!dirSummary) {
|
if (!dirSummary) {
|
||||||
dirSummary = <cpl.CompileDirectiveSummary>this._summaryResolver.resolveSummary(dirType);
|
|
||||||
if (dirSummary) {
|
|
||||||
this._directiveSummaryCache.set(dirType, dirSummary);
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Illegal state: Could not load the summary for directive ${stringify(dirType)}.`);
|
`Illegal state: Could not load the summary for directive ${stringify(dirType)}.`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return dirSummary;
|
return dirSummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,15 +310,13 @@ export class CompileMetadataResolver {
|
||||||
isPipe(type: any) { return this._pipeResolver.isPipe(type); }
|
isPipe(type: any) { return this._pipeResolver.isPipe(type); }
|
||||||
|
|
||||||
getNgModuleSummary(moduleType: any): cpl.CompileNgModuleSummary {
|
getNgModuleSummary(moduleType: any): cpl.CompileNgModuleSummary {
|
||||||
let moduleSummary = this._ngModuleSummaryCache.get(moduleType);
|
let moduleSummary =
|
||||||
if (!moduleSummary) {
|
<cpl.CompileNgModuleSummary>this._loadSummary(moduleType, cpl.CompileSummaryKind.NgModule);
|
||||||
moduleSummary = <cpl.CompileNgModuleSummary>this._summaryResolver.resolveSummary(moduleType);
|
|
||||||
if (!moduleSummary) {
|
if (!moduleSummary) {
|
||||||
const moduleMeta = this.getNgModuleMetadata(moduleType, false);
|
const moduleMeta = this.getNgModuleMetadata(moduleType, false);
|
||||||
moduleSummary = moduleMeta ? moduleMeta.toSummary() : null;
|
moduleSummary = moduleMeta ? moduleMeta.toSummary() : null;
|
||||||
}
|
|
||||||
if (moduleSummary) {
|
if (moduleSummary) {
|
||||||
this._ngModuleSummaryCache.set(moduleType, moduleSummary);
|
this._summaryCache.set(moduleType, moduleSummary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return moduleSummary;
|
return moduleSummary;
|
||||||
|
@ -419,12 +416,11 @@ export class CompileMetadataResolver {
|
||||||
}
|
}
|
||||||
const declaredIdentifier = this._getIdentifierMetadata(declaredType);
|
const declaredIdentifier = this._getIdentifierMetadata(declaredType);
|
||||||
if (this._directiveResolver.isDirective(declaredType)) {
|
if (this._directiveResolver.isDirective(declaredType)) {
|
||||||
transitiveModule.directivesSet.add(declaredType);
|
transitiveModule.addDirective(declaredIdentifier);
|
||||||
transitiveModule.directives.push(declaredIdentifier);
|
|
||||||
declaredDirectives.push(declaredIdentifier);
|
declaredDirectives.push(declaredIdentifier);
|
||||||
this._addTypeToModule(declaredType, moduleType);
|
this._addTypeToModule(declaredType, moduleType);
|
||||||
} else if (this._pipeResolver.isPipe(declaredType)) {
|
} else if (this._pipeResolver.isPipe(declaredType)) {
|
||||||
transitiveModule.pipesSet.add(declaredType);
|
transitiveModule.addPipe(declaredIdentifier);
|
||||||
transitiveModule.pipes.push(declaredIdentifier);
|
transitiveModule.pipes.push(declaredIdentifier);
|
||||||
declaredPipes.push(declaredIdentifier);
|
declaredPipes.push(declaredIdentifier);
|
||||||
this._addTypeToModule(declaredType, moduleType);
|
this._addTypeToModule(declaredType, moduleType);
|
||||||
|
@ -440,8 +436,10 @@ export class CompileMetadataResolver {
|
||||||
exportedNonModuleIdentifiers.forEach((exportedId) => {
|
exportedNonModuleIdentifiers.forEach((exportedId) => {
|
||||||
if (transitiveModule.directivesSet.has(exportedId.reference)) {
|
if (transitiveModule.directivesSet.has(exportedId.reference)) {
|
||||||
exportedDirectives.push(exportedId);
|
exportedDirectives.push(exportedId);
|
||||||
|
transitiveModule.addExportedDirective(exportedId);
|
||||||
} else if (transitiveModule.pipesSet.has(exportedId.reference)) {
|
} else if (transitiveModule.pipesSet.has(exportedId.reference)) {
|
||||||
exportedPipes.push(exportedId);
|
exportedPipes.push(exportedId);
|
||||||
|
transitiveModule.addExportedPipe(exportedId);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Can't export ${this._getTypeDescriptor(exportedId.reference)} ${stringify(exportedId.reference)} from ${stringify(moduleType)} as it was neither declared nor imported!`);
|
`Can't export ${this._getTypeDescriptor(exportedId.reference)} ${stringify(exportedId.reference)} from ${stringify(moduleType)} as it was neither declared nor imported!`);
|
||||||
|
@ -493,11 +491,9 @@ export class CompileMetadataResolver {
|
||||||
id: meta.id,
|
id: meta.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
transitiveModule.entryComponents.push(...entryComponents);
|
entryComponents.forEach((id) => transitiveModule.addEntryComponent(id));
|
||||||
providers.forEach((provider) => {
|
providers.forEach((provider) => transitiveModule.addProvider(provider, compileMeta.type));
|
||||||
transitiveModule.providers.push({provider: provider, module: compileMeta.type});
|
transitiveModule.addModule(compileMeta.type);
|
||||||
});
|
|
||||||
transitiveModule.modules.push(compileMeta.type);
|
|
||||||
this._ngModuleCache.set(moduleType, compileMeta);
|
this._ngModuleCache.set(moduleType, compileMeta);
|
||||||
return compileMeta;
|
return compileMeta;
|
||||||
}
|
}
|
||||||
|
@ -538,26 +534,11 @@ export class CompileMetadataResolver {
|
||||||
importedModules: cpl.CompileNgModuleSummary[],
|
importedModules: cpl.CompileNgModuleSummary[],
|
||||||
exportedModules: cpl.CompileNgModuleSummary[]): cpl.TransitiveCompileNgModuleMetadata {
|
exportedModules: cpl.CompileNgModuleSummary[]): cpl.TransitiveCompileNgModuleMetadata {
|
||||||
// collect `providers` / `entryComponents` from all imported and all exported modules
|
// collect `providers` / `entryComponents` from all imported and all exported modules
|
||||||
|
const result = new cpl.TransitiveCompileNgModuleMetadata();
|
||||||
const modulesByToken = new Map<any, Set<any>>();
|
const modulesByToken = new Map<any, Set<any>>();
|
||||||
const providers: {provider: cpl.CompileProviderMetadata,
|
|
||||||
module: cpl.CompileIdentifierMetadata}[] = [];
|
|
||||||
const entryComponents: cpl.CompileIdentifierMetadata[] = [];
|
|
||||||
const entryComponentSet = new Set<any>();
|
|
||||||
const modules: cpl.CompileTypeMetadata[] = [];
|
|
||||||
const moduleSet = new Set<any>();
|
|
||||||
importedModules.concat(exportedModules).forEach((modSummary) => {
|
importedModules.concat(exportedModules).forEach((modSummary) => {
|
||||||
modSummary.modules.forEach((mod) => {
|
modSummary.modules.forEach((mod) => result.addModule(mod));
|
||||||
if (!moduleSet.has(mod.reference)) {
|
modSummary.entryComponents.forEach((comp) => result.addEntryComponent(comp));
|
||||||
moduleSet.add(mod.reference);
|
|
||||||
modules.push(mod);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
modSummary.entryComponents.forEach((comp) => {
|
|
||||||
if (!entryComponentSet.has(comp.reference)) {
|
|
||||||
entryComponentSet.add(comp.reference);
|
|
||||||
entryComponents.push(comp);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const addedTokens = new Set<any>();
|
const addedTokens = new Set<any>();
|
||||||
modSummary.providers.forEach((entry) => {
|
modSummary.providers.forEach((entry) => {
|
||||||
const tokenRef = cpl.tokenReference(entry.provider.token);
|
const tokenRef = cpl.tokenReference(entry.provider.token);
|
||||||
|
@ -572,33 +553,19 @@ export class CompileMetadataResolver {
|
||||||
if (addedTokens.has(tokenRef) || !prevModules.has(moduleRef)) {
|
if (addedTokens.has(tokenRef) || !prevModules.has(moduleRef)) {
|
||||||
prevModules.add(moduleRef);
|
prevModules.add(moduleRef);
|
||||||
addedTokens.add(tokenRef);
|
addedTokens.add(tokenRef);
|
||||||
providers.push(entry);
|
result.addProvider(entry.provider, entry.module);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
exportedModules.forEach((modSummary) => {
|
||||||
|
modSummary.exportedDirectives.forEach((id) => result.addExportedDirective(id));
|
||||||
const transitiveExportedModules = this._getTransitiveExportedModules(importedModules);
|
modSummary.exportedPipes.forEach((id) => result.addExportedPipe(id));
|
||||||
const directives =
|
|
||||||
flattenArray(transitiveExportedModules.map((ngModule) => ngModule.exportedDirectives));
|
|
||||||
const pipes = flattenArray(transitiveExportedModules.map((ngModule) => ngModule.exportedPipes));
|
|
||||||
return new cpl.TransitiveCompileNgModuleMetadata(
|
|
||||||
modules, providers, entryComponents, directives, pipes);
|
|
||||||
}
|
|
||||||
|
|
||||||
private _getTransitiveExportedModules(
|
|
||||||
modules: cpl.CompileNgModuleSummary[], targetModules: cpl.CompileNgModuleSummary[] = [],
|
|
||||||
visitedModules = new Set<Type<any>>()): cpl.CompileNgModuleSummary[] {
|
|
||||||
modules.forEach((ngModule) => {
|
|
||||||
if (!visitedModules.has(ngModule.type.reference)) {
|
|
||||||
visitedModules.add(ngModule.type.reference);
|
|
||||||
targetModules.push(ngModule);
|
|
||||||
this._getTransitiveExportedModules(
|
|
||||||
ngModule.exportedModules.map(id => this.getNgModuleSummary(id.reference)),
|
|
||||||
targetModules, visitedModules);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return targetModules;
|
importedModules.forEach((modSummary) => {
|
||||||
|
modSummary.exportedDirectives.forEach((id) => result.addDirective(id));
|
||||||
|
modSummary.exportedPipes.forEach((id) => result.addPipe(id));
|
||||||
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getIdentifierMetadata(type: Type<any>): cpl.CompileIdentifierMetadata {
|
private _getIdentifierMetadata(type: Type<any>): cpl.CompileIdentifierMetadata {
|
||||||
|
@ -636,15 +603,10 @@ export class CompileMetadataResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
getPipeSummary(pipeType: any): cpl.CompilePipeSummary {
|
getPipeSummary(pipeType: any): cpl.CompilePipeSummary {
|
||||||
let pipeSummary = this._pipeSummaryCache.get(pipeType);
|
const pipeSummary =
|
||||||
|
<cpl.CompilePipeSummary>this._loadSummary(pipeType, cpl.CompileSummaryKind.Pipe);
|
||||||
if (!pipeSummary) {
|
if (!pipeSummary) {
|
||||||
pipeSummary = <cpl.CompilePipeSummary>this._summaryResolver.resolveSummary(pipeType);
|
throw new Error(`Illegal state: Could not load the summary for pipe ${stringify(pipeType)}.`);
|
||||||
if (pipeSummary) {
|
|
||||||
this._pipeSummaryCache.set(pipeType, pipeSummary);
|
|
||||||
} else {
|
|
||||||
throw new Error(
|
|
||||||
`Illegal state: Could not load the summary for pipe ${stringify(pipeType)}.`);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return pipeSummary;
|
return pipeSummary;
|
||||||
}
|
}
|
||||||
|
@ -667,7 +629,7 @@ export class CompileMetadataResolver {
|
||||||
pure: pipeAnnotation.pure
|
pure: pipeAnnotation.pure
|
||||||
});
|
});
|
||||||
this._pipeCache.set(pipeType, pipeMeta);
|
this._pipeCache.set(pipeType, pipeMeta);
|
||||||
this._pipeSummaryCache.set(pipeType, pipeMeta.toSummary());
|
this._summaryCache.set(pipeType, pipeMeta.toSummary());
|
||||||
return pipeMeta;
|
return pipeMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@ export class NgModuleCompiler {
|
||||||
const entryComponentFactories =
|
const entryComponentFactories =
|
||||||
ngModuleMeta.transitiveModule.entryComponents.map((entryComponent) => {
|
ngModuleMeta.transitiveModule.entryComponents.map((entryComponent) => {
|
||||||
const id: CompileIdentifierMetadata = {reference: null};
|
const id: CompileIdentifierMetadata = {reference: null};
|
||||||
if (ngModuleMeta.bootstrapComponents.indexOf(entryComponent) > -1) {
|
if (ngModuleMeta.bootstrapComponents.some(
|
||||||
|
(id) => id.reference === entryComponent.reference)) {
|
||||||
bootstrapComponentFactories.push(id);
|
bootstrapComponentFactories.push(id);
|
||||||
}
|
}
|
||||||
deps.push(new ComponentFactoryDependency(entryComponent, id));
|
deps.push(new ComponentFactoryDependency(entryComponent, id));
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {CompileSummary} from './compile_metadata';
|
import {CompileTypeSummary} from './compile_metadata';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SummaryResolver {
|
export class SummaryResolver {
|
||||||
resolveSummary(reference: any): CompileSummary { return null; }
|
resolveSummary(reference: any): CompileTypeSummary { return null; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {AotSummaryResolver, AotSummaryResolverHost, CompileTypeSummary, StaticReflector, StaticReflectorHost, StaticSymbol} from '@angular/compiler';
|
import {AotSummaryResolver, AotSummaryResolverHost, CompileNgModuleSummary, CompileSummaryKind, CompileTypeSummary, StaticReflector, StaticReflectorHost, StaticSymbol} from '@angular/compiler';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import {MockStaticReflectorHost} from './static_reflector_spec';
|
import {MockStaticReflectorHost} from './static_reflector_spec';
|
||||||
|
@ -36,36 +36,78 @@ export function main() {
|
||||||
expect(resolver.serializeSummaries('a.js', []).genFileUrl).toBe('a.ngsummary.json');
|
expect(resolver.serializeSummaries('a.js', []).genFileUrl).toBe('a.ngsummary.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should serialize plain data', () => {
|
|
||||||
init();
|
|
||||||
const data = <any>[{a: 'b'}];
|
|
||||||
expect(JSON.parse(resolver.serializeSummaries('someSourceFile', data).source)).toEqual(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should serialize summary for .ts files and deserialize based on .d.ts files', () => {
|
it('should serialize summary for .ts files and deserialize based on .d.ts files', () => {
|
||||||
init();
|
init();
|
||||||
const serializedData = resolver.serializeSummaries(
|
const serializedData = resolver.serializeSummaries(
|
||||||
'/tmp/some_class.ts', [{
|
'/tmp/some_pipe.ts', [{
|
||||||
isSummary: true,
|
summaryKind: CompileSummaryKind.Pipe,
|
||||||
type: {
|
type: {
|
||||||
reference: staticReflector.getStaticSymbol('/tmp/some_class.ts', 'SomeClass'),
|
reference: staticReflector.getStaticSymbol('/tmp/some_pipe.ts', 'SomePipe'),
|
||||||
diDeps: [],
|
diDeps: [],
|
||||||
lifecycleHooks: []
|
lifecycleHooks: []
|
||||||
}
|
},
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
// Note: this creates a new staticReflector!
|
// Note: this creates a new staticReflector!
|
||||||
init({[serializedData.genFileUrl]: serializedData.source});
|
init({[serializedData.genFileUrl]: serializedData.source});
|
||||||
|
|
||||||
expect(resolver.resolveSummary(
|
expect(resolver.resolveSummary(
|
||||||
staticReflector.getStaticSymbol('/tmp/some_class.d.ts', 'SomeClass')))
|
staticReflector.getStaticSymbol('/tmp/some_pipe.d.ts', 'SomePipe')))
|
||||||
.toEqual({
|
.toEqual({
|
||||||
isSummary: true,
|
summaryKind: CompileSummaryKind.Pipe,
|
||||||
type: {
|
type: {
|
||||||
reference: staticReflector.getStaticSymbol('/tmp/some_class.d.ts', 'SomeClass'),
|
reference: staticReflector.getStaticSymbol('/tmp/some_pipe.d.ts', 'SomePipe'),
|
||||||
diDeps: [],
|
diDeps: [],
|
||||||
lifecycleHooks: []
|
lifecycleHooks: []
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should store reexports in the same file', () => {
|
||||||
|
init();
|
||||||
|
const reexportedData = resolver.serializeSummaries(
|
||||||
|
'/tmp/some_pipe.ts', [{
|
||||||
|
summaryKind: CompileSummaryKind.Pipe,
|
||||||
|
type: {
|
||||||
|
reference: staticReflector.getStaticSymbol('/tmp/some_pipe.ts', 'SomeReexportedPipe'),
|
||||||
|
diDeps: [],
|
||||||
|
lifecycleHooks: []
|
||||||
|
},
|
||||||
|
}]);
|
||||||
|
|
||||||
|
init({[reexportedData.genFileUrl]: reexportedData.source});
|
||||||
|
const serializedData = resolver.serializeSummaries('/tmp/some_module.ts', [
|
||||||
|
<CompileNgModuleSummary>{
|
||||||
|
summaryKind: CompileSummaryKind.NgModule,
|
||||||
|
type: {
|
||||||
|
reference: staticReflector.getStaticSymbol('/tmp/some_module.ts', 'SomeModule'),
|
||||||
|
diDeps: [],
|
||||||
|
lifecycleHooks: []
|
||||||
|
},
|
||||||
|
exportedPipes: [{
|
||||||
|
reference: staticReflector.getStaticSymbol('/tmp/some_pipe.d.ts', 'SomeReexportedPipe')
|
||||||
|
}],
|
||||||
|
exportedDirectives: [],
|
||||||
|
providers: [],
|
||||||
|
entryComponents: [],
|
||||||
|
modules: []
|
||||||
}
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
init({[serializedData.genFileUrl]: serializedData.source});
|
||||||
|
|
||||||
|
resolver.resolveSummary(
|
||||||
|
staticReflector.getStaticSymbol('/tmp/some_module.d.ts', 'SomeModule'));
|
||||||
|
expect(resolver.resolveSummary(
|
||||||
|
staticReflector.getStaticSymbol('/tmp/some_pipe.d.ts', 'SomeReexportedPipe')))
|
||||||
|
.toEqual({
|
||||||
|
summaryKind: CompileSummaryKind.Pipe,
|
||||||
|
type: {
|
||||||
|
reference:
|
||||||
|
staticReflector.getStaticSymbol('/tmp/some_pipe.d.ts', 'SomeReexportedPipe'),
|
||||||
|
diDeps: [],
|
||||||
|
lifecycleHooks: []
|
||||||
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue