on master help sign in
Add nice error message for bad cyclic definitions
commit48781925fed2fa78b6811fedcebc30a4d5edf1e9 authorEvan Czaplicki <evancz@users.noreply.github.com> dateWed 31 Jan 2018, 22:20 (9 years ago) parentac7f11f
2 files changed+39−2
src/Generate/JavaScript.hs+25−2 src/Generate/JavaScript/Builder.hs+14
src/Generate/JavaScript.hs+25−2
@@ -28,6 +28,7 @@ import qualified Elm.Name as N
2828import qualified Generate.JavaScript.Builder as JS
2929import qualified Generate.JavaScript.Expression as Expr
3030import qualified Generate.JavaScript.Name as Name
31+import qualified Reporting.Helpers as H
3132
3233
3334
@@ -224,9 +225,19 @@ generateCycle mode (Opt.Global home _) cycle =
224225 let
225226 safeDefs = map (generateSafeCycle mode home) cycle
226227 realDefs = map (generateRealCycle home) cycle
227− -- TODO add `try` in debug mode nice infinite recursion reports
228+ block = JS.Block (safeDefs ++ realDefs)
228229 in
229− JS.Block (safeDefs ++ realDefs)
230+ case mode of
231+ Name.Prod _ _ ->
232+ block
233+
234+ Name.Debug _ ->
235+ JS.Try block Name.dollar $ JS.Throw $ JS.String $
236+ "The following top-level definitions are causing infinite recursion:\\n"
237+ <> drawCycle (map fst cycle)
238+ <> "\\n\\nThese errors are very tricky, so read "
239+ <> B.stringUtf8 (H.makeLink "halting-problem")
240+ <> " to learn how to fix it!"
230241
231242
232243generateSafeCycle :: Name.Mode -> ModuleName.Canonical -> (N.Name, Opt.Expr) -> JS.Stmt
@@ -248,6 +259,18 @@ generateRealCycle home (name, _) =
248259 ]
249260
250261
262+drawCycle :: [N.Name] -> B.Builder
263+drawCycle names =
264+ let
265+ topLine = "\\n ┌─────┐"
266+ nameLine name = "\\n │ " <> N.toBuilder name
267+ midLine = "\\n │ ↓"
268+ bottomLine = "\\n └─────┘"
269+ in
270+ mconcat (topLine : List.intersperse midLine (map nameLine names) ++ [ bottomLine ])
271+
272+
273+
251274
252275-- GENERATE KERNEL
253276
src/Generate/JavaScript/Builder.hs+14
@@ -67,6 +67,8 @@ data Stmt
6767 | Break (Maybe Name) -- break lab;
6868 | Continue (Maybe Name) -- continue lab;
6969 | Labelled Name Stmt -- lab: stmt
70+ | Try Stmt Name Stmt -- try stmt catch (x) stmt
71+ | Throw Expr -- throw expr;
7072 | Return (Maybe Expr) -- return expr;
7173 | Var [(Name, Maybe Expr)] -- var x, y=42;
7274 | FunctionStmt Name [Name] [Stmt] -- function f(x, y, z) {...}
@@ -210,6 +212,18 @@ fromStmt indent statement =
210212 , fromStmt indent stmt
211213 ]
212214
215+ Try tryStmt errorName catchStmt ->
216+ mconcat
217+ [ indent, "try {\n"
218+ , fromStmt (deeper indent) tryStmt
219+ , indent, "} catch (", Name.toBuilder errorName, ") {\n"
220+ , fromStmt (deeper indent) catchStmt
221+ , indent, "}\n"
222+ ]
223+
224+ Throw expr ->
225+ "throw " <> snd (fromExpr indent Whatever expr) <> ";"
226+
213227 Return Nothing ->
214228 indent <> "return;\n"
215229