1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Elm.Compiler.Type.Extract
9import qualified Control.Monad.Writer as Writer
10import qualified Data.Map as Map
11import qualified Data.Maybe as Maybe
12import qualified Data.Set as Set
13import Data.Text (Text)
15import qualified AST.Module as Module
16import qualified AST.Module.Name as ModuleName
17import qualified AST.Type as T
18import qualified AST.Variable as Var
19import Elm.Compiler.Type (Type(..), Program(Program))
26extract :: T.Canonical -> Type
28 fst $ Writer.runWriter $ extractHelp astType
32 ( Set.Set Var.Canonical -- aliases
33 , Set.Set Var.Canonical -- unions
37diff :: Deps -> Deps -> Deps
38diff (oldAliases, oldUnions) (newAliases, newUnions) =
39 ( Set.difference newAliases oldAliases
40 , Set.difference newUnions oldUnions
44extractHelp :: T.Canonical -> Writer.Writer Deps Type
47 T.Lambda arg result ->
48 Lambda <$> extractHelp arg <*> extractHelp result
54 do Writer.tell ( Set.empty, Set.singleton var )
55 return (Type (Var.toText var))
57 T.App constructor args ->
58 App <$> extractHelp constructor <*> traverse extractHelp args
60 T.Record fields ext ->
62 <$> traverse (traverse extractHelp) fields
63 <*> traverse extractHelp ext
65 T.Aliased name args aliasedType ->
66 do Writer.tell ( Set.singleton name, Set.empty )
67 _ <- extractHelp (T.dealias args aliasedType)
68 App (Type (Var.toText name)) <$> traverse (extractHelp . snd) args
72-- EXTRACT MODEL, MSG, AND ANY TRANSITIVE DEPENDENCIES
75extractProgram :: Module.Interfaces -> ModuleName.Canonical -> Maybe Program
76extractProgram interfaces name =
77 do iface <- Map.lookup name interfaces
78 mainType <- Map.lookup "main" (Module.iTypes iface)
81 case T.deepDealias mainType of
82 T.App _program [_flags, _model, msg] -> Just msg
83 T.App _node [msg] -> Just msg
86 let (msgType, msgDeps) = Writer.runWriter (extractHelp message)
87 let (aliases, unions) = extractTransitive interfaces mempty msgDeps
88 Just (Program msgType aliases unions)
92 ( Text, [Text], Type )
96 ( Text, [Text], [(Text, [Type])] )
99extractTransitive :: Module.Interfaces -> Deps -> Deps -> ( [Alias], [Union] )
100extractTransitive interfaces oldDeps currentDeps =
103 diff oldDeps currentDeps
105 if Set.null aliases && Set.null unions then
111 Writer.runWriter $ do
112 publicAliases <- mapM (extractAlias interfaces) (Set.toList aliases)
113 publicUnions <- mapM (extractUnion interfaces) (Set.toList unions)
114 return ( Maybe.catMaybes publicAliases, Maybe.catMaybes publicUnions )
117 extractTransitive interfaces (mappend oldDeps currentDeps) newDeps
119 mappend result remainingResult
122extractAlias :: Module.Interfaces -> Var.Canonical -> Writer.Writer Deps (Maybe Alias)
123extractAlias interfaces var =
125 toAlias (args, tipe) =
126 (,,) (Var.toText var) args <$> extractHelp tipe
128 traverse toAlias (get Module.iAliases interfaces var)
131extractUnion :: Module.Interfaces -> Var.Canonical -> Writer.Writer Deps (Maybe Union)
132extractUnion interfaces var =
134 toUnion (args, constructors) =
135 (,,) (Var.toText var) args
136 <$> traverse (traverse (traverse extractHelp)) constructors
138 traverse toUnion (get Module.iUnions interfaces var)
141get :: (Module.Interface -> Map.Map Text a) -> Module.Interfaces -> Var.Canonical -> Maybe a
142get getInfo interfaces var =
143 do (home, name) <- getHome var
144 iface <- Map.lookup home interfaces
145 Map.lookup name (getInfo iface)
148getHome :: Var.Canonical -> Maybe (ModuleName.Canonical, Text)
149getHome (Var.Canonical home name) =
154 Var.Module moduleName ->
155 Just (moduleName, name)
157 Var.TopLevel moduleName ->
158 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