on master help sign in
Find way to quote exported names and make code smaller

In the olden times, we had a series of definitions like this: var Elm = {}; Elm[‘Thing’] = Elm[‘Thing’] || {}; Elm[‘Thing’][‘Chart’] = Elm[‘Thing’][‘Chart’] || {}; initialize(Elm[‘Thing’][‘Chart’]); The idea was that Elm was a global object, so you would not want to clobber things added by other Elm scripts that may be on the page. I switched things so there is a _Platform_export function that will do the appropriate kind of export. It looks like this: _Platform_export({‘Thing’:initialize({‘Chart’:{}})}); Each module name should appear only once, and it is still possible to expose “mixed-level” modules like Thing.Chart and Thing.Chart.Custom with this scheme.

commit422e2506ebee52d89bf59eca391b536346a562a8 authorEvan Czaplicki <evancz@users.noreply.github.com> dateThu 14 Dec 2017, 17:26 (9 years ago) parentf8ace43
3 files changed+89−71
src/Elm/Compiler/Objects.hs+1−3 src/Generate/JavaScript.hs+67−40 src/Generate/JavaScript/Expression.hs+21−28
src/Elm/Compiler/Objects.hs+1−3
@@ -4,9 +4,7 @@ module Elm.Compiler.Objects
44 , JS.ReplBuilder(..)
55 , JS.generateForRepl
66 , JS.Mode(..)
7− , JS.MainsBuilder(..)
8− , JS.MainTrie(..)
9− , JS.generateMains
7+ , JS.generate
108 , Opt.Graph
119 , empty
1210 , union
src/Generate/JavaScript.hs+67−40
@@ -4,9 +4,7 @@ module Generate.JavaScript
44 ( ReplBuilder(..)
55 , generateForRepl
66 , Mode(..)
7− , MainsBuilder(..)
8− , MainTrie(..)
9− , generateMains
7+ , generate
108 )
119 where
1210
@@ -55,18 +53,11 @@ generateForRepl (Opt.Graph _ graph _) home name =
5553-- GENERATE MAINS
5654
5755
58−data MainsBuilder =
59− MainsBuilder
60− { _main_code :: B.Builder
61− , _main_trie :: MainTrie
62− }
63−
64−
6556data Mode = Debug | Prod
6657
6758
68−generateMains :: Mode -> Name.Target -> Opt.Graph -> I.Interfaces -> [ModuleName.Canonical] -> Either [ModuleName.Canonical] MainsBuilder
69−generateMains mode target (Opt.Graph mains graph fields) interfaces roots =
59+generate :: Mode -> Name.Target -> Opt.Graph -> I.Interfaces -> [ModuleName.Canonical] -> Either [ModuleName.Canonical] B.Builder
60+generate mode target (Opt.Graph mains graph fields) interfaces roots =
7061 let
7162 rootSet = Set.fromList roots
7263 rootMap = Map.restrictKeys mains rootSet
@@ -76,7 +67,7 @@ generateMains mode target (Opt.Graph mains graph fields) interfaces roots =
7667 realMode = toRealMode mode target fields
7768 state = Map.foldrWithKey (addMain realMode graph) emptyState rootMap
7869 in
79− Right $ MainsBuilder (stateToBuilder state) (toMainTrie realMode interfaces rootMap)
70+ Right $ stateToBuilder state <> toMainExports realMode interfaces rootMap
8071
8172 else
8273 Left $ Set.toList $
@@ -367,49 +358,85 @@ generateManagerHelp home effectsType =
367358
368359
369360
370−-- MAIN TRIE
361+-- MAIN EXPORTS
371362
372363
373−data MainTrie =
374− MainTrie
375− { _main :: Maybe B.Builder
376− , _subs :: Map.Map N.Name MainTrie
377− }
364+toMainExports :: Name.Mode -> I.Interfaces -> Map.Map ModuleName.Canonical Opt.Main -> B.Builder
365+toMainExports mode interfaces mains =
366+ let
367+ export =
368+ Name.fromKernel N.platform "export"
378369
370+ exports =
371+ generateExports mode interfaces $
372+ Map.foldrWithKey addToTrie emptyTrie mains
373+ in
374+ Name.toBuilder export <> "(" <> exports <> ");"
379375
380−emptyTrie :: MainTrie
381−emptyTrie =
382− MainTrie Nothing Map.empty
383376
377+generateExports :: Name.Mode -> I.Interfaces -> Trie -> B.Builder
378+generateExports mode interfaces (Trie maybeMain subs) =
379+ let
380+ object =
381+ case Map.toList subs of
382+ [] ->
383+ "{}"
384+
385+ (name, subTrie) : otherSubTries ->
386+ "{'" <> N.toBuilder name <> "':"
387+ <> generateExports mode interfaces subTrie
388+ <> List.foldl' (addSubTrie mode interfaces) "}" otherSubTries
389+ in
390+ case maybeMain of
391+ Nothing ->
392+ object
384393
385−toMainTrie :: Name.Mode -> I.Interfaces -> Map.Map ModuleName.Canonical Opt.Main -> MainTrie
386−toMainTrie mode interfaces mains =
387− Map.foldrWithKey (addMainTrie mode interfaces) emptyTrie mains
394+ Just (home, main) ->
395+ let initialize = Expr.generateMain mode interfaces home main in
396+ JS.exprToBuilder initialize <> "(" <> object <> ")"
388397
389398
390−addMainTrie :: Name.Mode -> I.Interfaces -> ModuleName.Canonical -> Opt.Main -> MainTrie -> MainTrie
391−addMainTrie mode interfaces home@(ModuleName.Canonical _ moduleName) main trie =
392− let
393− segments = Text.splitOn "." moduleName
394− initMain = Expr.generateMain mode interfaces home segments main
395− newTrie = segmentsToTrie segments (JS.exprToBuilder initMain)
396− in
397− merge trie newTrie
399+addSubTrie :: Name.Mode -> I.Interfaces -> B.Builder -> (N.Name, Trie) -> B.Builder
400+addSubTrie mode interfaces end (name, trie) =
401+ ",'" <> N.toBuilder name <> "':"
402+ <> generateExports mode interfaces trie
403+ <> end
404+
405+
406+
407+-- BUILD TRIES
408+
409+
410+data Trie =
411+ Trie
412+ { _main :: Maybe (ModuleName.Canonical, Opt.Main)
413+ , _subs :: Map.Map N.Name Trie
414+ }
415+
416+
417+emptyTrie :: Trie
418+emptyTrie =
419+ Trie Nothing Map.empty
420+
421+
422+addToTrie :: ModuleName.Canonical -> Opt.Main -> Trie -> Trie
423+addToTrie home@(ModuleName.Canonical _ moduleName) main trie =
424+ merge trie $ segmentsToTrie home (Text.splitOn "." moduleName) main
398425
399426
400−segmentsToTrie :: [N.Name] -> B.Builder -> MainTrie
401−segmentsToTrie segments mainBuilder =
427+segmentsToTrie :: ModuleName.Canonical -> [N.Name] -> Opt.Main -> Trie
428+segmentsToTrie home segments main =
402429 case segments of
403430 [] ->
404− MainTrie (Just mainBuilder) Map.empty
431+ Trie (Just (home, main)) Map.empty
405432
406433 segment : otherSegments ->
407− MainTrie Nothing (Map.singleton segment (segmentsToTrie otherSegments mainBuilder))
434+ Trie Nothing (Map.singleton segment (segmentsToTrie home otherSegments main))
408435
409436
410−merge :: MainTrie -> MainTrie -> MainTrie
411−merge (MainTrie main1 subs1) (MainTrie main2 subs2) =
412− MainTrie
437+merge :: Trie -> Trie -> Trie
438+merge (Trie main1 subs1) (Trie main2 subs2) =
439+ Trie
413440 (checkedMerge main1 main2)
414441 (Map.unionWith merge subs1 subs2)
415442
src/Generate/JavaScript/Expression.hs+21−28
@@ -16,6 +16,7 @@ import qualified Data.List as List
1616import qualified Data.Map as Map
1717import qualified Data.Text.Encoding as Text
1818
19+import qualified AST.Canonical as Can
1920import qualified AST.Optimized as Opt
2021import qualified AST.Module.Name as ModuleName
2122import qualified Data.Index as Index
@@ -171,6 +172,9 @@ codeToExpr code =
171172 JsExpr expr ->
172173 expr
173174
175+ JsBlock [ JS.Return (Just expr) ] ->
176+ expr
177+
174178 JsBlock stmts ->
175179 JS.Call (JS.Function Nothing [] stmts) []
176180
@@ -861,32 +865,19 @@ pathToJsExpr mode expr path =
861865-- GENERATE MAIN
862866
863867
864−generateMain :: Mode -> I.Interfaces -> ModuleName.Canonical -> [N.Name] -> Opt.Main -> JS.Expr
865−generateMain mode interfaces home segments main =
868+generateMain :: Mode -> I.Interfaces -> ModuleName.Canonical -> Opt.Main -> JS.Expr
869+generateMain mode interfaces home main =
866870 case main of
867871 Opt.Static ->
868872 JS.Ref (Name.fromKernel N.browser "staticPage")
869873 # JS.Ref (Name.fromGlobal home "main")
870− # List.foldl' addDot elm segments
874+ # JS.Int 0
875+ # JS.Int 0
871876
872877 Opt.Dynamic decoder msgType ->
873− let
874− initializer =
875− JS.Ref (Name.fromGlobal home "main")
876− # List.foldl' addDot elm segments
877− # generateJsExpr mode decoder
878− in
879− JS.Call initializer $
880− case mode of
881− Name.Prod _ _ ->
882− []
883−
884− Name.Debug _ ->
885− [ JS.Json $ Encode.object $
886− [ ("versions", Encode.object [ ("elm", Pkg.encodeVersion Version.version) ])
887− , ("types", Type.encodeMetadata (Extract.fromMsg interfaces msgType))
888− ]
889− ]
878+ JS.Ref (Name.fromGlobal home "main")
879+ # generateJsExpr mode decoder
880+ # toDebugMetadata mode interfaces msgType
890881
891882
892883(#) :: JS.Expr -> JS.Expr -> JS.Expr
@@ -894,12 +885,14 @@ generateMain mode interfaces home segments main =
894885 JS.Call func [arg]
895886
896887
897−addDot :: JS.Expr -> N.Name -> JS.Expr
898−addDot root name =
899− JS.Index root (JS.String (N.toBuilder name))
888+toDebugMetadata :: Mode -> I.Interfaces -> Can.Type -> JS.Expr
889+toDebugMetadata mode interfaces msgType =
890+ case mode of
891+ Name.Prod _ _ ->
892+ JS.Int 0
900893
901−
902−{-# NOINLINE elm #-}
903−elm :: JS.Expr
904−elm =
905− JS.Ref (Name.fromLocal "Elm")
894+ Name.Debug _ ->
895+ JS.Json $ Encode.object $
896+ [ ("versions", Encode.object [ ("elm", Pkg.encodeVersion Version.version) ])
897+ , ("types", Type.encodeMetadata (Extract.fromMsg interfaces msgType))
898+ ]