@@ -10,7 +10,7 @@ import Control.Monad.Writer.Class (MonadWriter(..))
10import Control.Monad.Error.Class (MonadError(..))
10import Control.Monad.Error.Class (MonadError(..))
12import Data.Foldable (traverse_)
12import Data.Foldable (traverse_)
13−import Data.List (find, intersect)
13+import Data.List (intersect)
14import Data.Maybe (fromMaybe, mapMaybe)
14import Data.Maybe (fromMaybe, mapMaybe)
15import qualified Data.Map as M
15import qualified Data.Map as M
@@ -76,11 +76,11 @@ resolveExports env ss mn imps exps refs =
76 elaborateModuleExports result (PositionedDeclarationRef pos _ r) =
76 elaborateModuleExports result (PositionedDeclarationRef pos _ r) =
77 warnAndRethrowWithPosition pos $ elaborateModuleExports result r
77 warnAndRethrowWithPosition pos $ elaborateModuleExports result r
78 elaborateModuleExports result (ModuleRef name) | name == mn = do
78 elaborateModuleExports result (ModuleRef name) | name == mn = do
79− let types' = exportedTypes result ++ exportedTypes exps
79+ let types' = exportedTypes result `M.union` exportedTypes exps
80− let typeOps' = exportedTypeOps result ++ exportedTypeOps exps
80+ let typeOps' = exportedTypeOps result `M.union` exportedTypeOps exps
81− let classes' = exportedTypeClasses result ++ exportedTypeClasses exps
81+ let classes' = exportedTypeClasses result `M.union` exportedTypeClasses exps
82− let values' = exportedValues result ++ exportedValues exps
82+ let values' = exportedValues result `M.union` exportedValues exps
83− let valueOps' = exportedValueOps result ++ exportedValueOps exps
83+ let valueOps' = exportedValueOps result `M.union` exportedValueOps exps
84 return result
84 return result
85 { exportedTypes = types'
85 { exportedTypes = types'
86 , exportedTypeOps = typeOps'
86 , exportedTypeOps = typeOps'
@@ -155,11 +155,12 @@ resolveExports env ss mn imps exps refs =
156 :: Qualified (ProperName 'TypeName)
156 :: Qualified (ProperName 'TypeName)
157 -> ((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)
157 -> ((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)
158+ go (Qualified (Just mn'') name) =
158− go (Qualified (Just mn'') name) = fromMaybe (internalError "Missing value in resolveTypeExports") $ do
159+ fromMaybe (internalError "Missing value in resolveTypeExports") $ do
159− exps' <- envModuleExports <$> mn'' `M.lookup` env
160+ exps' <- envModuleExports <$> mn'' `M.lookup` env
160− ((_, dctors'), mnOrig) <- find (\((name', _), _) -> name == name') (exportedTypes exps')
161+ (dctors', mnOrig) <- name `M.lookup` exportedTypes exps'
161− let relevantDctors = mapMaybe (\(Qualified mn''' dctor) -> if mn''' == Just mn'' then Just dctor else Nothing) dctors
162+ let relevantDctors = mapMaybe (disqualifyFor (Just mn'')) dctors
162− return ((name, relevantDctors `intersect` dctors'), mnOrig)
163+ return ((name, relevantDctors `intersect` dctors'), mnOrig)
163 go (Qualified Nothing _) = internalError "Unqualified value in resolveTypeExports"
164 go (Qualified Nothing _) = internalError "Unqualified value in resolveTypeExports"
165 -- Looks up an imported type operator and re-qualifies it with the original
166 -- Looks up an imported type operator and re-qualifies it with the original
@@ -194,10 +195,14 @@ resolveExports env ss mn imps exps refs =
194 . fromMaybe (internalError "Missing value in resolveValueOp")
195 . fromMaybe (internalError "Missing value in resolveValueOp")
195 $ resolve exportedValueOps op
196 $ resolve exportedValueOps op
197− resolve :: (Eq a) => (Exports -> [(a, ModuleName)]) -> Qualified a -> Maybe (Qualified a)
200+ => (Exports -> M.Map a ModuleName)
202+ -> Maybe (Qualified a)
198 resolve f (Qualified (Just mn'') a) = do
203 resolve f (Qualified (Just mn'') a) = do
199 exps' <- envModuleExports <$> mn'' `M.lookup` env
204 exps' <- envModuleExports <$> mn'' `M.lookup` env
200− mn''' <- snd <$> find ((== a) . fst) (f exps')
205+ mn''' <- a `M.lookup` f exps'
201 return $ Qualified (Just mn''') a
206 return $ Qualified (Just mn''') a
202 resolve _ _ = internalError "Unqualified value in resolve"
207 resolve _ _ = internalError "Unqualified value in resolve"
@@ -219,11 +224,11 @@ filterModule
219 -> [DeclarationRef]
224 -> [DeclarationRef]
220 -> m Exports
225 -> m Exports
221filterModule mn exps refs = do
226filterModule mn exps refs = do
222− types <- foldM filterTypes [] refs
227+ types <- foldM filterTypes M.empty refs
223− typeOps <- foldM (filterExport TyOpName getTypeOpRef exportedTypeOps) [] refs
228+ typeOps <- foldM (filterExport TyOpName getTypeOpRef exportedTypeOps) M.empty refs
224− classes <- foldM (filterExport TyClassName getTypeClassRef exportedTypeClasses) [] refs
229+ classes <- foldM (filterExport TyClassName getTypeClassRef exportedTypeClasses) M.empty refs
225− values <- foldM (filterExport IdentName getValueRef exportedValues) [] refs
230+ values <- foldM (filterExport IdentName getValueRef exportedValues) M.empty refs
226− valueOps <- foldM (filterExport ValOpName getValueOpRef exportedValueOps) [] refs
231+ valueOps <- foldM (filterExport ValOpName getValueOpRef exportedValueOps) M.empty refs
227 return Exports
232 return Exports
228 { exportedTypes = types
233 { exportedTypes = types
229 , exportedTypeOps = typeOps
234 , exportedTypeOps = typeOps
@@ -235,21 +240,19 @@ filterModule mn exps refs = do
237 filterTypes
242 filterTypes
238− :: [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
243+ :: M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName)
239 -> DeclarationRef
244 -> DeclarationRef
240− -> m [((ProperName 'TypeName, [ProperName 'ConstructorName]), ModuleName)]
245+ -> m (M.Map (ProperName 'TypeName) ([ProperName 'ConstructorName], ModuleName))
241 filterTypes result (PositionedDeclarationRef pos _ r) =
246 filterTypes result (PositionedDeclarationRef pos _ r) =
242 rethrowWithPosition pos $ filterTypes result r
247 rethrowWithPosition pos $ filterTypes result r
243 filterTypes result (TypeRef name expDcons) =
248 filterTypes result (TypeRef name expDcons) =
244− case matchType `find` exportedTypes exps of
249+ case name `M.lookup` exportedTypes exps of
245 Nothing -> throwError . errorMessage . UnknownExport $ TyName name
250 Nothing -> throwError . errorMessage . UnknownExport $ TyName name
246− Just ((_, dcons), _) -> do
251+ Just (dcons, _) -> do
247 let expDcons' = fromMaybe dcons expDcons
252 let expDcons' = fromMaybe dcons expDcons
248 traverse_ (checkDcon name dcons) expDcons'
253 traverse_ (checkDcon name dcons) expDcons'
249− return $ ((name, expDcons'), mn) : result
254+ return $ M.insert name (expDcons', mn) result
251− -- Finds a type declaration by matching its name and defining module
252− matchType ((name', _), mn') = name == name' && mn == mn'
253 -- Ensures a data constructor is exportable for a given type. Takes a type
256 -- Ensures a data constructor is exportable for a given type. Takes a type
254 -- name, a list of exportable data constructors for the type, and the name of
257 -- name, a list of exportable data constructors for the type, and the name of
255 -- the data constructor to check.
258 -- the data constructor to check.
@@ -264,18 +267,19 @@ filterModule mn exps refs = do
264 filterTypes result _ = return result
267 filterTypes result _ = return result
266 filterExport
269 filterExport
267− :: Eq a
270+ :: Ord a
268 => (a -> Name)
271 => (a -> Name)
269 -> (DeclarationRef -> Maybe a)
272 -> (DeclarationRef -> Maybe a)
270− -> (Exports -> [(a, ModuleName)])
273+ -> (Exports -> M.Map a ModuleName)
271− -> [(a, ModuleName)]
274+ -> M.Map a ModuleName
272 -> DeclarationRef
275 -> DeclarationRef
273− -> m [(a, ModuleName)]
276+ -> m (M.Map a ModuleName)
274 filterExport toName get fromExps result (PositionedDeclarationRef pos _ r) =
277 filterExport toName get fromExps result (PositionedDeclarationRef pos _ r) =
275 rethrowWithPosition pos $ filterExport toName get fromExps result r
278 rethrowWithPosition pos $ filterExport toName get fromExps result r
276 filterExport toName get fromExps result ref
279 filterExport toName get fromExps result ref
277 | Just name <- get ref =
280 | Just name <- get ref =
278− if (name, mn) `elem` fromExps exps
281+ case name `M.lookup` fromExps exps of
279− then return $ (name, mn) : result
282+ -- TODO: I'm not sure if we actually need to check mn == mn' here -gb
283+ Just mn' | mn == mn' -> return $ M.insert name mn result
280− else throwError . errorMessage . UnknownExport $ toName name
284+ _ -> throwError . errorMessage . UnknownExport $ toName name
281 filterExport _ _ _ result _ = return result
285 filterExport _ _ _ result _ = return result