1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Elm.Compiler.Type.Extract
9import qualified Control.Monad.Writer.Strict 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 Type (Var.toText var) <$> 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 Type (Var.toText 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.Type _program [_flags, _model, msg] -> Just msg
80 T.Type _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 ( Text, [Text], Type )
93 ( Text, [Text], [(Text, [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.toText 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.toText var) args
133 <$> traverse (traverse (traverse extractHelp)) constructors
135 traverse toUnion (get Module.iUnions interfaces var)
138get :: (Module.Interface -> Map.Map Text 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, Text)
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