1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Generate.JavaScript
9import Control.Monad (foldM)
10import Data.Monoid ((<>))
11import qualified Data.List as List
12import qualified Data.Map as Map
13import qualified Data.Set as Set
14import qualified Data.Text as Text
15import qualified Data.Text.Encoding as Text
16import qualified Data.ByteString.Builder as BS
18import qualified AST.Effects as Effects
19import qualified AST.Expression.Optimized as Opt
20import qualified AST.Kernel as Kernel
21import qualified AST.Module.Name as ModuleName
22import qualified AST.Variable as Var
23import qualified Elm.Package as Pkg
24import qualified Elm.Compiler.Objects.Internal as Obj
25import qualified Generate.JavaScript.Builder as JsBuilder
26import qualified Generate.JavaScript.Effects as JsEffects
27import qualified Generate.JavaScript.Expression as JsExpr
28import qualified Generate.JavaScript.Variable as JS
35generate :: Bool -> Target -> Obj.Graph -> Obj.Roots -> BS.Builder
36generate debug target graph roots =
38 (State builders _ _ effects) =
39 List.foldl' (crawl (Env debug target) graph) initialState (Obj.toGlobals roots)
42 JS.run (JsEffects.generate effects)
44 List.foldl' (\rest stmt -> stmt <> rest) managers builders
58data Target = Client | Server
67 { _builders :: [BS.Builder]
68 , _seenDecls :: Set.Set Var.Global
69 , _seenKernels :: Set.Set ModuleName.Raw
70 , _effects :: Map.Map ModuleName.Canonical Effects.ManagerType
76 State [] Set.empty Set.empty Map.empty
83crawl :: Env -> Obj.Graph -> State -> Var.Global -> State
84crawl env graph@(Obj.Graph decls kernels) state@(State _ seenDecls seenKernels _) name@(Var.Global home _) =
85 if Set.member name seenDecls then
88 else if home == virtualDomDebug then
92 case Map.lookup name decls of
94 crawlDecl env graph name decl state
99 ModuleName._module home
101 if Set.member kernelModule seenKernels then
104 case Map.lookup kernelModule kernels of
106 crawlKernel env graph kernelModule info state
109 error (crawlError name)
116crawlDecl :: Env -> Obj.Graph -> Var.Global -> Opt.Decl -> State -> State
117crawlDecl env graph var@(Var.Global home name) (Opt.Decl direct indirect fx body) state1 =
120 state1 { _seenDecls = Set.insert var (_seenDecls state1) }
122 (State builders seenDecls seenKernels effects) =
123 Set.foldl' (crawl env graph) state2 direct
126 JS.run (JsExpr.generateDecl home name body)
130 { _builders = JsBuilder.stmtToBuilder stmt : builders
131 , _seenDecls = seenDecls
132 , _seenKernels = seenKernels
133 , _effects = maybe id (Map.insert home) fx effects
136 Set.foldl' (crawl env graph) state4 indirect
143crawlKernel :: Env -> Obj.Graph -> ModuleName.Raw -> Kernel.Data -> State -> State
144crawlKernel env@(Env _ target) graph name (Kernel.Data client maybeServer) state =
149 maybe client id maybeServer
154 crawlKernelContent env graph name content state
157crawlKernelContent :: Env -> Obj.Graph -> ModuleName.Raw -> Kernel.Content -> State -> State
158crawlKernelContent env@(Env debug _) graph name (Kernel.Content imports chunks) state1 =
161 state1 { _seenKernels = Set.insert name (_seenKernels state1) }
163 (State builders seenDecls seenKernels effects) =
164 List.foldl' (crawl env graph) state2 (map toCoreGlobal imports)
167 JS.run (foldM (chunkToBuilder debug) mempty chunks)
170 { _builders = builder : builders
171 , _seenDecls = seenDecls
172 , _seenKernels = seenKernels
177toCoreGlobal :: ( ModuleName.Raw, Text.Text ) -> Var.Global
178toCoreGlobal (home, name) =
179 Var.Global (ModuleName.inCore home) name
182chunkToBuilder :: Bool -> BS.Builder -> Kernel.Chunk -> JS.Generator BS.Builder
183chunkToBuilder debug builder chunk =
185 Kernel.JS javascript ->
186 return $ BS.byteString javascript <> builder
188 Kernel.Var home name ->
189 do expr <- JS.global (Var.Global (ModuleName.inCore home) name)
190 return $ JsBuilder.exprToBuilder expr <> builder
193 -- TODO generate a smaller field
194 return $ Text.encodeUtf8Builder name <> builder
197 return $ if debug then builder else "_UNUSED" <> builder
200 return $ if debug then "_UNUSED" <> builder else builder
207crawlError :: Var.Global -> String
208crawlError (Var.Global (ModuleName.Canonical pkg home) name) =
210 "compiler bug manifesting in Generate.JavaScript\n"
211 <> "Could not find " <> Pkg.toText pkg <> " " <> ModuleName.toText home <> "." <> name <> "\n"
212 <> "Please report at <https://github.com/elm-lang/elm-compiler/issues>\n"
213 <> "Try to make an <http://sscce.org/> that demonstrates the issue!"
216virtualDomDebug :: ModuleName.Canonical
218 ModuleName.inVirtualDom "VirtualDom.Debug"
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