Skip to content

Commit b8a3564

Browse files
committed
use absolute path as key to store files, correctly handle scenarios when file names differ only in casing
1 parent 302db0a commit b8a3564

7 files changed

Lines changed: 244 additions & 123 deletions

File tree

src/compiler/commandLineParser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,12 @@ namespace ts {
247247
},
248248
description: Diagnostics.Specifies_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
249249
error: Diagnostics.Argument_for_moduleResolution_option_must_be_node_or_classic,
250-
}
250+
},
251+
{
252+
name: "forceConsistentCasingInFileNames",
253+
type: "boolean",
254+
description: Diagnostics.Raise_error_if_two_file_names_in_program_differ_only_in_case
255+
},
251256
];
252257

253258
/* @internal */

src/compiler/diagnosticMessages.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,6 +2298,10 @@
22982298
"category": "Message",
22992299
"code": 6072
23002300
},
2301+
"Raise error if two file names in program differ only in case.": {
2302+
"category": "Message",
2303+
"code": 6073
2304+
},
23012305

23022306
"Variable '{0}' implicitly has an '{1}' type.": {
23032307
"category": "Error",

src/compiler/program.ts

Lines changed: 66 additions & 56 deletions
Large diffs are not rendered by default.

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,7 @@ namespace ts {
20882088
experimentalDecorators?: boolean;
20892089
emitDecoratorMetadata?: boolean;
20902090
moduleResolution?: ModuleResolutionKind;
2091+
forceConsistentCasingInFileNames?: boolean;
20912092
/* @internal */ stripInternal?: boolean;
20922093

20932094
// Skip checking lib.d.ts to help speed up tests.

src/harness/harness.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -921,7 +921,9 @@ namespace Harness {
921921
function register(file: { unitName: string; content: string; }) {
922922
if (file.content !== undefined) {
923923
let fileName = ts.normalizePath(file.unitName);
924-
filemap[getCanonicalFileName(fileName)] = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
924+
const sourceFile = createSourceFileAndAssertInvariants(fileName, file.content, scriptTarget);
925+
filemap[getCanonicalFileName(fileName)] = sourceFile;
926+
filemap[getCanonicalFileName(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()))] = sourceFile;
925927
}
926928
};
927929
inputFiles.forEach(register);

src/harness/projectsRunner.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class ProjectRunner extends RunnerBase {
127127
}
128128

129129
function compileProjectFiles(moduleKind: ts.ModuleKind, getInputFiles: () => string[],
130-
getSourceFileText: (fileName: string) => string,
130+
getSourceFileTextImpl: (fileName: string) => string,
131131
writeFile: (fileName: string, data: string, writeByteOrderMark: boolean) => void): CompileProjectFilesResult {
132132

133133
let program = ts.createProgram(getInputFiles(), createCompilerOptions(), createCompilerHost());
@@ -170,6 +170,11 @@ class ProjectRunner extends RunnerBase {
170170
};
171171
}
172172

173+
function getSourceFileText(fileName: string): string {
174+
const text = getSourceFileTextImpl(fileName);
175+
return text !== undefined ? text : getSourceFileTextImpl(ts.getNormalizedAbsolutePath(fileName, getCurrentDirectory()));
176+
}
177+
173178
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget): ts.SourceFile {
174179
let sourceFile: ts.SourceFile = undefined;
175180
if (fileName === Harness.Compiler.defaultLibFileName) {
@@ -194,7 +199,7 @@ class ProjectRunner extends RunnerBase {
194199
getCanonicalFileName: Harness.Compiler.getCanonicalFileName,
195200
useCaseSensitiveFileNames: () => Harness.IO.useCaseSensitiveFileNames(),
196201
getNewLine: () => Harness.IO.newLine(),
197-
fileExists: fileName => getSourceFile(fileName, ts.ScriptTarget.ES5) !== undefined,
202+
fileExists: fileName => fileName === Harness.Compiler.defaultLibFileName || getSourceFileText(fileName) !== undefined,
198203
readFile: fileName => Harness.IO.readFile(fileName)
199204
};
200205
}
@@ -318,7 +323,16 @@ class ProjectRunner extends RunnerBase {
318323
return ts.map(allInputFiles, outputFile => outputFile.emittedFileName);
319324
}
320325
function getSourceFileText(fileName: string): string {
321-
return ts.forEach(allInputFiles, inputFile => inputFile.emittedFileName === fileName ? inputFile.code : undefined);
326+
for (const inputFile of allInputFiles) {
327+
const isMatchingFile = ts.isRootedDiskPath(fileName)
328+
? ts.getNormalizedAbsolutePath(inputFile.emittedFileName, getCurrentDirectory()) === fileName
329+
: inputFile.emittedFileName === fileName;
330+
331+
if (isMatchingFile) {
332+
return inputFile.code;
333+
}
334+
}
335+
return undefined;
322336
}
323337

324338
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {

0 commit comments

Comments
 (0)