@@ -40,29 +40,74 @@ defmodule Kernel.RecordRewriter do
40
40
41
41
## Expr
42
42
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
+
43
56
defp optimize_expr ( { :match , line , left , right } , dict ) do
44
57
{ left , dict , left_res } = optimize_expr ( left , dict )
45
58
{ right , dict , right_res } = optimize_expr ( right , dict )
46
59
47
60
match = { :match , line , left , right }
48
61
49
- if right_res do
50
- dict = assign_vars ( extract_vars ( left , [ ] ) , dict , right_res )
51
- end
52
-
53
62
if left_res do
54
63
dict = assign_vars ( extract_vars ( right , [ ] ) , dict , left_res )
55
64
end
56
65
66
+ if right_res do
67
+ dict = assign_vars ( extract_vars ( left , [ ] ) , dict , right_res )
68
+ end
69
+
57
70
{ match , dict , right_res || left_res }
58
71
end
59
72
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
+
60
105
defp optimize_expr ( { :tuple , line , args } , dict ) do
61
106
{ args , dict , args_res } = optimize_tuple_args ( args , dict )
62
107
63
108
res =
64
109
case args do
65
- [ { :atom , _ , atom } | t ] -> if is_record? ( atom ) , do: atom
110
+ [ { :atom , _ , atom } | t ] -> atom
66
111
_ -> nil
67
112
end
68
113
@@ -76,7 +121,19 @@ defmodule Kernel.RecordRewriter do
76
121
end
77
122
end
78
123
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
80
137
{ other , dict , nil }
81
138
end
82
139
@@ -97,7 +154,21 @@ defmodule Kernel.RecordRewriter do
97
154
end
98
155
99
156
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
101
172
end
102
173
103
174
defp assign_vars ( [ _ | t ] , dict , res ) do
0 commit comments