Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 36 additions & 4 deletions lib/iex/lib/iex/evaluator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,25 @@ defmodule IEx.Evaluator do

result =
with {:ok, tokens} <- :elixir.string_to_tokens(input, line, column, file, opts),
{:ok, adjusted_tokens} <- adjust_operator(tokens, line, column, file, opts, last_op),
{:ok, adjusted_tokens, adjusted_op} <-
adjust_operator(tokens, line, column, file, opts, last_op),
{:ok, forms} <- :elixir.tokens_to_quoted(adjusted_tokens, file, opts) do
last_op =
case forms do
{:=, _, [_, _]} -> :match
_ -> :other
end

forms =
if adjusted_op != nil do
quote do
IEx.Evaluator.assert_no_error!()
unquote(forms)
end
else
forms
end

{:ok, forms, last_op}
end

Expand Down Expand Up @@ -129,10 +140,22 @@ defmodule IEx.Evaluator do
defp adjust_operator([{op_type, _, _} | _] = tokens, line, column, file, opts, _last_op)
when op_type in @op_tokens do
{:ok, prefix} = :elixir.string_to_tokens(~c"v(-1)", line, column, file, opts)
{:ok, prefix ++ tokens}
{:ok, prefix ++ tokens, op_type}
end

defp adjust_operator(tokens, _line, _column, _file, _opts, _last_op), do: {:ok, tokens}
defp adjust_operator(tokens, _line, _column, _file, _opts, _last_op), do: {:ok, tokens, nil}

@doc """
Raises an error if the last iex result was itself an error
"""
def assert_no_error!() do
if Process.get(:iex_error, false) do
reraise RuntimeError.exception(
"skipping evaluation of expression because pipeline has failed"
),
[]
end
end

@doc """
Gets a value out of the binding, using the provided
Expand Down Expand Up @@ -293,9 +316,18 @@ defmodule IEx.Evaluator do
defp safe_eval_and_inspect(forms, counter, state) do
put_history(state)
put_whereami(state)
{:ok, eval_and_inspect(forms, counter, state)}
result = eval_and_inspect(forms, counter, state)

if Process.get(:iex_error) == :force do
Process.put(:iex_error, true)
else
Process.delete(:iex_error)
end

{:ok, result}
catch
kind, error ->
Process.put(:iex_error, true)
print_error(kind, error, __STACKTRACE__)
{:error, state}
after
Expand Down
9 changes: 9 additions & 0 deletions lib/iex/lib/iex/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,15 @@ defmodule IEx.Server do
end

{:io_reply, ^input, {:error, kind, error, stacktrace}} ->
send(
evaluator,
{:eval, self(),
quote do
Process.put(:iex_error, :force)
IEx.dont_display_result()
end, 0}
)

banner = Exception.format_banner(kind, error, stacktrace)

banner =
Expand Down