Skip to content

Commit a63e4da

Browse files
committed
Distinguish between TokenMissingError raised during parsing from the one
raised during evaluation in IEx
1 parent de1d47f commit a63e4da

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

lib/iex/lib/iex/server.ex

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# IEx needs to treat TokenMissingError error in a special way, so this one is
2+
# used only to distinguish from TokenMissingError in the rescue clause
3+
defexception IExTokenMissingError, [message: nil]
4+
15
defmodule IEx.Server do
26
@moduledoc false
37

@@ -13,18 +17,39 @@ defmodule IEx.Server do
1317
cache = config.cache
1418
code = cache ++ io_get(config)
1519

20+
file = nil # this needs to be config.scope.file
21+
1622
new_config =
1723
try do
24+
# Instead of doing just `eval`, we first parse the expression to see if
25+
# it's well formed. If parsing succeeds, we evaluate the AST as usual.
26+
#
27+
# If parsing fails, this might be a TokenMissingError which we treat in
28+
# a special way (to allow for continuation of an expression on the next
29+
# line in IEx). In case of any other error, we let :elixir_translator
30+
# to re-raise it.
1831
{ result, new_binding, scope } =
19-
:elixir.eval(code, config.binding, counter, config.scope)
32+
case :elixir_translator.forms(code, counter, file, []) do
33+
{ :ok, forms } ->
34+
:elixir.eval_forms(forms, config.binding, config.scope)
35+
36+
{ :error, { line, error, token } } ->
37+
if token == [] do
38+
# Let the rescue clause catch this error to wait for more input
39+
raise IExTokenMissingError[]
40+
else
41+
# Encountered malformed expression
42+
:elixir_translator.parse_error(line, file, error, token)
43+
end
44+
end
2045

2146
io_put result
2247

2348
config = config.result(result)
2449
update_history(config.cache(code).scope(nil))
2550
config.update_counter(&1+1).cache('').binding(new_binding).scope(scope)
2651
rescue
27-
TokenMissingError ->
52+
IExTokenMissingError ->
2853
config.cache(code)
2954
exception ->
3055
print_stacktrace System.stacktrace, fn ->
@@ -84,4 +109,4 @@ defmodule IEx.Server do
84109
defp remote_prefix do
85110
if node == node(:erlang.group_leader), do: "iex", else: "rem"
86111
end
87-
end
112+
end

0 commit comments

Comments
 (0)