Skip to content

Commit e79f16d

Browse files
committed
Fix tests for inverted linetable
JuliaLang/julia#52415 introduced a fundamental change in how line information is encoded. Because this package delves into internals, there were a couple tests that failed on Julia 1.12+. This adds a utility, `CodeTracking.linetable_scopes`, that makes it easier to work with the new representation across Julia versions.
1 parent 213f826 commit e79f16d

File tree

3 files changed

+28
-7
lines changed

3 files changed

+28
-7
lines changed

src/CodeTracking.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Otherwise `loc` will be `(filepath, line)`.
9898
"""
9999
function whereis(sf::StackTraces.StackFrame)
100100
sf.linfo === nothing && return nothing
101-
return whereis(sf, sf.linfo.def)
101+
return whereis(sf, getmethod(sf.linfo))
102102
end
103103

104104
"""

src/utils.jl

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ function linerange(def::Expr)
179179
end
180180
linerange(arg) = linerange(convert(Expr, arg)) # Handle Revise's RelocatableExpr
181181

182-
function findline(ex, order)
182+
function findline(ex::Expr, order)
183183
ex.head === :line && return ex.args[1], true
184184
for a in order(ex.args)
185185
a isa LineNumberNode && return a.line, true
@@ -194,6 +194,27 @@ end
194194
fileline(lin::LineInfoNode) = String(lin.file), lin.line
195195
fileline(lnn::LineNumberNode) = String(lnn.file), lnn.line
196196

197+
if VERSION v"1.12.0-DEV.173" # https://github.com/JuliaLang/julia/pull/52415
198+
function linetable_scopes(m::Method)
199+
src = Base.uncompressed_ast(m)
200+
lts = [Vector{Base.Compiler.IRShow.LineInfoNode}() for _ = eachindex(src.code)]
201+
for pc = eachindex(src.code)
202+
Base.IRShow.append_scopes!(lts[pc], pc, src.debuginfo, m)
203+
end
204+
return lts
205+
end
206+
else
207+
function linetable_scopes(m::Method)
208+
src = Base.uncompressed_ast(m)
209+
lt, cl = src.linetable, src.codelocs
210+
return [iszero(cl[pc]) ? Core.LineInfoNode[] : [lt[cl[pc]]] for pc = eachindex(cl)]
211+
end
212+
end
213+
214+
getmethod(m::Method) = m
215+
getmethod(mi::Core.MethodInstance) = getmethod(mi.def)
216+
getmethod(ci::Core.CodeInstance) = getmethod(ci.def)
217+
197218
# This regex matches the pseudo-file name of a REPL history entry.
198219
const rREPL = r"^REPL\[(\d+)\]$"
199220
# Match anonymous function names

test/runtests.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,13 @@ isdefined(Main, :Revise) ? Main.Revise.includet("script.jl") : include("script.j
129129
@info "hello"
130130
end
131131
m = first(methods(f150))
132-
src = Base.uncompressed_ast(m)
133-
idx = findfirst(lin -> String(lin.file) == @__FILE__, src.linetable)
134-
lin = src.linetable[idx]
132+
scopes = CodeTracking.linetable_scopes(m)
133+
idx = findfirst(sc -> all(lin -> String(lin.file) == @__FILE__, sc), scopes)
134+
lin = first(scopes[idx])
135135
file, line = whereis(lin, m)
136136
@test endswith(file, String(lin.file))
137-
idx = findfirst(lin -> String(lin.file) != @__FILE__, src.linetable)
138-
lin = src.linetable[idx]
137+
idx = findfirst(sc -> !all(lin -> String(lin.file) == @__FILE__, sc), scopes)
138+
lin = first(scopes[idx])
139139
file, line = whereis(lin, m)
140140
if !Sys.iswindows()
141141
@test endswith(file, String(lin.file))

0 commit comments

Comments
 (0)