|
13 | 13 | defmodule Kernel.ExpansionTest do
|
14 | 14 | use ExUnit.Case, async: true
|
15 | 15 |
|
16 |
| - defmacrop var_ver(var, version) do |
17 |
| - quote do |
18 |
| - {unquote(var), [version: unquote(version)], __MODULE__} |
19 |
| - end |
20 |
| - end |
21 |
| - |
22 |
| - test "tracks variable version" do |
23 |
| - assert {:__block__, _, [{:=, _, [var_ver(:x, 0), 0]}, {:=, _, [_, var_ver(:x, 0)]}]} = |
24 |
| - expand_with_version( |
25 |
| - quote do |
26 |
| - x = 0 |
27 |
| - _ = x |
28 |
| - end |
29 |
| - ) |
30 |
| - |
31 |
| - assert {:__block__, _, |
32 |
| - [ |
33 |
| - {:=, _, [var_ver(:x, 0), 0]}, |
34 |
| - {:=, _, [_, var_ver(:x, 0)]}, |
35 |
| - {:=, _, [var_ver(:x, 1), 1]}, |
36 |
| - {:=, _, [_, var_ver(:x, 1)]} |
37 |
| - ]} = |
38 |
| - expand_with_version( |
39 |
| - quote do |
40 |
| - x = 0 |
41 |
| - _ = x |
42 |
| - x = 1 |
43 |
| - _ = x |
44 |
| - end |
45 |
| - ) |
46 |
| - |
47 |
| - assert {:__block__, _, |
48 |
| - [ |
49 |
| - {:=, _, [var_ver(:x, 0), 0]}, |
50 |
| - {:fn, _, [{:->, _, [[var_ver(:x, 1)], {:=, _, [var_ver(:x, 2), 2]}]}]}, |
51 |
| - {:=, _, [_, var_ver(:x, 0)]}, |
52 |
| - {:=, _, [var_ver(:x, 3), 3]} |
53 |
| - ]} = |
54 |
| - expand_with_version( |
55 |
| - quote do |
56 |
| - x = 0 |
57 |
| - fn x -> x = 2 end |
58 |
| - _ = x |
59 |
| - x = 3 |
60 |
| - end |
61 |
| - ) |
62 |
| - |
63 |
| - assert {:__block__, _, |
64 |
| - [ |
65 |
| - {:=, _, [var_ver(:x, 0), 0]}, |
66 |
| - {:case, _, [:foo, [do: [{:->, _, [[var_ver(:x, 1)], var_ver(:x, 1)]}]]]}, |
67 |
| - {:=, _, [_, var_ver(:x, 0)]}, |
68 |
| - {:=, _, [var_ver(:x, 2), 2]} |
69 |
| - ]} = |
70 |
| - expand_with_version( |
71 |
| - quote do |
72 |
| - x = 0 |
73 |
| - case(:foo, do: (x -> x)) |
74 |
| - _ = x |
75 |
| - x = 2 |
76 |
| - end |
77 |
| - ) |
78 |
| - end |
79 |
| - |
80 |
| - defp expand_with_version(expr) do |
81 |
| - env = :elixir_env.reset_vars(__ENV__) |
82 |
| - {expr, _, _} = :elixir_expand.expand(expr, :elixir_env.env_to_ex(env), env) |
83 |
| - expr |
84 |
| - end |
85 |
| - |
86 | 16 | describe "__block__" do
|
87 | 17 | test "expands to nil when empty" do
|
88 | 18 | assert expand(quote(do: unquote(:__block__)())) == nil
|
@@ -328,12 +258,30 @@ defmodule Kernel.ExpansionTest do
|
328 | 258 | end
|
329 | 259 |
|
330 | 260 | describe "vars" do
|
331 |
| - test "expand to local call" do |
332 |
| - {output, env} = expand_env(quote(do: a), __ENV__) |
333 |
| - assert output == quote(do: a()) |
| 261 | + test "expands vars to local call" do |
| 262 | + {output, env} = expand_env({:a, [], nil}, __ENV__, []) |
| 263 | + assert output == {:a, [if_undefined: :warn], []} |
| 264 | + assert Macro.Env.vars(env) == [] |
| 265 | + end |
| 266 | + |
| 267 | + test "expands vars to local call without warning" do |
| 268 | + env = __ENV__ |
| 269 | + |
| 270 | + {output, _, env} = |
| 271 | + :elixir_expand.expand({:a, [if_undefined: :apply], nil}, :elixir_env.env_to_ex(env), env) |
| 272 | + |
| 273 | + assert output == {:a, [if_undefined: :apply], []} |
334 | 274 | assert Macro.Env.vars(env) == []
|
335 | 275 | end
|
336 | 276 |
|
| 277 | + test "raises when expanding var to local call" do |
| 278 | + env = __ENV__ |
| 279 | + |
| 280 | + assert_raise CompileError, ~r"undefined variable \"a\"", fn -> |
| 281 | + :elixir_expand.expand({:a, [if_undefined: :raise], nil}, :elixir_env.env_to_ex(env), env) |
| 282 | + end |
| 283 | + end |
| 284 | + |
337 | 285 | test "forces variable to exist" do
|
338 | 286 | code =
|
339 | 287 | quote do
|
@@ -361,6 +309,76 @@ defmodule Kernel.ExpansionTest do
|
361 | 309 | expand(quote(do: {1, 2, _}))
|
362 | 310 | end
|
363 | 311 | end
|
| 312 | + |
| 313 | + defmacrop var_ver(var, version) do |
| 314 | + quote do |
| 315 | + {unquote(var), [version: unquote(version)], __MODULE__} |
| 316 | + end |
| 317 | + end |
| 318 | + |
| 319 | + defp expand_with_version(expr) do |
| 320 | + env = :elixir_env.reset_vars(__ENV__) |
| 321 | + {expr, _, _} = :elixir_expand.expand(expr, :elixir_env.env_to_ex(env), env) |
| 322 | + expr |
| 323 | + end |
| 324 | + |
| 325 | + test "tracks variable version" do |
| 326 | + assert {:__block__, _, [{:=, _, [var_ver(:x, 0), 0]}, {:=, _, [_, var_ver(:x, 0)]}]} = |
| 327 | + expand_with_version( |
| 328 | + quote do |
| 329 | + x = 0 |
| 330 | + _ = x |
| 331 | + end |
| 332 | + ) |
| 333 | + |
| 334 | + assert {:__block__, _, |
| 335 | + [ |
| 336 | + {:=, _, [var_ver(:x, 0), 0]}, |
| 337 | + {:=, _, [_, var_ver(:x, 0)]}, |
| 338 | + {:=, _, [var_ver(:x, 1), 1]}, |
| 339 | + {:=, _, [_, var_ver(:x, 1)]} |
| 340 | + ]} = |
| 341 | + expand_with_version( |
| 342 | + quote do |
| 343 | + x = 0 |
| 344 | + _ = x |
| 345 | + x = 1 |
| 346 | + _ = x |
| 347 | + end |
| 348 | + ) |
| 349 | + |
| 350 | + assert {:__block__, _, |
| 351 | + [ |
| 352 | + {:=, _, [var_ver(:x, 0), 0]}, |
| 353 | + {:fn, _, [{:->, _, [[var_ver(:x, 1)], {:=, _, [var_ver(:x, 2), 2]}]}]}, |
| 354 | + {:=, _, [_, var_ver(:x, 0)]}, |
| 355 | + {:=, _, [var_ver(:x, 3), 3]} |
| 356 | + ]} = |
| 357 | + expand_with_version( |
| 358 | + quote do |
| 359 | + x = 0 |
| 360 | + fn x -> x = 2 end |
| 361 | + _ = x |
| 362 | + x = 3 |
| 363 | + end |
| 364 | + ) |
| 365 | + |
| 366 | + assert {:__block__, _, |
| 367 | + [ |
| 368 | + {:=, _, [var_ver(:x, 0), 0]}, |
| 369 | + {:case, _, [:foo, [do: [{:->, _, [[var_ver(:x, 1)], var_ver(:x, 1)]}]]]}, |
| 370 | + {:=, _, [_, var_ver(:x, 0)]}, |
| 371 | + {:=, _, [var_ver(:x, 2), 2]} |
| 372 | + ]} = |
| 373 | + expand_with_version( |
| 374 | + quote do |
| 375 | + x = 0 |
| 376 | + case(:foo, do: (x -> x)) |
| 377 | + _ = x |
| 378 | + x = 2 |
| 379 | + end |
| 380 | + ) |
| 381 | + end |
364 | 382 | end
|
365 | 383 |
|
366 | 384 | describe "^" do
|
@@ -2891,15 +2909,13 @@ defmodule Kernel.ExpansionTest do
|
2891 | 2909 | expand_env(expr, __ENV__) |> elem(0)
|
2892 | 2910 | end
|
2893 | 2911 |
|
2894 |
| - defp expand_env(expr, env) do |
2895 |
| - ExUnit.CaptureIO.capture_io(:stderr, fn -> |
2896 |
| - send(self(), {:expand_env, :elixir_expand.expand(expr, :elixir_env.env_to_ex(env), env)}) |
2897 |
| - end) |
| 2912 | + defp expand_env(expr, env, to_clean \\ [:version, :inferred_bitstring_spec, :if_undefined]) do |
| 2913 | + {{expr, scope, env}, _capture} = |
| 2914 | + ExUnit.CaptureIO.with_io(:stderr, fn -> |
| 2915 | + :elixir_expand.expand(expr, :elixir_env.env_to_ex(env), env) |
| 2916 | + end) |
2898 | 2917 |
|
2899 |
| - receive do |
2900 |
| - {:expand_env, {expr, scope, env}} -> |
2901 |
| - env = :elixir_env.to_caller({env.line, scope, env}) |
2902 |
| - {clean_meta(expr, [:version, :inferred_bitstring_spec]), env} |
2903 |
| - end |
| 2918 | + env = :elixir_env.to_caller({env.line, scope, env}) |
| 2919 | + {clean_meta(expr, to_clean), env} |
2904 | 2920 | end
|
2905 | 2921 | end
|
0 commit comments