diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 47d0dc71f2faa..f98f0dce2dbd0 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1743,7 +1743,9 @@ namespace ts.server { return project?.isSolution() ? project.getDefaultChildProjectFromSolution(info) : - project; + project && projectContainsInfoDirectly(project, info) ? + project : + undefined; } /** diff --git a/src/testRunner/unittests/tsbuild/watchMode.ts b/src/testRunner/unittests/tsbuild/watchMode.ts index 308c229776dc4..69faba35c318e 100644 --- a/src/testRunner/unittests/tsbuild/watchMode.ts +++ b/src/testRunner/unittests/tsbuild/watchMode.ts @@ -15,6 +15,13 @@ namespace ts.tscWatch { return ts.createSolutionBuilder(host, rootNames, defaultOptions || {}); } + export function ensureErrorFreeBuild(host: WatchedSystem, rootNames: readonly string[]) { + // ts build should succeed + const solutionBuilder = createSolutionBuilder(host, rootNames, {}); + solutionBuilder.build(); + assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " ")); + } + type OutputFileStamp = [string, Date | undefined, boolean]; function transformOutputToOutputFileStamp(f: string, host: TsBuildWatchSystem): OutputFileStamp { return [f, host.getModifiedTime(f), host.writtenFiles.has(host.toFullPath(f))] as OutputFileStamp; diff --git a/src/testRunner/unittests/tsserver/configuredProjects.ts b/src/testRunner/unittests/tsserver/configuredProjects.ts index 4c61106a1d67e..b8ec47946a302 100644 --- a/src/testRunner/unittests/tsserver/configuredProjects.ts +++ b/src/testRunner/unittests/tsserver/configuredProjects.ts @@ -1050,6 +1050,64 @@ declare var console: { }); }); }); + + it("when default configured project does not contain the file", () => { + const barConfig: File = { + path: `${tscWatch.projectRoot}/bar/tsconfig.json`, + content: "{}" + }; + const barIndex: File = { + path: `${tscWatch.projectRoot}/bar/index.ts`, + content: `import {foo} from "../foo/lib"; +foo();` + }; + const fooBarConfig: File = { + path: `${tscWatch.projectRoot}/foobar/tsconfig.json`, + content: barConfig.path + }; + const fooBarIndex: File = { + path: `${tscWatch.projectRoot}/foobar/index.ts`, + content: barIndex.content + }; + const fooConfig: File = { + path: `${tscWatch.projectRoot}/foo/tsconfig.json`, + content: JSON.stringify({ + include: ["index.ts"], + compilerOptions: { + declaration: true, + outDir: "lib" + } + }) + }; + const fooIndex: File = { + path: `${tscWatch.projectRoot}/foo/index.ts`, + content: `export function foo() {}` + }; + const host = createServerHost([barConfig, barIndex, fooBarConfig, fooBarIndex, fooConfig, fooIndex, libFile]); + tscWatch.ensureErrorFreeBuild(host, [fooConfig.path]); + const fooDts = `${tscWatch.projectRoot}/foo/lib/index.d.ts`; + assert.isTrue(host.fileExists(fooDts)); + const session = createSession(host); + const service = session.getProjectService(); + service.openClientFile(barIndex.path); + checkProjectActualFiles(service.configuredProjects.get(barConfig.path)!, [barIndex.path, fooDts, libFile.path, barConfig.path]); + service.openClientFile(fooBarIndex.path); + checkProjectActualFiles(service.configuredProjects.get(fooBarConfig.path)!, [fooBarIndex.path, fooDts, libFile.path, fooBarConfig.path]); + service.openClientFile(fooIndex.path); + checkProjectActualFiles(service.configuredProjects.get(fooConfig.path)!, [fooIndex.path, libFile.path, fooConfig.path]); + service.openClientFile(fooDts); + session.executeCommandSeq({ + command: protocol.CommandTypes.GetApplicableRefactors, + arguments: { + file: fooDts, + startLine: 1, + startOffset: 1, + endLine: 1, + endOffset: 1 + } + }); + assert.equal(service.tryGetDefaultProjectForFile(server.toNormalizedPath(fooDts)), service.configuredProjects.get(barConfig.path)); + }); }); describe("unittests:: tsserver:: ConfiguredProjects:: non-existing directories listed in config file input array", () => { diff --git a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts index e8442e07e69cd..e4301b3c271f7 100644 --- a/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts +++ b/src/testRunner/unittests/tsserver/projectReferenceCompileOnSave.ts @@ -469,9 +469,7 @@ ${appendDts}` const host = createServerHost([libFile, tsbaseJson, buttonConfig, buttonSource, siblingConfig, siblingSource], { useCaseSensitiveFileNames: true }); // ts build should succeed - const solutionBuilder = tscWatch.createSolutionBuilder(host, [siblingConfig.path], {}); - solutionBuilder.build(); - assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " ")); + tscWatch.ensureErrorFreeBuild(host, [siblingConfig.path]); const sourceJs = changeExtension(siblingSource.path, ".js"); const expectedSiblingJs = host.readFile(sourceJs); diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index 2eb7d7710cefb..8da081d82c1bf 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -2,12 +2,8 @@ namespace ts.projectSystem { describe("unittests:: tsserver:: with project references and tsbuild", () => { function createHost(files: readonly TestFSWithWatch.FileOrFolderOrSymLink[], rootNames: readonly string[]) { const host = createServerHost(files); - // ts build should succeed - const solutionBuilder = tscWatch.createSolutionBuilder(host, rootNames, {}); - solutionBuilder.build(); - assert.equal(host.getOutput().length, 0, JSON.stringify(host.getOutput(), /*replacer*/ undefined, " ")); - + tscWatch.ensureErrorFreeBuild(host, rootNames); return host; }