mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-02-24 14:58:35 +08:00
Use unambiguous mapping between erlang and elixir variable names (#2556)
This commit is contained in:
parent
1cac107402
commit
6d994a5542
2 changed files with 74 additions and 2 deletions
|
@ -808,17 +808,47 @@ defmodule Livebook.Runtime.Evaluator do
|
|||
defp elixir_to_erlang_var(name) do
|
||||
name
|
||||
|> :erlang.atom_to_binary()
|
||||
|> Macro.camelize()
|
||||
|> toggle_var_case()
|
||||
|> :erlang.binary_to_atom()
|
||||
end
|
||||
|
||||
defp erlang_to_elixir_var(name) do
|
||||
name
|
||||
|> :erlang.atom_to_binary()
|
||||
|> Macro.underscore()
|
||||
|> toggle_var_case()
|
||||
|> :erlang.binary_to_atom()
|
||||
end
|
||||
|
||||
# Unambiguously maps variable names from camel case to underscore
|
||||
# case, and vice-versa. The mapping is defined as follows:
|
||||
#
|
||||
# 1. The first character case is changed
|
||||
#
|
||||
# 2. Underscore followed by lower character maps to upper character,
|
||||
# and vice-versa
|
||||
#
|
||||
defp toggle_var_case(<<h, t::binary>>) do
|
||||
do_toggle_var_case(<<toggle_char_case(h)>>, t)
|
||||
end
|
||||
|
||||
defp do_toggle_var_case(acc, <<?_, h, t::binary>>) when h >= ?a and h <= ?z do
|
||||
do_toggle_var_case(<<acc::binary, toggle_char_case(h)>>, t)
|
||||
end
|
||||
|
||||
defp do_toggle_var_case(acc, <<h, t::binary>>) when h >= ?A and h <= ?Z do
|
||||
do_toggle_var_case(<<acc::binary, ?_, toggle_char_case(h)>>, t)
|
||||
end
|
||||
|
||||
defp do_toggle_var_case(acc, <<h, t::binary>>) do
|
||||
do_toggle_var_case(<<acc::binary, h>>, t)
|
||||
end
|
||||
|
||||
defp do_toggle_var_case(acc, <<>>), do: acc
|
||||
|
||||
defp toggle_char_case(char) when char >= ?a and char <= ?z, do: char - 32
|
||||
defp toggle_char_case(char) when char >= ?A and char <= ?Z, do: char + 32
|
||||
defp toggle_char_case(char), do: char
|
||||
|
||||
defp filter_erlang_code_markers(code_markers) do
|
||||
Enum.reject(code_markers, &(&1.line == 0))
|
||||
end
|
||||
|
|
|
@ -1268,6 +1268,48 @@ defmodule Livebook.Runtime.EvaluatorTest do
|
|||
assert [{:z, 1}, {:y, 1}, {:x, 1}] == binding
|
||||
end
|
||||
|
||||
test "uses unambiguous camelization for erlang/elixir bindings", %{evaluator: evaluator} do
|
||||
Evaluator.evaluate_code(evaluator, :erlang, "{JSON, JsOn, JsON} = {1, 2, 3}.", :code_1, [])
|
||||
|
||||
assert_receive {:runtime_evaluation_response, :code_1, terminal_text(_), metadata()}
|
||||
|
||||
Evaluator.evaluate_code(
|
||||
evaluator,
|
||||
:elixir,
|
||||
"""
|
||||
assertion1 = {j_s_o_n, js_on, js_o_n} == {1, 2, 3}
|
||||
{j_s_o_n, js_on, js_o_n} = {11, 12, 13}
|
||||
""",
|
||||
:code_2,
|
||||
[:code_1]
|
||||
)
|
||||
|
||||
assert_receive {:runtime_evaluation_response, :code_2, terminal_text(_), metadata()}
|
||||
|
||||
Evaluator.evaluate_code(
|
||||
evaluator,
|
||||
:erlang,
|
||||
"""
|
||||
Assertion2 = {JSON, JsOn, JsON} =:= {11, 12, 13}.
|
||||
""",
|
||||
:code_3,
|
||||
[:code_2]
|
||||
)
|
||||
|
||||
assert_receive {:runtime_evaluation_response, :code_3, terminal_text(_), metadata()}
|
||||
|
||||
%{binding: binding} =
|
||||
Evaluator.get_evaluation_context(evaluator, [:code_3, :code_2, :code_1])
|
||||
|
||||
assert [
|
||||
{:assertion2, true},
|
||||
{:js_on, 12},
|
||||
{:js_o_n, 13},
|
||||
{:j_s_o_n, 11},
|
||||
{:assertion1, true}
|
||||
] == binding
|
||||
end
|
||||
|
||||
test "inspects erlang results using erlang format", %{evaluator: evaluator} do
|
||||
code = ~S"#{x=>1}."
|
||||
Evaluator.evaluate_code(evaluator, :erlang, code, :code_1, [], file: "file.ex")
|
||||
|
|
Loading…
Reference in a new issue