1{-# OPTIONS_GHC -Wall #-}
2module Elm.Compiler.Type.Extract
8import qualified Control.Monad.Writer as Writer
9import qualified Data.Map as Map
10import qualified Data.Set as Set
11import qualified AST.Module as Module
12import qualified AST.Module.Name as ModuleName
13import qualified AST.Type as T
14import qualified AST.Variable as Var
15import Elm.Compiler.Type (Type(..), Program(Program))
22extract :: T.Canonical -> Type
24 fst $ Writer.runWriter $ extractHelp astType
28 ( Set.Set Var.Canonical -- aliases
29 , Set.Set Var.Canonical -- unions
33diff :: Deps -> Deps -> Deps
34diff (oldAliases, oldUnions) (newAliases, newUnions) =
35 ( Set.difference newAliases oldAliases
36 , Set.difference newUnions oldUnions
40extractHelp :: T.Canonical -> Writer.Writer Deps Type
43 T.Lambda arg result ->
44 Lambda <$> extractHelp arg <*> extractHelp result
50 do Writer.tell ( Set.empty, Set.singleton var )
51 return $ Type $ Var.toString var
53 T.App constructor args ->
54 App <$> extractHelp constructor <*> traverse extractHelp args
56 T.Record fields ext ->
58 <$> traverse (traverse extractHelp) fields
59 <*> traverse extractHelp ext
61 T.Aliased name args aliasedType ->
62 do Writer.tell ( Set.singleton name, Set.empty )
63 _ <- extractHelp (T.dealias args aliasedType)
64 App (Type (Var.toString name)) <$> traverse (extractHelp . snd) args
68-- EXTRACT MODEL, MSG, AND ANY TRANSITIVE DEPENDENCIES
71extractProgram :: Module.Interfaces -> ModuleName.Canonical -> Maybe Program
72extractProgram interfaces name =
73 do iface <- Map.lookup name interfaces
74 mainType <- Map.lookup "main" (Module.iTypes iface)
76 T.App _program [_flags, model, msg] ->
78 (modelType, modelDeps) =
79 Writer.runWriter (extractHelp model)
82 Writer.runWriter (extractHelp msg)
85 extractTransitive interfaces mempty (mappend modelDeps msgDeps)
87 Just $ Program modelType msgType aliases unions
94 ( String, [String], Type )
98 ( String, [String], [(String, [Type])] )
101extractTransitive :: Module.Interfaces -> Deps -> Deps -> ( [Alias], [Union] )
102extractTransitive interfaces oldDeps currentDeps =
105 diff oldDeps currentDeps
107 if Set.null aliases && Set.null unions then
115 <$> mapM (extractAlias interfaces) (Set.toList aliases)
116 <*> mapM (extractUnion interfaces) (Set.toList unions)
119 extractTransitive interfaces (mappend oldDeps currentDeps) newDeps
121 mappend result remainingResult
124extractAlias :: Module.Interfaces -> Var.Canonical -> Writer.Writer Deps Alias
125extractAlias interfaces var =
126 case get Module.iAliases interfaces var of
128 return ( Var.toString var, [], Type "_Tuple0" )
131 (,,) (Var.toString var) args
135extractUnion :: Module.Interfaces -> Var.Canonical -> Writer.Writer Deps Union
136extractUnion interfaces var =
137 case get Module.iUnions interfaces var of
139 return ( Var.toString var, [], [] )
141 Just (args, constructors) ->
142 (,,) (Var.toString var) args
143 <$> traverse (traverse (traverse extractHelp)) constructors
146get :: (Module.Interface -> Map.Map String a) -> Module.Interfaces -> Var.Canonical -> Maybe a
147get getInfo interfaces var =
148 do (home, name) <- getHome var
149 iface <- Map.lookup home interfaces
150 Map.lookup name (getInfo iface)
153getHome :: Var.Canonical -> Maybe (ModuleName.Canonical, String)
154getHome (Var.Canonical home name) =
159 Var.Module moduleName ->
160 Just (moduleName, name)
162 Var.TopLevel moduleName ->
163 Just (moduleName, name)
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