From 0ce2da979316994fc9760c25b8051422a639c7ee Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Tue, 29 Sep 2020 15:00:07 -0700 Subject: [PATCH] Use correct program when checking for reexports from AutoImportProviderProject --- src/services/codefixes/importFixes.ts | 12 +++++----- .../fourslash/server/autoImportProvider5.ts | 22 +++++++++++++++++++ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 tests/cases/fourslash/server/autoImportProvider5.ts diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 291dbdf55144f..4600dfcd9b0c6 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -498,7 +498,7 @@ namespace ts.codefix { const compilerOptions = program.getCompilerOptions(); const preferTypeOnlyImport = compilerOptions.importsNotUsedAsValues === ImportsNotUsedAsValues.Error && isValidTypeOnlyAliasUseSite(symbolToken); const useRequire = shouldUseRequire(sourceFile, compilerOptions); - const exportInfos = getExportInfos(symbolName, getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, checker, program, useAutoImportProvider, host); + const exportInfos = getExportInfos(symbolName, getMeaningFromLocation(symbolToken), cancellationToken, sourceFile, program, useAutoImportProvider, host); const fixes = arrayFrom(flatMapIterator(exportInfos.entries(), ([_, exportInfos]) => getFixForImport(exportInfos, symbolName, symbolToken.getStart(sourceFile), preferTypeOnlyImport, useRequire, program, sourceFile, host, preferences))); return { fixes, symbolName }; @@ -521,7 +521,6 @@ namespace ts.codefix { currentTokenMeaning: SemanticMeaning, cancellationToken: CancellationToken, sourceFile: SourceFile, - checker: TypeChecker, program: Program, useAutoImportProvider: boolean, host: LanguageServiceHost @@ -529,21 +528,22 @@ namespace ts.codefix { // For each original symbol, keep all re-exports of that symbol together so we can call `getCodeActionsForImport` on the whole group at once. // Maps symbol id to info for modules providing that symbol (original export + re-exports). const originalSymbolToExportInfos = createMultiMap(); - function addSymbol(moduleSymbol: Symbol, exportedSymbol: Symbol, importKind: ImportKind): void { + function addSymbol(moduleSymbol: Symbol, exportedSymbol: Symbol, importKind: ImportKind, checker: TypeChecker): void { originalSymbolToExportInfos.add(getUniqueSymbolId(exportedSymbol, checker).toString(), { moduleSymbol, importKind, exportedSymbolIsTypeOnly: isTypeOnlySymbol(exportedSymbol, checker) }); } - forEachExternalModuleToImportFrom(program, host, sourceFile, /*filterByPackageJson*/ true, useAutoImportProvider, moduleSymbol => { + forEachExternalModuleToImportFrom(program, host, sourceFile, /*filterByPackageJson*/ true, useAutoImportProvider, (moduleSymbol, _, program) => { + const checker = program.getTypeChecker(); cancellationToken.throwIfCancellationRequested(); const defaultInfo = getDefaultLikeExportInfo(sourceFile, moduleSymbol, checker, program.getCompilerOptions()); if (defaultInfo && defaultInfo.name === symbolName && symbolHasMeaning(defaultInfo.symbolForMeaning, currentTokenMeaning)) { - addSymbol(moduleSymbol, defaultInfo.symbol, defaultInfo.kind); + addSymbol(moduleSymbol, defaultInfo.symbol, defaultInfo.kind, checker); } // check exports with the same name const exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol); if (exportSymbolWithIdenticalName && symbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) { - addSymbol(moduleSymbol, exportSymbolWithIdenticalName, ImportKind.Named); + addSymbol(moduleSymbol, exportSymbolWithIdenticalName, ImportKind.Named, checker); } }); return originalSymbolToExportInfos; diff --git a/tests/cases/fourslash/server/autoImportProvider5.ts b/tests/cases/fourslash/server/autoImportProvider5.ts new file mode 100644 index 0000000000000..824666e91c931 --- /dev/null +++ b/tests/cases/fourslash/server/autoImportProvider5.ts @@ -0,0 +1,22 @@ +/// + +// @Filename: /package.json +//// { "dependencies": { "react-hook-form": "*" } } + +// @Filename: /node_modules/react-hook-form/package.json +//// { "types": "dist/index.d.ts" } + +// @Filename: /node_modules/react-hook-form/dist/index.d.ts +//// export * from "./useForm"; + +// @Filename: /node_modules/react-hook-form/dist/useForm.d.ts +//// export declare function useForm(): void; + +// @Filename: /index.ts +//// useForm/**/ + +goTo.marker(""); +verify.importFixAtPosition([ + `import { useForm } from "react-hook-form";\r\n\r\nuseForm`, + `import { useForm } from "react-hook-form/dist/useForm";\r\n\r\nuseForm` +]);