feat(compiler): make `.ngsummary.json` files portable

This also allows to customize the filePaths in `.ngsummary.json` file
via the new methods `toSummaryFileName` and `fromSummaryFileName`
on the `CompilerHost`.
This commit is contained in:
Tobias Bosch 2017-08-15 14:41:48 -07:00 committed by Hans
parent 6a1ab61cce
commit 2572bf508f
15 changed files with 149 additions and 53 deletions

View File

@ -42,6 +42,10 @@ export abstract class BaseAotCompilerHost<C extends BaseAotCompilerHostContext>
abstract fileNameToModuleName(importedFile: string, containingFile: string): string|null; abstract fileNameToModuleName(importedFile: string, containingFile: string): string|null;
abstract toSummaryFileName(fileName: string, referringSrcFileName: string): string;
abstract fromSummaryFileName(fileName: string, referringLibFileName: string): string;
protected getSourceFile(filePath: string): ts.SourceFile { protected getSourceFile(filePath: string): ts.SourceFile {
const sf = this.program.getSourceFile(filePath); const sf = this.program.getSourceFile(filePath);
if (!sf) { if (!sf) {
@ -144,10 +148,6 @@ export abstract class BaseAotCompilerHost<C extends BaseAotCompilerHostContext>
return null; return null;
} }
getOutputFileName(sourceFilePath: string): string {
return sourceFilePath.replace(EXT, '') + '.d.ts';
}
isSourceFile(filePath: string): boolean { isSourceFile(filePath: string): boolean {
const excludeRegex = const excludeRegex =
this.options.generateCodeForLibraries === false ? GENERATED_OR_DTS_FILES : GENERATED_FILES; this.options.generateCodeForLibraries === false ? GENERATED_OR_DTS_FILES : GENERATED_FILES;
@ -268,6 +268,12 @@ export class CompilerHost extends BaseAotCompilerHost<CompilerHostContext> {
}; };
} }
toSummaryFileName(fileName: string, referringSrcFileName: string): string {
return fileName.replace(EXT, '') + '.d.ts';
}
fromSummaryFileName(fileName: string, referringLibFileName: string): string { return fileName; }
calculateEmitPath(filePath: string): string { calculateEmitPath(filePath: string): string {
// Write codegen in a directory structure matching the sources. // Write codegen in a directory structure matching the sources.
let root = this.options.basePath !; let root = this.options.basePath !;

View File

@ -130,6 +130,20 @@ export interface CompilerHost extends ts.CompilerHost {
* See ImportResolver. * See ImportResolver.
*/ */
fileNameToModuleName(importedFilePath: string, containingFilePath: string): string|null; fileNameToModuleName(importedFilePath: string, containingFilePath: string): string|null;
/**
* Converts a file name into a representation that should be stored in a summary file.
* This has to include changing the suffix as well.
* E.g.
* `some_file.ts` -> `some_file.d.ts`
*
* @param referringSrcFileName the soure file that refers to fileName
*/
toSummaryFileName(fileName: string, referringSrcFileName: string): string;
/**
* Converts a fileName that was processed by `toSummaryFileName` back into a real fileName
* given the fileName of the library that is referrig to it.
*/
fromSummaryFileName(fileName: string, referringLibFileName: string): string;
/** /**
* Load a referenced resource either statically or asynchronously. If the host returns a * Load a referenced resource either statically or asynchronously. If the host returns a
* `Promise<string>` it is assumed the user of the corresponding `Program` will call * `Promise<string>` it is assumed the user of the corresponding `Program` will call

View File

@ -24,6 +24,8 @@ export function createCompilerHost(
host.moduleNameToFileName = mixin.moduleNameToFileName.bind(mixin); host.moduleNameToFileName = mixin.moduleNameToFileName.bind(mixin);
host.fileNameToModuleName = mixin.fileNameToModuleName.bind(mixin); host.fileNameToModuleName = mixin.fileNameToModuleName.bind(mixin);
host.toSummaryFileName = mixin.toSummaryFileName.bind(mixin);
host.fromSummaryFileName = mixin.fromSummaryFileName.bind(mixin);
// Make sure we do not `host.realpath()` from TS as we do not want to resolve symlinks. // Make sure we do not `host.realpath()` from TS as we do not want to resolve symlinks.
// https://github.com/Microsoft/TypeScript/issues/9552 // https://github.com/Microsoft/TypeScript/issues/9552
@ -109,9 +111,15 @@ class CompilerHostMixin {
let moduleName: string; let moduleName: string;
if (importedFilePackagName === containingFilePackageName) { if (importedFilePackagName === containingFilePackageName) {
moduleName = dotRelative( const rootedContainingFile = stripRootDir(this.rootDirs, containingFile);
path.dirname(stripRootDir(this.rootDirs, containingFile)), const rootedImportedFile = stripRootDir(this.rootDirs, importedFile);
stripRootDir(this.rootDirs, importedFile));
if (rootedContainingFile !== containingFile && rootedImportedFile !== importedFile) {
// if both files are contained in the `rootDirs`, then strip the rootDirs
containingFile = rootedContainingFile;
importedFile = rootedImportedFile;
}
moduleName = dotRelative(path.dirname(containingFile), importedFile);
} else if (importedFilePackagName) { } else if (importedFilePackagName) {
moduleName = stripNodeModulesPrefix(importedFile); moduleName = stripNodeModulesPrefix(importedFile);
} else { } else {
@ -120,6 +128,18 @@ class CompilerHostMixin {
} }
return moduleName; return moduleName;
} }
toSummaryFileName(fileName: string, referringSrcFileName: string): string {
return this.fileNameToModuleName(fileName, referringSrcFileName);
}
fromSummaryFileName(fileName: string, referringLibFileName: string): string {
const resolved = this.moduleNameToFileName(fileName, referringLibFileName);
if (!resolved) {
throw new Error(`Could not resolve ${fileName} from ${referringLibFileName}`);
}
return resolved;
}
} }
interface ModuleFilenameResolutionHost extends ts.ModuleResolutionHost { interface ModuleFilenameResolutionHost extends ts.ModuleResolutionHost {
@ -189,6 +209,11 @@ function stripNodeModulesPrefix(filePath: string): string {
return filePath.replace(/.*node_modules\//, ''); return filePath.replace(/.*node_modules\//, '');
} }
function getNodeModulesPrefix(filePath: string): string|null {
const match = /.*node_modules\//.exec(filePath);
return match ? match[1] : null;
}
function normalizePath(p: string): string { function normalizePath(p: string): string {
return path.normalize(path.join(p, '.')).replace(/\\/g, '/'); return path.normalize(path.join(p, '.')).replace(/\\/g, '/');
} }

View File

@ -314,6 +314,14 @@ class AotCompilerHostImpl extends BaseAotCompilerHost<CompilerHost> {
fileNameToModuleName(importedFile: string, containingFile: string): string|null { fileNameToModuleName(importedFile: string, containingFile: string): string|null {
return this.context.fileNameToModuleName(importedFile, containingFile); return this.context.fileNameToModuleName(importedFile, containingFile);
} }
toSummaryFileName(fileName: string, referringSrcFileName: string): string {
return this.context.toSummaryFileName(fileName, referringSrcFileName);
}
fromSummaryFileName(fileName: string, referringLibFileName: string): string {
return this.context.fromSummaryFileName(fileName, referringLibFileName);
}
} }
export function createProgram( export function createProgram(

View File

@ -105,7 +105,8 @@ const summaryResolver = new AotSummaryResolver(
{ {
loadSummary(filePath: string) { return null; }, loadSummary(filePath: string) { return null; },
isSourceFile(sourceFilePath: string) { return true; }, isSourceFile(sourceFilePath: string) { return true; },
getOutputFileName(sourceFilePath: string) { return sourceFilePath; } toSummaryFileName(sourceFilePath: string) { return sourceFilePath; },
fromSummaryFileName(filePath: string): string{return filePath;},
}, },
staticSymbolCache); staticSymbolCache);

View File

@ -67,8 +67,13 @@ describe('NgCompilerHost', () => {
] ]
} }
}); });
// both files are in the rootDirs
expect(ngHostWithMultipleRoots.fileNameToModuleName('/tmp/src/b/b.ts', '/tmp/src/a/a.ts')) expect(ngHostWithMultipleRoots.fileNameToModuleName('/tmp/src/b/b.ts', '/tmp/src/a/a.ts'))
.toBe('./b'); .toBe('./b');
// one file is not in the rootDirs
expect(ngHostWithMultipleRoots.fileNameToModuleName('/tmp/src/c/c.ts', '/tmp/src/a/a.ts'))
.toBe('../c/c');
}); });
it('should error if accessing a source file from a package', () => { it('should error if accessing a source file from a package', () => {

View File

@ -207,10 +207,10 @@ export class AotCompiler {
} }
private _createSummary( private _createSummary(
srcFileUrl: string, directives: StaticSymbol[], pipes: StaticSymbol[], srcFileName: string, directives: StaticSymbol[], pipes: StaticSymbol[],
ngModules: StaticSymbol[], injectables: StaticSymbol[], ngModules: StaticSymbol[], injectables: StaticSymbol[],
ngFactoryCtx: OutputContext): GeneratedFile[] { ngFactoryCtx: OutputContext): GeneratedFile[] {
const symbolSummaries = this._symbolResolver.getSymbolsOf(srcFileUrl) const symbolSummaries = this._symbolResolver.getSymbolsOf(srcFileName)
.map(symbol => this._symbolResolver.resolveSymbol(symbol)); .map(symbol => this._symbolResolver.resolveSymbol(symbol));
const typeData: { const typeData: {
summary: CompileTypeSummary, summary: CompileTypeSummary,
@ -235,18 +235,19 @@ export class AotCompiler {
metadata: this._metadataResolver.getInjectableSummary(ref) !.type metadata: this._metadataResolver.getInjectableSummary(ref) !.type
})) }))
]; ];
const forJitOutputCtx = this._createOutputContext(summaryForJitFileName(srcFileUrl, true)); const forJitOutputCtx = this._createOutputContext(summaryForJitFileName(srcFileName, true));
const {json, exportAs} = serializeSummaries( const {json, exportAs} = serializeSummaries(
forJitOutputCtx, this._summaryResolver, this._symbolResolver, symbolSummaries, typeData); srcFileName, forJitOutputCtx, this._summaryResolver, this._symbolResolver, symbolSummaries,
typeData);
exportAs.forEach((entry) => { exportAs.forEach((entry) => {
ngFactoryCtx.statements.push( ngFactoryCtx.statements.push(
o.variable(entry.exportAs).set(ngFactoryCtx.importExpr(entry.symbol)).toDeclStmt(null, [ o.variable(entry.exportAs).set(ngFactoryCtx.importExpr(entry.symbol)).toDeclStmt(null, [
o.StmtModifier.Exported o.StmtModifier.Exported
])); ]));
}); });
const summaryJson = new GeneratedFile(srcFileUrl, summaryFileName(srcFileUrl), json); const summaryJson = new GeneratedFile(srcFileName, summaryFileName(srcFileName), json);
if (this._enableSummariesForJit) { if (this._enableSummariesForJit) {
return [summaryJson, this._codegenSourceModule(srcFileUrl, forJitOutputCtx)]; return [summaryJson, this._codegenSourceModule(srcFileName, forJitOutputCtx)];
}; };
return [summaryJson]; return [summaryJson];

View File

@ -23,11 +23,20 @@ export interface AotSummaryResolverHost {
*/ */
isSourceFile(sourceFilePath: string): boolean; isSourceFile(sourceFilePath: string): boolean;
/** /**
* Returns the output file path of a source file. * Converts a file name into a representation that should be stored in a summary file.
* This has to include changing the suffix as well.
* E.g. * E.g.
* `some_file.ts` -> `some_file.d.ts` * `some_file.ts` -> `some_file.d.ts`
*
* @param referringSrcFileName the soure file that refers to fileName
*/ */
getOutputFileName(sourceFilePath: string): string; toSummaryFileName(fileName: string, referringSrcFileName: string): string;
/**
* Converts a fileName that was processed by `toSummaryFileName` back into a real fileName
* given the fileName of the library that is referrig to it.
*/
fromSummaryFileName(fileName: string, referringLibFileName: string): string;
} }
export class AotSummaryResolver implements SummaryResolver<StaticSymbol> { export class AotSummaryResolver implements SummaryResolver<StaticSymbol> {
@ -46,7 +55,13 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> {
return !this.host.isSourceFile(stripGeneratedFileSuffix(filePath)); return !this.host.isSourceFile(stripGeneratedFileSuffix(filePath));
} }
getLibraryFileName(filePath: string) { return this.host.getOutputFileName(filePath); } toSummaryFileName(filePath: string, referringSrcFileName: string) {
return this.host.toSummaryFileName(filePath, referringSrcFileName);
}
fromSummaryFileName(fileName: string, referringLibFileName: string) {
return this.host.fromSummaryFileName(fileName, referringLibFileName);
}
resolveSummary(staticSymbol: StaticSymbol): Summary<StaticSymbol> { resolveSummary(staticSymbol: StaticSymbol): Summary<StaticSymbol> {
staticSymbol.assertNoMembers(); staticSymbol.assertNoMembers();
@ -85,7 +100,8 @@ export class AotSummaryResolver implements SummaryResolver<StaticSymbol> {
throw e; throw e;
} }
if (json) { if (json) {
const {summaries, importAs} = deserializeSummaries(this.staticSymbolCache, json); const {summaries, importAs} =
deserializeSummaries(this.staticSymbolCache, this, filePath, json);
summaries.forEach((summary) => this.summaryCache.set(summary.symbol, summary)); summaries.forEach((summary) => this.summaryCache.set(summary.symbol, summary));
importAs.forEach((importAs) => { importAs.forEach((importAs) => {
this.importAs.set( this.importAs.set(

View File

@ -15,7 +15,7 @@ import {ResolvedStaticSymbol, StaticSymbolResolver} from './static_symbol_resolv
import {summaryForJitFileName, summaryForJitName} from './util'; import {summaryForJitFileName, summaryForJitName} from './util';
export function serializeSummaries( export function serializeSummaries(
forJitCtx: OutputContext, summaryResolver: SummaryResolver<StaticSymbol>, srcFileName: string, forJitCtx: OutputContext, summaryResolver: SummaryResolver<StaticSymbol>,
symbolResolver: StaticSymbolResolver, symbols: ResolvedStaticSymbol[], types: { symbolResolver: StaticSymbolResolver, symbols: ResolvedStaticSymbol[], types: {
summary: CompileTypeSummary, summary: CompileTypeSummary,
metadata: CompileNgModuleMetadata | CompileDirectiveMetadata | CompilePipeMetadata | metadata: CompileNgModuleMetadata | CompileDirectiveMetadata | CompilePipeMetadata |
@ -76,15 +76,17 @@ export function serializeSummaries(
}); });
} }
}); });
const {json, exportAs} = toJsonSerializer.serialize(); const {json, exportAs} = toJsonSerializer.serialize(srcFileName);
forJitSerializer.serialize(exportAs); forJitSerializer.serialize(exportAs);
return {json, exportAs}; return {json, exportAs};
} }
export function deserializeSummaries(symbolCache: StaticSymbolCache, json: string): export function deserializeSummaries(
symbolCache: StaticSymbolCache, summaryResolver: SummaryResolver<StaticSymbol>,
libraryFileName: string, json: string):
{summaries: Summary<StaticSymbol>[], importAs: {symbol: StaticSymbol, importAs: string}[]} { {summaries: Summary<StaticSymbol>[], importAs: {symbol: StaticSymbol, importAs: string}[]} {
const deserializer = new FromJsonDeserializer(symbolCache); const deserializer = new FromJsonDeserializer(symbolCache, summaryResolver);
return deserializer.deserialize(json); return deserializer.deserialize(libraryFileName, json);
} }
export function createForJitStub(outputCtx: OutputContext, reference: StaticSymbol) { export function createForJitStub(outputCtx: OutputContext, reference: StaticSymbol) {
@ -151,7 +153,8 @@ class ToJsonSerializer extends ValueTransformer {
} }
} }
serialize(): {json: string, exportAs: {symbol: StaticSymbol, exportAs: string}[]} { serialize(srcFileName: string):
{json: string, exportAs: {symbol: StaticSymbol, exportAs: string}[]} {
const exportAs: {symbol: StaticSymbol, exportAs: string}[] = []; const exportAs: {symbol: StaticSymbol, exportAs: string}[] = [];
const json = JSON.stringify({ const json = JSON.stringify({
summaries: this.processedSummaries, summaries: this.processedSummaries,
@ -165,10 +168,7 @@ class ToJsonSerializer extends ValueTransformer {
return { return {
__symbol: index, __symbol: index,
name: symbol.name, name: symbol.name,
// We convert the source filenames tinto output filenames, filePath: this.summaryResolver.toSummaryFileName(symbol.filePath, srcFileName),
// as the generated summary file will be used when the current
// compilation unit is used as a library
filePath: this.summaryResolver.getLibraryFileName(symbol.filePath),
importAs: importAs importAs: importAs
}; };
}) })
@ -317,15 +317,21 @@ class ForJitSerializer {
class FromJsonDeserializer extends ValueTransformer { class FromJsonDeserializer extends ValueTransformer {
private symbols: StaticSymbol[]; private symbols: StaticSymbol[];
constructor(private symbolCache: StaticSymbolCache) { super(); } constructor(
private symbolCache: StaticSymbolCache,
private summaryResolver: SummaryResolver<StaticSymbol>) {
super();
}
deserialize(json: string): deserialize(libraryFileName: string, json: string):
{summaries: Summary<StaticSymbol>[], importAs: {symbol: StaticSymbol, importAs: string}[]} { {summaries: Summary<StaticSymbol>[], importAs: {symbol: StaticSymbol, importAs: string}[]} {
const data: {summaries: any[], symbols: any[]} = JSON.parse(json); const data: {summaries: any[], symbols: any[]} = JSON.parse(json);
const importAs: {symbol: StaticSymbol, importAs: string}[] = []; const importAs: {symbol: StaticSymbol, importAs: string}[] = [];
this.symbols = []; this.symbols = [];
data.symbols.forEach((serializedSymbol) => { data.symbols.forEach((serializedSymbol) => {
const symbol = this.symbolCache.get(serializedSymbol.filePath, serializedSymbol.name); const symbol = this.symbolCache.get(
this.summaryResolver.fromSummaryFileName(serializedSymbol.filePath, libraryFileName),
serializedSymbol.name);
this.symbols.push(symbol); this.symbols.push(symbol);
if (serializedSymbol.importAs) { if (serializedSymbol.importAs) {
importAs.push({symbol: symbol, importAs: serializedSymbol.importAs}); importAs.push({symbol: symbol, importAs: serializedSymbol.importAs});

View File

@ -17,7 +17,8 @@ export interface Summary<T> {
export abstract class SummaryResolver<T> { export abstract class SummaryResolver<T> {
abstract isLibraryFile(fileName: string): boolean; abstract isLibraryFile(fileName: string): boolean;
abstract getLibraryFileName(fileName: string): string|null; abstract toSummaryFileName(fileName: string, referringSrcFileName: string): string;
abstract fromSummaryFileName(fileName: string, referringLibFileName: string): string;
abstract resolveSummary(reference: T): Summary<T>|null; abstract resolveSummary(reference: T): Summary<T>|null;
abstract getSymbolsOf(filePath: string): T[]; abstract getSymbolsOf(filePath: string): T[];
abstract getImportAs(reference: T): T; abstract getImportAs(reference: T): T;
@ -28,12 +29,13 @@ export abstract class SummaryResolver<T> {
export class JitSummaryResolver implements SummaryResolver<Type<any>> { export class JitSummaryResolver implements SummaryResolver<Type<any>> {
private _summaries = new Map<Type<any>, Summary<Type<any>>>(); private _summaries = new Map<Type<any>, Summary<Type<any>>>();
isLibraryFile(fileName: string): boolean { return false; }; isLibraryFile(): boolean { return false; };
getLibraryFileName(fileName: string): string|null { return null; } toSummaryFileName(fileName: string): string { return fileName; }
fromSummaryFileName(fileName: string): string { return fileName; }
resolveSummary(reference: Type<any>): Summary<Type<any>>|null { resolveSummary(reference: Type<any>): Summary<Type<any>>|null {
return this._summaries.get(reference) || null; return this._summaries.get(reference) || null;
}; };
getSymbolsOf(filePath: string): Type<any>[] { return []; } getSymbolsOf(): Type<any>[] { return []; }
getImportAs(reference: Type<any>): Type<any> { return reference; } getImportAs(reference: Type<any>): Type<any> { return reference; }
addSummary(summary: Summary<Type<any>>) { this._summaries.set(summary.symbol, summary); }; addSummary(summary: Summary<Type<any>>) { this._summaries.set(summary.symbol, summary); };
} }

View File

@ -386,7 +386,8 @@ export class MockSummaryResolver implements SummaryResolver<StaticSymbol> {
} }
isLibraryFile(filePath: string): boolean { return filePath.endsWith('.d.ts'); } isLibraryFile(filePath: string): boolean { return filePath.endsWith('.d.ts'); }
getLibraryFileName(filePath: string): string { return filePath.replace(/(\.d)?\.ts$/, '.d.ts'); } toSummaryFileName(filePath: string): string { return filePath.replace(/(\.d)?\.ts$/, '.d.ts'); }
fromSummaryFileName(filePath: string): string { return filePath; }
} }
export class MockStaticSymbolResolverHost implements StaticSymbolResolverHost { export class MockStaticSymbolResolverHost implements StaticSymbolResolverHost {

View File

@ -35,7 +35,8 @@ export function main() {
const symbolResolver = new StaticSymbolResolver( const symbolResolver = new StaticSymbolResolver(
new MockStaticSymbolResolverHost({}), symbolCache, mockSummaryResolver); new MockStaticSymbolResolverHost({}), symbolCache, mockSummaryResolver);
return serializeSummaries( return serializeSummaries(
createMockOutputContext(), mockSummaryResolver, symbolResolver, symbols, []) 'someFile.ts', createMockOutputContext(), mockSummaryResolver, symbolResolver,
symbols, [])
.json; .json;
} }
@ -105,10 +106,12 @@ export class MockAotSummaryResolverHost implements AotSummaryResolverHost {
return './' + path.basename(fileName).replace(EXT, ''); return './' + path.basename(fileName).replace(EXT, '');
} }
getOutputFileName(sourceFileName: string): string { toSummaryFileName(sourceFileName: string): string {
return sourceFileName.replace(EXT, '') + '.d.ts'; return sourceFileName.replace(EXT, '') + '.d.ts';
} }
fromSummaryFileName(filePath: string): string { return filePath; }
isSourceFile(filePath: string) { return !filePath.endsWith('.d.ts'); } isSourceFile(filePath: string) { return !filePath.endsWith('.d.ts'); }
loadSummary(filePath: string): string { return this.summaries[filePath]; } loadSummary(filePath: string): string { return this.summaries[filePath]; }

View File

@ -43,7 +43,7 @@ export function main() {
it('should serialize various data correctly', () => { it('should serialize various data correctly', () => {
init(); init();
const serializedData = serializeSummaries( const serializedData = serializeSummaries(
createMockOutputContext(), summaryResolver, symbolResolver, 'someFile.ts', createMockOutputContext(), summaryResolver, symbolResolver,
[ [
{ {
symbol: symbolCache.get('/tmp/some_values.ts', 'Values'), symbol: symbolCache.get('/tmp/some_values.ts', 'Values'),
@ -77,7 +77,9 @@ export function main() {
}]); }]);
const summaries = deserializeSummaries(symbolCache, serializedData.json).summaries; const summaries =
deserializeSummaries(symbolCache, summaryResolver, 'someFile.d.ts', serializedData.json)
.summaries;
expect(summaries.length).toBe(2); expect(summaries.length).toBe(2);
// Note: change from .ts to .d.ts is expected // Note: change from .ts to .d.ts is expected
@ -105,8 +107,8 @@ export function main() {
it('should automatically add exported directives / pipes of NgModules that are not source files', it('should automatically add exported directives / pipes of NgModules that are not source files',
() => { () => {
init(); init();
const externalSerialized = const externalSerialized = serializeSummaries(
serializeSummaries(createMockOutputContext(), summaryResolver, symbolResolver, [], [ 'someFile.ts', createMockOutputContext(), summaryResolver, symbolResolver, [], [
{ {
summary: { summary: {
summaryKind: CompileSummaryKind.Pipe, summaryKind: CompileSummaryKind.Pipe,
@ -133,7 +135,7 @@ export function main() {
}); });
const serialized = serializeSummaries( const serialized = serializeSummaries(
createMockOutputContext(), summaryResolver, symbolResolver, [], [{ 'someFile.ts', createMockOutputContext(), summaryResolver, symbolResolver, [], [{
summary: <any>{ summary: <any>{
summaryKind: CompileSummaryKind.NgModule, summaryKind: CompileSummaryKind.NgModule,
type: {reference: symbolCache.get('/tmp/some_module.ts', 'SomeModule')}, type: {reference: symbolCache.get('/tmp/some_module.ts', 'SomeModule')},
@ -151,7 +153,9 @@ export function main() {
metadata: null as any metadata: null as any
}]); }]);
const summaries = deserializeSummaries(symbolCache, serialized.json).summaries; const summaries =
deserializeSummaries(symbolCache, summaryResolver, 'someFile.d.ts', serialized.json)
.summaries;
expect(summaries.length).toBe(3); expect(summaries.length).toBe(3);
expect(summaries[0].symbol).toBe(symbolCache.get('/tmp/some_module.d.ts', 'SomeModule')); expect(summaries[0].symbol).toBe(symbolCache.get('/tmp/some_module.d.ts', 'SomeModule'));
expect(summaries[1].symbol).toBe(symbolCache.get('/tmp/external.d.ts', 'SomeExternalDir')); expect(summaries[1].symbol).toBe(symbolCache.get('/tmp/external.d.ts', 'SomeExternalDir'));
@ -163,7 +167,7 @@ export function main() {
() => { () => {
init(); init();
const externalSerialized = serializeSummaries( const externalSerialized = serializeSummaries(
createMockOutputContext(), summaryResolver, symbolResolver, 'someFile.ts', createMockOutputContext(), summaryResolver, symbolResolver,
[ [
{ {
symbol: symbolCache.get('/tmp/external.ts', 'PROVIDERS'), symbol: symbolCache.get('/tmp/external.ts', 'PROVIDERS'),
@ -195,7 +199,7 @@ export function main() {
{__symbolic: 'module', version: 3, metadata: {'external': 'b'}} {__symbolic: 'module', version: 3, metadata: {'external': 'b'}}
}); });
const serialized = serializeSummaries( const serialized = serializeSummaries(
createMockOutputContext(), summaryResolver, symbolResolver, [{ 'someFile.ts', createMockOutputContext(), summaryResolver, symbolResolver, [{
symbol: symbolCache.get('/tmp/test.ts', 'main'), symbol: symbolCache.get('/tmp/test.ts', 'main'),
metadata: { metadata: {
local: symbolCache.get('/tmp/local.ts', 'local'), local: symbolCache.get('/tmp/local.ts', 'local'),
@ -205,7 +209,9 @@ export function main() {
}], }],
[]); []);
const summaries = deserializeSummaries(symbolCache, serialized.json).summaries; const summaries =
deserializeSummaries(symbolCache, summaryResolver, 'someFile.d.ts', serialized.json)
.summaries;
// Note: local should not show up! // Note: local should not show up!
expect(summaries.length).toBe(4); expect(summaries.length).toBe(4);
expect(summaries[0].symbol).toBe(symbolCache.get('/tmp/test.d.ts', 'main')); expect(summaries[0].symbol).toBe(symbolCache.get('/tmp/test.d.ts', 'main'));
@ -230,7 +236,7 @@ export function main() {
it('should create "importAs" names for non source symbols', () => { it('should create "importAs" names for non source symbols', () => {
init(); init();
const serialized = serializeSummaries( const serialized = serializeSummaries(
createMockOutputContext(), summaryResolver, symbolResolver, [{ 'someFile.ts', createMockOutputContext(), summaryResolver, symbolResolver, [{
symbol: symbolCache.get('/tmp/test.ts', 'main'), symbol: symbolCache.get('/tmp/test.ts', 'main'),
metadata: [ metadata: [
symbolCache.get('/tmp/external.d.ts', 'lib'), symbolCache.get('/tmp/external.d.ts', 'lib'),
@ -243,7 +249,8 @@ export function main() {
{symbol: symbolCache.get('/tmp/external.d.ts', 'lib'), exportAs: 'lib_1'} {symbol: symbolCache.get('/tmp/external.d.ts', 'lib'), exportAs: 'lib_1'}
]); ]);
const deserialized = deserializeSummaries(symbolCache, serialized.json); const deserialized =
deserializeSummaries(symbolCache, summaryResolver, 'someFile.d.ts', serialized.json);
// Note: no entry for the symbol with members! // Note: no entry for the symbol with members!
expect(deserialized.importAs).toEqual([ expect(deserialized.importAs).toEqual([
{symbol: symbolCache.get('/tmp/external.d.ts', 'lib'), importAs: 'lib_1'} {symbol: symbolCache.get('/tmp/external.d.ts', 'lib'), importAs: 'lib_1'}

View File

@ -382,9 +382,9 @@ export class MockAotCompilerHost implements AotCompilerHost {
(this.dtsAreSource || !DTS.test(sourceFilePath)); (this.dtsAreSource || !DTS.test(sourceFilePath));
} }
getOutputFileName(sourceFilePath: string): string { toSummaryFileName(filePath: string): string { return filePath.replace(EXT, '') + '.d.ts'; }
return sourceFilePath.replace(EXT, '') + '.d.ts';
} fromSummaryFileName(filePath: string): string { return filePath; }
// AotCompilerHost // AotCompilerHost
fileNameToModuleName(importedFile: string, containingFile: string): string|null { fileNameToModuleName(importedFile: string, containingFile: string): string|null {

View File

@ -405,7 +405,8 @@ export class TypeScriptServiceHost implements LanguageServiceHost {
{ {
loadSummary(filePath: string) { return null; }, loadSummary(filePath: string) { return null; },
isSourceFile(sourceFilePath: string) { return true; }, isSourceFile(sourceFilePath: string) { return true; },
getOutputFileName(sourceFilePath: string) { return sourceFilePath; } toSummaryFileName(sourceFilePath: string) { return sourceFilePath; },
fromSummaryFileName(filePath: string): string{return filePath;},
}, },
this._staticSymbolCache); this._staticSymbolCache);
result = this._staticSymbolResolver = new StaticSymbolResolver( result = this._staticSymbolResolver = new StaticSymbolResolver(