Skip to content

Commit 5d6a5d0

Browse files
authored
Fix detecting default project when file is part for more than one project but not part of default configured project (eg because its output of that projet) (microsoft#38429)
Fixes microsoft#38366
1 parent 3f06adf commit 5d6a5d0

File tree

5 files changed

+70
-9
lines changed

5 files changed

+70
-9
lines changed

src/server/editorServices.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,9 @@ namespace ts.server {
17431743

17441744
return project?.isSolution() ?
17451745
project.getDefaultChildProjectFromSolution(info) :
1746-
project;
1746+
project && projectContainsInfoDirectly(project, info) ?
1747+
project :
1748+
undefined;
17471749
}
17481750

17491751
/**

src/testRunner/unittests/tsbuild/watchMode.ts

+7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ namespace ts.tscWatch {
1515
return ts.createSolutionBuilder(host, rootNames, defaultOptions || {});
1616
}
1717

18+
export function ensureErrorFreeBuild(host: WatchedSystem, rootNames: readonly string[]) {
19+
// ts build should succeed
20+
const solutionBuilder = createSolutionBuilder(host, rootNames, {});
21+
solutionBuilder.build();
22+
assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " "));
23+
}
24+
1825
type OutputFileStamp = [string, Date | undefined, boolean];
1926
function transformOutputToOutputFileStamp(f: string, host: TsBuildWatchSystem): OutputFileStamp {
2027
return [f, host.getModifiedTime(f), host.writtenFiles.has(host.toFullPath(f))] as OutputFileStamp;

src/testRunner/unittests/tsserver/configuredProjects.ts

+58
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,64 @@ declare var console: {
10501050
});
10511051
});
10521052
});
1053+
1054+
it("when default configured project does not contain the file", () => {
1055+
const barConfig: File = {
1056+
path: `${tscWatch.projectRoot}/bar/tsconfig.json`,
1057+
content: "{}"
1058+
};
1059+
const barIndex: File = {
1060+
path: `${tscWatch.projectRoot}/bar/index.ts`,
1061+
content: `import {foo} from "../foo/lib";
1062+
foo();`
1063+
};
1064+
const fooBarConfig: File = {
1065+
path: `${tscWatch.projectRoot}/foobar/tsconfig.json`,
1066+
content: barConfig.path
1067+
};
1068+
const fooBarIndex: File = {
1069+
path: `${tscWatch.projectRoot}/foobar/index.ts`,
1070+
content: barIndex.content
1071+
};
1072+
const fooConfig: File = {
1073+
path: `${tscWatch.projectRoot}/foo/tsconfig.json`,
1074+
content: JSON.stringify({
1075+
include: ["index.ts"],
1076+
compilerOptions: {
1077+
declaration: true,
1078+
outDir: "lib"
1079+
}
1080+
})
1081+
};
1082+
const fooIndex: File = {
1083+
path: `${tscWatch.projectRoot}/foo/index.ts`,
1084+
content: `export function foo() {}`
1085+
};
1086+
const host = createServerHost([barConfig, barIndex, fooBarConfig, fooBarIndex, fooConfig, fooIndex, libFile]);
1087+
tscWatch.ensureErrorFreeBuild(host, [fooConfig.path]);
1088+
const fooDts = `${tscWatch.projectRoot}/foo/lib/index.d.ts`;
1089+
assert.isTrue(host.fileExists(fooDts));
1090+
const session = createSession(host);
1091+
const service = session.getProjectService();
1092+
service.openClientFile(barIndex.path);
1093+
checkProjectActualFiles(service.configuredProjects.get(barConfig.path)!, [barIndex.path, fooDts, libFile.path, barConfig.path]);
1094+
service.openClientFile(fooBarIndex.path);
1095+
checkProjectActualFiles(service.configuredProjects.get(fooBarConfig.path)!, [fooBarIndex.path, fooDts, libFile.path, fooBarConfig.path]);
1096+
service.openClientFile(fooIndex.path);
1097+
checkProjectActualFiles(service.configuredProjects.get(fooConfig.path)!, [fooIndex.path, libFile.path, fooConfig.path]);
1098+
service.openClientFile(fooDts);
1099+
session.executeCommandSeq<protocol.GetApplicableRefactorsRequest>({
1100+
command: protocol.CommandTypes.GetApplicableRefactors,
1101+
arguments: {
1102+
file: fooDts,
1103+
startLine: 1,
1104+
startOffset: 1,
1105+
endLine: 1,
1106+
endOffset: 1
1107+
}
1108+
});
1109+
assert.equal(service.tryGetDefaultProjectForFile(server.toNormalizedPath(fooDts)), service.configuredProjects.get(barConfig.path));
1110+
});
10531111
});
10541112

10551113
describe("unittests:: tsserver:: ConfiguredProjects:: non-existing directories listed in config file input array", () => {

src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,7 @@ ${appendDts}`
469469
const host = createServerHost([libFile, tsbaseJson, buttonConfig, buttonSource, siblingConfig, siblingSource], { useCaseSensitiveFileNames: true });
470470

471471
// ts build should succeed
472-
const solutionBuilder = tscWatch.createSolutionBuilder(host, [siblingConfig.path], {});
473-
solutionBuilder.build();
474-
assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " "));
472+
tscWatch.ensureErrorFreeBuild(host, [siblingConfig.path]);
475473
const sourceJs = changeExtension(siblingSource.path, ".js");
476474
const expectedSiblingJs = host.readFile(sourceJs);
477475

src/testRunner/unittests/tsserver/projectReferences.ts

+1-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@ namespace ts.projectSystem {
22
describe("unittests:: tsserver:: with project references and tsbuild", () => {
33
function createHost(files: readonly TestFSWithWatch.FileOrFolderOrSymLink[], rootNames: readonly string[]) {
44
const host = createServerHost(files);
5-
65
// ts build should succeed
7-
const solutionBuilder = tscWatch.createSolutionBuilder(host, rootNames, {});
8-
solutionBuilder.build();
9-
assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " "));
10-
6+
tscWatch.ensureErrorFreeBuild(host, rootNames);
117
return host;
128
}
139

0 commit comments

Comments
 (0)