-
Notifications
You must be signed in to change notification settings - Fork 6
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
Add functionality to find out about locations from file numbers #19
Closed
Closed
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
0795fda
Add functionality to find out about files
oxinabox 04a573f
Remove mistaken include
oxinabox 6d1a086
Update Project.toml
oxinabox bf46485
Find the method that a given line is contained within
oxinabox c89326e
make sure can locate methods
oxinabox c9861a5
add ir statement finding
oxinabox 0e29aae
add Rebugger dependency
oxinabox d5f9362
add docstring
oxinabox 462eb66
connect tests
oxinabox 7c4e3bb
remove doubts
oxinabox 8021fd6
ignore dev folder
oxinabox d2c0a88
cleanup testing so can show breadcrumbs
oxinabox 7e8117d
link in to normal breadcrumbs, doesn't seem to always be right though
oxinabox ff81be2
stop using rebugger
oxinabox 6627820
undo the bug that deletes targets
oxinabox 4cce6a9
put back the old revise methods in code that is gettng deleted
oxinabox 0bfa356
rewrite to use CodeTracking.jl
oxinabox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,5 @@ | |
*.jl.cov | ||
*.jl.*.cov | ||
*.jl.mem | ||
|
||
dev/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
""" | ||
pkgdata(mod) | ||
|
||
Gets all the data Revise has on the given module. | ||
""" | ||
pkgdata(pkg_id::Base.PkgId) = Revise.pkgdatas[pkg_id] | ||
pkgdata(mod::Module) = pkgdata(Base.PkgId(mod)) | ||
|
||
""" | ||
filemap(mod, file) | ||
|
||
Retrieve all the data Revise has on the contents of given file | ||
from the given module. | ||
""" | ||
function filemap(mod, file) | ||
mdata = pkgdata(mod) | ||
mfiles = joinpath.(mdata.path, keys(mdata.fileinfos)) | ||
|
||
file = expanduser(file) | ||
if !isabspath(file) | ||
# We do not need it to be absolute | ||
# But we do want it to start with a "/" | ||
# So we can use `endswith` to check that it matchs one of the paths | ||
# that we know about, without worry of matching part of a filename | ||
file = "/" * file | ||
end | ||
matched_ind = findfirst(mfile->endswith(mfile, file) , mfiles) | ||
matched_ind === nothing && return nothing | ||
|
||
internal_file = collect(keys(mdata.fileinfos))[matched_ind] | ||
Revise.maybe_parse_from_cache!(mdata, internal_file) # Ensure fileinfo filled | ||
finfo = collect(values(mdata.fileinfos))[matched_ind] | ||
return finfo.fm | ||
end | ||
|
||
###################################################################### | ||
# These come from Rebugger.jl | ||
# Including them here as Rebugger itself is causing problems. | ||
# They can away once code tracking gets a bit more stuff. | ||
# https://github.com/timholy/CodeTracking.jl/issues/3 | ||
|
||
using Revise: ExLike | ||
|
||
|
||
""" | ||
r = linerange(expr, offset=0) | ||
Compute the range of lines occupied by `expr`. | ||
Returns `nothing` if no line statements can be found. | ||
""" | ||
function linerange(def::ExLike, offset=0) | ||
start, haslinestart = findline(def, identity) | ||
stop, haslinestop = findline(def, Iterators.reverse) | ||
(haslinestart & haslinestop) && return (start+offset):(stop+offset) | ||
return nothing | ||
end | ||
|
||
function findline(ex, order) | ||
ex.head == :line && return ex.args[1], true | ||
for a in order(ex.args) | ||
a isa LineNumberNode && return a.line, true | ||
if a isa ExLike | ||
ln, hasline = findline(a, order) | ||
hasline && return ln, true | ||
end | ||
end | ||
return 0, false | ||
end | ||
|
||
|
||
function linerange((def, (sig, offset))::Tuple{Any, Tuple{Any, Int}}) | ||
return linerange(def, offset) | ||
end | ||
|
||
# This is not a function so just return an empty range | ||
linerange((def, none)::Tuple{Any, Nothing}) = 1:0 | ||
|
||
|
||
######################################################################## | ||
""" | ||
containing_method([module], filename, linenum) | ||
|
||
Returns the method within which that line number, in that file, occurs. | ||
Returns `nothing` on no match. | ||
|
||
If the module is not provided, then all modules loaded | ||
will be searched for a file with that name that has a function over that line. | ||
|
||
Filenames can be absolute, or partial. | ||
E.g. `/home/user1/dev/MyMod/src/helpers/utils.jl`, | ||
`helpers/utils.jl` or `utils.jl` are all acceptable. | ||
|
||
However, if multiple files match the module (or lack of module), | ||
and filename specification then only one will be selected. | ||
""" | ||
function containing_method(mod, file, linenum) | ||
module_fmaps = filemap(mod, file) | ||
module_fmaps === nothing && return nothing | ||
for (inner_mod, fmaps) in module_fmaps | ||
for entry in fmaps.defmap | ||
def, info = entry | ||
lr = linerange((def, info)) | ||
# TODO: workout a way to round-forward as the linerange starts from first | ||
# statement within the functions body, not from the line it is "declared" | ||
# And there could be quiet some whitespace | ||
if linenum ∈ lr | ||
sigt, offset = info | ||
return sigt2meth(sigt[end]) | ||
end | ||
end | ||
end | ||
end | ||
|
||
function containing_method(file, linenum) | ||
for pkg_id in keys(Revise.pkgdatas) | ||
meth = containing_method(pkg_id, file, linenum) | ||
meth !== nothing && return meth | ||
end | ||
end | ||
|
||
function sigt2meth(::Type{SIGT}) where SIGT | ||
params = SIGT.parameters | ||
func_t = params[1] | ||
func = func_t.instance | ||
|
||
args_t = Tuple{params[2:end]...} | ||
|
||
return only(methods(func, args_t)) | ||
end | ||
|
||
|
||
|
||
############## | ||
""" | ||
src_line2ir_statement_ind(irr, src_line) | ||
|
||
Given a CodeIR, and line number from source code | ||
determines the index of the last IR statement that occurs on that line. | ||
""" | ||
function src_line2ir_statement_ind(ir, src_line) | ||
linetable_ind = findlast(ir.linetable) do lineinfo | ||
lineinfo.line == src_line | ||
end | ||
statement_ind = findlast(isequal(linetable_ind), ir.codelocs) | ||
return statement_ind | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using MagneticReadHead | ||
using Test | ||
@testset "breadcrumbs" begin | ||
iob = IOBuffer() | ||
MagneticReadHead.breadcrumbs(iob, "demo.jl", 4) | ||
@test String(take!(iob)) == | ||
" \n \n➧function eg1()\n z = eg2(2)\n eg_last(z)\n" | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
using Revise | ||
using MagneticReadHead | ||
using Test | ||
|
||
using MagneticReadHead: | ||
filemap, pkgdata, containing_method, src_line2ir_statement_ind | ||
|
||
@show Revise.pkgdatas #BLACKMAGIC: Remove this line and the tests fail | ||
|
||
@testset "src_line2ir_statement_ind" begin | ||
ir1line = first(methods(()->1)) |> Base.uncompressed_ast | ||
@test src_line2ir_statement_ind(ir1line, (@__LINE__)-1) == 1 | ||
@test src_line2ir_statement_ind(ir1line, 1000) == nothing | ||
|
||
ir1line2 = first(methods(()->(x=1;x*x))) |> Base.uncompressed_ast | ||
@test src_line2ir_statement_ind(ir1line2, (@__LINE__)-1) == 3 | ||
|
||
|
||
ir2line = first(methods(()->(x=1; | ||
x*x))) |> Base.uncompressed_ast | ||
@test src_line2ir_statement_ind(ir2line, (@__LINE__)-1) == 3 | ||
end | ||
|
||
|
||
@testset "pkgdata" begin | ||
@test pkgdata(MagneticReadHead) !==nothing | ||
end | ||
|
||
@testset "filemap" begin | ||
@test filemap(MagneticReadHead, "utils.jl") !==nothing | ||
@test filemap(MagneticReadHead, "src/utils.jl") == filemap(MagneticReadHead, "utils.jl") | ||
|
||
@test filemap(MagneticReadHead, "NOT_REAL") ===nothing | ||
end | ||
|
||
|
||
@testset "containing_method" begin | ||
|
||
meth = containing_method(MagneticReadHead, "src/locate.jl", 30) | ||
for ln in (29, 30, 31) | ||
@test meth == containing_method(MagneticReadHead, "src/locate.jl", ln) | ||
@test meth == containing_method(MagneticReadHead, "locate.jl", ln) | ||
@test meth == containing_method("locate.jl", ln) | ||
@test_broken meth == | ||
containing_method(MagneticReadHead, "../src/locate.jl", ln) | ||
cd(@__DIR__) do | ||
@test meth == containing_method( | ||
MagneticReadHead, | ||
realpath("../src/locate.jl"), | ||
ln | ||
) | ||
end | ||
end | ||
end | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
accidentally removed when doing a
rm
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
revolved in #23