Skip to content

Commit ff23748

Browse files
committed
Merge pull request #1131 from Microsoft/relativePathReferenceResolution
Fix the relative path reference resolution
2 parents d11660c + 7d103a1 commit ff23748

File tree

67 files changed

+555
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+555
-26
lines changed

src/compiler/core.ts

+4
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,10 @@ module ts {
459459
return normalizedPathComponents(path, rootLength);
460460
}
461461

462+
export function getNormalizedAbsolutePath(filename: string, currentDirectory: string) {
463+
return getNormalizedPathFromPathComponents(getNormalizedPathComponents(filename, currentDirectory));
464+
}
465+
462466
export function getNormalizedPathFromPathComponents(pathComponents: string[]) {
463467
if (pathComponents && pathComponents.length) {
464468
return pathComponents[0] + pathComponents.slice(1).join(directorySeparator);

src/compiler/emitter.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ module ts {
5757
var newLine = program.getCompilerHost().getNewLine();
5858

5959
function getSourceFilePathInNewDir(newDirPath: string, sourceFile: SourceFile) {
60-
var sourceFilePath = getNormalizedPathFromPathComponents(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory()));
60+
var sourceFilePath = getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory());
6161
sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), "");
6262
return combinePaths(newDirPath, sourceFilePath);
6363
}
@@ -3430,11 +3430,6 @@ module ts {
34303430
}
34313431
}
34323432

3433-
function tryResolveScriptReference(sourceFile: SourceFile, reference: FileReference) {
3434-
var referenceFileName = normalizePath(combinePaths(getDirectoryPath(sourceFile.filename), reference.filename));
3435-
return program.getSourceFile(referenceFileName);
3436-
}
3437-
34383433
// Contains the reference paths that needs to go in the declaration file.
34393434
// Collecting this separately because reference paths need to be first thing in the declaration file
34403435
// and we could be collecting these paths from multiple files into single one with --out option
@@ -3461,7 +3456,7 @@ module ts {
34613456
if (!compilerOptions.noResolve) {
34623457
var addedGlobalFileReference = false;
34633458
forEach(root.referencedFiles, fileReference => {
3464-
var referencedFile = tryResolveScriptReference(root, fileReference);
3459+
var referencedFile = tryResolveScriptReference(program, root, fileReference);
34653460

34663461
// All the references that are not going to be part of same file
34673462
if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference
@@ -3486,7 +3481,7 @@ module ts {
34863481
// Check what references need to be added
34873482
if (!compilerOptions.noResolve) {
34883483
forEach(sourceFile.referencedFiles, fileReference => {
3489-
var referencedFile = tryResolveScriptReference(sourceFile, fileReference);
3484+
var referencedFile = tryResolveScriptReference(program, sourceFile, fileReference);
34903485

34913486
// If the reference file is a declaration file or an external module, emit that reference
34923487
if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) &&

src/compiler/parser.ts

+31-5
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,14 @@ module ts {
643643
return false;
644644
}
645645

646+
export function tryResolveScriptReference(program: Program, sourceFile: SourceFile, reference: FileReference) {
647+
if (!program.getCompilerOptions().noResolve) {
648+
var referenceFileName = isRootedDiskPath(reference.filename) ? reference.filename : combinePaths(getDirectoryPath(sourceFile.filename), reference.filename);
649+
referenceFileName = getNormalizedAbsolutePath(referenceFileName, program.getCompilerHost().getCurrentDirectory());
650+
return program.getSourceFile(referenceFileName);
651+
}
652+
}
653+
646654
export function getAncestor(node: Node, kind: SyntaxKind): Node {
647655
switch (kind) {
648656
// special-cases that can be come first
@@ -4695,20 +4703,26 @@ module ts {
46954703
var canonicalName = host.getCanonicalFileName(filename);
46964704
if (hasProperty(filesByName, canonicalName)) {
46974705
// We've already looked for this file, use cached result
4698-
var file = filesByName[canonicalName];
4699-
if (file && host.useCaseSensitiveFileNames() && canonicalName !== file.filename) {
4700-
errors.push(createFileDiagnostic(refFile, refStart, refLength,
4701-
Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, file.filename));
4702-
}
4706+
return getSourceFileFromCache(filename, canonicalName, /*useAbsolutePath*/ false);
47034707
}
47044708
else {
4709+
var normalizedAbsolutePath = getNormalizedAbsolutePath(filename, host.getCurrentDirectory());
4710+
var canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath);
4711+
if (hasProperty(filesByName, canonicalAbsolutePath)) {
4712+
return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true);
4713+
}
4714+
47054715
// We haven't looked for this file, do so now and cache result
47064716
var file = filesByName[canonicalName] = host.getSourceFile(filename, options.target, hostErrorMessage => {
47074717
errors.push(createFileDiagnostic(refFile, refStart, refLength,
47084718
Diagnostics.Cannot_read_file_0_Colon_1, filename, hostErrorMessage));
47094719
});
47104720
if (file) {
47114721
seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib;
4722+
4723+
// Set the source file for normalized absolute path
4724+
filesByName[canonicalAbsolutePath] = file;
4725+
47124726
if (!options.noResolve) {
47134727
var basePath = getDirectoryPath(filename);
47144728
processReferencedFiles(file, basePath);
@@ -4726,6 +4740,18 @@ module ts {
47264740
}
47274741
}
47284742
return file;
4743+
4744+
function getSourceFileFromCache(filename: string, canonicalName: string, useAbsolutePath: boolean): SourceFile {
4745+
var file = filesByName[canonicalName];
4746+
if (file && host.useCaseSensitiveFileNames()) {
4747+
var sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.filename, host.getCurrentDirectory()) : file.filename;
4748+
if (canonicalName !== sourceFileName) {
4749+
errors.push(createFileDiagnostic(refFile, refStart, refLength,
4750+
Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, sourceFileName));
4751+
}
4752+
}
4753+
return file;
4754+
}
47294755
}
47304756

47314757
function processReferencedFiles(file: SourceFile, basePath: string) {

src/harness/harness.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,7 @@ module Harness {
866866
var sourceFileName: string;
867867
if (ts.isExternalModule(sourceFile) || !options.out) {
868868
if (options.outDir) {
869-
var sourceFilePath = ts.getNormalizedPathFromPathComponents(ts.getNormalizedPathComponents(sourceFile.filename, result.currentDirectoryForProgram));
869+
var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, result.currentDirectoryForProgram);
870870
sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), "");
871871
sourceFileName = ts.combinePaths(options.outDir, sourceFilePath);
872872
}

src/harness/projectsRunner.ts

+34-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface ProjectRunnerTestCase {
1717
baselineCheck?: boolean; // Verify the baselines of output files, if this is false, we will write to output to the disk but there is no verification of baselines
1818
runTest?: boolean; // Run the resulting test
1919
bug?: string; // If there is any bug associated with this test case
20+
noResolve?: boolean;
2021
}
2122

2223
interface ProjectRunnerTestCaseResolutionInfo extends ProjectRunnerTestCase {
@@ -162,7 +163,8 @@ class ProjectRunner extends RunnerBase {
162163
outDir: testCase.outDir,
163164
mapRoot: testCase.resolveMapRoot && testCase.mapRoot ? sys.resolvePath(testCase.mapRoot) : testCase.mapRoot,
164165
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot ? sys.resolvePath(testCase.sourceRoot) : testCase.sourceRoot,
165-
module: moduleKind
166+
module: moduleKind,
167+
noResolve: testCase.noResolve
166168
};
167169
}
168170

@@ -272,16 +274,40 @@ class ProjectRunner extends RunnerBase {
272274
}
273275

274276
function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) {
275-
var inputDtsSourceFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(),
276-
sourceFile => Harness.Compiler.isDTS(sourceFile.filename)),
277-
sourceFile => {
278-
return { emittedFileName: sourceFile.filename, code: sourceFile.text };
279-
});
277+
var allInputFiles: { emittedFileName: string; code: string; }[] = [];
278+
var compilerOptions = compilerResult.program.getCompilerOptions();
279+
var compilerHost = compilerResult.program.getCompilerHost();
280+
ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => {
281+
if (Harness.Compiler.isDTS(sourceFile.filename)) {
282+
allInputFiles.unshift({ emittedFileName: sourceFile.filename, code: sourceFile.text });
283+
}
284+
else if (ts.shouldEmitToOwnFile(sourceFile, compilerResult.program.getCompilerOptions())) {
285+
if (compilerOptions.outDir) {
286+
var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory());
287+
sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), "");
288+
var emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath));
289+
}
290+
else {
291+
var emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.filename);
292+
}
293+
294+
var outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts";
295+
allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName));
296+
}
297+
else {
298+
var outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts";
299+
var outputDtsFile = findOutpuDtsFile(outputDtsFileName);
300+
if (!ts.contains(allInputFiles, outputDtsFile)) {
301+
allInputFiles.unshift(outputDtsFile);
302+
}
303+
}
304+
});
280305

281-
var ouputDtsFiles = ts.filter(compilerResult.outputFiles, ouputFile => Harness.Compiler.isDTS(ouputFile.emittedFileName));
282-
var allInputFiles = inputDtsSourceFiles.concat(ouputDtsFiles);
283306
return compileProjectFiles(compilerResult.moduleKind,getInputFiles, getSourceFileText, writeFile);
284307

308+
function findOutpuDtsFile(fileName: string) {
309+
return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined);
310+
}
285311
function getInputFiles() {
286312
return ts.map(allInputFiles, outputFile => outputFile.emittedFileName);
287313
}

src/services/services.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -3332,11 +3332,10 @@ module ts {
33323332
/// Triple slash reference comments
33333333
var comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined);
33343334
if (comment) {
3335-
var targetFilename = isRootedDiskPath(comment.filename) ? comment.filename : combinePaths(getDirectoryPath(filename), comment.filename);
3336-
targetFilename = normalizePath(targetFilename);
3337-
if (program.getSourceFile(targetFilename)) {
3335+
var referenceFile = tryResolveScriptReference(program, sourceFile, comment);
3336+
if (referenceFile) {
33383337
return [{
3339-
fileName: targetFilename,
3338+
fileName: referenceFile.filename,
33403339
textSpan: TextSpan.fromBounds(0, 0),
33413340
kind: ScriptElementKind.scriptElement,
33423341
name: comment.filename,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="../src/ts/foo/foo.ts" />
2+
// This is bar.ts
3+
var bar = (function () {
4+
function bar() {
5+
}
6+
return bar;
7+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../src/ts/foo/foo.d.ts" />
2+
declare class bar {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../../../bar/bar.d.ts" />
2+
declare class foo {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference path="../../../bar/bar.ts" />
2+
var foo = (function () {
3+
function foo() {
4+
}
5+
return foo;
6+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"scenario": "referenceResolution1_FromFooFolder",
3+
"projectRoot": "tests/cases/projects/ReferenceResolution/src/ts/foo",
4+
"inputFiles": [
5+
"foo.ts"
6+
],
7+
"declaration": true,
8+
"baselineCheck": true,
9+
"resolvedInputFiles": [
10+
"lib.d.ts",
11+
"../../../bar/bar.ts",
12+
"foo.ts"
13+
],
14+
"emittedFiles": [
15+
"../../../bar/bar.js",
16+
"../../../bar/bar.d.ts",
17+
"foo.js",
18+
"foo.d.ts"
19+
]
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="../src/ts/foo/foo.ts" />
2+
// This is bar.ts
3+
var bar = (function () {
4+
function bar() {
5+
}
6+
return bar;
7+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../src/ts/foo/foo.d.ts" />
2+
declare class bar {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../../../bar/bar.d.ts" />
2+
declare class foo {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference path="../../../bar/bar.ts" />
2+
var foo = (function () {
3+
function foo() {
4+
}
5+
return foo;
6+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"scenario": "referenceResolution1_FromFooFolder",
3+
"projectRoot": "tests/cases/projects/ReferenceResolution/src/ts/foo",
4+
"inputFiles": [
5+
"foo.ts"
6+
],
7+
"declaration": true,
8+
"baselineCheck": true,
9+
"resolvedInputFiles": [
10+
"lib.d.ts",
11+
"../../../bar/bar.ts",
12+
"foo.ts"
13+
],
14+
"emittedFiles": [
15+
"../../../bar/bar.js",
16+
"../../../bar/bar.d.ts",
17+
"foo.js",
18+
"foo.d.ts"
19+
]
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../src/ts/foo/foo.d.ts" />
2+
declare class bar {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="../src/ts/foo/foo.ts" />
2+
// This is bar.ts
3+
var bar = (function () {
4+
function bar() {
5+
}
6+
return bar;
7+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"scenario": "referenceResolution1_FromRootDirectory",
3+
"projectRoot": "tests/cases/projects/ReferenceResolution",
4+
"inputFiles": [
5+
"src/ts/foo/foo.ts"
6+
],
7+
"declaration": true,
8+
"baselineCheck": true,
9+
"resolvedInputFiles": [
10+
"lib.d.ts",
11+
"bar/bar.ts",
12+
"src/ts/foo/foo.ts"
13+
],
14+
"emittedFiles": [
15+
"bar/bar.js",
16+
"bar/bar.d.ts",
17+
"src/ts/foo/foo.js",
18+
"src/ts/foo/foo.d.ts"
19+
]
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../../../bar/bar.d.ts" />
2+
declare class foo {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference path="../../../bar/bar.ts" />
2+
var foo = (function () {
3+
function foo() {
4+
}
5+
return foo;
6+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../src/ts/foo/foo.d.ts" />
2+
declare class bar {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="../src/ts/foo/foo.ts" />
2+
// This is bar.ts
3+
var bar = (function () {
4+
function bar() {
5+
}
6+
return bar;
7+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"scenario": "referenceResolution1_FromRootDirectory",
3+
"projectRoot": "tests/cases/projects/ReferenceResolution",
4+
"inputFiles": [
5+
"src/ts/foo/foo.ts"
6+
],
7+
"declaration": true,
8+
"baselineCheck": true,
9+
"resolvedInputFiles": [
10+
"lib.d.ts",
11+
"bar/bar.ts",
12+
"src/ts/foo/foo.ts"
13+
],
14+
"emittedFiles": [
15+
"bar/bar.js",
16+
"bar/bar.d.ts",
17+
"src/ts/foo/foo.js",
18+
"src/ts/foo/foo.d.ts"
19+
]
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="../../../bar/bar.d.ts" />
2+
declare class foo {
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference path="../../../bar/bar.ts" />
2+
var foo = (function () {
3+
function foo() {
4+
}
5+
return foo;
6+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/// <reference path="../src/ts/foo/foo.ts" />
2+
// This is bar.ts
3+
var bar = (function () {
4+
function bar() {
5+
}
6+
return bar;
7+
})();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare class bar {
2+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
declare class foo {
2+
}

0 commit comments

Comments
 (0)