fix(compiler): No longer writes 0 length files outside of genDir (#10023)
Fixes: #9984
This commit is contained in:
parent
42b0c1d8a2
commit
6518ff88b2
@ -18,9 +18,10 @@ const EXT = /(\.ts|\.d\.ts|\.js|\.jsx|\.tsx)$/;
|
|||||||
const DTS = /\.d\.ts$/;
|
const DTS = /\.d\.ts$/;
|
||||||
|
|
||||||
export interface ReflectorHostContext {
|
export interface ReflectorHostContext {
|
||||||
exists(fileName: string): boolean;
|
fileExists(fileName: string): boolean;
|
||||||
read(fileName: string): string;
|
directoryExists(directoryName: string): boolean;
|
||||||
write(fileName: string, data: string): void;
|
readFile(fileName: string): string;
|
||||||
|
assumeFileExists(fileName: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
||||||
@ -44,7 +45,7 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
|||||||
}
|
}
|
||||||
private resolve(m: string, containingFile: string) {
|
private resolve(m: string, containingFile: string) {
|
||||||
const resolved =
|
const resolved =
|
||||||
ts.resolveModuleName(m, containingFile, this.options, this.compilerHost).resolvedModule;
|
ts.resolveModuleName(m, containingFile, this.options, this.context).resolvedModule;
|
||||||
return resolved ? resolved.resolvedFileName : null;
|
return resolved ? resolved.resolvedFileName : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,8 +78,7 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
|||||||
if (this.options.trace) {
|
if (this.options.trace) {
|
||||||
console.log(`Generating empty file ${importedFile} to allow resolution of import`);
|
console.log(`Generating empty file ${importedFile} to allow resolution of import`);
|
||||||
}
|
}
|
||||||
this.compilerHost.writeFile(importedFile, '', false);
|
this.context.assumeFileExists(importedFile);
|
||||||
this.context.write(importedFile, '');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const importModuleName = importedFile.replace(EXT, '');
|
const importModuleName = importedFile.replace(EXT, '');
|
||||||
@ -178,7 +178,7 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getMetadataFor(filePath: string): ModuleMetadata {
|
getMetadataFor(filePath: string): ModuleMetadata {
|
||||||
if (!this.context.exists(filePath)) {
|
if (!this.context.fileExists(filePath)) {
|
||||||
// If the file doesn't exists then we cannot return metadata for the file.
|
// If the file doesn't exists then we cannot return metadata for the file.
|
||||||
// This will occur if the user refernced a declared module for which no file
|
// This will occur if the user refernced a declared module for which no file
|
||||||
// exists for the module (i.e. jQuery or angularjs).
|
// exists for the module (i.e. jQuery or angularjs).
|
||||||
@ -186,7 +186,7 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
|||||||
}
|
}
|
||||||
if (DTS.test(filePath)) {
|
if (DTS.test(filePath)) {
|
||||||
const metadataPath = filePath.replace(DTS, '.metadata.json');
|
const metadataPath = filePath.replace(DTS, '.metadata.json');
|
||||||
if (this.context.exists(metadataPath)) {
|
if (this.context.fileExists(metadataPath)) {
|
||||||
return this.readMetadata(metadataPath);
|
return this.readMetadata(metadataPath);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -200,7 +200,7 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
|||||||
|
|
||||||
readMetadata(filePath: string) {
|
readMetadata(filePath: string) {
|
||||||
try {
|
try {
|
||||||
const result = JSON.parse(this.context.read(filePath));
|
const result = JSON.parse(this.context.readFile(filePath));
|
||||||
return result;
|
return result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Failed to read JSON file ${filePath}`);
|
console.error(`Failed to read JSON file ${filePath}`);
|
||||||
@ -210,9 +210,21 @@ export class ReflectorHost implements StaticReflectorHost, ImportGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class NodeReflectorHostContext implements ReflectorHostContext {
|
export class NodeReflectorHostContext implements ReflectorHostContext {
|
||||||
exists(fileName: string): boolean { return fs.existsSync(fileName); }
|
private assumedExists: {[fileName: string]: boolean} = {};
|
||||||
|
|
||||||
read(fileName: string): string { return fs.readFileSync(fileName, 'utf8'); }
|
fileExists(fileName: string): boolean {
|
||||||
|
return this.assumedExists[fileName] || fs.existsSync(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
write(fileName: string, data: string): void { fs.writeFileSync(fileName, data, 'utf8'); }
|
directoryExists(directoryName: string): boolean {
|
||||||
|
try {
|
||||||
|
return fs.statSync(directoryName).isDirectory();
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readFile(fileName: string): string { return fs.readFileSync(fileName, 'utf8'); }
|
||||||
|
|
||||||
|
assumeFileExists(fileName: string): void { this.assumedExists[fileName] = true; }
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,11 @@ export interface Directory { [name: string]: Entry; }
|
|||||||
export class MockContext implements ReflectorHostContext {
|
export class MockContext implements ReflectorHostContext {
|
||||||
constructor(public currentDirectory: string, private files: Entry) {}
|
constructor(public currentDirectory: string, private files: Entry) {}
|
||||||
|
|
||||||
exists(fileName: string): boolean { return this.getEntry(fileName) !== undefined; }
|
fileExists(fileName: string): boolean { return typeof this.getEntry(fileName) === 'string'; }
|
||||||
|
|
||||||
read(fileName: string): string|undefined {
|
directoryExists(path: string): boolean { return typeof this.getEntry(path) === 'object' }
|
||||||
|
|
||||||
|
readFile(fileName: string): string|undefined {
|
||||||
let data = this.getEntry(fileName);
|
let data = this.getEntry(fileName);
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
return data;
|
return data;
|
||||||
@ -27,7 +29,7 @@ export class MockContext implements ReflectorHostContext {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
write(fileName: string, data: string): void {
|
writeFile(fileName: string, data: string): void {
|
||||||
let parts = fileName.split('/');
|
let parts = fileName.split('/');
|
||||||
let name = parts.pop();
|
let name = parts.pop();
|
||||||
let entry = this.getEntry(parts);
|
let entry = this.getEntry(parts);
|
||||||
@ -36,6 +38,8 @@ export class MockContext implements ReflectorHostContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assumeFileExists(fileName: string): void { this.writeFile(fileName, ''); }
|
||||||
|
|
||||||
getEntry(fileName: string|string[]): Entry|undefined {
|
getEntry(fileName: string|string[]): Entry|undefined {
|
||||||
let parts = typeof fileName === 'string' ? fileName.split('/') : fileName;
|
let parts = typeof fileName === 'string' ? fileName.split('/') : fileName;
|
||||||
if (parts[0]) {
|
if (parts[0]) {
|
||||||
@ -79,16 +83,18 @@ function normalize(parts: string[]): string[] {
|
|||||||
export class MockCompilerHost implements ts.CompilerHost {
|
export class MockCompilerHost implements ts.CompilerHost {
|
||||||
constructor(private context: MockContext) {}
|
constructor(private context: MockContext) {}
|
||||||
|
|
||||||
fileExists(fileName: string): boolean { return this.context.exists(fileName); }
|
fileExists(fileName: string): boolean { return this.context.fileExists(fileName); }
|
||||||
|
|
||||||
readFile(fileName: string): string { return this.context.read(fileName); }
|
readFile(fileName: string): string { return this.context.readFile(fileName); }
|
||||||
|
|
||||||
directoryExists(directoryName: string): boolean { return this.context.exists(directoryName); }
|
directoryExists(directoryName: string): boolean {
|
||||||
|
return this.context.directoryExists(directoryName);
|
||||||
|
}
|
||||||
|
|
||||||
getSourceFile(
|
getSourceFile(
|
||||||
fileName: string, languageVersion: ts.ScriptTarget,
|
fileName: string, languageVersion: ts.ScriptTarget,
|
||||||
onError?: (message: string) => void): ts.SourceFile {
|
onError?: (message: string) => void): ts.SourceFile {
|
||||||
let sourceText = this.context.read(fileName);
|
let sourceText = this.context.readFile(fileName);
|
||||||
if (sourceText) {
|
if (sourceText) {
|
||||||
return ts.createSourceFile(fileName, sourceText, languageVersion);
|
return ts.createSourceFile(fileName, sourceText, languageVersion);
|
||||||
} else {
|
} else {
|
||||||
@ -100,7 +106,7 @@ export class MockCompilerHost implements ts.CompilerHost {
|
|||||||
return ts.getDefaultLibFileName(options);
|
return ts.getDefaultLibFileName(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFile: ts.WriteFileCallback = (fileName, text) => { this.context.write(fileName, text); }
|
writeFile: ts.WriteFileCallback = (fileName, text) => { this.context.writeFile(fileName, text); }
|
||||||
|
|
||||||
getCurrentDirectory(): string {
|
getCurrentDirectory(): string {
|
||||||
return this.context.currentDirectory;
|
return this.context.currentDirectory;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user