Skip to content

workaround wrong paths reported for stdlib functions #32763

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,25 @@ end
# In case the line numbers in the source code have changed since the code was compiled,
# allow packages to set a callback function that corrects them.
# (Used by Revise and perhaps other packages.)
default_methodloc(method::Method) = method.file, method.line
const methodloc_callback = Ref{Function}(default_methodloc)
const methodloc_callback = Ref{Union{Function, Nothing}}(nothing)

# This function does the method location updating
function updated_methodloc(m::Method)::Tuple{String, Int32}
file, line = m.file, m.line
if methodloc_callback[] !== nothing
try
file, line = invokelatest(methodloc_callback[], m)
catch
end
end
# The file defining Base.Sys gets included after this file is included so make sure
# this function is valid even in this intermediary state
if isdefined(@__MODULE__, :Sys) && Sys.BUILD_STDLIB_PATH != Sys.STDLIB
# BUILD_STDLIB_PATH gets defined in sysinfo.jl
file = replace(string(file), normpath(Sys.BUILD_STDLIB_PATH) => normpath(Sys.STDLIB))
end
return string(file), line
end

functionloc(m::Core.MethodInstance) = functionloc(m.def)

Expand All @@ -130,7 +147,7 @@ functionloc(m::Core.MethodInstance) = functionloc(m.def)
Returns a tuple `(filename,line)` giving the location of a `Method` definition.
"""
function functionloc(m::Method)
file, ln = invokelatest(methodloc_callback[], m)
file, ln = updated_methodloc(m)
if ln <= 0
error("could not determine location of method definition")
end
Expand Down Expand Up @@ -195,10 +212,7 @@ function show(io::IO, m::Method)
show_method_params(io, tv)
print(io, " in ", m.module)
if line > 0
try
file, line = invokelatest(methodloc_callback[], m)
catch
end
file, line = updated_methodloc(m)
print(io, " at ", file, ":", line)
end
end
Expand Down Expand Up @@ -247,11 +261,7 @@ function show_method_table(io::IO, ms::MethodList, max::Int=-1, header::Bool=tru
println(io)
print(io, "[$(n)] ")
show(io, meth)
file, line = meth.file, meth.line
try
file, line = invokelatest(methodloc_callback[], meth)
catch
end
file, line = updated_methodloc(meth)
push!(LAST_SHOWN_LINE_INFOS, (string(file), line))
else
rest += 1
Expand Down Expand Up @@ -361,10 +371,7 @@ function show(io::IO, ::MIME"text/html", m::Method)
end
print(io, " in ", m.module)
if line > 0
try
file, line = invokelatest(methodloc_callback[], m)
catch
end
file, line = updated_methodloc(m)
u = url(m)
if isempty(u)
print(io, " at ", file, ":", line)
Expand Down Expand Up @@ -398,11 +405,7 @@ function show(io::IO, mime::MIME"text/plain", mt::AbstractVector{Method})
first = false
print(io, "[$(i)] ")
show(io, m)
file, line = m.file, m.line
try
file, line = invokelatest(methodloc_callback[], m)
catch
end
file, line = updated_methodloc(m)
push!(LAST_SHOWN_LINE_INFOS, (string(file), line))
end
end
Expand Down
3 changes: 3 additions & 0 deletions base/sysinfo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ A string containing the full path to the directory containing the `julia` execut
A string containing the full path to the directory containing the `stdlib` packages.
"""
STDLIB = "$BINDIR/../share/julia/stdlib/v$(VERSION.major).$(VERSION.minor)" # for bootstrap
# In case STDLIB change after julia is built, the variable below can be used
# to update cached method locations to updated ones.
const BUILD_STDLIB_PATH = STDLIB

# helper to avoid triggering precompile warnings

Expand Down
4 changes: 4 additions & 0 deletions stdlib/InteractiveUtils/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,7 @@ if Sys.iswindows() || Sys.isapple()
@test clipboard() == str
end
end

# buildbot path updating
file, ln = functionloc(versioninfo, Tuple{})
@test isfile(file)
3 changes: 1 addition & 2 deletions test/show.jl
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ else
end

# Method location correction (Revise integration)
methloc = Base.methodloc_callback[]
dummyloc(m::Method) = :nofile, 123456789
Base.methodloc_callback[] = dummyloc
let repr = sprint(show, "text/plain", methods(Base.inbase))
Expand All @@ -646,7 +645,7 @@ end
let repr = sprint(show, "text/html", methods(Base.inbase))
@test occursin("nofile:123456789", repr)
end
Base.methodloc_callback[] = methloc
Base.methodloc_callback[] = nothing

@testset "matrix printing" begin
# print_matrix should be able to handle small and large objects easily, test by
Expand Down