From 816c3e06bb2d7156beb7f8944cc71915a8ed7c7a Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Sun, 3 Mar 2019 10:33:50 -0600 Subject: [PATCH] Support CodeTracking's `signatures_at` --- src/Revise.jl | 39 +++++++++++++++++---------------------- src/recipes.jl | 23 ++++++++++++++--------- src/types.jl | 12 ++++++++++++ test/runtests.jl | 7 +++++++ 4 files changed, 50 insertions(+), 31 deletions(-) diff --git a/src/Revise.jl b/src/Revise.jl index 63d99f55..90e0a0c8 100644 --- a/src/Revise.jl +++ b/src/Revise.jl @@ -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 @@ -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() diff --git a/src/recipes.jl b/src/recipes.jl index 3cd11b9d..becda80f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -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) @@ -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 diff --git a/src/types.jl b/src/types.jl index 2dd024b0..fd6c0be5 100644 --- a/src/types.jl +++ b/src/types.jl @@ -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 diff --git a/test/runtests.jl b/test/runtests.jl index 2a5917a8..3a9badce 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -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