on master help sign in
Filter exports only when we are trying to import from a module

This way types that are not exported are still defined during type checking, but the user will get an error message if they try to use them directly.

commit14ef71a60e4ecfa896f3d145bacb33a4aa434797 authorEvan Czaplicki <info@elm-lang.org> dateSun 24 Aug 2014, 02:30 (12 years ago) parentdca59f7
6 files changed+69−54
Elm.cabal+2 compiler/AST/Module.hs+4−1 compiler/Build/Source.hs+2−3 compiler/Transform/Canonicalize.hs+1−48 compiler/Transform/Canonicalize/Setup.hs+3−2 compiler/Transform/Interface.hs+57
Elm.cabal+2
@@ -66,6 +66,7 @@ Library
6666 Transform.Expression,
6767 Transform.Declaration,
6868 Transform.Definition,
69+ Transform.Interface,
6970 Transform.SortDefinitions,
7071 Transform.Substitute,
7172 Metadata.Prelude,
@@ -156,6 +157,7 @@ Executable elm
156157 Transform.Expression,
157158 Transform.Declaration,
158159 Transform.Definition,
160+ Transform.Interface,
159161 Transform.SortDefinitions,
160162 Transform.Substitute,
161163 Metadata.Prelude,
compiler/AST/Module.hs+4−1
@@ -52,6 +52,7 @@ type CanonicalAdt = (Var.Canonical, AdtInfo Var.Canonical)
5252
5353data Interface = Interface
5454 { iVersion :: Version.Version
55+ , iExports :: [Var.Value]
5556 , iTypes :: Types
5657 , iImports :: [(String, ImportMethod)]
5758 , iAdts :: ADTs
@@ -65,6 +66,7 @@ toInterface modul =
6566 let body' = body modul in
6667 Interface
6768 { iVersion = Version.elmVersion
69+ , iExports = exports modul
6870 , iTypes = types body'
6971 , iImports = imports modul
7072 , iAdts = datatypes body'
@@ -74,9 +76,10 @@ toInterface modul =
7476 }
7577
7678instance Binary Interface where
77− get = Interface <$> get <*> get <*> get <*> get <*> get <*> get <*> get
79+ get = Interface <$> get <*> get <*> get <*> get <*> get <*> get <*> get <*> get
7880 put modul = do
7981 put (iVersion modul)
82+ put (iExports modul)
8083 put (iTypes modul)
8184 put (iImports modul)
8285 put (iAdts modul)
compiler/Build/Source.hs+2−3
@@ -29,8 +29,7 @@ build noPrelude interfaces source =
2929 -- Run type inference on the program.
3030 types <- TI.infer interfaces canonicalModule
3131
32− -- Trim down the set of exported values to the stuff that is actually exported.
33− let bodyWithTypes = (Module.body canonicalModule) { Module.types = types }
34− body = Canonical.filterExports bodyWithTypes (Module.exports canonicalModule)
32+ -- Add the real list of tyes
33+ let body = (Module.body canonicalModule) { Module.types = types }
3534
3635 return $ canonicalModule { Module.body = body }
compiler/Transform/Canonicalize.hs+1−48
@@ -1,5 +1,5 @@
11{-# OPTIONS_GHC -W #-}
2−module Transform.Canonicalize (module', filterExports) where
2+module Transform.Canonicalize (module') where
33
44import Control.Applicative ((<$>),(<*>))
55import Control.Monad.Error (runErrorT, throwError)
@@ -106,53 +106,6 @@ delist fullList (Var.Listing partial open)
106106
107107 _ -> go list xs partial
108108
109−filterExports :: Module.CanonicalBody -> [Var.Value] -> Module.CanonicalBody
110−filterExports body exportedValues =
111− body
112− { Module.types =
113− Map.fromList (concatMap getTypes exportedValues)
114− , Module.aliases =
115− Map.fromList (concatMap getAliases exportedValues)
116− , Module.datatypes =
117− Map.fromList (concatMap getAdts exportedValues)
118− }
119− where
120− get :: Map.Map String a -> String -> [(String, a)]
121− get dict x =
122− case Map.lookup x dict of
123− Just t -> [(x,t)]
124− Nothing -> []
125−
126− getTypes :: Var.Value -> [(String, Type.CanonicalType)]
127− getTypes value =
128− case value of
129− Var.Value x -> getType x
130− Var.Alias _ -> []
131− Var.ADT _ (Var.Listing ctors _) -> concatMap getType ctors
132−
133− getType :: String -> [(String, Type.CanonicalType)]
134− getType = get (Module.types body)
135−
136− getAliases :: Var.Value -> [(String, ([String], Type.CanonicalType))]
137− getAliases value =
138− case value of
139− Var.Value _ -> []
140− Var.Alias name -> get (Module.aliases body) name
141− Var.ADT _ _ -> []
142−
143− getAdts :: Var.Value -> [(String, Module.AdtInfo String)]
144− getAdts value =
145− case value of
146− Var.Value _ -> []
147− Var.Alias _ -> []
148− Var.ADT name (Var.Listing exportedCtors _) ->
149− case Map.lookup name (Module.datatypes body) of
150− Nothing -> []
151− Just (tvars, ctors) ->
152− [(name, (tvars, filter isExported ctors))]
153− where
154− isExported (ctor, _) = ctor `elem` exportedCtors
155−
156109
157110declToValue :: D.ValidDecl -> [Var.Value]
158111declToValue decl =
compiler/Transform/Canonicalize/Setup.hs+3−2
@@ -21,6 +21,7 @@ import Text.PrettyPrint as P
2121
2222import Transform.Canonicalize.Environment as Env
2323import qualified Transform.Canonicalize.Type as Canonicalize
24+import qualified Transform.Interface as Interface
2425
2526environment :: Module.Interfaces -> Module.ValidModule -> Canonicalizer [Doc] Environment
2627environment interfaces modul@(Module.Module _ _ _ imports decls) =
@@ -48,7 +49,7 @@ environment interfaces modul@(Module.Module _ _ _ imports decls) =
4849
4950addImports :: String -> Module.Interfaces -> Environment -> (String, Module.ImportMethod)
5051 -> Canonicalizer [Doc] Environment
51−addImports moduleName interfaces environ (name,method)
52+addImports moduleName interfaces environ (name, method)
5253 | List.isPrefixOf "Native." name = return environ
5354 | otherwise =
5455 case method of
@@ -59,7 +60,7 @@ addImports moduleName interfaces environ (name,method)
5960 | open -> return (updateEnviron "")
6061 | otherwise -> foldM (addValue name interface) environ vs
6162 where
62− interface = (Map.!) interfaces name
63+ interface = Interface.filterExports ((Map.!) interfaces name)
6364
6465 updateEnviron prefix =
6566 let dict' = dict . map (first (prefix++)) in
compiler/Transform/Interface.hsnew file+57
@@ -0,0 +1,57 @@
1+{-# OPTIONS_GHC -W #-}
2+module Transform.Interface (filterExports) where
3+
4+import qualified Data.Map as Map
5+import qualified AST.Module as Module
6+import qualified AST.Type as Type
7+import qualified AST.Variable as Var
8+
9+filterExports :: Module.Interface -> Module.Interface
10+filterExports interface =
11+ interface
12+ { Module.iTypes =
13+ Map.fromList (concatMap getTypes exportedValues)
14+ , Module.iAliases =
15+ Map.fromList (concatMap getAliases exportedValues)
16+ , Module.iAdts =
17+ Map.fromList (concatMap getAdts exportedValues)
18+ }
19+ where
20+ exportedValues :: [Var.Value]
21+ exportedValues = Module.iExports interface
22+
23+ get :: Map.Map String a -> String -> [(String, a)]
24+ get dict x =
25+ case Map.lookup x dict of
26+ Just t -> [(x,t)]
27+ Nothing -> []
28+
29+ getTypes :: Var.Value -> [(String, Type.CanonicalType)]
30+ getTypes value =
31+ case value of
32+ Var.Value x -> getType x
33+ Var.Alias _ -> []
34+ Var.ADT _ (Var.Listing ctors _) -> concatMap getType ctors
35+
36+ getType :: String -> [(String, Type.CanonicalType)]
37+ getType = get (Module.iTypes interface)
38+
39+ getAliases :: Var.Value -> [(String, ([String], Type.CanonicalType))]
40+ getAliases value =
41+ case value of
42+ Var.Value _ -> []
43+ Var.Alias name -> get (Module.iAliases interface) name
44+ Var.ADT _ _ -> []
45+
46+ getAdts :: Var.Value -> [(String, Module.AdtInfo String)]
47+ getAdts value =
48+ case value of
49+ Var.Value _ -> []
50+ Var.Alias _ -> []
51+ Var.ADT name (Var.Listing exportedCtors _) ->
52+ case Map.lookup name (Module.iAdts interface) of
53+ Nothing -> []
54+ Just (tvars, ctors) ->
55+ [(name, (tvars, filter isExported ctors))]
56+ where
57+ isExported (ctor, _) = ctor `elem` exportedCtors