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:
@ -42,6 +42,10 @@ export abstract class BaseAotCompilerHost<C extends BaseAotCompilerHostContext>
|
||||
|
||||
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 {
|
||||
const sf = this.program.getSourceFile(filePath);
|
||||
if (!sf) {
|
||||
@ -144,10 +148,6 @@ export abstract class BaseAotCompilerHost<C extends BaseAotCompilerHostContext>
|
||||
return null;
|
||||
}
|
||||
|
||||
getOutputFileName(sourceFilePath: string): string {
|
||||
return sourceFilePath.replace(EXT, '') + '.d.ts';
|
||||
}
|
||||
|
||||
isSourceFile(filePath: string): boolean {
|
||||
const excludeRegex =
|
||||
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 {
|
||||
// Write codegen in a directory structure matching the sources.
|
||||
let root = this.options.basePath !;
|
||||
|
@ -130,6 +130,20 @@ export interface CompilerHost extends ts.CompilerHost {
|
||||
* See ImportResolver.
|
||||
*/
|
||||
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
|
||||
* `Promise<string>` it is assumed the user of the corresponding `Program` will call
|
||||
|
@ -24,6 +24,8 @@ export function createCompilerHost(
|
||||
|
||||
host.moduleNameToFileName = mixin.moduleNameToFileName.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.
|
||||
// https://github.com/Microsoft/TypeScript/issues/9552
|
||||
@ -109,9 +111,15 @@ class CompilerHostMixin {
|
||||
|
||||
let moduleName: string;
|
||||
if (importedFilePackagName === containingFilePackageName) {
|
||||
moduleName = dotRelative(
|
||||
path.dirname(stripRootDir(this.rootDirs, containingFile)),
|
||||
stripRootDir(this.rootDirs, importedFile));
|
||||
const rootedContainingFile = stripRootDir(this.rootDirs, containingFile);
|
||||
const rootedImportedFile = 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) {
|
||||
moduleName = stripNodeModulesPrefix(importedFile);
|
||||
} else {
|
||||
@ -120,6 +128,18 @@ class CompilerHostMixin {
|
||||
}
|
||||
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 {
|
||||
@ -189,6 +209,11 @@ function stripNodeModulesPrefix(filePath: string): string {
|
||||
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 {
|
||||
return path.normalize(path.join(p, '.')).replace(/\\/g, '/');
|
||||
}
|
@ -314,6 +314,14 @@ class AotCompilerHostImpl extends BaseAotCompilerHost<CompilerHost> {
|
||||
fileNameToModuleName(importedFile: string, containingFile: string): string|null {
|
||||
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(
|
||||
|
@ -105,7 +105,8 @@ const summaryResolver = new AotSummaryResolver(
|
||||
{
|
||||
loadSummary(filePath: string) { return null; },
|
||||
isSourceFile(sourceFilePath: string) { return true; },
|
||||
getOutputFileName(sourceFilePath: string) { return sourceFilePath; }
|
||||
toSummaryFileName(sourceFilePath: string) { return sourceFilePath; },
|
||||
fromSummaryFileName(filePath: string): string{return filePath;},
|
||||
},
|
||||
staticSymbolCache);
|
||||
|
||||
|
@ -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'))
|
||||
.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', () => {
|
||||
|
Reference in New Issue
Block a user