Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Sep 28, 2017
1 parent 7039126 commit 8f506e1
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 32 deletions.
72 changes: 43 additions & 29 deletions src/Revise.jl
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ end

const file2modules = Dict{String,FileModules}()
const module2files = Dict{Symbol,Vector{String}}()
const new_files = String[]
const included_files = Tuple{Module,String}[]

function use_compiled_modules()
@static if VERSION >= v"0.7.0-DEV.1698"
Expand All @@ -290,22 +290,43 @@ function parse_pkg_files(modsym::Symbol)
# can't fully exploit this just yet, see below.
paths = Base.find_all_in_cache_path(modsym)
end
files = String[]
if !isempty(paths)
# We got it from the precompile cache
length(paths) > 1 && error("Multiple paths detected: ", paths)
_, files_mtimes = Base.cache_dependencies(paths[1])
files = map(ft->normpath(first(ft)), files_mtimes) # idx 1 is the filename, idx 2 is the mtime
mainfile = first(files)
# We still have to parse the source code, and if there are
# multiple modules then we don't know which module to `eval`
# them into.
parse_source(mainfile, Main, dirname(mainfile))
_, mods_files_mtimes = Base.parse_cache_header(paths[1])
for (modname, fname, _) in mods_files_mtimes
modname == "__external__" && continue
if modname == "Base.__toplevel__"
modname = "Main"
end
mod = eval(Main, parse(modname))
pr = parse_source(fname, mod, nothing)
if isa(pr, Pair)
push!(file2modules, pr)
end
push!(files, fname)
end
else
# Non-precompiled package, so we learn the list of files through parsing
mainfile = Base.find_source_file(string(modsym))
empty!(new_files)
parse_source(mainfile, Main, dirname(mainfile))
files = map(normpath, new_files)
# Non-precompiled package(s)
i = 1
while i <= length(included_files)
mod, fname = included_files[i]
if mod == Base.__toplevel__
mod = Main
end
modstring = string(modsym)
if startswith(string(mod), modstring) || endswith(fname, modstring*".jl")
pr = parse_source(fname, mod, nothing)
if isa(pr, Pair)
push!(file2modules, pr)
end
push!(files, normpath(fname))
deleteat!(included_files, i)
else
i += 1
end
end
end
module2files[modsym] = files
files
Expand All @@ -330,20 +351,9 @@ function parse_source(file::AbstractString, mod::Module, path)
# Create a blank ModDict to store the expressions. Parsing will "fill" this.
md = ModDict(mod=>OrderedSet{RelocatableExpr}())
nfile = normpath(file)
if path != nothing
# Parsing is recursive (depth-first), so to preserve the order
# we add `file` to the list now
push!(new_files, nfile)
end
if !parse_source!(md, file, mod, path)
pop!(new_files) # since it failed, remove it from the list
return nothing
end
parse_source!(md, file, mod, path) || return nothing
fm = FileModules(mod, md)
if path != nothing
file2modules[nfile] = fm
end
fm
nfile => fm
end

"""
Expand Down Expand Up @@ -596,8 +606,9 @@ function revise_file_now(file0)
error(file, " is not currently being tracked.")
end
oldmd = file2modules[file]
newmd = parse_source(file, oldmd.topmod, nothing)
if newmd != nothing
pr = parse_source(file, oldmd.topmod, nothing)
if pr != nothing
newmd = pr.second
revmd = revised_statements(newmd.md, oldmd.md)
try
eval_revised(revmd)
Expand Down Expand Up @@ -640,7 +651,8 @@ end
Revise.track(file::AbstractString)
Watch `file` for updates and [`revise`](@ref) loaded code with any
changes. If `mod` is omitted it defaults to `Main`.
changes. `mod` is the module into which `file` is evaluated; if omitted,
it defaults to `Main`.
"""
function track(mod::Module, file::AbstractString)
isfile(file) || error(file, " is not a file")
Expand Down Expand Up @@ -770,6 +782,8 @@ function __init__()
end
end
push!(Base.package_callbacks, watch_package)
push!(Base.include_callbacks,
(mod::Module, fn::AbstractString) -> push!(included_files, (mod, String(fn))))
mode = get(ENV, "JULIA_REVISE", "auto")
if mode == "auto"
if isdefined(Base, :active_repl_backend)
Expand Down
6 changes: 3 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ k(x) = 4
# test the "mistakes"
@test ReviseTest.cube(2) == 16
@test ReviseTest.Internal.mult3(2) == 8
oldmd = Revise.parse_source(fl1, Main, dirname(fl1))
newmd = Revise.parse_source(fl2, Main, nothing)
oldmd = Revise.parse_source(fl1, Main, dirname(fl1)).second
newmd = Revise.parse_source(fl2, Main, nothing).second
revmd = Revise.revised_statements(newmd, oldmd)
@test length(revmd) == 2
@test haskey(revmd, ReviseTest) && haskey(revmd, ReviseTest.Internal)
Expand All @@ -84,7 +84,7 @@ k(x) = 4
@test ReviseTest.Internal.mult3(2) == 6

# Backtraces
newmd = Revise.parse_source(fl3, Main, nothing)
newmd = Revise.parse_source(fl3, Main, nothing).second
revmd = Revise.revised_statements(newmd, oldmd)
Revise.eval_revised(revmd)
try
Expand Down

0 comments on commit 8f506e1

Please sign in to comment.