diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index c0b7053f93b73..592fe8817541a 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -879,7 +879,13 @@ namespace FourSlash { nameToEntries.set(entry.name, [entry]); } else { - if (entries.some(e => e.source === entry.source && this.deepEqual(e.data, entry.data))) { + if (entries.some(e => + e.source === entry.source && + e.data?.exportName === entry.data?.exportName && + e.data?.fileName === entry.data?.fileName && + e.data?.moduleSpecifier === entry.data?.moduleSpecifier && + e.data?.ambientModuleName === entry.data?.ambientModuleName + )) { this.raiseError(`Duplicate completions for ${entry.name}`); } entries.push(entry); @@ -1280,16 +1286,6 @@ namespace FourSlash { } - private deepEqual(a: unknown, b: unknown) { - try { - this.assertObjectsEqual(a, b); - return true; - } - catch { - return false; - } - } - public verifyDisplayPartsOfReferencedSymbol(expected: ts.SymbolDisplayPart[]) { const referencedSymbols = this.findReferencesAtCaret()!; diff --git a/src/server/project.ts b/src/server/project.ts index ef48ebf530bc2..e490851c0e6e5 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1928,20 +1928,25 @@ namespace ts.server { } } + /*@internal*/ + static readonly compilerOptionsOverrides: CompilerOptions = { + diagnostics: false, + skipLibCheck: true, + sourceMap: false, + types: ts.emptyArray, + lib: ts.emptyArray, + noLib: true, + }; + /*@internal*/ static create(dependencySelection: PackageJsonAutoImportPreference, hostProject: Project, moduleResolutionHost: ModuleResolutionHost, documentRegistry: DocumentRegistry): AutoImportProviderProject | undefined { if (dependencySelection === PackageJsonAutoImportPreference.Off) { return undefined; } - const compilerOptions: CompilerOptions = { + const compilerOptions = { ...hostProject.getCompilerOptions(), - noLib: true, - diagnostics: false, - skipLibCheck: true, - types: ts.emptyArray, - lib: ts.emptyArray, - sourceMap: false, + ...this.compilerOptionsOverrides, }; const rootNames = this.getRootFileNames(dependencySelection, hostProject, moduleResolutionHost, compilerOptions); diff --git a/src/testRunner/unittests/tsserver/autoImportProvider.ts b/src/testRunner/unittests/tsserver/autoImportProvider.ts index 36d17d59d06a2..9d1978849295b 100644 --- a/src/testRunner/unittests/tsserver/autoImportProvider.ts +++ b/src/testRunner/unittests/tsserver/autoImportProvider.ts @@ -302,6 +302,15 @@ namespace ts.projectSystem { assert.isDefined(projectService.configuredProjects.get("/packages/a/tsconfig.json")!.getPackageJsonAutoImportProvider()); assert.isDefined(projectService.configuredProjects.get("/packages/a/tsconfig.json")!.getPackageJsonAutoImportProvider()); }); + + it("Can use the same document registry bucket key as main program", () => { + for (const option of sourceFileAffectingCompilerOptions) { + assert( + !hasProperty(server.AutoImportProviderProject.compilerOptionsOverrides, option.name), + `'${option.name}' may cause AutoImportProviderProject not to share source files with main program` + ); + } + }); }); function setup(files: File[]) { diff --git a/tests/cases/fourslash/server/autoImportProvider6.ts b/tests/cases/fourslash/server/autoImportProvider6.ts new file mode 100644 index 0000000000000..b06d1557e45cd --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider6.ts @@ -0,0 +1,36 @@ +/// + +// @Filename: /tsconfig.json +//// { "compilerOptions": { "module": "commonjs", "lib": ["es2019"] } } + +// @Filename: /package.json +//// { "dependencies": { "antd": "*", "react": "*" } } + +// @Filename: /node_modules/@types/react/index.d.ts +//// export declare function Component(): void; + +// @Filename: /node_modules/antd/index.d.ts +//// import "react"; + +// @Filename: /index.ts +//// Component/**/ + +// react/index.d.ts will be in both the auto import provider program +// and the main program, and will result in duplicate completions +// unless the two programs successfully share the same source file. +// This tests the configuration of the AutoImportProviderProject. +// See also the 'Can use the same document registry bucket key as main program' +// unit test in autoImportProvider.ts. +goTo.marker(""); +verify.completions({ + marker: "", + includes: [{ + name: "Component", + hasAction: true, + source: "/node_modules/@types/react/index", + sortText: completion.SortText.AutoImportSuggestions, + }], + preferences: { + includeCompletionsForModuleExports: true, + }, +});