From 63a20863c1de137b9c97d86199de6a802ee184d9 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Tue, 11 Nov 2014 22:58:47 -0800 Subject: [PATCH] Fix the relative path reference resolution Fixes #1039 --- src/compiler/core.ts | 4 ++ src/compiler/emitter.ts | 11 ++--- src/compiler/parser.ts | 39 +++++++++++++--- src/harness/harness.ts | 2 +- src/harness/projectsRunner.ts | 44 ++++++++++++++++--- src/services/services.ts | 7 ++- .../amd/FieldManager.d.ts | 3 ++ .../amd/diskFile1.d.ts | 3 ++ ...eferenceResolutionRelativePaths.errors.txt | 23 ---------- .../amd/referenceResolutionRelativePaths.json | 6 +-- .../node/FieldManager.d.ts | 3 ++ .../node/diskFile1.d.ts | 3 ++ ...eferenceResolutionRelativePaths.errors.txt | 23 ---------- .../referenceResolutionRelativePaths.json | 6 +-- 14 files changed, 100 insertions(+), 77 deletions(-) create mode 100644 tests/baselines/reference/project/referenceResolutionRelativePaths/amd/FieldManager.d.ts create mode 100644 tests/baselines/reference/project/referenceResolutionRelativePaths/amd/diskFile1.d.ts delete mode 100644 tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.errors.txt create mode 100644 tests/baselines/reference/project/referenceResolutionRelativePaths/node/FieldManager.d.ts create mode 100644 tests/baselines/reference/project/referenceResolutionRelativePaths/node/diskFile1.d.ts delete mode 100644 tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.errors.txt diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e512688fee..4b412d051d 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -459,6 +459,10 @@ module ts { return normalizedPathComponents(path, rootLength); } + export function getNormalizedAbsolutePath(filename: string, currentDirectory: string) { + return getNormalizedPathFromPathComponents(getNormalizedPathComponents(filename, currentDirectory)); + } + export function getNormalizedPathFromPathComponents(pathComponents: string[]) { if (pathComponents && pathComponents.length) { return pathComponents[0] + pathComponents.slice(1).join(directorySeparator); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index f61d4403ee..eb423e214a 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -57,7 +57,7 @@ module ts { var newLine = program.getCompilerHost().getNewLine(); function getSourceFilePathInNewDir(newDirPath: string, sourceFile: SourceFile) { - var sourceFilePath = getNormalizedPathFromPathComponents(getNormalizedPathComponents(sourceFile.filename, compilerHost.getCurrentDirectory())); + var sourceFilePath = getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory()); sourceFilePath = sourceFilePath.replace(program.getCommonSourceDirectory(), ""); return combinePaths(newDirPath, sourceFilePath); } @@ -3370,11 +3370,6 @@ module ts { } } - function tryResolveScriptReference(sourceFile: SourceFile, reference: FileReference) { - var referenceFileName = normalizePath(combinePaths(getDirectoryPath(sourceFile.filename), reference.filename)); - return program.getSourceFile(referenceFileName); - } - // Contains the reference paths that needs to go in the declaration file. // Collecting this separately because reference paths need to be first thing in the declaration file // and we could be collecting these paths from multiple files into single one with --out option @@ -3401,7 +3396,7 @@ module ts { if (!compilerOptions.noResolve) { var addedGlobalFileReference = false; forEach(root.referencedFiles, fileReference => { - var referencedFile = tryResolveScriptReference(root, fileReference); + var referencedFile = tryResolveScriptReference(program, root, fileReference); // All the references that are not going to be part of same file if (referencedFile && ((referencedFile.flags & NodeFlags.DeclarationFile) || // This is a declare file reference @@ -3426,7 +3421,7 @@ module ts { // Check what references need to be added if (!compilerOptions.noResolve) { forEach(sourceFile.referencedFiles, fileReference => { - var referencedFile = tryResolveScriptReference(sourceFile, fileReference); + var referencedFile = tryResolveScriptReference(program, sourceFile, fileReference); // If the reference file is a declaration file or an external module, emit that reference if (referencedFile && (isExternalModuleOrDeclarationFile(referencedFile) && diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4849cb8c89..df557cef59 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -634,6 +634,15 @@ module ts { return false; } + export function tryResolveScriptReference(program: Program, sourceFile: SourceFile, reference: FileReference) { + var referenceFileName = isRootedDiskPath(reference.filename) ? reference.filename : combinePaths(getDirectoryPath(sourceFile.filename), reference.filename); + referenceFileName = normalizePath(referenceFileName); + if (!program.getCompilerOptions().noResolve) { + referenceFileName = getNormalizedAbsolutePath(referenceFileName, program.getCompilerHost().getCurrentDirectory()); + } + return program.getSourceFile(referenceFileName); + } + export function getAncestor(node: Node, kind: SyntaxKind): Node { switch (kind) { // special-cases that can be come first @@ -4373,13 +4382,18 @@ module ts { var canonicalName = host.getCanonicalFileName(filename); if (hasProperty(filesByName, canonicalName)) { // We've already looked for this file, use cached result - var file = filesByName[canonicalName]; - if (file && host.useCaseSensitiveFileNames() && canonicalName !== file.filename) { - errors.push(createFileDiagnostic(refFile, refStart, refLength, - Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, file.filename)); - } + return getSourceFileFromCache(filename, canonicalName, /*useAbsolutePath*/ false); } else { + // if --noResolve is not specified check if we have file for absolute path + if (!options.noResolve) { + var normalizedAbsolutePath = getNormalizedAbsolutePath(filename, host.getCurrentDirectory()); + var canonicalAbsolutePath = host.getCanonicalFileName(normalizedAbsolutePath); + if (hasProperty(filesByName, canonicalAbsolutePath)) { + return getSourceFileFromCache(normalizedAbsolutePath, canonicalAbsolutePath, /*useAbsolutePath*/ true); + } + } + // We haven't looked for this file, do so now and cache result var file = filesByName[canonicalName] = host.getSourceFile(filename, options.target, hostErrorMessage => { errors.push(createFileDiagnostic(refFile, refStart, refLength, @@ -4388,6 +4402,9 @@ module ts { if (file) { seenNoDefaultLib = seenNoDefaultLib || file.hasNoDefaultLib; if (!options.noResolve) { + // Set the source file for normalized absolute path + filesByName[canonicalAbsolutePath] = file; + var basePath = getDirectoryPath(filename); processReferencedFiles(file, basePath); processImportedModules(file, basePath); @@ -4404,6 +4421,18 @@ module ts { } } return file; + + function getSourceFileFromCache(filename: string, canonicalName: string, useAbsolutePath: boolean): SourceFile { + var file = filesByName[canonicalName]; + if (file && host.useCaseSensitiveFileNames()) { + var sourceFileName = useAbsolutePath ? getNormalizedAbsolutePath(file.filename, host.getCurrentDirectory()) : file.filename; + if (canonicalName !== sourceFileName) { + errors.push(createFileDiagnostic(refFile, refStart, refLength, + Diagnostics.Filename_0_differs_from_already_included_filename_1_only_in_casing, filename, sourceFileName)); + } + } + return file; + } } function processReferencedFiles(file: SourceFile, basePath: string) { diff --git a/src/harness/harness.ts b/src/harness/harness.ts index d385dd2afc..bbfc2f5678 100644 --- a/src/harness/harness.ts +++ b/src/harness/harness.ts @@ -863,7 +863,7 @@ module Harness { var sourceFileName: string; if (ts.isExternalModule(sourceFile) || !options.out) { if (options.outDir) { - var sourceFilePath = ts.getNormalizedPathFromPathComponents(ts.getNormalizedPathComponents(sourceFile.filename, result.currentDirectoryForProgram)); + var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, result.currentDirectoryForProgram); sourceFilePath = sourceFilePath.replace(result.program.getCommonSourceDirectory(), ""); sourceFileName = ts.combinePaths(options.outDir, sourceFilePath); } diff --git a/src/harness/projectsRunner.ts b/src/harness/projectsRunner.ts index d0972ac59b..35f71ccd5a 100644 --- a/src/harness/projectsRunner.ts +++ b/src/harness/projectsRunner.ts @@ -274,20 +274,50 @@ class ProjectRunner extends RunnerBase { } function compileCompileDTsFiles(compilerResult: BatchCompileProjectTestCaseResult) { - var inputDtsSourceFiles = ts.map(ts.filter(compilerResult.program.getSourceFiles(), - sourceFile => Harness.Compiler.isDTS(sourceFile.filename)), - sourceFile => { - return { emittedFileName: sourceFile.filename, code: sourceFile.text }; - }); + var allInputFiles: { emittedFileName: string; code: string; }[] = []; + var compilerOptions = compilerResult.program.getCompilerOptions(); + var compilerHost = compilerResult.program.getCompilerHost(); + ts.forEach(compilerResult.program.getSourceFiles(), sourceFile => { + if (Harness.Compiler.isDTS(sourceFile.filename)) { + allInputFiles.unshift({ emittedFileName: sourceFile.filename, code: sourceFile.text }); + } + else if (ts.shouldEmitToOwnFile(sourceFile, compilerResult.program.getCompilerOptions())) { + if (compilerOptions.outDir) { + var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.filename, compilerHost.getCurrentDirectory()); + sourceFilePath = sourceFilePath.replace(compilerResult.program.getCommonSourceDirectory(), ""); + var emitOutputFilePathWithoutExtension = ts.removeFileExtension(ts.combinePaths(compilerOptions.outDir, sourceFilePath)); + } + else { + var emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.filename); + } + + var outputDtsFileName = emitOutputFilePathWithoutExtension + ".d.ts"; + allInputFiles.unshift(findOutpuDtsFile(outputDtsFileName)); + } + else { + var outputDtsFileName = ts.removeFileExtension(compilerOptions.out) + ".d.ts"; + var outputDtsFile = findOutpuDtsFile(outputDtsFileName); + if (!ts.contains(allInputFiles, outputDtsFile)) { + allInputFiles.unshift(outputDtsFile); + } + } + }); + + console.log("inputFiles"); + ts.forEach(allInputFiles, inputFile => { + console.log(inputFile.emittedFileName); + }); - var ouputDtsFiles = ts.filter(compilerResult.outputFiles, ouputFile => Harness.Compiler.isDTS(ouputFile.emittedFileName)); - var allInputFiles = inputDtsSourceFiles.concat(ouputDtsFiles); return compileProjectFiles(compilerResult.moduleKind,getInputFiles, getSourceFileText, writeFile); + function findOutpuDtsFile(fileName: string) { + return ts.forEach(compilerResult.outputFiles, outputFile => outputFile.emittedFileName === fileName ? outputFile : undefined); + } function getInputFiles() { return ts.map(allInputFiles, outputFile => outputFile.emittedFileName); } function getSourceFileText(filename: string): string { + console.log("Reading: " + filename + ": " + (ts.forEach(allInputFiles, inputFile => inputFile.emittedFileName === filename ? inputFile.code : undefined) !== undefined)); return ts.forEach(allInputFiles, inputFile => inputFile.emittedFileName === filename ? inputFile.code : undefined); } diff --git a/src/services/services.ts b/src/services/services.ts index 800d63738f..0c1ffff3e7 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3383,11 +3383,10 @@ module ts { /// Triple slash reference comments var comment = forEach(sourceFile.referencedFiles, r => (r.pos <= position && position < r.end) ? r : undefined); if (comment) { - var targetFilename = isRootedDiskPath(comment.filename) ? comment.filename : combinePaths(getDirectoryPath(filename), comment.filename); - targetFilename = normalizePath(targetFilename); - if (program.getSourceFile(targetFilename)) { + var referenceFile = tryResolveScriptReference(program, sourceFile, comment); + if (referenceFile) { return [{ - fileName: targetFilename, + fileName: referenceFile.filename, textSpan: TypeScript.TextSpan.fromBounds(0, 0), kind: ScriptElementKind.scriptElement, name: comment.filename, diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/FieldManager.d.ts b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/FieldManager.d.ts new file mode 100644 index 0000000000..aee3544dd2 --- /dev/null +++ b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/FieldManager.d.ts @@ -0,0 +1,3 @@ +/// +declare class FieldManager { +} diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/diskFile1.d.ts b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/diskFile1.d.ts new file mode 100644 index 0000000000..d2cfdf658e --- /dev/null +++ b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/diskFile1.d.ts @@ -0,0 +1,3 @@ +/// +declare class tsd { +} diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.errors.txt b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.errors.txt deleted file mode 100644 index 3cca49932b..0000000000 --- a/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -../../../src/ts/Manager/FieldManager.ts(3,7): error TS2300: Duplicate identifier 'FieldManager'. -FieldManager.ts(3,7): error TS2300: Duplicate identifier 'FieldManager'. - - -==== ../../../src/ts/Manager/FieldManager.ts (1 errors) ==== - /// - - class FieldManager { - ~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier 'FieldManager'. - } -==== ../../../typings/tsd.ts (0 errors) ==== - /// - // This is tsd.ts - class tsd { - } -==== FieldManager.ts (1 errors) ==== - /// - - class FieldManager { - ~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier 'FieldManager'. - } \ No newline at end of file diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.json b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.json index 3d5aadcd5b..c757106757 100644 --- a/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.json +++ b/tests/baselines/reference/project/referenceResolutionRelativePaths/amd/referenceResolutionRelativePaths.json @@ -8,13 +8,13 @@ "baselineCheck": true, "resolvedInputFiles": [ "lib.d.ts", - "../../../src/ts/Manager/FieldManager.ts", "../../../typings/tsd.ts", "FieldManager.ts" ], "emittedFiles": [ - "../../../src/ts/Manager/FieldManager.js", "../../../typings/tsd.js", - "FieldManager.js" + "../../../typings/tsd.d.ts", + "FieldManager.js", + "FieldManager.d.ts" ] } \ No newline at end of file diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/node/FieldManager.d.ts b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/FieldManager.d.ts new file mode 100644 index 0000000000..aee3544dd2 --- /dev/null +++ b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/FieldManager.d.ts @@ -0,0 +1,3 @@ +/// +declare class FieldManager { +} diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/node/diskFile1.d.ts b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/diskFile1.d.ts new file mode 100644 index 0000000000..d2cfdf658e --- /dev/null +++ b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/diskFile1.d.ts @@ -0,0 +1,3 @@ +/// +declare class tsd { +} diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.errors.txt b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.errors.txt deleted file mode 100644 index 3cca49932b..0000000000 --- a/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.errors.txt +++ /dev/null @@ -1,23 +0,0 @@ -../../../src/ts/Manager/FieldManager.ts(3,7): error TS2300: Duplicate identifier 'FieldManager'. -FieldManager.ts(3,7): error TS2300: Duplicate identifier 'FieldManager'. - - -==== ../../../src/ts/Manager/FieldManager.ts (1 errors) ==== - /// - - class FieldManager { - ~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier 'FieldManager'. - } -==== ../../../typings/tsd.ts (0 errors) ==== - /// - // This is tsd.ts - class tsd { - } -==== FieldManager.ts (1 errors) ==== - /// - - class FieldManager { - ~~~~~~~~~~~~ -!!! error TS2300: Duplicate identifier 'FieldManager'. - } \ No newline at end of file diff --git a/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.json b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.json index 3d5aadcd5b..c757106757 100644 --- a/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.json +++ b/tests/baselines/reference/project/referenceResolutionRelativePaths/node/referenceResolutionRelativePaths.json @@ -8,13 +8,13 @@ "baselineCheck": true, "resolvedInputFiles": [ "lib.d.ts", - "../../../src/ts/Manager/FieldManager.ts", "../../../typings/tsd.ts", "FieldManager.ts" ], "emittedFiles": [ - "../../../src/ts/Manager/FieldManager.js", "../../../typings/tsd.js", - "FieldManager.js" + "../../../typings/tsd.d.ts", + "FieldManager.js", + "FieldManager.d.ts" ] } \ No newline at end of file