Skip to content

Commit 6a6493c

Browse files
committed
export map improvements
1 parent 2c01fb1 commit 6a6493c

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

ghcide/src/Development/IDE/Types/Exports.hs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module Development.IDE.Types.Exports
2121
updateExportsMapMg
2222
) where
2323

24-
import Control.DeepSeq (NFData (..))
24+
import Control.DeepSeq (NFData (..), force, ($!!))
2525
import Control.Monad
2626
import Data.Bifunctor (Bifunctor (second))
2727
import Data.Char (isUpper)
@@ -45,6 +45,9 @@ data ExportsMap = ExportsMap
4545
, getModuleExportsMap :: !(ModuleNameEnv (HashSet IdentInfo))
4646
}
4747

48+
instance NFData ExportsMap where
49+
rnf (ExportsMap a b) = foldOccEnv (\a b -> rnf a `seq` b) (seqEltsUFM rnf b) a
50+
4851
instance Show ExportsMap where
4952
show (ExportsMap occs mods) =
5053
unwords [ "ExportsMap { getExportsMap ="
@@ -154,7 +157,7 @@ createExportsMap :: [ModIface] -> ExportsMap
154157
createExportsMap modIface = do
155158
let exportList = concatMap doOne modIface
156159
let exportsMap = mkOccEnv_C (<>) $ map (\(a,_,c) -> (a, c)) exportList
157-
ExportsMap exportsMap $ buildModuleExportMap $ map (\(_,b,c) -> (b, c)) exportList
160+
force $ ExportsMap exportsMap $ buildModuleExportMap $ map (\(_,b,c) -> (b, c)) exportList -- UFM is lazy, so need to seq
158161
where
159162
doOne modIFace = do
160163
let getModDetails = unpackAvail $ moduleName $ mi_module modIFace
@@ -164,7 +167,7 @@ createExportsMapMg :: [ModGuts] -> ExportsMap
164167
createExportsMapMg modGuts = do
165168
let exportList = concatMap doOne modGuts
166169
let exportsMap = mkOccEnv_C (<>) $ map (\(a,_,c) -> (a, c)) exportList
167-
ExportsMap exportsMap $ buildModuleExportMap $ map (\(_,b,c) -> (b, c)) exportList
170+
force $ ExportsMap exportsMap $ buildModuleExportMap $ map (\(_,b,c) -> (b, c)) exportList -- UFM is lazy, so need to seq
168171
where
169172
doOne mi = do
170173
let getModuleName = moduleName $ mg_module mi
@@ -188,7 +191,7 @@ createExportsMapHieDb withHieDb = do
188191
fmap (unwrap mn) <$> withHieDb (\hieDb -> getExportsForModule hieDb mn)
189192
let idents = concat idents'
190193
let exportsMap = mkOccEnv_C (<>) (keyWith name idents)
191-
return $! ExportsMap exportsMap $ buildModuleExportMap (keyWith identModuleName idents)
194+
return $!! ExportsMap exportsMap $ buildModuleExportMap (keyWith identModuleName idents) -- UFM is lazy so need to seq
192195
where
193196
unwrap m ExportRow{..} = IdentInfo exportName exportParent m
194197
keyWith f xs = [(f x, Set.singleton x) | x <- xs]

plugins/hls-refactor-plugin/src/Development/IDE/Plugin/CodeAction.hs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,19 +1037,21 @@ suggestExtendImport exportsMap (L _ HsModule {hsmodImports}) Diagnostic{_range=_
10371037
]
10381038
| otherwise = []
10391039
lookupExportMap binding mod
1040-
| Just match <- Map.lookup binding (getExportsMap exportsMap)
1040+
| let em = getExportsMap exportsMap
1041+
match1 = lookupOccEnv em (mkVarOrDataOcc binding)
1042+
match2 = lookupOccEnv em (mkTypeOcc binding)
1043+
, Just match <- match1 <> match2
10411044
-- Only for the situation that data constructor name is same as type constructor name,
10421045
-- let ident with parent be in front of the one without.
10431046
, sortedMatch <- sortBy (\ident1 ident2 -> parent ident2 `compare` parent ident1) (Set.toList match)
10441047
, idents <- filter (\ident -> moduleNameText ident == mod && (canUseDatacon || not (isDatacon ident))) sortedMatch
1045-
, (not . null) idents -- Ensure fallback while `idents` is empty
1046-
, ident <- head idents
1048+
, (ident:_) <- idents -- Ensure fallback while `idents` is empty
10471049
= Just ident
10481050

10491051
-- fallback to using GHC suggestion even though it is not always correct
10501052
| otherwise
10511053
= Just IdentInfo
1052-
{ name = mkVarOccFS $ mkFastStringByteString $ T.encodeUtf8 binding
1054+
{ name = mkVarOrDataOcc binding
10531055
, parent = Nothing
10541056
, identModuleName = mkModuleNameFS $ mkFastStringByteString $ T.encodeUtf8 mod}
10551057
#endif
@@ -1452,7 +1454,7 @@ suggestNewOrExtendImportForClassMethod packageExportsMap ps fileContents Diagnos
14521454
"‘([^’]*)’ is not a \\(visible\\) method of class ‘([^’]*)’",
14531455
idents <-
14541456
maybe [] (Set.toList . Set.filter (\x -> fmap occNameText (parent x) == Just className)) $
1455-
Map.lookup methodName $ getExportsMap packageExportsMap =
1457+
lookupOccEnv (getExportsMap packageExportsMap) (mkVarOrDataOcc methodName) =
14561458
mconcat $ suggest <$> idents
14571459
| otherwise = []
14581460
where
@@ -1507,7 +1509,7 @@ constructNewImportSuggestions
15071509
constructNewImportSuggestions exportsMap (qual, thingMissing) notTheseModules = nubOrdOn snd
15081510
[ suggestion
15091511
| Just name <- [T.stripPrefix (maybe "" (<> ".") qual) $ notInScope thingMissing]
1510-
, identInfo <- maybe [] Set.toList $ Map.lookup name (getExportsMap exportsMap)
1512+
, identInfo <- maybe [] Set.toList $ (lookupOccEnv (getExportsMap exportsMap) (mkVarOrDataOcc name)) <> (lookupOccEnv (getExportsMap exportsMap) (mkTypeOcc name))
15111513
, canUseIdent thingMissing identInfo
15121514
, moduleNameText identInfo `notElem` fromMaybe [] notTheseModules
15131515
, suggestion <- renderNewImport identInfo

0 commit comments

Comments
 (0)