Skip to content
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
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
CodeTracking is a minimal package designed to work with (a future version of)
[Revise.jl](https://github.com/timholy/Revise.jl).
Its main purpose is to support packages that need to interact with code that might move
around as it's edited.
around as it gets edited.

CodeTracking is a very lightweight dependency.

Expand All @@ -23,7 +23,10 @@ In this (ficticious) example, `sum` moved because I deleted a few lines higher i
these didn't affect the functionality of `sum` (so we didn't need to redefine and recompile it),
but it does change the starting line number of the file at which this method appears.

Other features:
Other methods of `whereis` allow you to obtain the current position corresponding to a single
statement inside a method; see `?whereis` for details.

CodeTracking can also be used to find out what files define a particular package:

```julia
julia> using CodeTracking, ColorTypes
Expand All @@ -32,7 +35,11 @@ julia> pkgfiles(ColorTypes)
PkgFiles(ColorTypes [3da002f7-5984-5a60-b8a6-cbb66c0b333f]):
basedir: /home/tim/.julia/packages/ColorTypes/BsAWO
files: ["src/ColorTypes.jl", "src/types.jl", "src/traits.jl", "src/conversions.jl", "src/show.jl", "src/operations.jl"]
```

or to extract the expression that defines a method:

```julia
julia> m = @which red(RGB(1,1,1))
red(c::AbstractRGB) in ColorTypes at /home/tim/.julia/packages/ColorTypes/BsAWO/src/traits.jl:14

Expand Down
26 changes: 26 additions & 0 deletions src/CodeTracking.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,32 @@ function whereis(method::Method)
return normpath(file), line
end

"""
loc = whereis(sf::StackFrame)

Return location information for a single frame of a stack trace.
If `sf` corresponds to a frame that was inlined, `loc` will be `nothing`.
Otherwise `loc` will be `(filepath, line)`.
"""
function whereis(sf::StackTraces.StackFrame)
sf.linfo === nothing && return nothing
return whereis(sf, sf.linfo.def)
end

"""
filepath, line = whereis(lineinfo, method::Method)

Return the file and line number associated with a specific statement in `method`.
`lineinfo.line` should contain the line number of the statement at the time `method`
was compiled. The current location is returned.
"""
function whereis(lineinfo, method::Method)
file, line1 = whereis(method)
return file, lineinfo.line-method.line+line1
end



"""
src = definition(method::Method, String)

Expand Down
12 changes: 11 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@ include("script.jl")
@testset "CodeTracking.jl" begin
m = first(methods(f1))
file, line = whereis(m)
@test file == normpath(joinpath(@__DIR__, "script.jl"))
scriptpath = normpath(joinpath(@__DIR__, "script.jl"))
@test file == scriptpath
@test line == 3
trace = try
call_throws()
catch
stacktrace(catch_backtrace())
end
@test whereis(trace[2]) == (scriptpath, 10)
@test whereis(trace[3]) === nothing

src = definition(m, String)
@test src == """
function f1(x, y)
Expand Down
8 changes: 8 additions & 0 deletions test/script.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# NOTE: tests are sensitive to the line number at which statements appear
function f1(x, y)
return x + y
end

f2(x, y) = x + y

@noinline function throws()
x = nothing
error("oops")
end
@inline inlined() = throws()
call_throws() = inlined()