1{-# OPTIONS_GHC -Wall #-}
2module Canonicalize.Setup (environment) where
4import Control.Applicative ((<$>))
5import Control.Arrow (second)
6import qualified Data.Graph as Graph
7import qualified Data.Map as Map
8import qualified Data.Maybe as Maybe
9import qualified Data.Traversable as Trav
11import qualified AST.Declaration as D
12import qualified AST.Expression.Valid as Valid
13import qualified AST.Module as Module
14import qualified AST.Pattern as P
15import qualified AST.Type as Type
16import qualified AST.Variable as Var
17import Elm.Utils ((|>))
18import qualified Reporting.Annotation as A
19import qualified Reporting.Error.Canonicalize as Error
20import qualified Reporting.Region as R
21import qualified Canonicalize.Environment as Env
22import qualified Canonicalize.Result as Result
23import qualified Canonicalize.Type as Canonicalize
29 -> Result.ResultErr Env.Environment
30environment interfaces modul@(Module.Module _ _ _ (defaults, imports) decls) =
35 imports ++ map (A.A (error "default import not found")) defaults
38 concat <$> Trav.traverse (importPatches interfaces) allImports
40 (typeAliasNodes, declPatches) =
41 declarationsToPatches moduleName decls
44 (++) (Env.builtinPatches ++ declPatches) <$> importPatchesResult
46 (Env.fromPatches moduleName <$> patches)
47 `Result.andThen` addTypeAliases moduleName typeAliasNodes
54 -> A.Located (Module.Name, Module.ImportMethod)
55 -> Result.ResultErr [Env.Patch]
56importPatches allInterfaces (A.A region (importName, method)) =
57 case restrictToPublicApi <$> Map.lookup importName allInterfaces of
59 | Module.nameIsNative importName ->
65 |> Error.nearbyNames Module.nameToString importName
66 |> Error.moduleNotFound importName
71 let (Module.ImportMethod maybeAlias listing) =
74 (Var.Listing exposedValues open) =
78 maybe (Module.nameToString importName) id maybeAlias
81 interfacePatches importName (qualifier ++ ".") interface
85 then Result.ok (interfacePatches importName "" interface)
86 else concat <$> Trav.traverse (valueToPatches region importName interface) exposedValues
88 (++) qualifiedPatches <$> unqualifiedPatches
91interfacePatches :: Module.Name -> String -> Module.Interface -> [Env.Patch]
92interfacePatches moduleName prefix interface =
93 let genericPatch mkPatch name value =
94 mkPatch (prefix ++ name) value
97 genericPatch mkPatch name (Var.fromModule moduleName name)
99 aliasPatch (name, (tvars, tipe)) =
100 genericPatch Env.Alias name
101 (Var.fromModule moduleName name, tvars, tipe)
103 patternPatch (name, args) =
104 genericPatch Env.Pattern name
105 (Var.fromModule moduleName name, length args)
108 concatMap snd (Map.elems (Module.iAdts interface))
114 [ map (patch Env.Value) (Map.keys (Module.iTypes interface))
115 , map (patch Env.Value) ctorNames
116 , map (patch Env.Union) (Map.keys (Module.iAdts interface))
117 , map aliasPatch (Map.toList (Module.iAliases interface))
118 , map patternPatch ctors
122-- PATCHES FOR INDIVIDUAL VALUES
129 -> Result.ResultErr [Env.Patch]
130valueToPatches region moduleName interface value =
131 let patch mkPatch x =
132 mkPatch x (Var.fromModule moduleName x)
134 patternPatch (x, numArgs) =
135 Env.Pattern x (Var.fromModule moduleName x, numArgs)
137 notFound getNames x =
138 Module.iExports interface
140 |> Error.nearbyNames id x
141 |> Error.valueNotFound moduleName x
147 | Map.notMember x (Module.iTypes interface) ->
148 notFound Var.getValues x
151 Result.ok [patch Env.Value x]
154 case Map.lookup x (Module.iAliases interface) of
157 Env.Alias x (Var.fromModule moduleName x, tvars, t)
160 if Map.member x (Module.iTypes interface)
161 then [alias, patch Env.Value x]
165 case Map.lookup x (Module.iAdts interface) of
167 Result.ok [patch Env.Union x]
170 let getNames values =
171 Var.getAliases values
172 ++ map fst (Var.getUnions values)
176 Var.Union givenName (Var.Listing givenCtorNames open) ->
177 case Map.lookup givenName (Module.iAdts interface) of
179 notFound (map fst . Var.getUnions) givenName
181 Just (_tvars, realCtors) ->
184 then Result.ok realCtorList
185 else Trav.traverse ctorExists givenCtorNames
188 map (second length) realCtors
191 Map.fromList realCtorList
193 ctorExists givenCtorName =
194 case Map.lookup givenCtorName realCtorDict of
196 Result.ok (givenCtorName, numArgs)
198 notFound (const (map fst realCtors)) givenCtorName
201 patch Env.Union givenName
202 : map (patch Env.Value . fst) ctors
203 ++ map patternPatch ctors
206-- PATCHES FOR TYPE ALIASES
208type Node = ((R.Region, String, [String], Type.Raw), String, [String])
211node :: R.Region -> String -> [String] -> Type.Raw -> Node
212node region name tvars alias =
213 ((region, name, tvars, alias), name, edges alias)
217 Type.RLambda t1 t2 ->
223 Type.RType (Var.Raw x) ->
227 edges t ++ concatMap edges ts
229 Type.RRecord fs ext ->
230 maybe [] edges ext ++ concatMap (edges . snd) fs
237 -> Result.ResultErr Env.Environment
238addTypeAliases moduleName typeAliasNodes initialEnv =
240 (addTypeAlias moduleName)
242 (Graph.stronglyConnComp typeAliasNodes)
247 -> Graph.SCC (R.Region, String, [String], Type.Raw)
249 -> Result.ResultErr Env.Environment
250addTypeAlias moduleName scc env =
252 Graph.AcyclicSCC (_, name, tvars, alias) ->
253 addToEnv <$> Canonicalize.tipe env alias
257 (Var.fromModule moduleName name, tvars, alias')
259 env { Env._aliases = Env.insert name value (Env._aliases env) }
261 Graph.CyclicSCC [] ->
264 Graph.CyclicSCC [(region, name, tvars, alias)] ->
265 Result.err (A.A region (Error.Alias (Error.SelfRecursive name tvars alias)))
267 Graph.CyclicSCC aliases@((region, _, _, _) : _) ->
268 Result.err (A.A region (Error.Alias (Error.MutuallyRecursive aliases)))
271-- DECLARATIONS TO PATCHES
276 -> ([Node], [Env.Patch])
277declarationsToPatches moduleName decls =
278 let (maybeNodes, patchLists) =
279 unzip (map (declToPatches moduleName) decls)
281 (Maybe.catMaybes maybeNodes, concat patchLists)
284-- When canonicalizing, all _values should be Local, but all _adts and _patterns
285-- should be fully namespaced. With _adts, they may appear in types that can
290 -> (Maybe Node, [Env.Patch])
291declToPatches moduleName (A.A region decl) =
292 let local mkPatch x =
293 mkPatch x (Var.local x)
295 namespaced mkPatch x =
296 mkPatch x (Var.fromModule moduleName x)
298 patternPatch (name, args) =
299 Env.Pattern name (Var.fromModule moduleName name, length args)
302 D.Definition (Valid.Definition pattern _ _) ->
304 , map (local Env.Value) (P.boundVarList pattern)
307 D.Datatype name _ ctors ->
308 let ctorNames = map fst ctors
311 , namespaced Env.Union name
312 : map (local Env.Value) ctorNames
313 ++ map patternPatch ctors
316 D.TypeAlias name tvars alias ->
317 ( Just (node region name tvars alias)
319 A.A _ (Type.RRecord _ _) ->
320 [local Env.Value name]
327 , [local Env.Value (D.validPortName port)]
336-- RESTRICT VISIBLE API OF INTERFACES
338restrictToPublicApi :: Module.Interface -> Module.Interface
339restrictToPublicApi interface =
344 (get (Module.iTypes interface))
345 (Var.getValues exports ++ ctors)
350 (get (Module.iAliases interface))
351 (Var.getAliases exports)
355 (Maybe.mapMaybe (trimUnions interface) unions)
358 exports :: [Var.Value]
360 Module.iExports interface
362 unions :: [(String, Var.Listing String)]
364 Var.getUnions exports
368 concatMap (\(_, Var.Listing ctorList _) -> ctorList) unions
371get :: Map.Map String a -> String -> Maybe (String, a)
373 case Map.lookup key dict of
375 Just value -> Just (key, value)
380 -> (String, Var.Listing String)
381 -> Maybe (String, Module.AdtInfo String)
382trimUnions interface (name, Var.Listing exportedCtors _) =
383 case Map.lookup name (Module.iAdts interface) of
385 Just (tvars, ctors) ->
386 let isExported (ctor, _) =
387 ctor `elem` exportedCtors
389 Just (name, (tvars, filter isExported ctors))
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list