hls-explicit-imports-plugin 2.2.0.0 → 2.3.0.0
raw patch · 6 files changed
+62/−39 lines, 6 filesdep ~ghcidedep ~hls-plugin-apiPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: ghcide, hls-plugin-api
API changes (from Hackage documentation)
Files
- hls-explicit-imports-plugin.cabal +3/−3
- src/Ide/Plugin/ExplicitImports.hs +35/−35
- test/Main.hs +2/−0
- test/testdata/RefineQualified.hs +10/−0
- test/testdata/RefineQualifiedExplicit.hs +10/−0
- test/testdata/hie.yaml +2/−1
hls-explicit-imports-plugin.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: hls-explicit-imports-plugin-version: 2.2.0.0+version: 2.3.0.0 synopsis: Explicit imports plugin for Haskell Language Server description: Please see the README on GitHub at <https://github.com/haskell/haskell-language-server#readme>@@ -38,9 +38,9 @@ , containers , deepseq , ghc- , ghcide == 2.2.0.0+ , ghcide == 2.3.0.0 , hls-graph- , hls-plugin-api == 2.2.0.0+ , hls-plugin-api == 2.3.0.0 , lens , lsp , mtl
src/Ide/Plugin/ExplicitImports.hs view
@@ -29,7 +29,7 @@ fromList, (!?)) import Data.IORef (readIORef) import qualified Data.Map.Strict as Map-import Data.Maybe (mapMaybe)+import Data.Maybe (isNothing, mapMaybe) import qualified Data.Set as S import Data.String (fromString) import qualified Data.Text as T@@ -316,42 +316,32 @@ return $ mi_exports $ hirModIface imp_hir -- Use the GHC api to extract the "minimal" imports- (imports, mbMinImports) <- MaybeT $ liftIO $ extractMinimalImports hsc tmr+ locationImportWithMinimal <- MaybeT $ liftIO $ extractMinimalImports hsc tmr - let importsMap =- Map.fromList- [ (realSrcSpanStart l, printOutputable i)- | L (locA -> RealSrcSpan l _) i <- mbMinImports- ]- minimalImportsResult =- [ (range, (minImport, ExplicitImport))- | imp@(L _ impDecl) <- imports+ let minimalImportsResult =+ [ (range, (printOutputable minImport, ExplicitImport))+ | (location, impDecl, minImport) <- locationImportWithMinimal , not (isQualifiedImport impDecl) , not (isExplicitImport impDecl) , let L _ moduleName = ideclName impDecl , modFilter moduleName- , RealSrcSpan location _ <- [getLoc imp]- , let range = realSrcSpanToRange location- , Just minImport <- [Map.lookup (realSrcSpanStart location) importsMap]- ]+ , let range = realSrcSpanToRange location]+ refineImportsResult = [ (range, (T.intercalate "\n"- . map (printOutputable . constructImport i)+ . map (printOutputable . constructImport origImport minImport) . Map.toList $ filteredInnerImports, RefineImport)) -- for every minimal imports- | minImports <- [mbMinImports]- , i@(L _ ImportDecl{ideclName = L _ mn}) <- minImports+ | (location, origImport, minImport@(ImportDecl{ideclName = L _ mn})) <- locationImportWithMinimal -- (almost) no one wants to see an refine import list for Prelude , mn /= moduleName pRELUDE -- we check for the inner imports , Just innerImports <- [Map.lookup mn import2Map] -- and only get those symbols used- , Just filteredInnerImports <- [filterByImport i innerImports]+ , Just filteredInnerImports <- [filterByImport minImport innerImports] -- if no symbols from this modules then don't need to generate new import , not $ null filteredInnerImports- -- get the location- , RealSrcSpan location _ <- [getLoc i] -- and then convert that to a Range , let range = realSrcSpanToRange location ]@@ -370,7 +360,7 @@ extractMinimalImports :: HscEnvEq -> TcModuleResult ->- IO (Maybe ([LImportDecl GhcRn], [LImportDecl GhcRn]))+ IO (Maybe [(RealSrcSpan, ImportDecl GhcRn, ImportDecl GhcRn)]) extractMinimalImports hsc TcModuleResult {..} = runMaybeT $ do -- extract the original imports and the typechecking environment let tcEnv = tmrTypechecked@@ -391,16 +381,22 @@ (_, Just minimalImports) <- liftIO $ initTcWithGbl (hscEnv hsc) tcEnv srcSpan $ getMinimalImports usage + let minimalImportsMap =+ Map.fromList+ [ (realSrcSpanStart l, impDecl)+ | L (locA -> RealSrcSpan l _) impDecl <- minimalImports+ ]+ results =+ [ (location, imp, minImport)+ | L (locA -> RealSrcSpan location _) imp <- imports+ , Just minImport <- [Map.lookup (realSrcSpanStart location) minimalImportsMap]] -- return both the original imports and the computed minimal ones- return (imports, minimalImports)+ return results where notExported :: [String] -> LImportDecl GhcRn -> Bool notExported [] _ = True notExported exports (L _ ImportDecl{ideclName = L _ name}) = not $ any (\e -> ("module " ++ moduleNameString name) == e) exports-#if !MIN_VERSION_ghc (9,0,0)- notExported _ _ = True-#endif isExplicitImport :: ImportDecl GhcRn -> Bool #if MIN_VERSION_ghc (9,5,0)@@ -454,11 +450,11 @@ -------------------------------------------------------------------------------- -filterByImport :: LImportDecl GhcRn -> Map.Map ModuleName [AvailInfo] -> Maybe (Map.Map ModuleName [AvailInfo])+filterByImport :: ImportDecl GhcRn -> Map.Map ModuleName [AvailInfo] -> Maybe (Map.Map ModuleName [AvailInfo]) #if MIN_VERSION_ghc(9,5,0)-filterByImport (L _ ImportDecl{ideclImportList = Just (_, L _ names)})+filterByImport (ImportDecl{ideclImportList = Just (_, L _ names)}) #else-filterByImport (L _ ImportDecl{ideclHiding = Just (_, L _ names)})+filterByImport (ImportDecl{ideclHiding = Just (_, L _ names)}) #endif avails = -- if there is a function defined in the current module and is used@@ -477,18 +473,22 @@ $ Map.elems res filterByImport _ _ = Nothing -constructImport :: LImportDecl GhcRn -> (ModuleName, [AvailInfo]) -> LImportDecl GhcRn+constructImport :: ImportDecl GhcRn -> ImportDecl GhcRn -> (ModuleName, [AvailInfo]) -> ImportDecl GhcRn #if MIN_VERSION_ghc(9,5,0)-constructImport (L lim imd@ImportDecl {ideclName = L _ _, ideclImportList = Just (hiding, L _ names)})+constructImport ImportDecl{ideclQualified = qualified, ideclImportList = origHiding} imd@ImportDecl{ideclImportList = Just (hiding, L _ names)} #else-constructImport (L lim imd@ImportDecl{ideclName = L _ _, ideclHiding = Just (hiding, L _ names)})+constructImport ImportDecl{ideclQualified = qualified, ideclHiding = origHiding} imd@ImportDecl{ideclHiding = Just (hiding, L _ names)} #endif- (newModuleName, avails) = L lim imd+ (newModuleName, avails) = imd { ideclName = noLocA newModuleName #if MIN_VERSION_ghc(9,5,0)- , ideclImportList = Just (hiding, noLocA newNames)+ , ideclImportList = if isNothing origHiding && qualified /= NotQualified+ then Nothing+ else Just (hiding, noLocA newNames) #else- , ideclHiding = Just (hiding, noLocA newNames)+ , ideclHiding = if isNothing origHiding && qualified /= NotQualified+ then Nothing+ else Just (hiding, noLocA newNames) #endif } where newNames = filter (\n -> any (n `containsAvail`) avails) names@@ -498,4 +498,4 @@ any (\an -> printOutputable an == (printOutputable . ieName . unLoc $ name)) $ availNamesWithSelectors avail -constructImport lim _ = lim+constructImport _ lim _ = lim
test/Main.hs view
@@ -31,6 +31,8 @@ "Refine Imports" [ codeActionGoldenTest "RefineWithOverride" 3 1 , codeLensGoldenTest isRefineImports "RefineUsualCase" 1+ , codeLensGoldenTest isRefineImports "RefineQualified" 0+ , codeLensGoldenTest isRefineImports "RefineQualifiedExplicit" 0 ], testGroup "Make imports explicit"
+ test/testdata/RefineQualified.hs view
@@ -0,0 +1,10 @@+module Main where++import qualified RefineA as RA+import RefineD+import Data.List (intercalate)++main :: IO ()+main = putStrLn + $ "hello " + <> intercalate ", " [RA.b1, RA.c1, e2]
+ test/testdata/RefineQualifiedExplicit.hs view
@@ -0,0 +1,10 @@+module Main where++import qualified RefineA as RA (b1, c1)+import RefineD+import Data.List (intercalate)++main :: IO ()+main = putStrLn + $ "hello " + <> intercalate ", " [RA.b1, RA.c1, e2]
test/testdata/hie.yaml view
@@ -1,4 +1,3 @@- cradle: direct: arguments:@@ -9,6 +8,8 @@ - ExplicitA.hs - ExplicitB.hs - RefineUsualCase.hs+ - RefineQualified.hs+ - RefineQualifiedExplicit.hs - RefineWithOverride.hs - RefineA.hs - RefineB.hs