@@ -8,27 +8,31 @@ module Development.IDE.Types.Exports
88 rendered,
99 moduleNameText,
1010 occNameText,
11+ renderOcc,
12+ mkTypeOcc,
13+ mkVarOrDataOcc,
1114 isDatacon,
1215 createExportsMap,
1316 createExportsMapMg,
14- createExportsMapTc,
1517 buildModuleExportMapFrom,
1618 createExportsMapHieDb,
1719 size,
20+ exportsMapSize,
1821 updateExportsMapMg
1922 ) where
2023
2124import Control.DeepSeq (NFData (.. ))
2225import Control.Monad
2326import Data.Bifunctor (Bifunctor (second ))
27+ import Data.Char (isUpper )
2428import Data.Hashable (Hashable )
2529import Data.HashMap.Strict (HashMap , elems )
2630import qualified Data.HashMap.Strict as Map
2731import Data.HashSet (HashSet )
2832import qualified Data.HashSet as Set
2933import Data.List (foldl' , isSuffixOf )
30- import Data.Text (Text , pack )
31- import Data.Text.Encoding (decodeUtf8 )
34+ import Data.Text (Text , uncons )
35+ import Data.Text.Encoding (decodeUtf8 , encodeUtf8 )
3236import Development.IDE.GHC.Compat
3337import Development.IDE.GHC.Orphans ()
3438import Development.IDE.GHC.Util
@@ -37,52 +41,72 @@ import HieDb
3741
3842
3943data ExportsMap = ExportsMap
40- { getExportsMap :: ! (HashMap IdentifierText (HashSet IdentInfo ))
41- , getModuleExportsMap :: ! (HashMap ModuleNameText (HashSet IdentInfo ))
44+ { getExportsMap :: ! (OccEnv (HashSet IdentInfo ))
45+ , getModuleExportsMap :: ! (ModuleNameEnv (HashSet IdentInfo ))
4246 }
43- deriving (Show )
44-
45- deleteEntriesForModule :: ModuleNameText -> ExportsMap -> ExportsMap
46- deleteEntriesForModule m em = ExportsMap
47- { getExportsMap =
48- let moduleIds = Map. lookupDefault mempty m (getModuleExportsMap em)
49- in deleteAll
50- (rendered <$> Set. toList moduleIds)
51- (getExportsMap em)
52- , getModuleExportsMap = Map. delete m (getModuleExportsMap em)
53- }
54- where
55- deleteAll keys map = foldr Map. delete map keys
47+
48+ instance Show ExportsMap where
49+ show (ExportsMap occs mods) =
50+ unwords [ " ExportsMap { getExportsMap ="
51+ , printWithoutUniques $ mapOccEnv (text . show ) occs
52+ , " getModuleExportsMap ="
53+ , printWithoutUniques $ mapUFM (text . show ) mods
54+ , " }"
55+ ]
56+
57+ -- | `updateExportsMap old new` results in an export map containing
58+ -- the union of old and new, but with all the module entries new overriding
59+ -- those in old.
60+ updateExportsMap :: ExportsMap -> ExportsMap -> ExportsMap
61+ updateExportsMap old new = ExportsMap
62+ { getExportsMap = delListFromOccEnv (getExportsMap old) old_occs `plusOccEnv` getExportsMap new -- plusOccEnv is right biased
63+ , getModuleExportsMap = (getModuleExportsMap old) `plusUFM` (getModuleExportsMap new) -- plusUFM is right biased
64+ }
65+ where old_occs = concat [map name $ Set. toList (lookupWithDefaultUFM_Directly (getModuleExportsMap old) mempty m_uniq)
66+ | m_uniq <- nonDetKeysUFM (getModuleExportsMap new)]
5667
5768size :: ExportsMap -> Int
58- size = sum . map length . elems . getExportsMap
69+ size = sum . map ( Set. size) . occEnvElts . getExportsMap
5970
60- instance Semigroup ExportsMap where
61- ExportsMap a b <> ExportsMap c d = ExportsMap (Map. unionWith (<>) a c) (Map. unionWith (<>) b d)
71+ mkVarOrDataOcc :: Text -> OccName
72+ mkVarOrDataOcc t = mkOcc $ mkFastStringByteString $ encodeUtf8 t
73+ where
74+ mkOcc
75+ | Just (c,_) <- uncons t
76+ , c == ' :' || isUpper c = mkDataOccFS
77+ | otherwise = mkVarOccFS
6278
63- instance Monoid ExportsMap where
64- mempty = ExportsMap Map. empty Map. empty
79+ mkTypeOcc :: Text -> OccName
80+ mkTypeOcc t = mkTcOccFS $ mkFastStringByteString $ encodeUtf8 t
6581
66- type IdentifierText = Text
67- type ModuleNameText = Text
82+ exportsMapSize :: ExportsMap -> Int
83+ exportsMapSize = foldOccEnv ( \ _ x -> x + 1 ) 0 . getExportsMap
6884
85+ instance Semigroup ExportsMap where
86+ ExportsMap a b <> ExportsMap c d = ExportsMap (plusOccEnv_C (<>) a c) (plusUFM_C (<>) b d)
6987
70- rendered :: IdentInfo -> IdentifierText
88+ instance Monoid ExportsMap where
89+ mempty = ExportsMap emptyOccEnv emptyUFM
90+
91+ rendered :: IdentInfo -> Text
7192rendered = occNameText . name
7293
7394-- | Render an identifier as imported or exported style.
7495-- TODO: pattern synonymoccNameText :: OccName -> Text
75- occNameText :: OccName -> IdentifierText
96+ occNameText :: OccName -> Text
7697occNameText name
77- | isTcOcc name && isSymOcc name = " type " <> renderOcc
78- | otherwise = renderOcc
98+ | isTcOcc name && isSymOcc name = " type " <> renderedOcc
99+ | otherwise = renderedOcc
79100 where
80- renderOcc = decodeUtf8 . bytesFS . occNameFS $ name
101+ renderedOcc = renderOcc name
102+
103+ renderOcc :: OccName -> Text
104+ renderOcc = decodeUtf8 . bytesFS . occNameFS
81105
82- moduleNameText :: IdentInfo -> ModuleNameText
106+ moduleNameText :: IdentInfo -> Text
83107moduleNameText = moduleNameText' . identModuleName
84108
85- moduleNameText' :: ModuleName -> ModuleNameText
109+ moduleNameText' :: ModuleName -> Text
86110moduleNameText' = decodeUtf8 . bytesFS . moduleNameFS
87111
88112data IdentInfo = IdentInfo
@@ -129,39 +153,27 @@ mkIdentInfos mod (AvailTC _ nn flds)
129153createExportsMap :: [ModIface ] -> ExportsMap
130154createExportsMap modIface = do
131155 let exportList = concatMap doOne modIface
132- let exportsMap = Map. fromListWith (<>) $ map (\ (a,_,c) -> (a, c)) exportList
156+ let exportsMap = mkOccEnv_C (<>) $ map (\ (a,_,c) -> (a, c)) exportList
133157 ExportsMap exportsMap $ buildModuleExportMap $ map (\ (_,b,c) -> (b, c)) exportList
134158 where
135159 doOne modIFace = do
136160 let getModDetails = unpackAvail $ moduleName $ mi_module modIFace
137- concatMap (fmap (second Set. fromList) . getModDetails) (mi_exports modIFace)
161+ concatMap (getModDetails) (mi_exports modIFace)
138162
139163createExportsMapMg :: [ModGuts ] -> ExportsMap
140164createExportsMapMg modGuts = do
141165 let exportList = concatMap doOne modGuts
142- let exportsMap = Map. fromListWith (<>) $ map (\ (a,_,c) -> (a, c)) exportList
166+ let exportsMap = mkOccEnv_C (<>) $ map (\ (a,_,c) -> (a, c)) exportList
143167 ExportsMap exportsMap $ buildModuleExportMap $ map (\ (_,b,c) -> (b, c)) exportList
144168 where
145169 doOne mi = do
146170 let getModuleName = moduleName $ mg_module mi
147- concatMap (fmap (second Set. fromList) . unpackAvail getModuleName) (mg_exports mi)
171+ concatMap (unpackAvail getModuleName) (mg_exports mi)
148172
149173updateExportsMapMg :: [ModGuts ] -> ExportsMap -> ExportsMap
150- updateExportsMapMg modGuts old = old' <> new
174+ updateExportsMapMg modGuts old = updateExportsMap old new
151175 where
152176 new = createExportsMapMg modGuts
153- old' = deleteAll old (Map. keys $ getModuleExportsMap new)
154- deleteAll = foldl' (flip deleteEntriesForModule)
155-
156- createExportsMapTc :: [TcGblEnv ] -> ExportsMap
157- createExportsMapTc modIface = do
158- let exportList = concatMap doOne modIface
159- let exportsMap = Map. fromListWith (<>) $ map (\ (a,_,c) -> (a, c)) exportList
160- ExportsMap exportsMap $ buildModuleExportMap $ map (\ (_,b,c) -> (b, c)) exportList
161- where
162- doOne mi = do
163- let getModuleName = moduleName $ tcg_mod mi
164- concatMap (fmap (second Set. fromList) . unpackAvail getModuleName) (tcg_exports mi)
165177
166178nonInternalModules :: ModuleName -> Bool
167179nonInternalModules = not . (" .Internal" `isSuffixOf` ) . moduleNameString
@@ -171,44 +183,44 @@ type WithHieDb = forall a. (HieDb -> IO a) -> IO a
171183createExportsMapHieDb :: WithHieDb -> IO ExportsMap
172184createExportsMapHieDb withHieDb = do
173185 mods <- withHieDb getAllIndexedMods
174- idents <- forM (filter (nonInternalModules . modInfoName . hieModInfo) mods) $ \ m -> do
186+ idents' <- forM (filter (nonInternalModules . modInfoName . hieModInfo) mods) $ \ m -> do
175187 let mn = modInfoName $ hieModInfo m
176- fmap (wrap . unwrap mn) <$> withHieDb (\ hieDb -> getExportsForModule hieDb mn)
177- let exportsMap = Map. fromListWith (<>) (concat idents)
178- return $! ExportsMap exportsMap $ buildModuleExportMap (concat idents)
188+ fmap (unwrap mn) <$> withHieDb (\ hieDb -> getExportsForModule hieDb mn)
189+ let idents = concat idents'
190+ let exportsMap = mkOccEnv_C (<>) (keyWith name idents)
191+ return $! ExportsMap exportsMap $ buildModuleExportMap (keyWith identModuleName idents)
179192 where
180- wrap identInfo = (rendered identInfo, Set. fromList [identInfo])
181- -- unwrap :: ExportRow -> IdentInfo
182193 unwrap m ExportRow {.. } = IdentInfo exportName exportParent m
194+ keyWith f xs = [(f x, Set. singleton x) | x <- xs]
183195
184- unpackAvail :: ModuleName -> IfaceExport -> [(Text , Text , [ IdentInfo ] )]
196+ unpackAvail :: ModuleName -> IfaceExport -> [(OccName , ModuleName , HashSet IdentInfo )]
185197unpackAvail mn
186198 | nonInternalModules mn = map f . mkIdentInfos mn
187199 | otherwise = const []
188200 where
189- f id @ IdentInfo {.. } = (printOutputable name, moduleNameText id ,[ id ] )
201+ f id @ IdentInfo {.. } = (name, mn, Set. singleton id )
190202
191203
192- identInfoToKeyVal :: IdentInfo -> (ModuleNameText , IdentInfo )
204+ identInfoToKeyVal :: IdentInfo -> (ModuleName , IdentInfo )
193205identInfoToKeyVal identInfo =
194- (moduleNameText identInfo, identInfo)
206+ (identModuleName identInfo, identInfo)
195207
196- buildModuleExportMap :: [(Text , HashSet IdentInfo )] -> Map. HashMap ModuleNameText (HashSet IdentInfo )
208+ buildModuleExportMap :: [(ModuleName , HashSet IdentInfo )] -> ModuleNameEnv (HashSet IdentInfo )
197209buildModuleExportMap exportsMap = do
198210 let lst = concatMap (Set. toList. snd ) exportsMap
199211 let lstThree = map identInfoToKeyVal lst
200212 sortAndGroup lstThree
201213
202- buildModuleExportMapFrom :: [ModIface ] -> Map. HashMap Text (HashSet IdentInfo )
214+ buildModuleExportMapFrom :: [ModIface ] -> ModuleNameEnv (HashSet IdentInfo )
203215buildModuleExportMapFrom modIfaces = do
204216 let exports = map extractModuleExports modIfaces
205- Map. fromListWith (<>) exports
217+ listToUFM_C (<>) exports
206218
207- extractModuleExports :: ModIface -> (Text , HashSet IdentInfo )
219+ extractModuleExports :: ModIface -> (ModuleName , HashSet IdentInfo )
208220extractModuleExports modIFace = do
209221 let modName = moduleName $ mi_module modIFace
210222 let functionSet = Set. fromList $ concatMap (mkIdentInfos modName) $ mi_exports modIFace
211- (moduleNameText' modName, functionSet)
223+ (modName, functionSet)
212224
213- sortAndGroup :: [(ModuleNameText , IdentInfo )] -> Map. HashMap ModuleNameText (HashSet IdentInfo )
214- sortAndGroup assocs = Map. fromListWith (<>) [(k, Set. fromList [v]) | (k, v) <- assocs]
225+ sortAndGroup :: [(ModuleName , IdentInfo )] -> ModuleNameEnv (HashSet IdentInfo )
226+ sortAndGroup assocs = listToUFM_C (<>) [(k, Set. fromList [v]) | (k, v) <- assocs]
0 commit comments