@@ -104,6 +104,7 @@ defmodule Kernel.RecordRewriter do
104
104
105
105
defp optimize_expr ( { :tuple , line , args } , dict ) do
106
106
{ args , dict , args_res } = optimize_tuple_args ( args , dict )
107
+ args_res = if Enum . any? ( args_res ) , do: args_res , else: nil
107
108
108
109
res =
109
110
case args do
@@ -116,7 +117,7 @@ defmodule Kernel.RecordRewriter do
116
117
117
118
defp optimize_expr ( { :var , _ , name } = var , dict ) do
118
119
case :orddict . find ( name , dict ) do
119
- { :ok , res } -> { var , dict , { res , nil } }
120
+ { :ok , res } -> { var , dict , res }
120
121
:error -> { var , dict , nil }
121
122
end
122
123
end
@@ -130,6 +131,38 @@ defmodule Kernel.RecordRewriter do
130
131
{ { :case , line , expr , clauses } , dict , res }
131
132
end
132
133
134
+ defp optimize_expr ( { :receive , line , clauses } , dict ) do
135
+ tuples = lc clause inlist clauses , do: optimize_clause ( clause , dict )
136
+ clauses = lc { clause , _ , _ } in list tuples , do: clause
137
+ dict = join_dict ( tuples )
138
+ res = join_result ( tuples )
139
+ { { :receive , line , clauses } , dict , res }
140
+ end
141
+
142
+ defp optimize_expr ( { :receive , line , clauses , after_key , after_value } , dict ) do
143
+ tuples = lc clause inlist clauses , do: optimize_clause ( clause , dict )
144
+ clauses = lc { clause , _ , _ } in list tuples , do: clause
145
+
146
+ { after_key , dict , _ } = optimize_expr ( after_key , dict )
147
+ { after_value , dict , res } = optimize_body ( after_value , dict , [ ] )
148
+
149
+ dict = join_dict ( tuples , dict )
150
+ res = join_result ( tuples , res )
151
+
152
+ { { :receive , line , clauses , after_key , after_value } , dict , res }
153
+ end
154
+
155
+ defp optimize_expr ( { :try , line , body , [ ] , clauses , try_after } , dict ) do
156
+ tuples = lc clause inlist clauses , do: optimize_clause ( clause , dict )
157
+ clauses = lc { clause , _ , _ } in list tuples , do: clause
158
+
159
+ { body , _ , res } = optimize_body ( body , dict , [ ] )
160
+ res = join_result ( tuples , res )
161
+
162
+ { try_after , _ , _ } = optimize_body ( try_after , dict , [ ] )
163
+ { { :try , line , body , [ ] , clauses , try_after } , dict , res }
164
+ end
165
+
133
166
defp optimize_expr ( { :fun , line , { :function , module , name , arity } } , dict ) do
134
167
{ module , dict , _ } = optimize_expr ( module , dict )
135
168
{ name , dict , _ } = optimize_expr ( name , dict )
@@ -179,14 +212,16 @@ defmodule Kernel.RecordRewriter do
179
212
if is_record? ( value ) do
180
213
dict =
181
214
case :orddict . find ( key , dict ) do
182
- { :ok , ^ value } ->
215
+ { :ok , ^ res } ->
183
216
dict
217
+ { :ok , { ^ value , _ } } ->
218
+ :orddict . store ( key , { value , nil } , dict )
184
219
{ :ok , _ } ->
185
220
# We are overriding a type of an existing variable,
186
221
# which means the source code is invalid.
187
222
:orddict . store ( key , nil , dict )
188
223
:error ->
189
- :orddict . store ( key , value , dict )
224
+ :orddict . store ( key , res , dict )
190
225
end
191
226
end
192
227
@@ -232,9 +267,10 @@ defmodule Kernel.RecordRewriter do
232
267
233
268
defp join_dict ( [ { _ , dict , _ } | t ] , other ) do
234
269
other = Enum . reduce other , other , fn
235
- { key , value } , acc ->
270
+ { key , { value , _ } = res } , acc ->
236
271
case :orddict . find ( key , dict ) do
237
- { :ok , ^ value } -> acc
272
+ { :ok , ^ res } -> acc
273
+ { :ok , { ^ value , _ } } -> :orddict . store ( key , { value , nil } , acc )
238
274
{ :ok , _ } -> :orddict . store ( key , nil , acc )
239
275
:error -> :orddict . erase ( key , acc )
240
276
end
@@ -255,6 +291,10 @@ defmodule Kernel.RecordRewriter do
255
291
join_result ( t , res )
256
292
end
257
293
294
+ defp join_result ( [ { _ , _ , { res , _ } } | t ] , { res , _ } ) do
295
+ join_result ( t , { res , nil } )
296
+ end
297
+
258
298
defp join_result ( [ { _ , _ , _ } | _ ] , _res ) do
259
299
nil
260
300
end
0 commit comments