Skip to content

Commit

Permalink
Support CodeTracking's signatures_at
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Mar 3, 2019
1 parent e345e3e commit 816c3e0
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 31 deletions.
39 changes: 17 additions & 22 deletions src/Revise.jl
Original file line number Diff line number Diff line change
Expand Up @@ -691,35 +691,29 @@ function get_def(method, pkgdata, filename)
return nothing
end

function get_tracked_id(mod::Module; modified_files=revision_queue)
id = PkgId(mod)
function get_tracked_id(id::PkgId; modified_files=revision_queue)
# Methods from Base or the stdlibs may require that we start tracking
if !haskey(pkgdatas, id)
recipemod = mod
if id.name == "Base"
recipemod = Base
elseif id.name == "Core"
recipemod = Core.Compiler
elseif Symbol(id.name) stdlib_names
prevmod = recipemod
while String(nameof(recipemod)) != id.name
recipemod = parentmodule(recipemod)
recipemod == prevmod && break
prevmod = recipemod
end
else
@warn "$id not found, not able to track"
return nothing
end
@info "tracking $recipemod"
track(recipemod; modified_files=modified_files)
recipe = id.name === "Compiler" ? :Compiler : Symbol(id.name)
_track(id, recipe; modified_files=modified_files)
@info "tracking $recipe"
if !haskey(pkgdatas, id)
@warn "despite tracking $recipemod, $id was not found"
@warn "despite tracking $recipe, $id was not found"
return nothing
end
end
return id
end
get_tracked_id(mod::Module; modified_files=revision_queue) =
get_tracked_id(PkgId(mod); modified_files=modified_files)

function get_expressions(id::PkgId, filename)
get_tracked_id(id)
pkgdata = pkgdatas[id]
maybe_parse_from_cache!(pkgdata, filename)
fi = fileinfo(pkgdata, filename)
return fi.fm
end

function fix_line_statements!(ex::Expr, file::Symbol, line_offset::Int=0)
if ex.head == :line
Expand Down Expand Up @@ -870,8 +864,9 @@ function __init__()
# Populate CodeTracking data for dependencies
parse_pkg_files(PkgId(CodeTracking))
parse_pkg_files(PkgId(OrderedCollections))
# Set the lookup callback
# Set the lookup callbacks
CodeTracking.method_lookup_callback[] = get_def
CodeTracking.expressions_callback[] = get_expressions

# Watch the manifest file for changes
mfile = manifest_file()
Expand Down
23 changes: 14 additions & 9 deletions src/recipes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,34 @@ Track updates to the code in Julia's `base` directory, `base/compiler`, or one o
standard libraries.
"""
function track(mod::Module; modified_files=revision_queue)
inpath(path, dirs) = all(dir->occursin(dir, path), dirs)
id = PkgId(mod)
isbase = mod == Base
isstdlib = !isbase && nameof(mod) stdlib_names
modname = nameof(mod)
return _track(id, modname; modified_files=modified_files)
end

function _track(id, modname; modified_files=revision_queue)
inpath(path, dirs) = all(dir->occursin(dir, path), dirs)
isbase = modname == :Base
isstdlib = !isbase && modname stdlib_names
if isbase || isstdlib
# Test whether we know where to find the files
if isbase
srcdir = fixpath(joinpath(juliadir, "base"))
dirs = ["base"]
else
stdlibv = joinpath("stdlib", "v$(VERSION.major).$(VERSION.minor)", String(nameof(mod)))
stdlibv = joinpath("stdlib", "v$(VERSION.major).$(VERSION.minor)", String(modname))
srcdir = fixpath(joinpath(juliadir, stdlibv))
if !isdir(srcdir)
srcdir = fixpath(joinpath(juliadir, "stdlib", String(nameof(mod))))
srcdir = fixpath(joinpath(juliadir, "stdlib", String(modname)))
end
if !isdir(srcdir)
# This can happen for Pkg, since it's developed out-of-tree
srcdir = joinpath(juliadir, "usr", "share", "julia", stdlibv)
end
dirs = ["stdlib", String(nameof(mod))]
dirs = ["stdlib", String(modname)]
end
if !isdir(srcdir)
@error "unable to find path containing source for $mod, tracking is not possible"
@error "unable to find path containing source for $modname, tracking is not possible"
end
# Determine when the basesrccache was built
mtcache = mtime(basesrccache)
Expand Down Expand Up @@ -59,14 +64,14 @@ function track(mod::Module; modified_files=revision_queue)
end
# Add the files to the watch list
init_watching(pkgdata, srcfiles(pkgdata))
elseif mod == Core.Compiler
elseif modname == :Compiler
compilerdir = normpath(joinpath(juliadir, "base", "compiler"))
if !haskey(pkgdatas, id)
pkgdatas[id] = PkgData(id, compilerdir)
end
track_subdir_from_git(id, compilerdir; modified_files=modified_files)
else
error("no Revise.track recipe for module ", mod)
error("no Revise.track recipe for module ", modname)
end
return nothing
end
Expand Down
12 changes: 12 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ function Base.show(io::IO, fmm::FMMaps)
end
end

Base.iterate(fmm::FMMaps) = _returnval(iterate(fmm.defmap))
Base.iterate(fmm::FMMaps, state) = _returnval(iterate(fmm.defmap, state))

function _returnval(ret)
ret === nothing && return nothing
(rex, val), state = ret
if val !== nothing
val = val[1]
end
return (rex, val), state
end

"""
FileModules
Expand Down
7 changes: 7 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,13 @@ end
ex.args[end].args[end] = 2
@test Revise.relocatable!(definition(m)) == ex2
@test Revise.relocatable!(definition(m)) != ex
# CodeTracking methods
m3 = first(methods(eval(fn3)))
m3file = joinpath(dn, "subdir", "file3.jl")
@test whereis(m3) == (m3file, 1)
@test signatures_at(m3file, 1) == [m3.sig]
@test signatures_at(eval(Symbol(modname)), joinpath("src", "subdir", "file3.jl"), 1) == [m3.sig]

sleep(0.1) # to ensure that the file watching has kicked in
# Change the definition of function 1 (easiest to just rewrite the whole file)
open(joinpath(dn, modname*".jl"), "w") do io
Expand Down

0 comments on commit 816c3e0

Please sign in to comment.