From 690e69a1e0055f62c05784be90c7622561f3d406 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 20 Jun 2018 15:04:07 -0700 Subject: [PATCH] Fix module specifier case handling for declaration emit --- src/compiler/moduleSpecifiers.ts | 3 +- src/compiler/program.ts | 1 + src/compiler/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 1 + ...ileSystemWithCapsImportTypeDeclarations.js | 66 +++++++++++++++++++ ...stemWithCapsImportTypeDeclarations.symbols | 45 +++++++++++++ ...SystemWithCapsImportTypeDeclarations.types | 47 +++++++++++++ ...ileSystemWithCapsImportTypeDeclarations.ts | 23 +++++++ 8 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.js create mode 100644 tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.symbols create mode 100644 tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.types create mode 100644 tests/cases/compiler/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.ts diff --git a/src/compiler/moduleSpecifiers.ts b/src/compiler/moduleSpecifiers.ts index 3ab03ecbbfcb8..f62e2384ff62f 100644 --- a/src/compiler/moduleSpecifiers.ts +++ b/src/compiler/moduleSpecifiers.ts @@ -140,10 +140,11 @@ namespace ts.moduleSpecifiers { const result = createMap(); if (symlinks) { const currentDirectory = host.getCurrentDirectory ? host.getCurrentDirectory() : ""; + const compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? compareStringsCaseSensitive : compareStringsCaseInsensitive; for (const [resolvedPath, originalPath] of symlinks) { const resolvedParts = getPathComponents(toPath(resolvedPath, currentDirectory, getCanonicalFileName)); const originalParts = getPathComponents(toPath(originalPath, currentDirectory, getCanonicalFileName)); - while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) { + while (compareStrings(resolvedParts[resolvedParts.length - 1], originalParts[originalParts.length - 1]) === Comparison.EqualTo) { resolvedParts.pop(); originalParts.pop(); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 3289271e7c6df..6e273f0bb591b 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -1241,6 +1241,7 @@ namespace ts { readFile: f => host.readFile(f), fileExists: f => host.fileExists(f), ...(host.directoryExists ? { directoryExists: f => host.directoryExists!(f) } : {}), + useCaseSensitiveFileNames: () => host.useCaseSensitiveFileNames(), }; } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b1e52d68bc01e..e727bed1757ec 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4997,6 +4997,7 @@ namespace ts { /* @internal */ export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolutionHost { getSourceFiles(): ReadonlyArray; + useCaseSensitiveFileNames(): boolean; getCurrentDirectory(): string; /* @internal */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 114b2341fa95e..1fc495928bdd0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4236,6 +4236,7 @@ declare namespace ts { } interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolutionHost { getSourceFiles(): ReadonlyArray; + useCaseSensitiveFileNames(): boolean; getCurrentDirectory(): string; isSourceFileFromExternalLibrary(file: SourceFile): boolean; getCommonSourceDirectory(): string; diff --git a/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.js b/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.js new file mode 100644 index 0000000000000..ac6e4b7e13502 --- /dev/null +++ b/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.js @@ -0,0 +1,66 @@ +//// [tests/cases/compiler/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.ts] //// + +//// [index.ts] +import { TypeB } from './type-b'; + +export class Broken { + method () { + return { } as TypeB; + } +} +//// [type-b.ts] +import { Merge } from './types'; +import { TypeA } from './type-a'; + +export type TypeB = Merge; +//// [type-a.ts] +export type TypeA = { + a: string; +} +//// [types.ts] +export type Merge = T & U; + + +//// [types.js] +"use strict"; +exports.__esModule = true; +//// [type-a.js] +"use strict"; +exports.__esModule = true; +//// [type-b.js] +"use strict"; +exports.__esModule = true; +//// [index.js] +"use strict"; +exports.__esModule = true; +var Broken = /** @class */ (function () { + function Broken() { + } + Broken.prototype.method = function () { + return {}; + }; + return Broken; +}()); +exports.Broken = Broken; + + +//// [types.d.ts] +export declare type Merge = T & U; +//// [type-a.d.ts] +export declare type TypeA = { + a: string; +}; +//// [type-b.d.ts] +import { Merge } from './types'; +import { TypeA } from './type-a'; +export declare type TypeB = Merge; +//// [index.d.ts] +export declare class Broken { + method(): import("./types").Merge; +} diff --git a/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.symbols b/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.symbols new file mode 100644 index 0000000000000..2b5c3accb2712 --- /dev/null +++ b/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.symbols @@ -0,0 +1,45 @@ +=== tests/cases/compiler/Uppercased_Dir/src/index.ts === +import { TypeB } from './type-b'; +>TypeB : Symbol(TypeB, Decl(index.ts, 0, 8)) + +export class Broken { +>Broken : Symbol(Broken, Decl(index.ts, 0, 33)) + + method () { +>method : Symbol(Broken.method, Decl(index.ts, 2, 21)) + + return { } as TypeB; +>TypeB : Symbol(TypeB, Decl(index.ts, 0, 8)) + } +} +=== tests/cases/compiler/Uppercased_Dir/src/type-b.ts === +import { Merge } from './types'; +>Merge : Symbol(Merge, Decl(type-b.ts, 0, 8)) + +import { TypeA } from './type-a'; +>TypeA : Symbol(TypeA, Decl(type-b.ts, 1, 8)) + +export type TypeB = MergeTypeB : Symbol(TypeB, Decl(type-b.ts, 1, 33)) +>Merge : Symbol(Merge, Decl(type-b.ts, 0, 8)) +>TypeA : Symbol(TypeA, Decl(type-b.ts, 1, 8)) + + b: string; +>b : Symbol(b, Decl(type-b.ts, 3, 34)) + +}>; +=== tests/cases/compiler/Uppercased_Dir/src/type-a.ts === +export type TypeA = { +>TypeA : Symbol(TypeA, Decl(type-a.ts, 0, 0)) + + a: string; +>a : Symbol(a, Decl(type-a.ts, 0, 21)) +} +=== tests/cases/compiler/Uppercased_Dir/src/types.ts === +export type Merge = T & U; +>Merge : Symbol(Merge, Decl(types.ts, 0, 0)) +>T : Symbol(T, Decl(types.ts, 0, 18)) +>U : Symbol(U, Decl(types.ts, 0, 20)) +>T : Symbol(T, Decl(types.ts, 0, 18)) +>U : Symbol(U, Decl(types.ts, 0, 20)) + diff --git a/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.types b/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.types new file mode 100644 index 0000000000000..59401c34ae720 --- /dev/null +++ b/tests/baselines/reference/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.types @@ -0,0 +1,47 @@ +=== tests/cases/compiler/Uppercased_Dir/src/index.ts === +import { TypeB } from './type-b'; +>TypeB : any + +export class Broken { +>Broken : Broken + + method () { +>method : () => import("tests/cases/compiler/Uppercased_Dir/src/types").Merge + + return { } as TypeB; +>{ } as TypeB : import("tests/cases/compiler/Uppercased_Dir/src/types").Merge +>{ } : {} +>TypeB : import("tests/cases/compiler/Uppercased_Dir/src/types").Merge + } +} +=== tests/cases/compiler/Uppercased_Dir/src/type-b.ts === +import { Merge } from './types'; +>Merge : any + +import { TypeA } from './type-a'; +>TypeA : any + +export type TypeB = MergeTypeB : Merge +>Merge : Merge +>TypeA : TypeA + + b: string; +>b : string + +}>; +=== tests/cases/compiler/Uppercased_Dir/src/type-a.ts === +export type TypeA = { +>TypeA : TypeA + + a: string; +>a : string +} +=== tests/cases/compiler/Uppercased_Dir/src/types.ts === +export type Merge = T & U; +>Merge : Merge +>T : T +>U : U +>T : T +>U : U + diff --git a/tests/cases/compiler/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.ts b/tests/cases/compiler/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.ts new file mode 100644 index 0000000000000..08e6f227be4ba --- /dev/null +++ b/tests/cases/compiler/caseInsensitiveFileSystemWithCapsImportTypeDeclarations.ts @@ -0,0 +1,23 @@ +// @declaration: true +// @useCaseSensitiveFileNames: false +// @filename: Uppercased_Dir/src/index.ts +import { TypeB } from './type-b'; + +export class Broken { + method () { + return { } as TypeB; + } +} +// @filename: Uppercased_Dir/src/type-b.ts +import { Merge } from './types'; +import { TypeA } from './type-a'; + +export type TypeB = Merge; +// @filename: Uppercased_Dir/src/type-a.ts +export type TypeA = { + a: string; +} +// @filename: Uppercased_Dir/src/types.ts +export type Merge = T & U;