@@ -17,63 +17,84 @@ module Language.PureScript.Sugar.Names (
19import Control.Applicative ((<$>))
19import Control.Applicative ((<$>))
20−import Control.Arrow (first)
21−import Data.Maybe (fromJust)
22−import Data.Generics (mkM, everywhereM)
20+import Data.Generics (extM, mkM, everywhereM)
23import qualified Data.Map as M
21import qualified Data.Map as M
24import qualified Data.Set as S
22import qualified Data.Set as S
25−import Data.Generics.Extras
26import Language.PureScript.Declarations
23import Language.PureScript.Declarations
27import Language.PureScript.Names
24import Language.PureScript.Names
28import Language.PureScript.Types
25import Language.PureScript.Types
29−import Language.PureScript.Pretty.Types
26+import Language.PureScript.Values
30import Debug.Trace
27import Debug.Trace
29+data ExportEnvironment = ExportEnvironment
30+ { exportedDataConstructors :: M.Map ModuleName (S.Set ProperName)
32−data ExportEnvironment = ExportEnvironment { exportedTypeClasses :: M.Map ModuleName (S.Set ProperName) } deriving (Show)
31+ , exportedTypeClasses :: M.Map ModuleName (S.Set ProperName)
34+data ImportEnvironment = ImportEnvironment
35+ { importedDataConstructors :: M.Map ProperName (Qualified ProperName)
33−data ImportEnvironment = ImportEnvironment { importedTypeClasses :: M.Map ProperName (Qualified ProperName) } deriving (Show)
36+ , importedTypeClasses :: M.Map ProperName (Qualified ProperName)
35−nullEnv = ExportEnvironment M.empty
39+nullEnv = ExportEnvironment M.empty M.empty
41+addDataConstructor :: ExportEnvironment -> ModuleName -> ProperName -> ExportEnvironment
42+addDataConstructor env mn id = env { exportedDataConstructors = M.insertWith S.union mn (S.singleton id) (exportedDataConstructors env) }
37addTypeclass :: ExportEnvironment -> ModuleName -> ProperName -> ExportEnvironment
44addTypeclass :: ExportEnvironment -> ModuleName -> ProperName -> ExportEnvironment
38addTypeclass env mn id = env { exportedTypeClasses = M.insertWith S.union mn (S.singleton id) (exportedTypeClasses env) }
45addTypeclass env mn id = env { exportedTypeClasses = M.insertWith S.union mn (S.singleton id) (exportedTypeClasses env) }
40rename :: [Module] -> Either String [Module]
47rename :: [Module] -> Either String [Module]
41−rename modules = mapM (renameInModule $ findExports modules) modules
48+rename modules = trace (show $ findExports modules) $ mapM (renameInModule $ findExports modules) modules
43renameInModule :: ExportEnvironment -> Module -> Either String Module
50renameInModule :: ExportEnvironment -> Module -> Either String Module
44−renameInModule exports m@(Module mn decls) = Module mn <$> everywhereM (mkM updateDecl) decls >>= everywhereM (mkM updateType)
51+renameInModule exports m@(Module mn decls) = Module mn <$> mapM updateDecl decls >>= everywhereM (mkM updateType) >>= everywhereM (mkM updateValue) >>= everywhereM (mkM updateBinder)
46− updateDecl (TypeInstanceDeclaration cs cn ts ds) = do
53+ updateDecl (TypeInstanceDeclaration cs (Qualified Nothing cn) ts ds) = do
47 cn' <- updateClassName cn
54 cn' <- updateClassName cn
48 cs' <- updateConstraints cs
55 cs' <- updateConstraints cs
49 return $ TypeInstanceDeclaration cs' cn' ts ds
56 return $ TypeInstanceDeclaration cs' cn' ts ds
50 updateDecl d = return d
57 updateDecl d = return d
58+ updateValue (Constructor (Qualified Nothing nm)) = do
59+ nm' <- updateDataConstructorName nm
60+ return $ Constructor nm'
61+ updateValue v = return v
62+ updateBinder (ConstructorBinder (Qualified Nothing nm) b) = do
63+ nm' <- updateDataConstructorName nm
64+ return $ ConstructorBinder nm' b
65+ updateBinder v = return v
51 updateType (ConstrainedType cs t) = do
66 updateType (ConstrainedType cs t) = do
52 cs' <- updateConstraints cs
67 cs' <- updateConstraints cs
53 return $ ConstrainedType cs' t
68 return $ ConstrainedType cs' t
54 updateType t = return t
69 updateType t = return t
55 updateConstraints = mapM updateConstraint
70 updateConstraints = mapM updateConstraint
56− updateConstraint (nm, ts) = do
71+ updateConstraint (Qualified Nothing nm, ts) = do
57 nm' <- updateClassName nm
72 nm' <- updateClassName nm
58 return (nm', ts)
73 return (nm', ts)
59− updateClassName (Qualified Nothing nm) =
74+ updateConstraint other = return other
60− maybe (Left $ "Unknown typeclass '" ++ show nm ++ "'") Right $ M.lookup nm (importedTypeClasses imports)
76+ maybe (err "typeclass" nm mn) return $ M.lookup nm (importedTypeClasses imports)
61− updateClassName q = return q
77+ updateDataConstructorName nm =
78+ maybe (err "data constructor" nm mn) return $ M.lookup nm (importedDataConstructors imports)
62 imports = resolveImports exports m
79 imports = resolveImports exports m
80+ err t nm mn = Left $ "Unknown " ++ t ++ " '" ++ show nm ++ "' in module '" ++ show mn ++ "'"
64findExports :: [Module] -> ExportEnvironment
82findExports :: [Module] -> ExportEnvironment
65findExports = foldl addModule nullEnv
83findExports = foldl addModule nullEnv
67 addModule env (Module mn ds) = foldl (addDecl mn) env ds
85 addModule env (Module mn ds) = foldl (addDecl mn) env ds
68 addDecl mn env (TypeClassDeclaration tcn _ _) = addTypeclass env mn tcn
86 addDecl mn env (TypeClassDeclaration tcn _ _) = addTypeclass env mn tcn
87+ addDecl mn env (DataDeclaration tcn _ dcs) = foldl (flip addDataConstructor mn) env (map fst dcs)
69 addDecl _ env _ = env
88 addDecl _ env _ = env
71findImports :: [Declaration] -> [ModuleName]
90findImports :: [Declaration] -> [ModuleName]
72findImports decls = [ mn | (ImportDeclaration mn Nothing) <- decls ]
91findImports decls = [ mn | (ImportDeclaration mn Nothing) <- decls ]
74resolveImports :: ExportEnvironment -> Module -> ImportEnvironment
93resolveImports :: ExportEnvironment -> Module -> ImportEnvironment
75−resolveImports env (Module mn decls) = ImportEnvironment $ resolve (mn : findImports decls) (exportedTypeClasses env)
94+resolveImports env (Module mn decls) = ImportEnvironment (resolve scope $ exportedDataConstructors env)
95+ (resolve scope $ exportedTypeClasses env)
97+ scope = (mn : findImports decls)
77 resolve imns = M.foldlWithKey (resolveDefs imns) M.empty
98 resolve imns = M.foldlWithKey (resolveDefs imns) M.empty
78 resolveDefs imns result mn ids | mn `elem` imns = S.foldl (resolveDef mn) result ids
99 resolveDefs imns result mn ids | mn `elem` imns = S.foldl (resolveDef mn) result ids
79 resolveDefs imns result mn ids = result
100 resolveDefs imns result mn ids = result