@@ -10,6 +10,7 @@ module Language.PureScript.Sugar.Names.Env
10 , envModuleSourceSpan
10 , envModuleSourceSpan
11 , envModuleImports
11 , envModuleImports
12 , envModuleExports
12 , envModuleExports
13 , exportType
14 , exportType
14 , exportTypeOp
15 , exportTypeOp
15 , exportTypeClass
16 , exportTypeClass
@@ -26,6 +27,7 @@ import Control.Monad.Error.Class (MonadError(..))
26import Control.Monad.Writer.Class (MonadWriter(..))
27import Control.Monad.Writer.Class (MonadWriter(..))
28import Data.Function (on)
29import Data.Function (on)
30+import Data.Foldable (find)
29import Data.List (groupBy, sortBy, delete)
31import Data.List (groupBy, sortBy, delete)
30import Data.Maybe (fromJust, mapMaybe)
32import Data.Maybe (fromJust, mapMaybe)
31import qualified Data.Map as M
33import qualified Data.Map as M
@@ -205,32 +207,51 @@ primEnv = M.singleton
205 primModuleName
207 primModuleName
206 (internalModuleSourceSpan "<Prim>", nullImports, primExports)
208 (internalModuleSourceSpan "<Prim>", nullImports, primExports)
211+-- When updating the `Exports` the behaviour is slightly different depending
212+-- on whether we are exporting values defined within the module or elaborating
213+-- re-exported values. This type is used to indicate which behaviour should be
216+data ExportMode = Internal | ReExport
209-- Safely adds a type and its data constructors to some exports, returning an
220-- Safely adds a type and its data constructors to some exports, returning an
210-- error if a conflict occurs.
221-- error if a conflict occurs.
212exportType
223exportType
213 :: MonadError MultipleErrors m
224 :: MonadError MultipleErrors m
214− => Exports
226+ -> Exports
215 -> ProperName 'TypeName
227 -> ProperName 'TypeName
216 -> [ProperName 'ConstructorName]
228 -> [ProperName 'ConstructorName]
217 -> ModuleName
229 -> ModuleName
218 -> m Exports
230 -> m Exports
219−exportType exps name dctors mn = do
231+exportType exportMode exps name dctors mn = do
220 let exTypes = exportedTypes exps
232 let exTypes = exportedTypes exps
221 let exClasses = exportedTypeClasses exps
233 let exClasses = exportedTypeClasses exps
236+ when (name `M.member` exTypes) $
237+ throwDeclConflict (TyName name) (TyName name)
238+ when (coerceProperName name `M.member` exClasses) $
239+ throwDeclConflict (TyName name) (TyClassName (coerceProperName name))
240+ forM_ dctors $ \dctor -> do
241+ when ((elem dctor . fst) `any` exTypes) $
242+ throwDeclConflict (DctorName dctor) (DctorName dctor)
243+ when (coerceProperName dctor `M.member` exClasses) $
244+ throwDeclConflict (DctorName dctor) (TyClassName (coerceProperName dctor))
222− forM_ (name `M.lookup` exTypes) $ \(_, mn') ->
246+ forM_ (name `M.lookup` exTypes) $ \(_, mn') ->
223− when (mn /= mn') $ throwConflictError ConflictingTypeDecls name
247+ when (mn /= mn') $
224− when (coerceProperName name `M.member` exClasses) $
248+ throwExportConflict mn mn' (TyName name)
225− throwConflictError TypeConflictsWithClass name
226− forM_ dctors $ \dctor -> do
249+ forM_ dctors $ \dctor ->
227− when (dctorExists (coerceProperName dctor) `any` exTypes) $
250+ forM_ ((elem dctor . fst) `find` exTypes) $ \(_, mn') ->
228− throwConflictError ConflictingCtorDecls dctor
251+ when (mn /= mn') $
229− when (coerceProperName dctor `M.member` exClasses) $
252+ throwExportConflict mn mn' (DctorName dctor)
230− throwConflictError CtorConflictsWithClass dctor
231 return $ exps { exportedTypes = M.alter updateOrInsert name exTypes }
253 return $ exps { exportedTypes = M.alter updateOrInsert name exTypes }
233− dctorExists dctor (dctors', mn') = mn /= mn' && elem dctor dctors'
234 updateOrInsert Nothing = Just (dctors, mn)
255 updateOrInsert Nothing = Just (dctors, mn)
235 updateOrInsert (Just (dctors', _)) = Just (dctors ++ dctors', mn)
256 updateOrInsert (Just (dctors', _)) = Just (dctors ++ dctors', mn)
@@ -245,7 +266,7 @@ exportTypeOp
245 -> ModuleName
266 -> ModuleName
246 -> m Exports
267 -> m Exports
247exportTypeOp exps op mn = do
268exportTypeOp exps op mn = do
248− typeOps <- addExport DuplicateTypeOpExport op mn (exportedTypeOps exps)
269+ typeOps <- addExport TyOpName op mn (exportedTypeOps exps)
249 return $ exps { exportedTypeOps = typeOps }
270 return $ exps { exportedTypeOps = typeOps }
@@ -253,17 +274,19 @@ exportTypeOp exps op mn = do
254exportTypeClass
275exportTypeClass
255 :: MonadError MultipleErrors m
276 :: MonadError MultipleErrors m
256− => Exports
278+ -> Exports
257 -> ProperName 'ClassName
279 -> ProperName 'ClassName
258 -> ModuleName
280 -> ModuleName
259 -> m Exports
281 -> m Exports
260−exportTypeClass exps name mn = do
282+exportTypeClass exportMode exps name mn = do
261 let exTypes = exportedTypes exps
283 let exTypes = exportedTypes exps
284+ when (exportMode == Internal) $ do
262− when (coerceProperName name `M.member` exTypes) $
285+ when (coerceProperName name `M.member` exTypes) $
263− throwConflictError ClassConflictsWithType name
286+ throwDeclConflict (TyClassName name) (TyName (coerceProperName name))
264− when ((elem (coerceProperName name) . fst) `any` exTypes) $
287+ when ((elem (coerceProperName name) . fst) `any` exTypes) $
265− throwConflictError ClassConflictsWithCtor name
288+ throwDeclConflict (TyClassName name) (DctorName (coerceProperName name))
266− classes <- addExport DuplicateClassExport name mn (exportedTypeClasses exps)
289+ classes <- addExport TyClassName name mn (exportedTypeClasses exps)
267 return $ exps { exportedTypeClasses = classes }
290 return $ exps { exportedTypeClasses = classes }
@@ -276,7 +299,7 @@ exportValue
276 -> ModuleName
299 -> ModuleName
277 -> m Exports
300 -> m Exports
278exportValue exps name mn = do
301exportValue exps name mn = do
279− values <- addExport DuplicateValueExport name mn (exportedValues exps)
302+ values <- addExport IdentName name mn (exportedValues exps)
280 return $ exps { exportedValues = values }
303 return $ exps { exportedValues = values }
@@ -290,7 +313,7 @@ exportValueOp
290 -> ModuleName
313 -> ModuleName
291 -> m Exports
314 -> m Exports
292exportValueOp exps op mn = do
315exportValueOp exps op mn = do
293− valueOps <- addExport DuplicateValueOpExport op mn (exportedValueOps exps)
316+ valueOps <- addExport ValOpName op mn (exportedValueOps exps)
294 return $ exps { exportedValueOps = valueOps }
317 return $ exps { exportedValueOps = valueOps }
@@ -299,28 +322,42 @@ exportValueOp exps op mn = do
301 :: (MonadError MultipleErrors m, Ord a)
324 :: (MonadError MultipleErrors m, Ord a)
302− => (a -> SimpleErrorMessage)
325+ => (a -> Name)
304 -> ModuleName
327 -> ModuleName
305 -> M.Map a ModuleName
328 -> M.Map a ModuleName
306 -> m (M.Map a ModuleName)
329 -> m (M.Map a ModuleName)
307−addExport what name mn exports =
330+addExport toName name mn exports =
308 case M.lookup name exports of
331 case M.lookup name exports of
310 | mn == mn' -> return exports
333 | mn == mn' -> return exports
311− | otherwise -> throwConflictError what name
334+ | otherwise -> throwExportConflict mn mn' (toName name)
312 Nothing ->
335 Nothing ->
313 return $ M.insert name mn exports
336 return $ M.insert name mn exports
316-- Raises an error for when there is more than one definition for something.
339-- Raises an error for when there is more than one definition for something.
318−throwConflictError
341+throwDeclConflict
319 :: MonadError MultipleErrors m
342 :: MonadError MultipleErrors m
320− => (a -> SimpleErrorMessage)
343+ => Name
346+throwDeclConflict new existing =
347+ throwError . errorMessage $ DeclConflict new existing
350+-- Raises an error for when there are conflicting names in the exports.
353+ :: MonadError MultipleErrors m
358+throwExportConflict new existing name =
323−throwConflictError conflict = throwError . errorMessage . conflict
359+ throwError . errorMessage $
360+ ExportConflict (Qualified (Just new) name) (Qualified (Just existing) name)
326-- Gets the exports for a module, or raise an error if the module doesn't exist.
363-- Gets the exports for a module, or raise an error if the module doesn't exist.