@@ -17,7 +17,7 @@
18module Language.PureScript.TypeChecker (
18module Language.PureScript.TypeChecker (
20− typeCheckAll
20+ typeCheckModule
23import Language.PureScript.TypeChecker.Monad as T
23import Language.PureScript.TypeChecker.Monad as T
@@ -26,7 +26,7 @@ import Language.PureScript.TypeChecker.Types as T
26import Language.PureScript.TypeChecker.Synonyms as T
26import Language.PureScript.TypeChecker.Synonyms as T
28import Data.Maybe
28import Data.Maybe
29−import Data.List (nub, (\\))
29+import Data.List (nub, (\\), find)
30import Data.Monoid ((<>))
30import Data.Monoid ((<>))
31import Data.Foldable (for_)
31import Data.Foldable (for_)
32import qualified Data.Map as M
32import qualified Data.Map as M
@@ -119,7 +119,7 @@ checkTypeClassInstance _ ty = throwError $ mkErrorStack "Type class instance hea
120-- * Process module imports
120-- * Process module imports
122−typeCheckAll :: Maybe ModuleName -> ModuleName -> Maybe [DeclarationRef] -> [Declaration] -> Check [Declaration]
122+typeCheckAll :: Maybe ModuleName -> ModuleName -> [DeclarationRef] -> [Declaration] -> Check [Declaration]
123typeCheckAll mainModuleName moduleName exps = go
123typeCheckAll mainModuleName moduleName exps = go
125 go :: [Declaration] -> Check [Declaration]
125 go :: [Declaration] -> Check [Declaration]
@@ -229,18 +229,49 @@ typeCheckAll mainModuleName moduleName exps = go
229 return $ d : ds
229 return $ d : ds
231 isInstanceExported :: Bool
231 isInstanceExported :: Bool
232− isInstanceExported = maybe True (any exportsInstance) exps
232+ isInstanceExported = any exportsInstance exps
234 exportsInstance :: DeclarationRef -> Bool
234 exportsInstance :: DeclarationRef -> Bool
235 exportsInstance (TypeInstanceRef name) | name == dictName = True
235 exportsInstance (TypeInstanceRef name) | name == dictName = True
236 exportsInstance (PositionedDeclarationRef _ r) = exportsInstance r
236 exportsInstance (PositionedDeclarationRef _ r) = exportsInstance r
237 exportsInstance _ = False
237 exportsInstance _ = False
239 go (PositionedDeclaration pos d : rest) =
239 go (PositionedDeclaration pos d : rest) =
240 rethrowWithPosition pos $ do
240 rethrowWithPosition pos $ do
241 (d' : rest') <- go (d : rest)
241 (d' : rest') <- go (d : rest)
242 return (PositionedDeclaration pos d' : rest')
242 return (PositionedDeclaration pos d' : rest')
244+typeCheckModule :: Maybe ModuleName -> Module -> Check Module
245+typeCheckModule _ (Module _ _ Nothing) = error "exports should have been elaborated"
246+typeCheckModule mainModuleName (Module mn decls (Just exps)) = do
247+ modify (\s -> s { checkCurrentModule = Just mn })
248+ decls' <- typeCheckAll mainModuleName mn exps decls
249+ mapM_ checkTypesAreExported exps
250+ return $ Module mn decls' (Just exps)
253+ -- Check that all the type constructors defined in the current module that appear in member types
254+ -- have also been exported from the module
255+ checkTypesAreExported :: DeclarationRef -> Check ()
256+ checkTypesAreExported (ValueRef name) = do
257+ ty <- lookupVariable mn (Qualified (Just mn) name)
258+ case find isTconHidden (findTcons ty) of
259+ Just hiddenType -> throwError . strMsg $
260+ "Error in module '" ++ show mn ++ "':\n\
261+ \Exporting declaration '" ++ show name ++ "' requires type '" ++ show hiddenType ++ "' to be exported as well"
262+ Nothing -> return ()
263+ checkTypesAreExported _ = return ()
265+ -- Find the type constructors exported from the current module used in a type
266+ findTcons :: Type -> [ProperName]
267+ findTcons = everythingOnTypes (++) go
269+ go (TypeConstructor (Qualified (Just mn') name)) | mn' == mn = [name]
272+ -- Checks whether a type constructor is not being exported from the current module
273+ isTconHidden :: ProperName -> Bool
274+ isTconHidden tyName = all go exps
276+ go (TypeRef tyName' _) = tyName' /= tyName