@@ -21,11 +21,12 @@ module Language.PureScript.Sugar.Names (
23import Data.List (find, nub, (\\))
23import Data.List (find, nub, (\\))
24−import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe)
24+import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing, mapMaybe)
26import Control.Applicative (Applicative(..), (<$>), (<*>))
26import Control.Applicative (Applicative(..), (<$>), (<*>))
27import Control.Monad
27import Control.Monad
28import Control.Monad.Error.Class (MonadError(..))
28import Control.Monad.Error.Class (MonadError(..))
29+import Control.Monad.Writer (MonadWriter(..), censor)
30import qualified Data.Map as M
31import qualified Data.Map as M
@@ -160,7 +161,7 @@ addExport what exports name =
161-- Replaces all local names with qualified names within a set of modules.
162-- Replaces all local names with qualified names within a set of modules.
163−desugarImports :: forall m. (Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]
164+desugarImports :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [Module] -> m [Module]
164desugarImports modules = do
165desugarImports modules = do
165 unfilteredExports <- findExports modules
166 unfilteredExports <- findExports modules
166 exports <- foldM filterModuleExports unfilteredExports modules
167 exports <- foldM filterModuleExports unfilteredExports modules
@@ -481,9 +482,10 @@ findImports = foldl (findImports' Nothing) M.empty
482-- Constructs a local environment for a module.
483-- Constructs a local environment for a module.
484−resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> Module -> m ImportEnvironment
485+resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => ExportEnvironment -> Module -> m ImportEnvironment
485resolveImports env (Module _ _ currentModule decls _) =
486resolveImports env (Module _ _ currentModule decls _) =
487+ censor (onErrorMessages (ErrorInModule currentModule)) $
486− foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
488+ foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)
489 -- A Map from module name to the source position for the import, the list of imports from that
491 -- A Map from module name to the source position for the import, the list of imports from that
@@ -507,17 +509,15 @@ resolveImports env (Module _ _ currentModule decls _) =
508-- Extends the local environment for a module by resolving an import of another module.
510-- Extends the local environment for a module by resolving an import of another module.
510−resolveImport :: forall m. (Applicative m, MonadError MultipleErrors m) => ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> m ImportEnvironment
512+resolveImport :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> m ImportEnvironment
511resolveImport currentModule importModule exps imps impQual =
513resolveImport currentModule importModule exps imps impQual =
512 resolveByType
514 resolveByType
515 resolveByType :: ImportDeclarationType -> m ImportEnvironment
517 resolveByType :: ImportDeclarationType -> m ImportEnvironment
516 resolveByType Implicit = importAll importExplicit
518 resolveByType Implicit = importAll importExplicit
517− resolveByType (Explicit explImports) = (checkedRefs >=> foldM importExplicit imps) explImports
519+ resolveByType (Explicit explImports) = checkedRefs explImports >> foldM importExplicit imps explImports
518− resolveByType (Hiding hiddenImports) = do
519− hiddenImports' <- checkedRefs hiddenImports
520− importAll (importNonHidden hiddenImports')
520+ resolveByType (Hiding hiddenImports) = checkedRefs hiddenImports >> importAll (importNonHidden hiddenImports)
522 importNonHidden :: [DeclarationRef] -> ImportEnvironment -> DeclarationRef -> m ImportEnvironment
522 importNonHidden :: [DeclarationRef] -> ImportEnvironment -> DeclarationRef -> m ImportEnvironment
523 importNonHidden hidden m ref =
523 importNonHidden hidden m ref =
@@ -529,6 +529,7 @@ resolveImport currentModule importModule exps imps impQual =
529 isHidden hidden ref@(TypeRef _ _) =
529 isHidden hidden ref@(TypeRef _ _) =
531 checkTypeRef _ True _ = True
531 checkTypeRef _ True _ = True
532+ checkTypeRef r acc (PositionedDeclarationRef _ _ h) = checkTypeRef r acc h
532 checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc
533 checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc
533 checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'
534 checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'
534 checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'
535 checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'
@@ -546,38 +547,39 @@ resolveImport currentModule importModule exps imps impQual =
547 -- Import something explicitly
548 -- Import something explicitly
548 importExplicit :: ImportEnvironment -> DeclarationRef -> m ImportEnvironment
549 importExplicit :: ImportEnvironment -> DeclarationRef -> m ImportEnvironment
549− importExplicit imp (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ importExplicit imp r
550+ importExplicit imp (PositionedDeclarationRef pos _ r) =
551+ rethrowWithPosition pos . warnWithPosition pos $ importExplicit imp r
550 importExplicit imp (ValueRef name) = do
552 importExplicit imp (ValueRef name) = do
551 values' <- updateImports (importedValues imp) name
553 values' <- updateImports (importedValues imp) name
552 return $ imp { importedValues = values' }
554 return $ imp { importedValues = values' }
553 importExplicit imp (TypeRef name dctors) = do
555 importExplicit imp (TypeRef name dctors) = do
554 types' <- updateImports (importedTypes imp) name
556 types' <- updateImports (importedTypes imp) name
555 let allDctors = allExportedDataConstructors name
557 let allDctors = allExportedDataConstructors name
556− dctors' <- maybe (return allDctors) (mapM $ (checkDctorExists name) allDctors) dctors
558+ maybe (return ()) (mapM_ $ checkDctorExists name allDctors) dctors
559+ when (null allDctors && isNothing dctors) . tell . errorMessage $ MisleadingEmptyTypeImport importModule name
557− dctors'' <- foldM updateImports (importedDataConstructors imp) dctors'
560+ dctors' <- foldM updateImports (importedDataConstructors imp) (fromMaybe allDctors dctors)
558− return $ imp { importedTypes = types', importedDataConstructors = dctors'' }
561+ return $ imp { importedTypes = types', importedDataConstructors = dctors' }
559 importExplicit imp (TypeClassRef name) = do
562 importExplicit imp (TypeClassRef name) = do
560 typeClasses' <- updateImports (importedTypeClasses imp) name
563 typeClasses' <- updateImports (importedTypeClasses imp) name
561 return $ imp { importedTypeClasses = typeClasses' }
564 return $ imp { importedTypeClasses = typeClasses' }
562 importExplicit _ _ = error "Invalid argument to importExplicit"
565 importExplicit _ _ = error "Invalid argument to importExplicit"
564 -- Check if DeclarationRef points to an existent symbol
567 -- Check if DeclarationRef points to an existent symbol
565− checkedRefs :: [DeclarationRef] -> m [DeclarationRef]
568+ checkedRefs :: [DeclarationRef] -> m ()
566− checkedRefs = mapM check
569+ checkedRefs = mapM_ check
568 check (PositionedDeclarationRef pos _ r) =
571 check (PositionedDeclarationRef pos _ r) =
569 rethrowWithPosition pos $ check r
572 rethrowWithPosition pos $ check r
570− check ref@(ValueRef name) =
573+ check (ValueRef name) =
571− checkImportExists UnknownImportValue values name >> return ref
574+ checkImportExists UnknownImportValue values name
572− check ref@(TypeRef name dctors) = do
575+ check (TypeRef name dctors) = do
573− _ <- checkImportExists UnknownImportType availableTypes name
576+ checkImportExists UnknownImportType availableTypes name
574 let allDctors = allExportedDataConstructors name
577 let allDctors = allExportedDataConstructors name
575− _ <- maybe (return allDctors) (mapM $ (checkDctorExists name) allDctors) dctors
578+ maybe (return ()) (mapM_ $ checkDctorExists name allDctors) dctors
577− check ref@(TypeClassRef name) =
579+ check (TypeClassRef name) =
578− checkImportExists UnknownImportTypeClass classes name >> return ref
580+ checkImportExists UnknownImportTypeClass classes name
579− check ref@(ModuleRef name) =
581+ check (ModuleRef name) =
580− checkImportExists (const UnknownModule) (exportedModules exps) name >> return ref
582+ checkImportExists (const UnknownModule) (exportedModules exps) name
581 check _ = error "Invalid argument to checkRefIsValid"
583 check _ = error "Invalid argument to checkRefIsValid"
583 -- Find all exported data constructors for a given type
585 -- Find all exported data constructors for a given type
@@ -605,15 +607,13 @@ resolveImport currentModule importModule exps imps impQual =
606 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
608 -- Ensure that an explicitly imported data constructor exists for the type it is being imported
608− checkDctorExists :: ProperName -> [ProperName] -> ProperName -> m ProperName
610+ checkDctorExists :: ProperName -> [ProperName] -> ProperName -> m ()
609 checkDctorExists tcon = checkImportExists (flip UnknownImportDataConstructor tcon)
611 checkDctorExists tcon = checkImportExists (flip UnknownImportDataConstructor tcon)
611 -- Check that an explicitly imported item exists in the module it is being imported from
613 -- Check that an explicitly imported item exists in the module it is being imported from
612− checkImportExists :: (Eq a, Show a) => (ModuleName -> a -> SimpleErrorMessage) -> [a] -> a -> m a
614+ checkImportExists :: (Eq a, Show a) => (ModuleName -> a -> SimpleErrorMessage) -> [a] -> a -> m ()
613 checkImportExists unknown exports item =
615 checkImportExists unknown exports item =
614− if item `elem` exports
616− else throwError . errorMessage $ unknown importModule item
616+ when (item `notElem` exports) $ throwError . errorMessage $ unknown importModule item
619-- Raises an error for when there is more than one definition for something.
619-- Raises an error for when there is more than one definition for something.