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.Maybe as Maybe
11import qualified Data.Set as Set
12import qualified AST.Module as Module
13import qualified AST.Module.Name as ModuleName
14import qualified AST.Type as T
15import qualified AST.Variable as Var
16import Elm.Compiler.Type (Type(..), Program(Program))
23extract :: T.Canonical -> Type
25 fst $ Writer.runWriter $ extractHelp astType
29 ( Set.Set Var.Canonical -- aliases
30 , Set.Set Var.Canonical -- unions
34diff :: Deps -> Deps -> Deps
35diff (oldAliases, oldUnions) (newAliases, newUnions) =
36 ( Set.difference newAliases oldAliases
37 , Set.difference newUnions oldUnions
41extractHelp :: T.Canonical -> Writer.Writer Deps Type
44 T.Lambda arg result ->
45 Lambda <$> extractHelp arg <*> extractHelp result
51 do Writer.tell ( Set.empty, Set.singleton var )
52 return $ Type $ Var.toString var
54 T.App constructor args ->
55 App <$> extractHelp constructor <*> traverse extractHelp args
57 T.Record fields ext ->
59 <$> traverse (traverse extractHelp) fields
60 <*> traverse extractHelp ext
62 T.Aliased name args aliasedType ->
63 do Writer.tell ( Set.singleton name, Set.empty )
64 _ <- extractHelp (T.dealias args aliasedType)
65 App (Type (Var.toString name)) <$> traverse (extractHelp . snd) args
69-- EXTRACT MODEL, MSG, AND ANY TRANSITIVE DEPENDENCIES
72extractProgram :: Module.Interfaces -> ModuleName.Canonical -> Maybe Program
73extractProgram interfaces name =
74 do iface <- Map.lookup name interfaces
75 mainType <- Map.lookup "main" (Module.iTypes iface)
78 case T.deepDealias mainType of
79 T.App _program [_flags, _model, msg] -> Just msg
80 T.App _node [msg] -> Just msg
83 let (msgType, msgDeps) = Writer.runWriter (extractHelp message)
84 let (aliases, unions) = extractTransitive interfaces mempty msgDeps
85 Just $ Program msgType aliases unions
89 ( String, [String], Type )
93 ( String, [String], [(String, [Type])] )
96extractTransitive :: Module.Interfaces -> Deps -> Deps -> ( [Alias], [Union] )
97extractTransitive interfaces oldDeps currentDeps =
100 diff oldDeps currentDeps
102 if Set.null aliases && Set.null unions then
108 Writer.runWriter $ do
109 publicAliases <- mapM (extractAlias interfaces) (Set.toList aliases)
110 publicUnions <- mapM (extractUnion interfaces) (Set.toList unions)
111 return ( Maybe.catMaybes publicAliases, Maybe.catMaybes publicUnions )
114 extractTransitive interfaces (mappend oldDeps currentDeps) newDeps
116 mappend result remainingResult
119extractAlias :: Module.Interfaces -> Var.Canonical -> Writer.Writer Deps (Maybe Alias)
120extractAlias interfaces var =
122 toAlias (args, tipe) =
123 (,,) (Var.toString var) args <$> extractHelp tipe
125 traverse toAlias (get Module.iAliases interfaces var)
128extractUnion :: Module.Interfaces -> Var.Canonical -> Writer.Writer Deps (Maybe Union)
129extractUnion interfaces var =
131 toUnion (args, constructors) =
132 (,,) (Var.toString var) args
133 <$> traverse (traverse (traverse extractHelp)) constructors
135 traverse toUnion (get Module.iUnions interfaces var)
138get :: (Module.Interface -> Map.Map String a) -> Module.Interfaces -> Var.Canonical -> Maybe a
139get getInfo interfaces var =
140 do (home, name) <- getHome var
141 iface <- Map.lookup home interfaces
142 Map.lookup name (getInfo iface)
145getHome :: Var.Canonical -> Maybe (ModuleName.Canonical, String)
146getHome (Var.Canonical home name) =
151 Var.Module moduleName ->
152 Just (moduleName, name)
154 Var.TopLevel moduleName ->
155 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