@@ -40,29 +40,74 @@ defmodule Kernel.RecordRewriter do
4040
4141 ## Expr
4242
43+ defp optimize_expr ( { :call , call_line , { :remote , line , left , right } , args } , dict ) do
44+ { left , dict , _ } = optimize_expr ( left , dict )
45+ { right , dict , _ } = optimize_expr ( right , dict )
46+ { args , dict } = optimize_args ( args , dict )
47+ { { :call , call_line , { :remote , line , left , right } , args } , dict , nil }
48+ end
49+
50+ defp optimize_expr ( { :call , line , expr , args } , dict ) do
51+ { expr , dict , _ } = optimize_expr ( expr , dict )
52+ { args , dict } = optimize_args ( args , dict )
53+ { { :call , line , expr , args } , dict , nil }
54+ end
55+
4356 defp optimize_expr ( { :match , line , left , right } , dict ) do
4457 { left , dict , left_res } = optimize_expr ( left , dict )
4558 { right , dict , right_res } = optimize_expr ( right , dict )
4659
4760 match = { :match , line , left , right }
4861
49- if right_res do
50- dict = assign_vars ( extract_vars ( left , [ ] ) , dict , right_res )
51- end
52-
5362 if left_res do
5463 dict = assign_vars ( extract_vars ( right , [ ] ) , dict , left_res )
5564 end
5665
66+ if right_res do
67+ dict = assign_vars ( extract_vars ( left , [ ] ) , dict , right_res )
68+ end
69+
5770 { match , dict , right_res || left_res }
5871 end
5972
73+ defp optimize_expr ( { :op , line , op , left , right } , dict ) do
74+ { left , dict , _ } = optimize_expr ( left , dict )
75+ { right , dict , _ } = optimize_expr ( right , dict )
76+ { { :op , line , op , left , right } , dict , nil }
77+ end
78+
79+ defp optimize_expr ( { :op , line , op , expr } , dict ) do
80+ { expr , dict , _ } = optimize_expr ( expr , dict )
81+ { { :op , line , op , expr } , dict , nil }
82+ end
83+
84+ defp optimize_expr ( { :bin , line , elements } , dict ) do
85+ { elements , dict } = optimize_args ( elements , dict )
86+ { { :bin , line , elements } , dict , nil }
87+ end
88+
89+ defp optimize_expr ( { :bin_element , line , expr , type1 , type2 } , dict ) do
90+ { expr , dict , _ } = optimize_expr ( expr , dict )
91+ { { :bin_element , line , expr , type1 , type2 } , dict , nil }
92+ end
93+
94+ defp optimize_expr ( { :cons , line , left , right } , dict ) do
95+ { left , dict , _ } = optimize_expr ( left , dict )
96+ { right , dict , _ } = optimize_expr ( right , dict )
97+ { { :cons , line , left , right } , dict , nil }
98+ end
99+
100+ defp optimize_expr ( { :block , line , args } , dict ) do
101+ { args , dict , res } = optimize_body ( args , dict , [ ] )
102+ { { :block , line , args } , dict , res }
103+ end
104+
60105 defp optimize_expr ( { :tuple , line , args } , dict ) do
61106 { args , dict , args_res } = optimize_tuple_args ( args , dict )
62107
63108 res =
64109 case args do
65- [ { :atom , _ , atom } | t ] -> if is_record? ( atom ) , do: atom
110+ [ { :atom , _ , atom } | t ] -> atom
66111 _ -> nil
67112 end
68113
@@ -76,7 +121,19 @@ defmodule Kernel.RecordRewriter do
76121 end
77122 end
78123
79- defp optimize_expr ( other , dict ) do
124+ defp optimize_expr ( { comprehension , line , expr , args } , dict ) when comprehension in [ :lc , :bc ] do
125+ { args , new_dict } = optimize_args ( args , dict )
126+ { expr , _ , _ } = optimize_expr ( expr , new_dict )
127+ { { comprehension , line , expr , args } , dict , nil }
128+ end
129+
130+ defp optimize_expr ( { generate , line , left , right } , dict ) when generate in [ :generate , :b_generate ] do
131+ { left , dict , _ } = optimize_expr ( left , dict )
132+ { right , dict , _ } = optimize_expr ( right , dict )
133+ { { generate , line , left , right } , dict , nil }
134+ end
135+
136+ defp optimize_expr ( other , dict ) when elem ( other , 0 ) in [ :string , :atom , :integer , :float , :nil ] do
80137 { other , dict , nil }
81138 end
82139
@@ -97,7 +154,21 @@ defmodule Kernel.RecordRewriter do
97154 end
98155
99156 defp assign_vars ( [ key | t ] , dict , { value , _ } = res ) when is_atom ( key ) and value != nil do
100- assign_vars t , :orddict . store ( key , value , dict ) , res
157+ if is_record? ( value ) do
158+ dict =
159+ case :orddict . find ( key , dict ) do
160+ { :ok , ^ value } ->
161+ dict
162+ { :ok , _ } ->
163+ # We are overriding a type of an existing variable,
164+ # which means the source code is invalid.
165+ :orddict . store ( key , nil , dict )
166+ :error ->
167+ :orddict . store ( key , value , dict )
168+ end
169+ end
170+
171+ assign_vars t , dict , res
101172 end
102173
103174 defp assign_vars ( [ _ | t ] , dict , res ) do
0 commit comments