1{-# LANGUAGE OverloadedStrings #-}
2module Generate.JavaScript.Expression
15import qualified Data.IntMap as IntMap
16import qualified Data.List as List
18import qualified Data.Map as Map
19import qualified Data.Name as Name
20import qualified Data.Set as Set
21import qualified Data.Utf8 as Utf8
23import qualified AST.Canonical as Can
24import qualified AST.Optimized as Opt
25import qualified Data.Index as Index
26import qualified Elm.Compiler.Type as Type
27import qualified Elm.Compiler.Type.Extract as Extract
28import qualified Elm.Version as V
29import qualified Elm.ModuleName as ModuleName
30import qualified Elm.Package as Pkg
31import qualified Generate.JavaScript.Builder as JS
32import qualified Generate.JavaScript.Name as JsName
33import qualified Generate.Mode as Mode
34import qualified Json.Encode as Encode
35import qualified Optimize.DecisionTree as DT
36import qualified Reporting.Annotation as A
43generateJsExpr :: Mode.Mode -> Opt.Expr -> JS.Expr
44generateJsExpr mode expression =
45 codeToExpr (generate mode expression)
48generate :: Mode.Mode -> Opt.Expr -> Code
49generate mode expression =
58 JS.Call toChar [ JS.String (Utf8.toBuilder char) ]
61 JS.String (Utf8.toBuilder char)
64 JsExpr $ JS.String (Utf8.toBuilder string)
70 JsExpr $ JS.Float (Utf8.toBuilder float)
73 JsExpr $ JS.Ref (JsName.fromLocal name)
75 Opt.VarGlobal (Opt.Global home name) ->
76 JsExpr $ JS.Ref (JsName.fromGlobal home name)
78 Opt.VarEnum (Opt.Global home name) index ->
81 JsExpr $ JS.Ref (JsName.fromGlobal home name)
84 JsExpr $ JS.Int (Index.toMachine index)
86 Opt.VarBox (Opt.Global home name) ->
89 Mode.Dev _ -> JsName.fromGlobal home name
90 Mode.Prod _ -> JsName.fromGlobal ModuleName.basics Name.identity
92 Opt.VarCycle home name ->
93 JsExpr $ JS.Call (JS.Ref (JsName.fromCycle home name)) []
95 Opt.VarDebug name home region unhandledValueName ->
96 JsExpr $ generateDebug name home region unhandledValueName
98 Opt.VarKernel home name ->
99 JsExpr $ JS.Ref (JsName.fromKernel home name)
104 JsExpr $ JS.Ref (JsName.fromKernel Name.list "Nil")
109 (JS.Ref (JsName.fromKernel Name.list "fromArray"))
110 [ JS.Array $ map (generateJsExpr mode) entries
113 Opt.Function args body ->
114 generateFunction (map JsName.fromLocal args) (generate mode body)
116 Opt.Call func args ->
117 JsExpr $ generateCall mode func args
119 Opt.TailCall name args ->
120 JsBlock $ generateTailCall mode name args
122 Opt.If branches final ->
123 generateIf mode branches final
127 generateDef mode def : codeToStmtList (generate mode body)
129 Opt.Destruct (Opt.Destructor name path) body ->
131 pathExpr = generatePath mode path
132 pathDef = JS.Var [ (JsName.fromLocal name, Just pathExpr) ]
134 JsBlock $ pathDef : codeToStmtList (generate mode body)
136 Opt.Case label root decider jumps ->
137 JsBlock $ generateCase mode label root decider jumps
139 Opt.Accessor field ->
140 JsExpr $ JS.Function Nothing [JsName.dollar]
142 JS.Access (JS.Ref JsName.dollar) (generateField mode field)
145 Opt.Access record field ->
146 JsExpr $ JS.Access (generateJsExpr mode record) (generateField mode field)
148 Opt.Update record fields ->
150 JS.Call (JS.Ref (JsName.fromKernel Name.utils "update"))
151 [ generateJsExpr mode record
152 , generateRecord mode fields
156 JsExpr $ generateRecord mode fields
161 JsExpr $ JS.Ref (JsName.fromKernel Name.utils "Tuple0")
166 Opt.Tuple a b maybeC ->
170 JS.Call (JS.Ref (JsName.fromKernel Name.utils "Tuple2"))
171 [ generateJsExpr mode a
172 , generateJsExpr mode b
176 JS.Call (JS.Ref (JsName.fromKernel Name.utils "Tuple3"))
177 [ generateJsExpr mode a
178 , generateJsExpr mode b
179 , generateJsExpr mode c
182 Opt.Shader src attributes uniforms ->
185 ( JsName.fromLocal field
186 , JS.String (JsName.toBuilder (generateField mode field))
189 toTranslationObject fields =
190 JS.Object (map toTranlation (Set.toList fields))
193 [ ( JsName.fromLocal "src", JS.String (Utf8.toBuilder src) )
194 , ( JsName.fromLocal "attributes", toTranslationObject attributes )
195 , ( JsName.fromLocal "uniforms", toTranslationObject uniforms )
208codeToExpr :: Code -> JS.Expr
214 JsBlock [ JS.Return (Just expr) ] ->
218 JS.Call (JS.Function Nothing [] stmts) []
221codeToStmtList :: Code -> [JS.Stmt]
224 JsExpr (JS.Call (JS.Function Nothing [] stmts) []) ->
228 [ JS.Return (Just expr) ]
234codeToStmt :: Code -> JS.Stmt
237 JsExpr (JS.Call (JS.Function Nothing [] stmts) []) ->
241 JS.Return (Just expr)
254{-# NOINLINE toChar #-}
257 JS.Ref (JsName.fromKernel Name.utils "chr")
264generateCtor :: Mode.Mode -> Opt.Global -> Index.ZeroBased -> Int -> Code
265generateCtor mode (Opt.Global home name) index arity =
268 Index.indexedMap (\i _ -> JsName.fromIndex i) [1 .. arity]
272 Mode.Dev _ -> JS.String (Name.toBuilder name)
273 Mode.Prod _ -> JS.Int (ctorToInt home name index)
275 generateFunction argNames $ JsExpr $ JS.Object $
276 (JsName.dollar, ctorTag) : map (\n -> (n, JS.Ref n)) argNames
279ctorToInt :: ModuleName.Canonical -> Name.Name -> Index.ZeroBased -> Int
280ctorToInt home name index =
281 if home == ModuleName.dict && name == "RBNode_elm_builtin" || name == "RBEmpty_elm_builtin" then
282 0 - Index.toHuman index
284 Index.toMachine index
291generateRecord :: Mode.Mode -> Map.Map Name.Name Opt.Expr -> JS.Expr
292generateRecord mode fields =
294 toPair (field, value) =
295 (generateField mode field, generateJsExpr mode value)
297 JS.Object (map toPair (Map.toList fields))
300generateField :: Mode.Mode -> Name.Name -> JsName.Name
301generateField mode name =
304 JsName.fromLocal name
315generateDebug :: Name.Name -> ModuleName.Canonical -> A.Region -> Maybe Name.Name -> JS.Expr
316generateDebug name (ModuleName.Canonical _ home) region unhandledValueName =
317 if name /= "todo" then
318 JS.Ref (JsName.fromGlobal ModuleName.debug name)
320 case unhandledValueName of
322 JS.Call (JS.Ref (JsName.fromKernel Name.debug "todo")) $
323 [ JS.String (Name.toBuilder home)
324 , regionToJsExpr region
328 JS.Call (JS.Ref (JsName.fromKernel Name.debug "todoCase")) $
329 [ JS.String (Name.toBuilder home)
330 , regionToJsExpr region
331 , JS.Ref (JsName.fromLocal valueName)
335regionToJsExpr :: A.Region -> JS.Expr
336regionToJsExpr (A.Region start end) =
338 [ ( JsName.fromLocal "start", positionToJsExpr start )
339 , ( JsName.fromLocal "end", positionToJsExpr end )
343positionToJsExpr :: A.Position -> JS.Expr
344positionToJsExpr (A.Position line column) =
346 [ ( JsName.fromLocal "line", JS.Int (fromIntegral line) )
347 , ( JsName.fromLocal "column", JS.Int (fromIntegral column) )
355generateFunction :: [JsName.Name] -> Code -> Code
356generateFunction args body =
357 case IntMap.lookup (length args) funcHelpers of
361 [ JS.Function Nothing args $
368 JsExpr $ JS.Function Nothing [arg] $
371 foldr addArg body args
374{-# NOINLINE funcHelpers #-}
375funcHelpers :: IntMap.IntMap JS.Expr
378 map (\n -> (n, JS.Ref (JsName.makeF n))) [2..9]
385generateCall :: Mode.Mode -> Opt.Expr -> [Opt.Expr] -> JS.Expr
386generateCall mode func args =
388 Opt.VarGlobal global@(Opt.Global (ModuleName.Canonical pkg _) _) | pkg == Pkg.core ->
389 generateCoreCall mode global args
394 generateCallHelp mode func args
399 generateJsExpr mode arg
402 generateCallHelp mode func args
405 generateCallHelp mode func args
408generateCallHelp :: Mode.Mode -> Opt.Expr -> [Opt.Expr] -> JS.Expr
409generateCallHelp mode func args =
411 (generateJsExpr mode func)
412 (map (generateJsExpr mode) args)
415generateGlobalCall :: ModuleName.Canonical -> Name.Name -> [JS.Expr] -> JS.Expr
416generateGlobalCall home name args =
417 generateNormalCall (JS.Ref (JsName.fromGlobal home name)) args
420generateNormalCall :: JS.Expr -> [JS.Expr] -> JS.Expr
421generateNormalCall func args =
422 case IntMap.lookup (length args) callHelpers of
424 JS.Call helper (func:args)
427 List.foldl' (\f a -> JS.Call f [a]) func args
430{-# NOINLINE callHelpers #-}
431callHelpers :: IntMap.IntMap JS.Expr
434 map (\n -> (n, JS.Ref (JsName.makeA n))) [2..9]
441generateCoreCall :: Mode.Mode -> Opt.Global -> [Opt.Expr] -> JS.Expr
442generateCoreCall mode (Opt.Global home@(ModuleName.Canonical _ moduleName) name) args =
443 if moduleName == Name.basics then
444 generateBasicsCall mode home name args
446 else if moduleName == Name.bitwise then
447 generateBitwiseCall home name (map (generateJsExpr mode) args)
449 else if moduleName == Name.tuple then
450 generateTupleCall home name (map (generateJsExpr mode) args)
452 else if moduleName == Name.jsArray then
453 generateJsArrayCall home name (map (generateJsExpr mode) args)
456 generateGlobalCall home name (map (generateJsExpr mode) args)
459generateTupleCall :: ModuleName.Canonical -> Name.Name -> [JS.Expr] -> JS.Expr
460generateTupleCall home name args =
464 "first" -> JS.Access value (JsName.fromLocal "a")
465 "second" -> JS.Access value (JsName.fromLocal "b")
466 _ -> generateGlobalCall home name args
469 generateGlobalCall home name args
472generateJsArrayCall :: ModuleName.Canonical -> Name.Name -> [JS.Expr] -> JS.Expr
473generateJsArrayCall home name args =
475 [entry] | name == "singleton" -> JS.Array [entry]
476 [index, array] | name == "unsafeGet" -> JS.Index array index
477 _ -> generateGlobalCall home name args
480generateBitwiseCall :: ModuleName.Canonical -> Name.Name -> [JS.Expr] -> JS.Expr
481generateBitwiseCall home name args =
485 "complement" -> JS.Prefix JS.PrefixBNot arg
486 _ -> generateGlobalCall home name args
490 "and" -> JS.Infix JS.OpBAnd left right
491 "or" -> JS.Infix JS.OpBOr left right
492 "xor" -> JS.Infix JS.OpBXor left right
493 "shiftLeftBy" -> JS.Infix JS.OpLShift right left
494 "shiftRightBy" -> JS.Infix JS.OpSpRShift right left
495 "shiftRightZfBy" -> JS.Infix JS.OpZfRShift right left
496 _ -> generateGlobalCall home name args
499 generateGlobalCall home name args
502generateBasicsCall :: Mode.Mode -> ModuleName.Canonical -> Name.Name -> [Opt.Expr] -> JS.Expr
503generateBasicsCall mode home name args =
506 let arg = generateJsExpr mode elmArg in
508 "not" -> JS.Prefix JS.PrefixLNot arg
509 "negate" -> JS.Prefix JS.PrefixMinus arg
511 "truncate" -> JS.Infix JS.OpBOr arg (JS.Int 0)
512 _ -> generateGlobalCall home name [arg]
514 [elmLeft, elmRight] ->
516 -- NOTE: removed "composeL" and "composeR" because of this issue:
517 -- https://github.com/elm/compiler/issues/1722
518 "append" -> append mode elmLeft elmRight
519 "apL" -> generateJsExpr mode $ apply elmLeft elmRight
520 "apR" -> generateJsExpr mode $ apply elmRight elmLeft
523 left = generateJsExpr mode elmLeft
524 right = generateJsExpr mode elmRight
527 "add" -> JS.Infix JS.OpAdd left right
528 "sub" -> JS.Infix JS.OpSub left right
529 "mul" -> JS.Infix JS.OpMul left right
530 "fdiv" -> JS.Infix JS.OpDiv left right
531 "idiv" -> JS.Infix JS.OpBOr (JS.Infix JS.OpDiv left right) (JS.Int 0)
532 "eq" -> equal left right
533 "neq" -> notEqual left right
534 "lt" -> cmp JS.OpLT JS.OpLT 0 left right
535 "gt" -> cmp JS.OpGT JS.OpGT 0 left right
536 "le" -> cmp JS.OpLEq JS.OpLT 1 left right
537 "ge" -> cmp JS.OpGEq JS.OpGT (-1) left right
538 "or" -> JS.Infix JS.OpLOr left right
539 "and" -> JS.Infix JS.OpLAnd left right
540 "xor" -> JS.Infix JS.OpStrictNEq left right
541 "remainderBy" -> JS.Infix JS.OpMod right left
542 _ -> generateGlobalCall home name [left, right]
545 generateGlobalCall home name (map (generateJsExpr mode) args)
548equal :: JS.Expr -> JS.Expr -> JS.Expr
550 if isLiteral left || isLiteral right then
553 JS.Call (JS.Ref (JsName.fromKernel Name.utils "eq")) [left, right]
556notEqual :: JS.Expr -> JS.Expr -> JS.Expr
558 if isLiteral left || isLiteral right then
561 JS.Prefix JS.PrefixLNot $
562 JS.Call (JS.Ref (JsName.fromKernel Name.utils "eq")) [left, right]
565cmp :: JS.InfixOp -> JS.InfixOp -> Int -> JS.Expr -> JS.Expr -> JS.Expr
566cmp idealOp backupOp backupInt left right =
567 if isLiteral left || isLiteral right then
568 JS.Infix idealOp left right
571 (JS.Call (JS.Ref (JsName.fromKernel Name.utils "cmp")) [left, right])
575isLiteral :: JS.Expr -> Bool
594apply :: Opt.Expr -> Opt.Expr -> Opt.Expr
597 Opt.Accessor field ->
598 Opt.Access value field
601 Opt.Call f (args ++ [value])
604 Opt.Call func [value]
607append :: Mode.Mode -> Opt.Expr -> Opt.Expr -> JS.Expr
608append mode left right =
609 let seqs = generateJsExpr mode left : toSeqs mode right in
610 if any isStringLiteral seqs then
611 foldr1 (JS.Infix JS.OpAdd) seqs
616jsAppend :: JS.Expr -> JS.Expr -> JS.Expr
618 JS.Call (JS.Ref (JsName.fromKernel Name.utils "ap")) [a, b]
621toSeqs :: Mode.Mode -> Opt.Expr -> [JS.Expr]
624 Opt.Call (Opt.VarGlobal (Opt.Global home "append")) [left, right]
625 | home == ModuleName.basics ->
626 generateJsExpr mode left : toSeqs mode right
629 [generateJsExpr mode expr]
632isStringLiteral :: JS.Expr -> Bool
633isStringLiteral expr =
643-- SIMPLIFY INFIX OPERATORS
646strictEq :: JS.Expr -> JS.Expr -> JS.Expr
650 JS.Prefix JS.PrefixLNot right
653 if bool then right else JS.Prefix JS.PrefixLNot right
658 JS.Prefix JS.PrefixLNot left
661 if bool then left else JS.Prefix JS.PrefixLNot left
664 JS.Infix JS.OpStrictEq left right
667strictNEq :: JS.Expr -> JS.Expr -> JS.Expr
668strictNEq left right =
671 JS.Prefix JS.PrefixLNot (JS.Prefix JS.PrefixLNot right)
674 if bool then JS.Prefix JS.PrefixLNot right else right
679 JS.Prefix JS.PrefixLNot (JS.Prefix JS.PrefixLNot left)
682 if bool then JS.Prefix JS.PrefixLNot left else left
685 JS.Infix JS.OpStrictNEq left right
692-- TODO check if JS minifiers collapse unnecessary temporary variables
694generateTailCall :: Mode.Mode -> Name.Name -> [(Name.Name, Opt.Expr)] -> [JS.Stmt]
695generateTailCall mode name args =
697 toTempVars (argName, arg) =
698 ( JsName.makeTemp argName, Just (generateJsExpr mode arg) )
700 toRealVars (argName, _) =
702 JS.Assign (JS.LRef (JsName.fromLocal argName)) (JS.Ref (JsName.makeTemp argName))
704 JS.Var (map toTempVars args)
705 : map toRealVars args
706 ++ [ JS.Continue (Just (JsName.fromLocal name)) ]
713generateDef :: Mode.Mode -> Opt.Def -> JS.Stmt
714generateDef mode def =
717 JS.Var [ (JsName.fromLocal name, Just (generateJsExpr mode body)) ]
719 Opt.TailDef name argNames body ->
720 JS.Var [ (JsName.fromLocal name, Just (codeToExpr (generateTailDef mode name argNames body))) ]
723generateTailDef :: Mode.Mode -> Name.Name -> [Name.Name] -> Opt.Expr -> Code
724generateTailDef mode name argNames body =
725 generateFunction (map JsName.fromLocal argNames) $ JsBlock $
726 [ JS.Labelled (JsName.fromLocal name) $
727 JS.While (JS.Bool True) $
728 codeToStmt $ generate mode body
736generatePath :: Mode.Mode -> Opt.Path -> JS.Expr
737generatePath mode path =
739 Opt.Index index subPath ->
740 JS.Access (generatePath mode subPath) (JsName.fromIndex index)
743 JS.Ref (JsName.fromLocal name)
745 Opt.Field field subPath ->
746 JS.Access (generatePath mode subPath) (generateField mode field)
751 JS.Access (generatePath mode subPath) (JsName.fromIndex Index.first)
754 generatePath mode subPath
761generateIf :: Mode.Mode -> [(Opt.Expr, Opt.Expr)] -> Opt.Expr -> Code
762generateIf mode givenBranches givenFinal =
765 crushIfs givenBranches givenFinal
767 convertBranch (condition, expr) =
768 ( generateJsExpr mode condition
772 branchExprs = map convertBranch branches
773 finalCode = generate mode final
775 if isBlock finalCode || any (isBlock . snd) branchExprs then
776 JsBlock [ foldr addStmtIf (codeToStmt finalCode) branchExprs ]
778 JsExpr $ foldr addExprIf (codeToExpr finalCode) branchExprs
781addExprIf :: (JS.Expr, Code) -> JS.Expr -> JS.Expr
782addExprIf (condition, branch) final =
783 JS.If condition (codeToExpr branch) final
786addStmtIf :: (JS.Expr, Code) -> JS.Stmt -> JS.Stmt
787addStmtIf (condition, branch) final =
788 JS.IfStmt condition (codeToStmt branch) final
791isBlock :: Code -> Bool
798crushIfs :: [(Opt.Expr, Opt.Expr)] -> Opt.Expr -> ([(Opt.Expr, Opt.Expr)], Opt.Expr)
799crushIfs branches final =
800 crushIfsHelp [] branches final
804 :: [(Opt.Expr, Opt.Expr)]
805 -> [(Opt.Expr, Opt.Expr)]
807 -> ([(Opt.Expr, Opt.Expr)], Opt.Expr)
808crushIfsHelp visitedBranches unvisitedBranches final =
809 case unvisitedBranches of
812 Opt.If subBranches subFinal ->
813 crushIfsHelp visitedBranches subBranches subFinal
816 (reverse visitedBranches, final)
818 visiting : unvisited ->
819 crushIfsHelp (visiting : visitedBranches) unvisited final
826generateCase :: Mode.Mode -> Name.Name -> Name.Name -> Opt.Decider Opt.Choice -> [(Int, Opt.Expr)] -> [JS.Stmt]
827generateCase mode label root decider jumps =
828 foldr (goto mode label) (generateDecider mode label root decider) jumps
831goto :: Mode.Mode -> Name.Name -> (Int, Opt.Expr) -> [JS.Stmt] -> [JS.Stmt]
832goto mode label (index, branch) stmts =
836 (JsName.makeLabel label index)
837 (JS.While (JS.Bool True) (JS.Block stmts))
839 labeledDeciderStmt : codeToStmtList (generate mode branch)
842generateDecider :: Mode.Mode -> Name.Name -> Name.Name -> Opt.Decider Opt.Choice -> [JS.Stmt]
843generateDecider mode label root decisionTree =
845 Opt.Leaf (Opt.Inline branch) ->
846 codeToStmtList (generate mode branch)
848 Opt.Leaf (Opt.Jump index) ->
849 [ JS.Break (Just (JsName.makeLabel label index)) ]
851 Opt.Chain testChain success failure ->
853 (List.foldl1' (JS.Infix JS.OpLAnd) (map (generateIfTest mode root) testChain))
854 (JS.Block $ generateDecider mode label root success)
855 (JS.Block $ generateDecider mode label root failure)
858 Opt.FanOut path edges fallback ->
860 (generateCaseTest mode root path (fst (head edges)))
862 (\edge cases -> generateCaseBranch mode label root edge : cases)
863 [ JS.Default (generateDecider mode label root fallback) ]
869generateIfTest :: Mode.Mode -> Name.Name -> (DT.Path, DT.Test) -> JS.Expr
870generateIfTest mode root (path, test) =
872 value = pathToJsExpr mode root path
875 DT.IsCtor home name index _ opts ->
879 Mode.Dev _ -> JS.Access value JsName.dollar
882 Can.Normal -> JS.Access value JsName.dollar
888 Mode.Dev _ -> JS.String (Name.toBuilder name)
889 Mode.Prod _ -> JS.Int (ctorToInt home name index)
895 JS.Prefix JS.PrefixLNot value
898 strictEq value (JS.Int int)
901 strictEq (JS.String (Utf8.toBuilder char)) $
903 Mode.Dev _ -> JS.Call (JS.Access value (JsName.fromLocal "valueOf")) []
907 strictEq value (JS.String (Utf8.toBuilder string))
910 JS.Access value (JsName.fromLocal "b")
913 JS.Prefix JS.PrefixLNot $
914 JS.Access value (JsName.fromLocal "b")
917 error "COMPILER BUG - there should never be tests on a tuple"
921generateCaseBranch :: Mode.Mode -> Name.Name -> Name.Name -> (DT.Test, Opt.Decider Opt.Choice) -> JS.Case
922generateCaseBranch mode label root (test, subTree) =
924 (generateCaseValue mode test)
925 (generateDecider mode label root subTree)
928generateCaseValue :: Mode.Mode -> DT.Test -> JS.Expr
929generateCaseValue mode test =
931 DT.IsCtor home name index _ _ ->
933 Mode.Dev _ -> JS.String (Name.toBuilder name)
934 Mode.Prod _ -> JS.Int (ctorToInt home name index)
940 JS.String (Utf8.toBuilder char)
943 JS.String (Utf8.toBuilder string)
946 error "COMPILER BUG - there should never be three tests on a boolean"
949 error "COMPILER BUG - there should never be three tests on a list"
952 error "COMPILER BUG - there should never be three tests on a list"
955 error "COMPILER BUG - there should never be three tests on a tuple"
958generateCaseTest :: Mode.Mode -> Name.Name -> DT.Path -> DT.Test -> JS.Expr
959generateCaseTest mode root path exampleTest =
961 value = pathToJsExpr mode root path
964 DT.IsCtor home name _ _ opts ->
965 if name == Name.bool && home == ModuleName.basics then
970 JS.Access value JsName.dollar
975 JS.Access value JsName.dollar
992 JS.Call (JS.Access value (JsName.fromLocal "valueOf")) []
998 error "COMPILER BUG - there should never be three tests on a list"
1001 error "COMPILER BUG - there should never be three tests on a list"
1004 error "COMPILER BUG - there should never be three tests on a list"
1007 error "COMPILER BUG - there should never be three tests on a list"
1014pathToJsExpr :: Mode.Mode -> Name.Name -> DT.Path -> JS.Expr
1015pathToJsExpr mode root path =
1017 DT.Index index subPath ->
1018 JS.Access (pathToJsExpr mode root subPath) (JsName.fromIndex index)
1023 JS.Access (pathToJsExpr mode root subPath) (JsName.fromIndex Index.first)
1026 pathToJsExpr mode root subPath
1029 JS.Ref (JsName.fromLocal root)
1036generateMain :: Mode.Mode -> ModuleName.Canonical -> Opt.Main -> JS.Expr
1037generateMain mode home main =
1040 JS.Ref (JsName.fromKernel Name.virtualDom "init")
1041 # JS.Ref (JsName.fromGlobal home "main")
1045 Opt.Dynamic msgType decoder ->
1046 JS.Ref (JsName.fromGlobal home "main")
1047 # generateJsExpr mode decoder
1048 # toDebugMetadata mode msgType
1051(#) :: JS.Expr -> JS.Expr -> JS.Expr
1056toDebugMetadata :: Mode.Mode -> Can.Type -> JS.Expr
1057toDebugMetadata mode msgType =
1065 Mode.Dev (Just interfaces) ->
1066 JS.Json $ Encode.object $
1067 [ ("versions", Encode.object [ ("elm", V.encode V.compiler) ])
1068 , ("types", Type.encodeMetadata (Extract.fromMsg interfaces msgType))
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