Skip to content

Commit

Permalink
Cherry-pick PR #50364 into release-4.8 (#50365)
Browse files Browse the repository at this point in the history
Component commits:
4a808aa Add tests when realpath supresses the casing error

97011d6 Fix when real path results in value that differs only in case Fixes #49470

1e62da1 Comment

Co-authored-by: Sheetal Nandi <shkamat@microsoft.com>
  • Loading branch information
TypeScript Bot and sheetalkamat authored Aug 18, 2022
1 parent ccfc09d commit 99b7928
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 12 deletions.
12 changes: 8 additions & 4 deletions src/compiler/moduleNameResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,10 +392,12 @@ namespace ts {
if (resolved) {
const { fileName, packageId } = resolved;
const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
const pathsAreEqual = arePathsEqual(fileName, resolvedFileName, host);
resolvedTypeReferenceDirective = {
primary,
resolvedFileName,
originalPath: arePathsEqual(fileName, resolvedFileName, host) ? undefined : fileName,
// If the fileName and realpath are differing only in casing prefer fileName so that we can issue correct errors for casing under forceConsistentCasingInFileNames
resolvedFileName: pathsAreEqual ? fileName : resolvedFileName,
originalPath: pathsAreEqual ? undefined : fileName,
packageId,
isExternalLibraryImport: pathContainsNodeModules(fileName),
};
Expand Down Expand Up @@ -1406,8 +1408,10 @@ namespace ts {
let resolvedValue = resolved.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
const path = realPath(resolvedValue.path, host, traceEnabled);
const originalPath = arePathsEqual(path, resolvedValue.path, host) ? undefined : resolvedValue.path;
resolvedValue = { ...resolvedValue, path, originalPath };
const pathsAreEqual = arePathsEqual(path, resolvedValue.path, host);
const originalPath = pathsAreEqual ? undefined : resolvedValue.path;
// If the path and realpath are differing only in casing prefer path so that we can issue correct errors for casing under forceConsistentCasingInFileNames
resolvedValue = { ...resolvedValue, path: pathsAreEqual ? resolvedValue.path : path, originalPath };
}
// For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
Expand Down
1 change: 1 addition & 0 deletions src/testRunner/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
"unittests/tsc/cancellationToken.ts",
"unittests/tsc/composite.ts",
"unittests/tsc/declarationEmit.ts",
"unittests/tsc/forceConsistentCasingInFileNames.ts",
"unittests/tsc/incremental.ts",
"unittests/tsc/listFilesOnly.ts",
"unittests/tsc/projectReferences.ts",
Expand Down
18 changes: 18 additions & 0 deletions src/testRunner/unittests/tsc/forceConsistentCasingInFileNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace ts {
describe("unittests:: tsc:: forceConsistentCasingInFileNames::", () => {
verifyTsc({
scenario: "forceConsistentCasingInFileNames",
subScenario: "with relative and non relative file resolutions",
commandLineArgs: ["/src/project/src/struct.d.ts", "--forceConsistentCasingInFileNames", "--explainFiles"],
fs: () => loadProjectFromFiles({
"/src/project/src/struct.d.ts": Utils.dedent`
import * as xs1 from "fp-ts/lib/Struct";
import * as xs2 from "fp-ts/lib/struct";
import * as xs3 from "./Struct";
import * as xs4 from "./struct";
`,
"/src/project/node_modules/fp-ts/lib/struct.d.ts": `export function foo(): void`,
}),
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const Fragment: unique symbol;
path: `${projectRoot}/tsconfig.json`,
content: JSON.stringify({
compilerOptions: { jsx: "react-jsx", jsxImportSource: "react", forceConsistentCasingInFileNames: true },
files: ["node_modules/react/jsx-Runtime/index.d.ts", "index.tsx"] // NB: casing does not match disk
files: ["node_modules/react/Jsx-Runtime/index.d.ts", "index.tsx"]
})
}
], { currentDirectory: projectRoot }),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
Input::
//// [/lib/lib.d.ts]
/// <reference no-default-lib="true"/>
interface Boolean {}
interface Function {}
interface CallableFunction {}
interface NewableFunction {}
interface IArguments {}
interface Number { toExponential: any; }
interface Object {}
interface RegExp {}
interface String { charAt: any; }
interface Array<T> { length: number; [n: number]: T; }
interface ReadonlyArray<T> {}
declare const console: { log(msg: any): void; };

//// [/src/project/node_modules/fp-ts/lib/struct.d.ts]
export function foo(): void

//// [/src/project/src/struct.d.ts]
import * as xs1 from "fp-ts/lib/Struct";
import * as xs2 from "fp-ts/lib/struct";
import * as xs3 from "./Struct";
import * as xs4 from "./struct";




Output::
/lib/tsc /src/project/src/struct.d.ts --forceConsistentCasingInFileNames --explainFiles
src/project/src/struct.d.ts:2:22 - error TS1149: File name '/src/project/node_modules/fp-ts/lib/struct.d.ts' differs from already included file name '/src/project/node_modules/fp-ts/lib/Struct.d.ts' only in casing.
The file is in the program because:
Imported via "fp-ts/lib/Struct" from file '/src/project/src/struct.d.ts'
Imported via "fp-ts/lib/struct" from file '/src/project/src/struct.d.ts'

2 import * as xs2 from "fp-ts/lib/struct";
   ~~~~~~~~~~~~~~~~~~

src/project/src/struct.d.ts:1:22
1 import * as xs1 from "fp-ts/lib/Struct";
   ~~~~~~~~~~~~~~~~~~
File is included via import here.

src/project/src/struct.d.ts:3:22 - error TS1149: File name '/src/project/src/Struct.d.ts' differs from already included file name '/src/project/src/struct.d.ts' only in casing.
The file is in the program because:
Root file specified for compilation
Imported via "./Struct" from file '/src/project/src/struct.d.ts'
Imported via "./struct" from file '/src/project/src/struct.d.ts'

3 import * as xs3 from "./Struct";
   ~~~~~~~~~~

src/project/src/struct.d.ts:4:22
4 import * as xs4 from "./struct";
   ~~~~~~~~~~
File is included via import here.

lib/lib.d.ts
Default library for target 'es3'
src/project/node_modules/fp-ts/lib/Struct.d.ts
Imported via "fp-ts/lib/Struct" from file 'src/project/src/struct.d.ts'
Imported via "fp-ts/lib/struct" from file 'src/project/src/struct.d.ts'
src/project/src/struct.d.ts
Root file specified for compilation
Imported via "./Struct" from file 'src/project/src/struct.d.ts'
Imported via "./struct" from file 'src/project/src/struct.d.ts'

Found 2 errors in the same file, starting at: src/project/src/struct.d.ts:2

exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated


Original file line number Diff line number Diff line change
Expand Up @@ -33,27 +33,27 @@ export const Fragment: unique symbol;
export const App = () => <div propA={true}></div>;

//// [/user/username/projects/myproject/tsconfig.json]
{"compilerOptions":{"jsx":"react-jsx","jsxImportSource":"react","forceConsistentCasingInFileNames":true},"files":["node_modules/react/jsx-Runtime/index.d.ts","index.tsx"]}
{"compilerOptions":{"jsx":"react-jsx","jsxImportSource":"react","forceConsistentCasingInFileNames":true},"files":["node_modules/react/Jsx-Runtime/index.d.ts","index.tsx"]}


/a/lib/tsc.js --w --p . --explainFiles
Output::
>> Screen clear
[12:00:31 AM] Starting compilation in watch mode...

[91merror[0m[90m TS1149: [0mFile name '/user/username/projects/myproject/node_modules/react/Jsx-runtime/index.d.ts' differs from already included file name '/user/username/projects/myproject/node_modules/react/jsx-Runtime/index.d.ts' only in casing.
[91merror[0m[90m TS1149: [0mFile name '/user/username/projects/myproject/node_modules/react/jsx-runtime/index.d.ts' differs from already included file name '/user/username/projects/myproject/node_modules/react/Jsx-Runtime/index.d.ts' only in casing.
The file is in the program because:
Part of 'files' list in tsconfig.json
Imported via "react/jsx-runtime" from file '/user/username/projects/myproject/index.tsx' with packageId 'react/jsx-runtime/index.d.ts@0.0.1' to import 'jsx' and 'jsxs' factory functions

tsconfig.json:1:115
[7m1[0m {"compilerOptions":{"jsx":"react-jsx","jsxImportSource":"react","forceConsistentCasingInFileNames":true},"files":["node_modules/react/jsx-Runtime/index.d.ts","index.tsx"]}
[7m1[0m {"compilerOptions":{"jsx":"react-jsx","jsxImportSource":"react","forceConsistentCasingInFileNames":true},"files":["node_modules/react/Jsx-Runtime/index.d.ts","index.tsx"]}
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
File is matched by 'files' list specified here.

../../../../a/lib/lib.d.ts
Default library for target 'es3'
node_modules/react/jsx-Runtime/index.d.ts
node_modules/react/Jsx-Runtime/index.d.ts
Part of 'files' list in tsconfig.json
Imported via "react/jsx-runtime" from file 'index.tsx' with packageId 'react/jsx-runtime/index.d.ts@0.0.1' to import 'jsx' and 'jsxs' factory functions
index.tsx
Expand All @@ -62,12 +62,12 @@ index.tsx



Program root files: ["/user/username/projects/myproject/node_modules/react/jsx-Runtime/index.d.ts","/user/username/projects/myproject/index.tsx"]
Program root files: ["/user/username/projects/myproject/node_modules/react/Jsx-Runtime/index.d.ts","/user/username/projects/myproject/index.tsx"]
Program options: {"jsx":4,"jsxImportSource":"react","forceConsistentCasingInFileNames":true,"watch":true,"project":"/user/username/projects/myproject","explainFiles":true,"configFilePath":"/user/username/projects/myproject/tsconfig.json"}
Program structureReused: Not
Program files::
/a/lib/lib.d.ts
/user/username/projects/myproject/node_modules/react/jsx-Runtime/index.d.ts
/user/username/projects/myproject/node_modules/react/Jsx-Runtime/index.d.ts
/user/username/projects/myproject/index.tsx

No cached semantic diagnostics in the builder::
Expand All @@ -81,7 +81,7 @@ WatchedFiles::
/user/username/projects/myproject/tsconfig.json:
{"fileName":"/user/username/projects/myproject/tsconfig.json","pollingInterval":250}
/user/username/projects/myproject/node_modules/react/jsx-runtime/index.d.ts:
{"fileName":"/user/username/projects/myproject/node_modules/react/jsx-Runtime/index.d.ts","pollingInterval":250}
{"fileName":"/user/username/projects/myproject/node_modules/react/Jsx-Runtime/index.d.ts","pollingInterval":250}
/user/username/projects/myproject/index.tsx:
{"fileName":"/user/username/projects/myproject/index.tsx","pollingInterval":250}
/a/lib/lib.d.ts:
Expand Down

0 comments on commit 99b7928

Please sign in to comment.