107 lines
3.8 KiB
TypeScript
107 lines
3.8 KiB
TypeScript
|
|
/**
|
||
|
|
* @license
|
||
|
|
* Copyright Google Inc. All Rights Reserved.
|
||
|
|
*
|
||
|
|
* 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
|
||
|
|
*/
|
||
|
|
import {CompileIdentifierMetadata, CompileTypeMetadata, CompileTypeSummary, identifierModuleUrl, identifierName} from '../compile_metadata';
|
||
|
|
import {SummaryResolver} from '../summary_resolver';
|
||
|
|
|
||
|
|
import {GeneratedFile} from './generated_file';
|
||
|
|
import {StaticReflector} from './static_reflector';
|
||
|
|
import {StaticSymbol, isStaticSymbol} from './static_symbol';
|
||
|
|
import {filterFileByPatterns} from './utils';
|
||
|
|
|
||
|
|
const STRIP_SRC_FILE_SUFFIXES = /(\.ts|\.d\.ts|\.js|\.jsx|\.tsx)$/;
|
||
|
|
|
||
|
|
export interface AotSummaryResolverHost {
|
||
|
|
/**
|
||
|
|
* Loads an NgModule/Directive/Pipe summary file
|
||
|
|
*/
|
||
|
|
loadSummary(filePath: string): string;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns the output file path of a source file.
|
||
|
|
* E.g.
|
||
|
|
* `some_file.ts` -> `some_file.d.ts`
|
||
|
|
*/
|
||
|
|
getOutputFileName(sourceFilePath: string): string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface AotSummaryResolverOptions {
|
||
|
|
includeFilePattern?: RegExp;
|
||
|
|
excludeFilePattern?: RegExp;
|
||
|
|
}
|
||
|
|
|
||
|
|
export class AotSummaryResolver implements SummaryResolver {
|
||
|
|
private summaryCache: {[srcFilePath: string]: CompileTypeSummary[]} = {};
|
||
|
|
|
||
|
|
constructor(
|
||
|
|
private host: AotSummaryResolverHost, private staticReflector: StaticReflector,
|
||
|
|
private options: AotSummaryResolverOptions) {}
|
||
|
|
|
||
|
|
serializeSummaries(srcFileUrl: string, summaries: CompileTypeSummary[]): GeneratedFile {
|
||
|
|
const jsonReplacer = (key: string, value: any) => {
|
||
|
|
if (key === 'reference' && isStaticSymbol(value)) {
|
||
|
|
// We convert the source filenames into output filenames,
|
||
|
|
// as the generated summary file will be used when the current
|
||
|
|
// compilation unit is used as a library
|
||
|
|
return {
|
||
|
|
'__symbolic__': 'symbol',
|
||
|
|
'name': value.name,
|
||
|
|
'path': this.host.getOutputFileName(value.filePath),
|
||
|
|
'members': value.members
|
||
|
|
};
|
||
|
|
}
|
||
|
|
return value;
|
||
|
|
};
|
||
|
|
|
||
|
|
return new GeneratedFile(
|
||
|
|
srcFileUrl, summaryFileName(srcFileUrl), JSON.stringify(summaries, jsonReplacer));
|
||
|
|
}
|
||
|
|
|
||
|
|
resolveSummary(staticSymbol: StaticSymbol): any {
|
||
|
|
const filePath = staticSymbol.filePath;
|
||
|
|
const name = staticSymbol.name;
|
||
|
|
if (!filterFileByPatterns(filePath, this.options)) {
|
||
|
|
let summaries = this.summaryCache[filePath];
|
||
|
|
const summaryFilePath = summaryFileName(filePath);
|
||
|
|
if (!summaries) {
|
||
|
|
try {
|
||
|
|
const jsonReviver = (key: string, value: any) => {
|
||
|
|
if (key === 'reference' && value && value['__symbolic__'] === 'symbol') {
|
||
|
|
// Note: We can't use staticReflector.findDeclaration here:
|
||
|
|
// Summary files can contain symbols of transitive compilation units
|
||
|
|
// (via the providers), and findDeclaration needs .metadata.json / .d.ts files,
|
||
|
|
// but we don't want to depend on these for transitive dependencies.
|
||
|
|
return this.staticReflector.getStaticSymbol(
|
||
|
|
value['path'], value['name'], value['members']);
|
||
|
|
} else {
|
||
|
|
return value;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
summaries = JSON.parse(this.host.loadSummary(summaryFilePath), jsonReviver);
|
||
|
|
} catch (e) {
|
||
|
|
console.error(`Error loading summary file ${summaryFilePath}`);
|
||
|
|
throw e;
|
||
|
|
}
|
||
|
|
this.summaryCache[filePath] = summaries;
|
||
|
|
}
|
||
|
|
const result = summaries.find((summary) => summary.type.reference === staticSymbol);
|
||
|
|
if (!result) {
|
||
|
|
throw new Error(
|
||
|
|
`Could not find the symbol ${name} in the summary file ${summaryFilePath}!`);
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
} else {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function summaryFileName(fileName: string): string {
|
||
|
|
const fileNameWithoutSuffix = fileName.replace(STRIP_SRC_FILE_SUFFIXES, '');
|
||
|
|
return `${fileNameWithoutSuffix}.ngsummary.json`;
|
||
|
|
}
|