on master help sign in
Start localizing the types printed out by the REPL
acb8662Evan Czaplicki
builder/src/Elm/Project.hs+4−3
@@ -26,6 +26,7 @@ import qualified File.Compile as Compile
26import qualified File.Crawl as Crawl
26import qualified File.Crawl as Crawl
27import qualified File.Plan as Plan
27import qualified File.Plan as Plan
28import qualified Generate.Output as Output
28import qualified Generate.Output as Output
29+import qualified Reporting.Render.Type.Localizer as L
29import qualified Reporting.Task as Task
30import qualified Reporting.Task as Task
30import qualified Stuff.Paths as Path
31import qualified Stuff.Paths as Path
31
32
@@ -70,15 +71,15 @@ compile mode target maybeOutput docs summary@(Summary.Summary root project _ _ _
70-- COMPILE FOR REPL
71-- COMPILE FOR REPL
71
72
72
73
73−compileForRepl :: BS.ByteString -> Maybe N.Name -> Task.Task (Maybe FilePath)
74+compileForRepl :: L.Localizer -> BS.ByteString -> Maybe N.Name -> Task.Task (Maybe FilePath)
74−compileForRepl source maybeName =
75+compileForRepl localizer source maybeName =
75 do summary@(Summary.Summary root project _ _ _) <- getRoot
76 do summary@(Summary.Summary root project _ _ _) <- getRoot
76 graph <- Crawl.crawlFromSource summary source
77 graph <- Crawl.crawlFromSource summary source
77 (dirty, ifaces) <- Plan.plan Nothing summary graph
78 (dirty, ifaces) <- Plan.plan Nothing summary graph
78 answers <- Compile.compile project Nothing ifaces dirty
79 answers <- Compile.compile project Nothing ifaces dirty
79 results <- Artifacts.write root answers
80 results <- Artifacts.write root answers
80 let (Compiler.Artifacts elmi _ _) = results ! "Elm_Repl"
81 let (Compiler.Artifacts elmi _ _) = results ! "Elm_Repl"
81− traverse (Output.generateReplFile summary graph elmi) maybeName
82+ traverse (Output.generateReplFile localizer summary graph elmi) maybeName
82
83
83
84
84
85
builder/src/Generate/Output.hs+10−3
@@ -40,6 +40,7 @@ import qualified Generate.Nitpick as Nitpick
40import qualified Generate.JavaScript.Mode as Mode
40import qualified Generate.JavaScript.Mode as Mode
41import qualified Reporting.Exit as Exit
41import qualified Reporting.Exit as Exit
42import qualified Reporting.Exit.Make as E
42import qualified Reporting.Exit.Make as E
43+import qualified Reporting.Render.Type.Localizer as L
43import qualified Reporting.Task as Task
44import qualified Reporting.Task as Task
44import qualified Stuff.Paths as Paths
45import qualified Stuff.Paths as Paths
45import Terminal.Args (Parser(..))
46import Terminal.Args (Parser(..))
@@ -143,13 +144,19 @@ generateMonolith mode maybeOutput (Summary.Summary _ project _ _ _) graph rootNa
143-- GENERATE REPL MONOLITH
144-- GENERATE REPL MONOLITH
144
145
145
146
146−generateReplFile :: Summary.Summary -> Crawl.Result -> I.Interface -> N.Name -> Task.Task FilePath
147+generateReplFile
148+ :: L.Localizer
149+ -> Summary.Summary
150+ -> Crawl.Result
151+ -> I.Interface
152+ -> N.Name
153+ -> Task.Task FilePath
147−generateReplFile summary@(Summary.Summary _ project _ _ _) graph iface name =
154+generateReplFile localizer summary@(Summary.Summary _ project _ _ _) graph iface name =
148 do
155 do
149 objectGraph <- organize summary graph
156 objectGraph <- organize summary graph
150
157
151 let home = Module.Canonical (Project.getName project) "Elm_Repl"
158 let home = Module.Canonical (Project.getName project) "Elm_Repl"
152− let builder = Obj.generateForRepl True objectGraph iface home name
159+ let builder = Obj.generateForRepl True localizer objectGraph iface home name
153
160
154 liftIO $ IO.writeBuilder (Paths.temp "js") $
161 liftIO $ IO.writeBuilder (Paths.temp "js") $
155 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
162 replRecovery <> "(function(){\n'use strict';" <> Functions.functions <> builder <> "}());"
compiler/src/Parse/Module.hs+1
@@ -4,6 +4,7 @@ module Parse.Module
4 ( module_
4 ( module_
5 , chompImports
5 , chompImports
6 , freshLine
6 , freshLine
7+ , exposing
7 )
8 )
8 where
9 where
9
10
compiler/src/Parse/Repl.hs+29−2
@@ -13,6 +13,7 @@ import Data.Text (Text)
13
13
14import qualified AST.Source as Src
14import qualified AST.Source as Src
15import qualified Elm.Name as N
15import qualified Elm.Name as N
16+import qualified Parse.Module as Module
16import Parse.Primitives
17import Parse.Primitives
17import qualified Parse.Primitives.Keyword as Keyword
18import qualified Parse.Primitives.Keyword as Keyword
18import qualified Parse.Primitives.Symbol as Symbol
19import qualified Parse.Primitives.Symbol as Symbol
@@ -26,7 +27,7 @@ import qualified Reporting.Annotation as A
26
27
27
28
28data Entry
29data Entry
29− = Import N.Name Text
30+ = Import N.Name (Maybe N.Name) Src.Exposing Text
30 | Type N.Name Text
31 | Type N.Name Text
31 | Def (Maybe N.Name) Text
32 | Def (Maybe N.Name) Text
32 | Other Text
33 | Other Text
@@ -58,7 +59,9 @@ entryParser source =
58 [ do Keyword.import_
59 [ do Keyword.import_
59 spaces
60 spaces
60 name <- Var.moduleName
61 name <- Var.moduleName
62+ alias <- tryAlias
63+ exposing <- tryExposing
61− return (Import name source)
64+ return (Import name alias exposing source)
62
65
63 , do Keyword.port_
66 , do Keyword.port_
64 return Port
67 return Port
@@ -99,3 +102,27 @@ chompArgs =
99 , do Symbol.equals
102 , do Symbol.equals
100 return ()
103 return ()
101 ]
104 ]
105+
106+
107+tryAlias :: Parser (Maybe N.Name)
108+tryAlias =
109+ oneOf
110+ [ try $
111+ do spaces
112+ Keyword.as_
113+ spaces
114+ Just <$> Var.upper
115+ , return Nothing
116+ ]
117+
118+
119+tryExposing :: Parser Src.Exposing
120+tryExposing =
121+ oneOf
122+ [ try $
123+ do spaces
124+ Keyword.exposing_
125+ spaces
126+ Module.exposing
127+ , return (Src.Explicit [])
128+ ]
compiler/src/Reporting/Render/Type/Localizer.hs+20
@@ -6,6 +6,8 @@ module Reporting.Render.Type.Localizer
6 , empty
6 , empty
7 , fromNames
7 , fromNames
8 , fromModule
8 , fromModule
9+ , replEmpty
10+ , replAdd
9 )
11 )
10 where
12 where
11
13
@@ -15,7 +17,9 @@ import qualified Data.Set as Set
15
17
16import qualified AST.Source as Src
18import qualified AST.Source as Src
17import qualified AST.Valid as Valid
19import qualified AST.Valid as Valid
20+import qualified Elm.Compiler.Imports as Imports
18import qualified Elm.Name as N
21import qualified Elm.Name as N
22+import qualified Elm.Package as Pkg
19import Reporting.Doc ((<>))
23import Reporting.Doc ((<>))
20import qualified Reporting.Doc as D
24import qualified Reporting.Doc as D
21import qualified Reporting.Annotation as A
25import qualified Reporting.Annotation as A
@@ -110,3 +114,19 @@ addType (A.At _ exposed) types =
110 Src.Lower _ -> types
114 Src.Lower _ -> types
111 Src.Upper name _ -> Set.insert name types
115 Src.Upper name _ -> Set.insert name types
112 Src.Operator _ -> types
116 Src.Operator _ -> types
117+
118+
119+
120+-- REPL STUFF
121+
122+
123+replEmpty :: Localizer
124+replEmpty =
125+ Localizer $ Map.fromList $ map toPair $
126+ Imports.addDefaults Pkg.dummyName []
127+
128+
129+replAdd :: N.Name -> Maybe N.Name -> Src.Exposing -> Localizer -> Localizer
130+replAdd name alias exposing (Localizer localizer) =
131+ Localizer $ Map.insert name (Import alias (toExposing exposing)) localizer
132+
ui/terminal/src/Repl.hs+23−17
@@ -34,6 +34,7 @@ import Reporting.Doc ((<+>))
34import qualified Reporting.Doc as D
34import qualified Reporting.Doc as D
35import qualified Reporting.Task as Task
35import qualified Reporting.Task as Task
36import qualified Reporting.Progress.Repl as Repl
36import qualified Reporting.Progress.Repl as Repl
37+import qualified Reporting.Render.Type.Localizer as L
37
38
38
39
39
40
@@ -53,7 +54,7 @@ run () (Flags maybeAlternateInterpreter) =
53 printWelcomeMessage
54 printWelcomeMessage
54 settings <- initSettings
55 settings <- initSettings
55 let manager = Repl.runInputT settings (Repl.withInterrupt loop)
56 let manager = Repl.runInputT settings (Repl.withInterrupt loop)
56− (exitCode,_,_) <- RWS.runRWST manager interpreter initalState
57+ (exitCode,_,_) <- RWS.runRWST manager interpreter initialState
57 Exit.exitWith exitCode
58 Exit.exitWith exitCode
58
59
59
60
@@ -107,7 +108,7 @@ eval input =
107 return (Just Exit.ExitSuccess)
108 return (Just Exit.ExitSuccess)
108
109
109 Reset ->
110 Reset ->
110− do RWS.put initalState
111+ do RWS.put initialState
111 report "<reset>"
112 report "<reset>"
112
113
113 Help info ->
114 Help info ->
@@ -115,10 +116,14 @@ eval input =
115
116
116 Code entry ->
117 Code entry ->
117 Repl.handleInterrupt (report "<cancelled>") $
118 Repl.handleInterrupt (report "<cancelled>") $
118− do state@(State _ imports types defs tricks) <- RWS.get
119+ do state@(State _ imports types defs tricks localizer) <- RWS.get
119 case entry of
120 case entry of
120− Elm.Import name src ->
121+ Elm.Import name alias exposing src ->
122+ interpret None $
123+ state
121− interpret None $ state { _imports = Map.insert name src imports }
124+ { _imports = Map.insert name src imports
125+ , _localizer = L.replAdd name alias exposing localizer
126+ }
122
127
123 Elm.Type name src ->
128 Elm.Type name src ->
124 interpret None $ state { _types = Map.insert name src types }
129 interpret None $ state { _types = Map.insert name src types }
@@ -217,16 +222,17 @@ data State =
217 , _types :: Map.Map N.Name Text.Text
222 , _types :: Map.Map N.Name Text.Text
218 , _defs :: Map.Map N.Name Text.Text
223 , _defs :: Map.Map N.Name Text.Text
219 , _tricks :: [Text.Text]
224 , _tricks :: [Text.Text]
225+ , _localizer :: L.Localizer
220 }
226 }
221
227
222
228
223−initalState :: State
229+initialState :: State
224−initalState =
230+initialState =
225− State 0 Map.empty Map.empty Map.empty []
231+ State 0 Map.empty Map.empty Map.empty [] L.replEmpty
226
232
227
233
228compile :: Output -> State -> Task.Task (Maybe FilePath)
234compile :: Output -> State -> Task.Task (Maybe FilePath)
229−compile output (State count imports types defs tricks) =
235+compile output (State count imports types defs tricks localizer) =
230 let
236 let
231 elmSourceCode =
237 elmSourceCode =
232 (<>) "module Elm_Repl exposing (..)\n\n" $
238 (<>) "module Elm_Repl exposing (..)\n\n" $
@@ -236,12 +242,12 @@ compile output (State count imports types defs tricks) =
236 case output of
242 case output of
237 None ->
243 None ->
238 if Map.null types && Map.null defs && null tricks then
244 if Map.null types && Map.null defs && null tricks then
239− evaluate (elmSourceCode <> "unit = ()") Nothing
245+ evaluate localizer (elmSourceCode <> "unit = ()") Nothing
240 else
246 else
241− evaluate elmSourceCode Nothing
247+ evaluate localizer elmSourceCode Nothing
242
248
243 Def name ->
249 Def name ->
244− evaluate elmSourceCode (Just name)
250+ evaluate localizer elmSourceCode (Just name)
245
251
246 Expr expr ->
252 Expr expr ->
247 let
253 let
@@ -249,7 +255,7 @@ compile output (State count imports types defs tricks) =
249 text = Text.replace "\n" "\n " expr
255 text = Text.replace "\n" "\n " expr
250 def = N.toBuilder name <> " =\n " <> Text.encodeUtf8Builder text <> "\n"
256 def = N.toBuilder name <> " =\n " <> Text.encodeUtf8Builder text <> "\n"
251 in
257 in
252− evaluate (elmSourceCode <> def) (Just name)
258+ evaluate localizer (elmSourceCode <> def) (Just name)
253
259
254
260
255addLines :: Map.Map N.Name Text.Text -> B.Builder -> B.Builder
261addLines :: Map.Map N.Name Text.Text -> B.Builder -> B.Builder
@@ -257,9 +263,9 @@ addLines dict builder =
257 Map.foldr (\text b -> Text.encodeUtf8Builder text <> "\n" <> b) builder dict
263 Map.foldr (\text b -> Text.encodeUtf8Builder text <> "\n" <> b) builder dict
258
264
259
265
260−evaluate :: B.Builder -> Maybe N.Name -> Task.Task (Maybe FilePath)
266+evaluate :: L.Localizer -> B.Builder -> Maybe N.Name -> Task.Task (Maybe FilePath)
261−evaluate builder maybeName =
267+evaluate localizer builder maybeName =
262− Project.compileForRepl (LBS.toStrict (B.toLazyByteString builder)) maybeName
268+ Project.compileForRepl localizer (LBS.toStrict (B.toLazyByteString builder)) maybeName
263
269
264
270
265
271
@@ -279,7 +285,7 @@ initSettings =
279
285
280lookupCompletions :: String -> Runner [Repl.Completion]
286lookupCompletions :: String -> Runner [Repl.Completion]
281lookupCompletions string =
287lookupCompletions string =
282− do (State _ imports types defs _) <- RWS.get
288+ do (State _ imports types defs _ _) <- RWS.get
283 return $
289 return $
284 addMatches string False defs $
290 addMatches string False defs $
285 addMatches string False types $
291 addMatches string False types $