Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unwanted import refinement #1801

Merged
merged 1 commit into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions plugins/hls-refine-imports-plugin/src/Ide/Plugin/RefineImports.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Data.IORef (readIORef)
import Data.List (intercalate)
import qualified Data.Map.Strict as Map
import Data.Maybe (catMaybes, fromMaybe)
import qualified Data.Set as S
import qualified Data.Text as T
import Data.Traversable (forM)
import Development.IDE
Expand Down Expand Up @@ -197,13 +198,23 @@ refineImportsRule = define $ \RefineImports nfp -> do
let filterByImport
:: LImportDecl GhcRn
-> Map.Map ModuleName [AvailInfo]
-> Map.Map ModuleName [AvailInfo]
-> Maybe (Map.Map ModuleName [AvailInfo])
filterByImport (L _ ImportDecl{ideclHiding = Just (_, L _ names)}) avails =
let importedNames = map (ieName . unLoc) names
in flip Map.filter avails $ \a ->
any (`elem` importedNames)
$ concatMap availNamesWithSelectors a
filterByImport _ _ = mempty
let importedNames = S.fromList $ map (ieName . unLoc) names
res = flip Map.filter avails $ \a ->
any (`S.member` importedNames)
$ concatMap availNamesWithSelectors a
allFilteredAvailsNames = S.fromList
$ concatMap availNamesWithSelectors
$ mconcat
$ Map.elems res
-- if there is a function defined in the current module and is used
-- i.e. if a function is not reexported but defined in current
-- module then this import cannot be refined
in if importedNames `S.isSubsetOf` allFilteredAvailsNames
then Just res
else Nothing
filterByImport _ _ = Nothing
let constructImport
:: LImportDecl GhcRn
-> (ModuleName, [AvailInfo])
Expand All @@ -229,7 +240,7 @@ refineImportsRule = define $ \RefineImports nfp -> do
-- we check for the inner imports
, Just innerImports <- [Map.lookup mn import2Map]
-- and only get those symbols used
, filteredInnerImports <- [filterByImport i innerImports]
, Just filteredInnerImports <- [filterByImport i innerImports]
-- if no symbols from this modules then don't need to generate new import
, not $ null filteredInnerImports
]
Expand Down
7 changes: 7 additions & 0 deletions plugins/hls-refine-imports-plugin/test/testdata/F.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module F (module F, module G) where

import G

f1 :: String
f1 = "f1"

4 changes: 4 additions & 0 deletions plugins/hls-refine-imports-plugin/test/testdata/G.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module G where

g1 :: String
g1 = "g1"
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ module Main where
import B ( b1 )
import C ( c1 )
import D
import F
import Data.List (intercalate)

main :: IO ()
main = putStrLn
$ "hello "
<> intercalate ", " [b1, c1, e1]
<> intercalate ", " [b1, c1, e1, f1, g1]
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ module Main where

import A
import D
import F
import Data.List (intercalate)

main :: IO ()
main = putStrLn
$ "hello "
<> intercalate ", " [b1, c1, e1]
<> intercalate ", " [b1, c1, e1, f1, g1]
4 changes: 3 additions & 1 deletion plugins/hls-refine-imports-plugin/test/testdata/hie.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ cradle:
- B.hs
- C.hs
- D.hs
- E.hs
- E.hs
- F.hs
- G.hs