Skip to content

Commit 9445657

Browse files
authored
Correctly set filesByName map when reusing program to ensure it is same as old (microsoft#35784)
It was previously not populated correctly if preserveSymlinks with useSourceOfProjectReference was true, in that case if module was resolved to symlink and we deduced it refers to source of project reference we want to set "resolvedFileName" correctly otherwise it results in incorrect module not found errors.
1 parent 8c9e96b commit 9445657

File tree

3 files changed

+87
-45
lines changed

3 files changed

+87
-45
lines changed

src/compiler/program.ts

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ namespace ts {
933933
getSourceFiles: () => files,
934934
getMissingFilePaths: () => missingFilePaths!, // TODO: GH#18217
935935
getRefFileMap: () => refFileMap,
936+
getFilesByNameMap: () => filesByName,
936937
getCompilerOptions: () => options,
937938
getSyntacticDiagnostics,
938939
getOptionsDiagnostics,
@@ -1422,21 +1423,25 @@ namespace ts {
14221423
refFileMap = oldProgram.getRefFileMap();
14231424

14241425
// update fileName -> file mapping
1426+
Debug.assert(newSourceFiles.length === oldProgram.getSourceFiles().length);
14251427
for (const newSourceFile of newSourceFiles) {
1426-
const filePath = newSourceFile.path;
1427-
addFileToFilesByName(newSourceFile, filePath, newSourceFile.resolvedPath);
1428-
if (useSourceOfProjectReferenceRedirect) {
1429-
const redirectProject = getProjectReferenceRedirectProject(newSourceFile.fileName);
1430-
if (redirectProject && !(redirectProject.commandLine.options.outFile || redirectProject.commandLine.options.out)) {
1431-
const redirect = getProjectReferenceOutputName(redirectProject, newSourceFile.fileName);
1432-
addFileToFilesByName(newSourceFile, toPath(redirect), /*redirectedPath*/ undefined);
1433-
}
1428+
filesByName.set(newSourceFile.path, newSourceFile);
1429+
}
1430+
const oldFilesByNameMap = oldProgram.getFilesByNameMap();
1431+
oldFilesByNameMap.forEach((oldFile, path) => {
1432+
if (!oldFile) {
1433+
filesByName.set(path, oldFile);
1434+
return;
14341435
}
1435-
// Set the file as found during node modules search if it was found that way in old progra,
1436-
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(newSourceFile.resolvedPath)!)) {
1437-
sourceFilesFoundSearchingNodeModules.set(filePath, true);
1436+
if (oldFile.path === path) {
1437+
// Set the file as found during node modules search if it was found that way in old progra,
1438+
if (oldProgram!.isSourceFileFromExternalLibrary(oldFile)) {
1439+
sourceFilesFoundSearchingNodeModules.set(oldFile.path, true);
1440+
}
1441+
return;
14381442
}
1439-
}
1443+
filesByName.set(path, filesByName.get(oldFile.path));
1444+
});
14401445

14411446
files = newSourceFiles;
14421447
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();

src/compiler/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3131,6 +3131,8 @@ namespace ts {
31313131
getMissingFilePaths(): readonly Path[];
31323132
/* @internal */
31333133
getRefFileMap(): MultiMap<RefFile> | undefined;
3134+
/* @internal */
3135+
getFilesByNameMap(): Map<SourceFile | false | undefined>;
31343136

31353137
/**
31363138
* Emits the JavaScript and declaration files. If targetSourceFile is not specified, then

src/testRunner/unittests/tsserver/projectReferences.ts

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,6 +1433,7 @@ function foo() {
14331433
aTest: File;
14341434
bFoo: File;
14351435
bBar: File;
1436+
bSymlink: SymLink;
14361437
}
14371438
function verifySymlinkScenario(packages: () => Packages) {
14381439
describe("when solution is not built", () => {
@@ -1456,13 +1457,9 @@ function foo() {
14561457
});
14571458
}
14581459

1459-
function verifySession({ bPackageJson, aTest, bFoo, bBar }: Packages, alreadyBuilt: boolean, extraOptions: CompilerOptions) {
1460+
function verifySession({ bPackageJson, aTest, bFoo, bBar, bSymlink }: Packages, alreadyBuilt: boolean, extraOptions: CompilerOptions) {
14601461
const aConfig = config("A", extraOptions, ["../B"]);
14611462
const bConfig = config("B", extraOptions);
1462-
const bSymlink: SymLink = {
1463-
path: `${tscWatch.projectRoot}/node_modules/b`,
1464-
symLink: `${tscWatch.projectRoot}/packages/B`
1465-
};
14661463
const files = [libFile, bPackageJson, aConfig, bConfig, aTest, bFoo, bBar, bSymlink];
14671464
const host = alreadyBuilt ?
14681465
createHost(files, [aConfig.path]) :
@@ -1485,6 +1482,26 @@ function foo() {
14851482
{ file: aTest, syntax: [], semantic: [], suggestion: [] }
14861483
]
14871484
});
1485+
session.executeCommandSeq<protocol.UpdateOpenRequest>({
1486+
command: protocol.CommandTypes.UpdateOpen,
1487+
arguments: {
1488+
changedFiles: [{
1489+
fileName: aTest.path,
1490+
textChanges: [{
1491+
newText: "\n",
1492+
start: { line: 5, offset: 1 },
1493+
end: { line: 5, offset: 1 }
1494+
}]
1495+
}]
1496+
}
1497+
});
1498+
verifyGetErrRequest({
1499+
host,
1500+
session,
1501+
expected: [
1502+
{ file: aTest, syntax: [], semantic: [], suggestion: [] }
1503+
]
1504+
});
14881505
}
14891506

14901507
function config(packageName: string, extraOptions: CompilerOptions, references?: string[]): File {
@@ -1510,37 +1527,55 @@ function foo() {
15101527
};
15111528
}
15121529

1513-
describe("when packageJson has types field and has index.ts", () => {
1514-
verifySymlinkScenario(() => ({
1515-
bPackageJson: {
1516-
path: `${tscWatch.projectRoot}/packages/B/package.json`,
1517-
content: JSON.stringify({
1518-
main: "lib/index.js",
1519-
types: "lib/index.d.ts"
1520-
})
1521-
},
1522-
aTest: file("A", "index.ts", `import { foo } from 'b';
1523-
import { bar } from 'b/lib/bar';
1530+
function verifyMonoRepoLike(scope = "") {
1531+
describe("when packageJson has types field and has index.ts", () => {
1532+
verifySymlinkScenario(() => ({
1533+
bPackageJson: {
1534+
path: `${tscWatch.projectRoot}/packages/B/package.json`,
1535+
content: JSON.stringify({
1536+
main: "lib/index.js",
1537+
types: "lib/index.d.ts"
1538+
})
1539+
},
1540+
aTest: file("A", "index.ts", `import { foo } from '${scope}b';
1541+
import { bar } from '${scope}b/lib/bar';
15241542
foo();
1525-
bar();`),
1526-
bFoo: file("B", "index.ts", `export function foo() { }`),
1527-
bBar: file("B", "bar.ts", `export function bar() { }`)
1528-
}));
1529-
});
1543+
bar();
1544+
`),
1545+
bFoo: file("B", "index.ts", `export function foo() { }`),
1546+
bBar: file("B", "bar.ts", `export function bar() { }`),
1547+
bSymlink: {
1548+
path: `${tscWatch.projectRoot}/node_modules/${scope}b`,
1549+
symLink: `${tscWatch.projectRoot}/packages/B`
1550+
}
1551+
}));
1552+
});
15301553

1531-
describe("when referencing file from subFolder", () => {
1532-
verifySymlinkScenario(() => ({
1533-
bPackageJson: {
1534-
path: `${tscWatch.projectRoot}/packages/B/package.json`,
1535-
content: "{}"
1536-
},
1537-
aTest: file("A", "test.ts", `import { foo } from 'b/lib/foo';
1538-
import { bar } from 'b/lib/bar/foo';
1554+
describe("when referencing file from subFolder", () => {
1555+
verifySymlinkScenario(() => ({
1556+
bPackageJson: {
1557+
path: `${tscWatch.projectRoot}/packages/B/package.json`,
1558+
content: "{}"
1559+
},
1560+
aTest: file("A", "test.ts", `import { foo } from '${scope}b/lib/foo';
1561+
import { bar } from '${scope}b/lib/bar/foo';
15391562
foo();
1540-
bar();`),
1541-
bFoo: file("B", "foo.ts", `export function foo() { }`),
1542-
bBar: file("B", "bar/foo.ts", `export function bar() { }`)
1543-
}));
1563+
bar();
1564+
`),
1565+
bFoo: file("B", "foo.ts", `export function foo() { }`),
1566+
bBar: file("B", "bar/foo.ts", `export function bar() { }`),
1567+
bSymlink: {
1568+
path: `${tscWatch.projectRoot}/node_modules/${scope}b`,
1569+
symLink: `${tscWatch.projectRoot}/packages/B`
1570+
}
1571+
}));
1572+
});
1573+
}
1574+
describe("when package is not scoped", () => {
1575+
verifyMonoRepoLike();
1576+
});
1577+
describe("when package is scoped", () => {
1578+
verifyMonoRepoLike("@issue/");
15441579
});
15451580
});
15461581

0 commit comments

Comments
 (0)