@@ -130,17 +130,12 @@ defmodule ElixirSense.Core.Compiler.Quote do
130130
131131 def escape ( expr , op , unquote , state ) do
132132 try do
133- q = % __MODULE__ {
133+ do_quote ( expr , % __MODULE__ {
134134 line: true ,
135135 file: nil ,
136136 op: op ,
137137 unquote: unquote
138- }
139-
140- case unquote do
141- true -> do_quote ( expr , q , state )
142- false -> do_escape ( expr , q , state )
143- end
138+ } , state )
144139 catch
145140 _kind , _reason ->
146141 # elixir reraises here with trimmed stacktrace
@@ -172,7 +167,8 @@ defmodule ElixirSense.Core.Compiler.Quote do
172167 meta
173168 end
174169
175- { { :{} , [ ] , [ :quote , meta ( new_meta , q ) , [ t_arg ] ] } , state }
170+ { quoted_meta , state } = meta ( new_meta , q , state )
171+ { { :{} , [ ] , [ :quote , quoted_meta , [ t_arg ] ] } , state }
176172 end
177173
178174 defp do_quote ( { :quote , meta , [ opts , arg ] } , % __MODULE__ { } = q , state ) when is_list ( meta ) do
@@ -188,7 +184,8 @@ defmodule ElixirSense.Core.Compiler.Quote do
188184 meta
189185 end
190186
191- { { :{} , [ ] , [ :quote , meta ( new_meta , q ) , [ t_opts , t_arg ] ] } , state }
187+ { quoted_meta , state } = meta ( new_meta , q , state )
188+ { { :{} , [ ] , [ :quote , quoted_meta , [ t_opts , t_arg ] ] } , state }
192189 end
193190
194191 defp do_quote (
@@ -235,7 +232,8 @@ defmodule ElixirSense.Core.Compiler.Quote do
235232 e -> import_meta ( meta , name , 0 , q , e )
236233 end
237234
238- { { :{} , [ ] , [ name , meta ( import_meta , q ) , q . context ] } , state }
235+ { quoted_meta , state } = meta ( import_meta , q , state )
236+ { { :{} , [ ] , [ name , quoted_meta , q . context ] } , state }
239237 end
240238
241239 # cursor
@@ -371,7 +369,8 @@ defmodule ElixirSense.Core.Compiler.Quote do
371369 end )
372370
373371 # elixir does not emit remote_function in quoted as AST is meaningless
374- { { { :. , meta , [ :elixir_quote , :dot ] } , meta , [ meta ( meta , q ) | Enum . reverse ( tall_reverse ) ] } ,
372+ { quoted_meta , state } = meta ( meta , q , state )
373+ { { { :. , meta , [ :elixir_quote , :dot ] } , meta , [ quoted_meta | Enum . reverse ( tall_reverse ) ] } ,
375374 state }
376375 end
377376
@@ -382,7 +381,8 @@ defmodule ElixirSense.Core.Compiler.Quote do
382381 defp do_quote_tuple ( left , meta , right , q , state ) do
383382 { t_left , state } = do_quote ( left , q , state )
384383 { t_right , state } = do_quote ( right , q , state )
385- { { :{} , [ ] , [ t_left , meta ( meta , q ) , t_right ] } , state }
384+ { quoted_meta , state } = meta ( meta , q , state )
385+ { { :{} , [ ] , [ t_left , quoted_meta , t_right ] } , state }
386386 end
387387
388388 defp do_quote_simple_list ( [ ] , prev , _ , state ) , do: { [ prev ] , state }
@@ -443,8 +443,12 @@ defmodule ElixirSense.Core.Compiler.Quote do
443443 { { :. , meta , [ :elixir_quote , fun ] } , meta , args }
444444 end
445445
446- defp meta ( meta , q ) do
447- generated ( keep ( Keyword . delete ( meta , :column ) , q ) , q )
446+ defp meta ( meta , % __MODULE__ { op: :quote } = q , state ) do
447+ { generated ( keep ( Keyword . delete ( meta , :column ) , q ) , q ) , state }
448+ end
449+
450+ defp meta ( meta , q , state ) do
451+ do_quote ( meta , q , state )
448452 end
449453
450454 defp generated ( meta , % __MODULE__ { generated: true } ) , do: [ { :generated , true } | meta ]
@@ -512,19 +516,19 @@ defmodule ElixirSense.Core.Compiler.Quote do
512516
513517 defp do_escape ( { left , meta , right } , q = % { op: :escape_and_prune } , state ) when is_list ( meta ) do
514518 tm = for { k , v } <- meta , k == :no_parens or k == :line or k == :delimiter , do: { k , v }
515- { tl , state } = do_escape ( left , q , state )
516- { tr , state } = do_escape ( right , q , state )
519+ { tl , state } = do_quote ( left , q , state )
520+ { tr , state } = do_quote ( right , q , state )
517521 { { :{} , [ ] , [ tl , tm , tr ] } , state }
518522 end
519523
520524 defp do_escape ( { left , right } , q , state ) do
521- { tl , state } = do_escape ( left , q , state )
522- { tr , state } = do_escape ( right , q , state )
525+ { tl , state } = do_quote ( left , q , state )
526+ { tr , state } = do_quote ( right , q , state )
523527 { { tl , tr } , state }
524528 end
525529
526530 defp do_escape ( tuple , q , state ) when is_tuple ( tuple ) do
527- { tt , state } = do_escape ( Tuple . to_list ( tuple ) , q , state )
531+ { tt , state } = do_quote ( Tuple . to_list ( tuple ) , q , state )
528532 { { :{} , [ ] , tt } , state }
529533 end
530534
@@ -560,37 +564,25 @@ defmodule ElixirSense.Core.Compiler.Quote do
560564 end
561565 else
562566 _ ->
563- # elixir errors if value is reference
564- keys =
567+ { tt , state } =
565568 map
566569 |> 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 )
572570 |> Enum . sort ( )
571+ |> Enum . reduce ( { [ ] , state } , fn { k , v } , { acc , s } ->
572+ { k_quoted , s } = do_quote ( k , q , s )
573+ { v_quoted , s } = do_quote ( v , q , s )
574+ { [ { k_quoted , v_quoted } | acc ] , s }
575+ end )
573576
574- { tt , state } = do_escape ( keys , q , state )
575- { { :%{} , [ ] , tt } , state }
577+ { { :%{} , [ ] , Enum . reverse ( tt ) } , state }
576578 end
577579 end
578580
579581 defp do_escape ( [ ] , _ , state ) , do: { [ ] , state }
580582
581583 defp do_escape ( [ h | t ] , % __MODULE__ { unquote: false } = q , state ) do
582584 { eh , state } = do_escape ( h , q , state )
583-
584- case is_list ( t ) do
585- true ->
586- { et , state } = do_escape ( t , q , state )
587- { [ eh | et ] , state }
588-
589- # improper list
590- false ->
591- { et , state } = do_escape ( t , q , state )
592- { [ { :| , [ ] , [ eh , et ] } ] , state }
593- end
585+ do_quote_simple_list ( t , eh , q , state )
594586 end
595587
596588 defp do_escape ( [ h | t ] , q , state ) do
@@ -602,7 +594,7 @@ defmodule ElixirSense.Core.Compiler.Quote do
602594 _ , _ ->
603595 { l , r } = reverse_improper ( t , [ h ] )
604596 { tl , state } = do_quote_splice ( l , q , [ ] , [ ] , state )
605- { tr , state } = do_escape ( r , q , state )
597+ { tr , state } = do_quote ( r , q , state )
606598 { update_last ( tl , fn x -> { :| , [ ] , [ x , tr ] } end ) , state }
607599 end
608600 end
@@ -626,14 +618,6 @@ defmodule ElixirSense.Core.Compiler.Quote do
626618 { nil , state }
627619 end
628620
629- defp find_tuple_ref ( tuple , index ) when index >= tuple_size ( tuple ) , do: false
630- defp find_tuple_ref ( tuple , index ) do
631- case elem ( tuple , index ) do
632- ref when is_reference ( ref ) -> true
633- _ -> find_tuple_ref ( tuple , index + 1 )
634- end
635- end
636-
637621 defp reverse_improper ( [ h | t ] , acc ) , do: reverse_improper ( t , [ h | acc ] )
638622 defp reverse_improper ( [ ] , acc ) , do: acc
639623 defp reverse_improper ( t , acc ) , do: { acc , t }
0 commit comments