Skip to content

Commit a45ddd4

Browse files
committed
Parametrize method_info by (mt, sig)
1 parent 4f3819c commit a45ddd4

File tree

3 files changed

+15
-11
lines changed

3 files changed

+15
-11
lines changed

src/CodeTracking.jl

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ CodeTracking can be thought of as an extension of InteractiveUtils, and pairs we
1111
module CodeTracking
1212

1313
using Base: PkgId
14-
using Core: LineInfoNode
14+
using Core: LineInfoNode, MethodTable
1515
using Base.Meta: isexpr
1616
using UUIDs
1717
using InteractiveUtils
@@ -29,12 +29,12 @@ include("utils.jl")
2929

3030
# These values get populated by Revise
3131

32-
# `method_info[sig]` is either:
32+
# `method_info[mt => sig]` is either:
3333
# - `missing`, to indicate that the method cannot be located
3434
# - a list of `(lnn,ex)` pairs. In almost all cases there will be just one of these,
3535
# but "mistakes" in moving methods from one file to another can result in more than
3636
# definition. The last pair in the list is the currently-active definition.
37-
const method_info = IdDict{Type,Union{Missing,Vector{Tuple{LineNumberNode,Expr}}}}()
37+
const method_info = IdDict{Pair{<:Union{Nothing, MethodTable}, <:Type},Union{Missing,Vector{Tuple{LineNumberNode,Expr}}}}()
3838

3939
const _pkgfiles = Dict{PkgId,PkgFiles}()
4040

@@ -58,6 +58,9 @@ const expressions_callback = Ref{Any}(nothing)
5858
const juliabase = joinpath("julia", "base")
5959
const juliastdlib = joinpath("julia", "stdlib", "v$(VERSION.major).$(VERSION.minor)")
6060

61+
method_table(method::Method) = isdefined(method, :external_mt) ? method.external_mt::MethodTable : nothing
62+
method_info_key(method::Method) = method_table(method) => method.sig
63+
6164
### Public API
6265

6366
"""
@@ -70,13 +73,13 @@ the method declaration, otherwise it is the first line of the method's body.
7073
function whereis(method::Method)
7174
file, line = String(method.file), method.line
7275
startswith(file, "REPL[") && return file, line
73-
lin = get(method_info, method.sig, nothing)
76+
lin = get(method_info, method_info_key(method), nothing)
7477
if lin === nothing
7578
f = method_lookup_callback[]
7679
if f !== nothing
7780
try
7881
Base.invokelatest(f, method)
79-
lin = get(method_info, method.sig, nothing)
82+
lin = get(method_info, method_info_key(method), nothing)
8083
catch
8184
end
8285
end
@@ -298,13 +301,13 @@ See also [`code_expr`](@ref).
298301
"""
299302
function definition(::Type{Expr}, method::Method)
300303
file = String(method.file)
301-
def = startswith(file, "REPL[") ? nothing : get(method_info, method.sig, nothing)
304+
def = startswith(file, "REPL[") ? nothing : get(method_info, method_info_key(method), nothing)
302305
if def === nothing
303306
f = method_lookup_callback[]
304307
if f !== nothing
305308
try
306309
Base.invokelatest(f, method)
307-
def = get(method_info, method.sig, nothing)
310+
def = get(method_info, method_info_key(method), nothing)
308311
catch
309312
end
310313
end

src/utils.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,5 +400,5 @@ getpkgid(uuid::UUID, libname) = PkgId(uuid, libname)
400400
# callers vulnerable to invalidation. These convenience utilities allow callers to insulate
401401
# themselves from invalidation. These are used by Revise.
402402
# example package triggering invalidation: StaticArrays (new `convert(Type{Array{T,N}}, ::AbstractArray)` methods)
403-
invoked_setindex!(dct::IdDict{K,V}, @nospecialize(val), @nospecialize(key)) where {K,V} = Base.invokelatest(setindex!, dct, val, key)::typeof(dct)
404-
invoked_get!(::Type{T}, dct::IdDict{K,V}, @nospecialize(key)) where {K,V,T<:V} = Base.invokelatest(get!, T, dct, key)::V
403+
invoked_setindex!(dct::IdDict{K,V}, @nospecialize(val), @nospecialize(key)) where {K,V} = Base.invokelatest(setindex!, dct, val, convert(K, key))::typeof(dct)
404+
invoked_get!(::Type{T}, dct::IdDict{K,V}, @nospecialize(key)) where {K,V,T<:V} = Base.invokelatest(get!, T, dct, convert(K, key))::V

test/runtests.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
101101

102102
# Test a method marked as missing
103103
m = @which sum(1:5)
104-
CodeTracking.method_info[m.sig] = missing
104+
CodeTracking.method_info[nothing => m.sig] = missing
105105
@test whereis(m) == (CodeTracking.maybe_fix_path(String(m.file)), m.line)
106106
@test definition(m) === nothing
107107

@@ -323,7 +323,8 @@ end
323323
Revise.add_revise_deps()
324324
sigs = signatures_at(CodeTracking, "src/utils.jl", 5)
325325
@test length(sigs) == 1 # only isn't available on julia 1.0
326-
@test first(sigs) == Tuple{typeof(CodeTracking.checkname), Expr, Any}
326+
(mt, sig) = first(sigs)
327+
@test sig == Tuple{typeof(CodeTracking.checkname), Expr, Any}
327328
@test pkgfiles(CodeTracking).id == Base.PkgId(CodeTracking)
328329
end
329330

0 commit comments

Comments
 (0)