Skip to content

Commit 20dfa1b

Browse files
committed
apply upstream change
1 parent 348524c commit 20dfa1b

File tree

2 files changed

+49
-30
lines changed

2 files changed

+49
-30
lines changed

lib/elixir_sense/core/compiler/map.ex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ defmodule ElixirSense.Core.Compiler.Map do
2121
struct = load_struct(meta, e_left, [assocs], se, ee)
2222
keys = [:__struct__ | assoc_keys]
2323
without_keys = Elixir.Map.drop(struct, keys)
24+
|> Elixir.Map.to_list
25+
|> Enum.sort
2426

25-
{struct_assocs, se} =
26-
Compiler.Macro.escape(Enum.sort(Elixir.Map.to_list(without_keys)), se)
27-
28-
{e_struct_assocs, sa, ea} = Compiler.expand(struct_assocs, se, ee)
27+
{struct_assocs, se} = Compiler.Quote.escape(without_keys, :escape, false, se)
2928

3029
{{:%, meta, [e_left, {:%{}, map_meta, struct_assocs ++ assocs}]}, se, ee}
3130

lib/elixir_sense/core/compiler/quote.ex

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule ElixirSense.Core.Compiler.Quote do
66
file: nil,
77
context: nil,
88
op: :escape,
9+
# :escape | :escape_and_prune | {:struct, module} | :quote
910
aliases_hygiene: nil,
1011
imports_hygiene: nil,
1112
unquote: true,
@@ -128,16 +129,22 @@ defmodule ElixirSense.Core.Compiler.Quote do
128129
defp default(:generated), do: false
129130

130131
def escape(expr, op, unquote, state) do
131-
q = %__MODULE__{
132-
line: true,
133-
file: nil,
134-
op: op,
135-
unquote: unquote
136-
}
137-
138-
case unquote do
139-
true -> do_quote(expr, q, state)
140-
false -> do_escape(expr, q, state)
132+
try do
133+
q = %__MODULE__{
134+
line: true,
135+
file: nil,
136+
op: op,
137+
unquote: unquote
138+
}
139+
140+
case unquote do
141+
true -> do_quote(expr, q, state)
142+
false -> do_escape(expr, q, state)
143+
end
144+
catch
145+
_kind, _reason ->
146+
# elixir reraises here with trimmed stacktrace
147+
{nil, state}
141148
end
142149
end
143150

@@ -536,23 +543,36 @@ defmodule ElixirSense.Core.Compiler.Quote do
536543

537544
defp do_escape(map, q, state) when is_map(map) do
538545
with %{__struct__: module} when is_atom(module) <- map,
539-
true <- Code.ensure_loaded?(module),
540-
true <- function_exported?(module, :__escape__, 1) do
541-
module.__escape__(map)
546+
true <- q.op != {:struct, module},
547+
{:module, ^module} <- Code.ensure_loaded(module),
548+
true <- function_exported?(module, :__escape__, 1) do
549+
case q.op do
550+
{:struct, _module} ->
551+
# elixir raises here error about custom escaping rules in struct defaults
552+
{{:%{}, [], []}, state}
553+
554+
_ ->
555+
expr = module.__escape__(map)
556+
557+
# elixir validates if expr is valid AST
558+
# we skip validation
559+
{expr, state}
560+
end
542561
else
543562
_ ->
544-
# elixir errors if value is reference
545-
keys = map
546-
|> Map.to_list
547-
|> Enum.filter(fn
548-
{_k, v} when is_reference(v) -> false
549-
{_k, v} when is_tuple(v) ->
550-
not find_tuple_ref(v, 0)
551-
_ -> true
552-
end)
553-
|> Enum.sort
554-
{tt, state} = do_escape(keys, q, state)
555-
{{:%{}, [], tt}, state}
563+
# elixir errors if value is reference
564+
keys =
565+
map
566+
|> Map.to_list()
567+
|> Enum.filter(fn
568+
{_k, v} when is_reference(v) -> false
569+
{_k, v} when is_tuple(v) -> not find_tuple_ref(v, 0)
570+
_ -> true
571+
end)
572+
|> Enum.sort()
573+
574+
{tt, state} = do_escape(keys, q, state)
575+
{{:%{}, [], tt}, state}
556576
end
557577
end
558578

@@ -579,7 +599,7 @@ defmodule ElixirSense.Core.Compiler.Quote do
579599
l = Enum.reverse(t, [h])
580600
do_quote_tail(l, q, state)
581601
catch
582-
_ ->
602+
_, _ ->
583603
{l, r} = reverse_improper(t, [h])
584604
{tl, state} = do_quote_splice(l, q, [], [], state)
585605
{tr, state} = do_escape(r, q, state)

0 commit comments

Comments
 (0)