@@ -26,15 +26,15 @@ import Language.PureScript.TypeChecker.Synonyms as T
2626
2727import Data.Maybe
2828import qualified Data.Map as M
29+import Control.Monad.State
30+import Control.Monad.Error
31+import Data.Either (rights, lefts)
2932
3033import Language.PureScript.Types
3134import Language.PureScript.Names
3235import Language.PureScript.Kinds
3336import Language.PureScript.Declarations
3437
35−import Control.Monad.State
36−import Control.Monad.Error
37−
3838typeCheckAll :: ModuleName -> [Declaration] -> Check ()
3939typeCheckAll _ [] = return ()
4040typeCheckAll moduleName (DataDeclaration name args dctors : rest) = do
@@ -122,15 +122,39 @@ typeCheckAll currentModule (ImportDeclaration moduleName idents : rest) = do
122122 rethrow errorMessage $ do
123123 guardWith ("Module " ++ show moduleName ++ " does not exist") $ moduleExists env
124124 case idents of
125− Nothing -> bindIdents (map snd $ filterModule env) env
126− Just idents' -> bindIdents idents' env
127− typeCheckAll moduleName rest
125+ Nothing -> do
126+ bindIdents (map snd $ filterModule (names env)) env
127+ bindTypes (map snd $ filterModule (types env)) env
128+ Just idents' -> do
129+ bindIdents (lefts idents') env
130+ bindTypes (rights idents') env
131+ typeCheckAll currentModule rest
128132 where errorMessage = (("Error in import declaration " ++ show moduleName ++ ":\n") ++)
129− filterModule = filter ((== moduleName) . fst) . M.keys . names
130− moduleExists env = not $ null $ filterModule env
133+ filterModule = filter ((== moduleName) . fst) . M.keys
134+ moduleExists env = not (null (filterModule (names env))) || not (null (filterModule (types env)))
131135 bindIdents idents' env =
132136 forM_ idents' $ \ident -> do
133137 guardWith (show currentModule ++ "." ++ show ident ++ " is already defined") $ (currentModule, ident) `M.notMember` names env
134138 case (moduleName, ident) `M.lookup` names env of
135139 Just (pt, _) -> modifyEnv (\e -> e { names = M.insert (currentModule, ident) (pt, Alias moduleName ident) (names e) })
136140 Nothing -> throwError (show moduleName ++ "." ++ show ident ++ " is undefined")
141+ bindTypes pns env =
142+ forM_ pns $ \pn -> do
143+ guardWith (show currentModule ++ "." ++ show pn ++ " is already defined") $ (currentModule, pn) `M.notMember` types env
144+ case (moduleName, pn) `M.lookup` types env of
145+ Nothing -> throwError (show moduleName ++ "." ++ show pn ++ " is undefined")
146+ Just (k, _) -> do
147+ modifyEnv (\e -> e { types = M.insert (currentModule, pn) (k, DataAlias moduleName pn) (types e) })
148+ let keys = map (snd . fst) . filter (\(_, fn) -> fn `constructs` pn) . M.toList . dataConstructors $ env
149+ forM_ keys $ \dctor -> do
150+ guardWith (show currentModule ++ "." ++ show dctor ++ " is already defined") $ (currentModule, dctor) `M.notMember` dataConstructors env
151+ case (moduleName, dctor) `M.lookup` dataConstructors env of
152+ Just ctorTy -> modifyEnv (\e -> e { dataConstructors = M.insert (currentModule, dctor) ctorTy (dataConstructors e) })
153+ Nothing -> throwError (show moduleName ++ "." ++ show dctor ++ " is undefined")
154+ constructs (TypeConstructor (Qualified (Just mn) pn')) pn
155+ = mn == moduleName && pn' == pn
156+ constructs (ForAll _ ty) pn = ty `constructs` pn
157+ constructs (Function _ ty) pn = ty `constructs` pn
158+ constructs (TypeApp ty _) pn = ty `constructs` pn
159+ constructs fn _ = error $ "Invalid arguments to construct" ++ show fn
160+