@@ -121,8 +121,8 @@ MethodInfo(start) = MethodInfo(start, -1, Int[])
121121struct SelfCall
122122 linetop:: Int
123123 linebody:: Int
124- callee:: Symbol
125- caller:: Union{Symbol ,Bool,Nothing}
124+ callee:: GlobalRef
125+ caller:: Union{GlobalRef ,Bool,Nothing}
126126end
127127
128128"""
@@ -140,14 +140,17 @@ which will correspond to a 3-argument `:method` expression containing a `CodeInf
140140`callee` is the Symbol of the called method.
141141"""
142142function identify_framemethod_calls (frame)
143- refs = Pair{Symbol ,Int}[]
144- methodinfos = Dict {Symbol ,MethodInfo} ()
143+ refs = Pair{GlobalRef ,Int}[]
144+ methodinfos = Dict {GlobalRef ,MethodInfo} ()
145145 selfcalls = SelfCall[]
146146 for (i, stmt) in enumerate (frame. framecode. src. code)
147147 isa (stmt, Expr) || continue
148148 if stmt. head === :global && length (stmt. args) == 1
149149 key = stmt. args[1 ]
150150 if isa (key, Symbol)
151+ key = GlobalRef (moduleof (frame), key)
152+ end
153+ if isa (key, GlobalRef)
151154 # We don't know for sure if this is a reference to a method, but let's
152155 # tentatively cue it
153156 push! (refs, key=> i)
@@ -159,7 +162,10 @@ function identify_framemethod_calls(frame)
159162 if is_return (tstmt)
160163 tex = tstmt. val
161164 if isa (tex, Expr)
162- if tex. head === :method && (methname = tex. args[1 ]; isa (methname, Symbol))
165+ if tex. head === :method && (methname = tex. args[1 ]; isa (methname, Union{Symbol, GlobalRef}))
166+ if isa (methname, Symbol)
167+ methname = GlobalRef (moduleof (frame), methname)
168+ end
163169 push! (refs, methname=> i)
164170 end
165171 end
@@ -168,7 +174,7 @@ function identify_framemethod_calls(frame)
168174 elseif ismethod1 (stmt)
169175 key = stmt. args[1 ]
170176 key = normalize_defsig (key, frame)
171- key = key:: Symbol
177+ key = key:: GlobalRef
172178 mi = get (methodinfos, key, nothing )
173179 if mi === nothing
174180 methodinfos[key] = MethodInfo (i)
@@ -178,7 +184,7 @@ function identify_framemethod_calls(frame)
178184 elseif ismethod3 (stmt)
179185 key = stmt. args[1 ]
180186 key = normalize_defsig (key, frame)
181- if key isa Symbol
187+ if key isa GlobalRef
182188 # XXX A temporary hack to fix https://github.com/JuliaDebug/LoweredCodeUtils.jl/issues/80
183189 # We should revisit it.
184190 mi = get (methodinfos, key, MethodInfo (1 ))
@@ -188,20 +194,23 @@ function identify_framemethod_calls(frame)
188194 end
189195 msrc = stmt. args[3 ]
190196 if msrc isa CodeInfo
191- key = key:: Union{Symbol ,Bool,Nothing}
197+ key = key:: Union{GlobalRef ,Bool,Nothing}
192198 for (j, mstmt) in enumerate (msrc. code)
193199 isa (mstmt, Expr) || continue
194200 jj = j
195201 if mstmt. head === :call
196- mkey = mstmt. args[1 ]
202+ mkey = normalize_defsig ( mstmt. args[1 ], frame)
197203 if isa (mkey, SSAValue) || isa (mkey, Core. SSAValue)
198204 refstmt = msrc. code[mkey. id]
199- if isa (refstmt, Symbol)
205+ if isa (refstmt, Union{ Symbol, GlobalRef} )
200206 jj = mkey. id
201207 mkey = refstmt
202208 end
203209 end
204210 if isa (mkey, Symbol)
211+ mkey = GlobalRef (moduleof (frame), mkey)
212+ end
213+ if isa (mkey, GlobalRef)
205214 # Could be a GlobalRef but then it's outside frame
206215 haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
207216 elseif is_global_ref (mkey, Core, isdefined (Core, :_apply_iterate ) ? :_apply_iterate : :_apply )
@@ -212,14 +221,20 @@ function identify_framemethod_calls(frame)
212221 end
213222 mkey = mstmt. args[end - 2 ]
214223 if isa (mkey, Symbol)
224+ mkey = GlobalRef (moduleof (frame), mkey)
225+ end
226+ if isa (mkey, GlobalRef)
215227 haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
216228 end
217229 end
218230 elseif mstmt. head === :meta && mstmt. args[1 ] === :generated
219231 newex = mstmt. args[2 ]
220232 if isa (newex, Expr)
221233 if newex. head === :new && length (newex. args) >= 2 && is_global_ref (newex. args[1 ], Core, :GeneratedFunctionStub )
222- mkey = newex. args[2 ]:: Symbol
234+ mkey = newex. args[2 ]
235+ if isa (mkey, Symbol)
236+ mkey = GlobalRef (moduleof (frame), mkey)
237+ end
223238 haskey (methodinfos, mkey) && push! (selfcalls, SelfCall (i, jj, mkey, key))
224239 end
225240 end
@@ -235,20 +250,22 @@ function identify_framemethod_calls(frame)
235250 return methodinfos, selfcalls
236251end
237252
238- # try to normalize `def` to `Symbol ` representation
239- function normalize_defsig (@nospecialize (def), frame :: Frame )
253+ # try to normalize `def` to `GlobalRef ` representation
254+ function normalize_defsig (@nospecialize (def), mod :: Module )
240255 if def isa QuoteNode
241256 def = nameof (def. value)
242- elseif def isa GlobalRef
243- def = def. name
257+ end
258+ if def isa Symbol
259+ def = GlobalRef (mod, def)
244260 end
245261 return def
246262end
263+ normalize_defsig (@nospecialize (def), frame:: Frame ) = normalize_defsig (def, moduleof (frame))
247264
248265function callchain (selfcalls)
249- calledby = Dict {Symbol ,Union{Symbol ,Bool,Nothing}} ()
266+ calledby = Dict {GlobalRef ,Union{GlobalRef ,Bool,Nothing}} ()
250267 for sc in selfcalls
251- startswith (String (sc. callee), ' #' ) || continue
268+ startswith (String (sc. callee. name ), ' #' ) || continue
252269 caller = get (calledby, sc. callee, nothing )
253270 if caller === nothing
254271 calledby[sc. callee] = sc. caller
@@ -261,7 +278,7 @@ function callchain(selfcalls)
261278end
262279
263280function set_to_running_name! (@nospecialize (recurse), replacements, frame, methodinfos, selfcall, calledby, callee, caller)
264- if isa (caller, Symbol ) && startswith (String (caller), ' #' )
281+ if isa (caller, GlobalRef ) && startswith (String (caller. name ), ' #' )
265282 rep = get (replacements, caller, nothing )
266283 if rep === nothing
267284 parentcaller = get (calledby, caller, nothing )
@@ -313,9 +330,9 @@ the same name in the `start:stop` range.
313330"""
314331function rename_framemethods! (@nospecialize (recurse), frame:: Frame , methodinfos, selfcalls, calledby)
315332 src = frame. framecode. src
316- replacements = Dict {Symbol,Symbol } ()
333+ replacements = Dict {GlobalRef,GlobalRef } ()
317334 for (callee, caller) in calledby
318- (! startswith (String (callee), ' #' ) || haskey (replacements, callee)) && continue
335+ (! startswith (String (callee. name ), ' #' ) || haskey (replacements, callee)) && continue
319336 idx = findfirst (sc-> sc. callee === callee && sc. caller === caller, selfcalls)
320337 idx === nothing && continue
321338 try
@@ -364,7 +381,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
364381 stmt = pc_expr (frame, pc)
365382 end
366383 body = stmt. args[3 ]
367- if stmt. args[1 ] != = name && isa (body, CodeInfo)
384+ if normalize_defsig ( stmt. args[1 ], frame) != = name && isa (body, CodeInfo)
368385 # This might be the GeneratedFunctionStub for a @generated method
369386 for (i, bodystmt) in enumerate (body. code)
370387 if isexpr (bodystmt, :meta ) && (bodystmt:: Expr ). args[1 ] === :generated
@@ -374,7 +391,7 @@ function find_name_caller_sig(@nospecialize(recurse), frame, pc, name, parentnam
374391 end
375392 if length (body. code) > 1
376393 bodystmt = body. code[end - 1 ] # the line before the final return
377- iscallto (bodystmt, name, body) && return signature_top (frame, stmt, pc), false
394+ iscallto (bodystmt, moduleof (frame), name, body) && return signature_top (frame, stmt, pc), false
378395 end
379396 end
380397 pc = next_or_nothing (frame, pc)
@@ -412,6 +429,8 @@ function replacename!(args::AbstractVector, pr)
412429 replacename! (a. val:: Expr , pr)
413430 elseif a === oldname
414431 args[i] = newname
432+ elseif isa (a, Symbol) && a == oldname. name
433+ args[i] = newname. name
415434 end
416435 end
417436 return args
@@ -438,7 +457,7 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
438457 methparent = whichtt (sigtparent)
439458 methparent === nothing && return name, pc, lastpcparent # caller isn't defined, no correction is needed
440459 if isgen
441- cname = nameof (methparent. generator. gen)
460+ cname = GlobalRef ( moduleof (frame), nameof (methparent. generator. gen) )
442461 else
443462 bodyparent = Base. uncompressed_ast (methparent)
444463 bodystmt = bodyparent. code[end - 1 ]
@@ -450,7 +469,7 @@ function get_running_name(@nospecialize(recurse), frame, pc, name, parentname)
450469 isa (ref, GlobalRef) || @show ref typeof (ref)
451470 @assert isa (ref, GlobalRef)
452471 @assert ref. mod == moduleof (frame)
453- cname = ref. name
472+ cname = ref
454473 end
455474 return cname, pc, lastpcparent
456475end
@@ -519,21 +538,20 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
519538 return pc, pc3
520539 end
521540 ismethod1 (stmt) || Base. invokelatest (error, " expected method opening, got " , stmt)
522- name = stmt. args[1 ]
523- name = normalize_defsig (name, frame)
541+ name = normalize_defsig (stmt. args[1 ], frame)
524542 if isa (name, Bool)
525543 error (" not valid for anonymous methods" )
526544 elseif name === missing
527545 Base. invokelatest (error, " given invalid definition: " , stmt)
528546 end
529- name = name:: Symbol
547+ name = name:: GlobalRef
530548 # Is there any 3-arg method definition with the same name? If not, avoid risk of executing code that
531549 # we shouldn't (fixes https://github.com/timholy/Revise.jl/issues/758)
532550 found = false
533551 for i = pc+ 1 : length (framecode. src. code)
534552 newstmt = framecode. src. code[i]
535553 if ismethod3 (newstmt)
536- if ismethod_with_name (framecode. src, newstmt, string (name))
554+ if ismethod_with_name (framecode. src, newstmt, string (name. name ))
537555 found = true
538556 break
539557 end
@@ -550,7 +568,7 @@ function methoddef!(@nospecialize(recurse), signatures, frame::Frame, @nospecial
550568 end
551569 pc3 = pc
552570 stmt = stmt:: Expr
553- name3 = stmt. args[1 ]
571+ name3 = normalize_defsig ( stmt. args[1 ], frame)
554572 sigt === nothing && (error (" expected a signature" ); return next_or_nothing (frame, pc)), pc3
555573 # Methods like f(x::Ref{<:Real}) that use gensymmed typevars will not have the *exact*
556574 # signature of the active method. So let's get the active signature.
0 commit comments