Skip to content

Commit 41dd15f

Browse files
authored
Merge pull request #140 from serenity4/parametrize-by-mt
Add method table as key for `method_info`
2 parents 332c21f + c0ca2ff commit 41dd15f

File tree

5 files changed

+52
-26
lines changed

5 files changed

+52
-26
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
fail-fast: false
1616
matrix:
1717
version:
18-
- '1.6' # latest LTS
18+
- 'lts'
1919
- '1'
2020
- 'pre'
2121
- 'nightly'

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
name = "CodeTracking"
22
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
33
authors = ["Tim Holy <[email protected]>"]
4-
version = "1.3.9"
4+
version = "2.0.0-DEV"
55

66
[deps]
77
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
88
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
99

1010
[compat]
11-
julia = "1.6"
11+
julia = "1.10"
1212

1313
[extras]
1414
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,14 +116,16 @@ You can also find the method-signatures at a particular location:
116116
117117
```julia
118118
julia> signatures_at(ColorTypes, "src/traits.jl", 14)
119-
1-element Array{Any,1}:
120-
Tuple{typeof(red),AbstractRGB}
119+
1-element Vector{Pair{Union{Nothing, Core.MethodTable}, Type}}:
120+
nothing => Tuple{typeof(red),AbstractRGB}
121121

122122
julia> signatures_at("/home/tim/.julia/packages/ColorTypes/BsAWO/src/traits.jl", 14)
123-
1-element Array{Any,1}:
124-
Tuple{typeof(red),AbstractRGB}
123+
1-element Vector{Pair{Union{Nothing, Core.MethodTable}, Type}}:
124+
nothing => Tuple{typeof(red),AbstractRGB}
125125
```
126126
127+
with the first element being the method table for which the method has been defined (a value of `nothing` denotes the default method table).
128+
127129
CodeTracking also helps correcting for [Julia issue #26314](https://github.com/JuliaLang/julia/issues/26314):
128130
129131
```julia

src/CodeTracking.jl

Lines changed: 14 additions & 8 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,15 @@ 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
36-
# definition. The last pair in the list is the currently-active definition.
37-
const method_info = IdDict{Type,Union{Missing,Vector{Tuple{LineNumberNode,Expr}}}}()
36+
# one definition. The last pair in the list is the currently-active definition.
37+
38+
const MethodInfoKey = Pair{Union{Nothing, MethodTable}, Type}
39+
40+
const method_info = IdDict{MethodInfoKey,Union{Missing,Vector{Tuple{LineNumberNode,Expr}}}}()
3841

3942
const _pkgfiles = Dict{PkgId,PkgFiles}()
4043

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

64+
method_table(method::Method) = isdefined(method, :external_mt) ? method.external_mt::MethodTable : nothing
65+
MethodInfoKey(method::Method) = MethodInfoKey(method_table(method), method.sig)
66+
6167
### Public API
6268

6369
"""
@@ -70,13 +76,13 @@ the method declaration, otherwise it is the first line of the method's body.
7076
function whereis(method::Method)
7177
file, line = String(method.file), method.line
7278
startswith(file, "REPL[") && return file, line
73-
lin = get(method_info, method.sig, nothing)
79+
lin = get(method_info, MethodInfoKey(method), nothing)
7480
if lin === nothing
7581
f = method_lookup_callback[]
7682
if f !== nothing
7783
try
7884
Base.invokelatest(f, method)
79-
lin = get(method_info, method.sig, nothing)
85+
lin = get(method_info, MethodInfoKey(method), nothing)
8086
catch
8187
end
8288
end
@@ -298,13 +304,13 @@ See also [`code_expr`](@ref).
298304
"""
299305
function definition(::Type{Expr}, method::Method)
300306
file = String(method.file)
301-
def = startswith(file, "REPL[") ? nothing : get(method_info, method.sig, nothing)
307+
def = startswith(file, "REPL[") ? nothing : get(method_info, MethodInfoKey(method), nothing)
302308
if def === nothing
303309
f = method_lookup_callback[]
304310
if f !== nothing
305311
try
306312
Base.invokelatest(f, method)
307-
def = get(method_info, method.sig, nothing)
313+
def = get(method_info, MethodInfoKey(method), nothing)
308314
catch
309315
end
310316
end

test/runtests.jl

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ using CodeTracking
44
using Test, InteractiveUtils, REPL, LinearAlgebra, SparseArrays
55
# Note: ColorTypes needs to be installed, but note the intentional absence of `using ColorTypes`
66

7-
using CodeTracking: line_is_decl
7+
using CodeTracking: line_is_decl, MethodInfoKey
88

99
if !isempty(ARGS) && "revise" ARGS
1010
# For running tests with and without Revise
@@ -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[MethodInfoKey(nothing, m.sig)] = missing
105105
@test whereis(m) == (CodeTracking.maybe_fix_path(String(m.file)), m.line)
106106
@test definition(m) === nothing
107107

@@ -297,8 +297,8 @@ end
297297
@testset "With Revise" begin
298298
if isdefined(Main, :Revise)
299299
m = @which gcd(10, 20)
300-
sigs = signatures_at(Base.find_source_file(String(m.file)), m.line)
301-
@test !isempty(sigs)
300+
mt_sigs = signatures_at(Base.find_source_file(String(m.file)), m.line)
301+
@test !isempty(mt_sigs)
302302
ex = @code_expr(gcd(10, 20))
303303
@test ex isa Expr
304304
body = ex.args[2]
@@ -308,10 +308,10 @@ end
308308

309309
if Base.VERSION < v"1.11.0-0"
310310
m = first(methods(edit))
311-
sigs = signatures_at(String(m.file), m.line)
312-
@test !isempty(sigs)
313-
sigs = signatures_at(Base.find_source_file(String(m.file)), m.line)
314-
@test !isempty(sigs)
311+
mt_sigs = signatures_at(String(m.file), m.line)
312+
@test !isempty(mt_sigs)
313+
mt_sigs = signatures_at(Base.find_source_file(String(m.file)), m.line)
314+
@test !isempty(mt_sigs)
315315
end
316316

317317
# issue #23
@@ -321,9 +321,10 @@ end
321321

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

@@ -454,3 +455,20 @@ end
454455
@test CodeTracking.strip_gensym("#𝓔′#90") == :𝓔′
455456
@test CodeTracking.strip_gensym("𝓔′##kw") == :𝓔′
456457
end
458+
459+
@testset "External method tables" begin
460+
mod = @eval module $(gensym(:ExternalMT))
461+
Base.Experimental.@MethodTable method_table
462+
end
463+
ex = :(Base.Experimental.@overlay method_table +(x::String, y::String) = x * y)
464+
if VERSION v"1.13-"
465+
method = Core.eval(mod, ex)
466+
else
467+
Core.eval(mod, ex)
468+
method = only(Base.MethodList(mod.method_table).ms)
469+
end
470+
lnn = LineNumberNode(Int(method.line), method.file)
471+
@test CodeTracking.definition(Expr, method) === nothing
472+
CodeTracking.method_info[MethodInfoKey(method)] = [(lnn, ex)]
473+
@test CodeTracking.definition(Expr, method) == ex
474+
end

0 commit comments

Comments
 (0)