@@ -138,8 +138,8 @@ defmodule Module.LocalsTracker do
138138
139139 # Reattach a previously yanked node
140140 @ doc false
141- def reattach ( pid , kind , tuple , neighbours ) do
142- :gen_server . cast ( to_pid ( pid ) , { :reattach , kind , tuple , neighbours } )
141+ def reattach ( pid , tuple , kind , function , neighbours ) do
142+ :gen_server . cast ( to_pid ( pid ) , { :reattach , tuple , kind , function , neighbours } )
143143 end
144144
145145 # Collecting all conflicting imports with the given functions
@@ -162,15 +162,25 @@ defmodule Module.LocalsTracker do
162162 def collect_unused_locals ( ref , private ) do
163163 d = :gen_server . call ( to_pid ( ref ) , :digraph , @ timeout )
164164 reachable = reachable_from ( d , :local )
165- { unreachable ( reachable , private ) , collect_warnings ( reachable , private ) }
165+ reattached = :digraph . out_neighbours ( d , :reattach )
166+ { unreachable ( reachable , reattached , private ) , collect_warnings ( reachable , private ) }
166167 end
167168
168- defp unreachable ( reachable , private ) do
169- for { tuple , _ , _ , _ } <- private ,
170- not :sets . is_element ( tuple , reachable ) ,
169+ defp unreachable ( reachable , reattached , private ) do
170+ for { tuple , kind , _ , _ } <- private ,
171+ not reachable? ( tuple , kind , reachable , reattached ) ,
171172 do: tuple
172173 end
173174
175+ defp reachable? ( tuple , :defmacrop , reachable , reattached ) do
176+ # All private micros are unreachable unless they have been
177+ # reattached and they are reachable.
178+ :lists . member ( tuple , reattached ) and :sets . is_element ( tuple , reachable )
179+ end
180+ defp reachable? ( tuple , :defp , reachable , _reattached ) do
181+ :sets . is_element ( tuple , reachable )
182+ end
183+
174184 defp collect_warnings ( reachable , private ) do
175185 :lists . foldl ( & collect_warnings ( & 1 , & 2 , reachable ) , [ ] , private )
176186 end
@@ -221,6 +231,7 @@ defmodule Module.LocalsTracker do
221231 def init ( [ ] ) do
222232 d = :digraph . new ( [ :protected ] )
223233 :digraph . add_vertex ( d , :local )
234+ :digraph . add_vertex ( d , :reattach )
224235 { :ok , d }
225236 end
226237
@@ -262,17 +273,29 @@ defmodule Module.LocalsTracker do
262273 { :noreply , d }
263274 end
264275
265- def handle_cast ( { :reattach , _kind , tuple , { in_neigh , out_neigh } } , d ) do
276+ def handle_cast ( { :reattach , tuple , kind , function , { in_neigh , out_neigh } } , d ) do
277+ # Reattach the old function
266278 for from <- in_neigh do
267279 :digraph . add_vertex ( d , from )
268- replace_edge! ( d , from , tuple )
280+ replace_edge! ( d , from , function )
269281 end
270282
271283 for to <- out_neigh do
272284 :digraph . add_vertex ( d , to )
273- replace_edge! ( d , tuple , to )
285+ replace_edge! ( d , function , to )
286+ end
287+
288+ # Add the new definition
289+ handle_add_definition ( d , kind , tuple )
290+
291+ # Make a call from the old function to the new one
292+ if function != tuple do
293+ handle_add_local ( d , function , tuple )
274294 end
275295
296+ # Finally marked the new one as reattached
297+ replace_edge! ( d , :reattach , tuple )
298+
276299 { :noreply , d }
277300 end
278301
0 commit comments