Skip to content

Commit

Permalink
Use isglobal for usings
Browse files Browse the repository at this point in the history
  • Loading branch information
Pangoraw committed Nov 14, 2023
1 parent 2aacc50 commit ffc1bc0
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 38 deletions.
19 changes: 9 additions & 10 deletions src/analysis/ExpressionExplorer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,19 @@ maybe_macroexpand_pluto(ex::Any; kwargs...) = ex

###############

function collect_implicit_usings(usings_imports::ExpressionExplorer.UsingsImports)
implicit_usings = Set{Expr}()
for (using_, isglobal) in zip(usings_imports.usings, usings_imports.usings_isglobal)
if !(isglobal && is_implicit_using(using_))
continue
end


function collect_implicit_usings(ex::Expr)
if is_implicit_using(ex)
Set{Expr}(Iterators.map(transform_dot_notation, ex.args))
else
return Set{Expr}()
mapreduce(transform_dot_notation, push!,
using_.args; init=implicit_usings)
end
implicit_usings
end

collect_implicit_usings(usings::Union{AbstractSet{Expr},AbstractVector{Expr}}) = mapreduce(collect_implicit_usings, union!, usings; init = Set{Expr}())
collect_implicit_usings(usings_imports::ExpressionExplorer.UsingsImports) = collect_implicit_usings(usings_imports.usings)


is_implicit_using(ex::Expr) = Meta.isexpr(ex, :using) && length(ex.args) >= 1 && !Meta.isexpr(ex.args[1], :(:))

function transform_dot_notation(ex::Expr)
Expand Down
3 changes: 2 additions & 1 deletion src/evaluation/MacroAnalysis.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ function with_new_soft_definitions(topology::NotebookTopology, cell::Cell, soft_
)
end

collect_implicit_usings(topology::NotebookTopology, cell::Cell) = ExpressionExplorerExtras.collect_implicit_usings(topology.codes[cell].module_usings_imports)
collect_implicit_usings(topology::NotebookTopology, cell::Cell) =
ExpressionExplorerExtras.collect_implicit_usings(topology.codes[cell].module_usings_imports)

function cells_with_deleted_macros(old_topology::NotebookTopology, new_topology::NotebookTopology)
old_macros = mapreduce(c -> defined_macros(old_topology, c), union!, all_cells(old_topology); init=Set{Symbol}())
Expand Down
43 changes: 17 additions & 26 deletions src/evaluation/Run.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import REPL: ends_with_semicolon
import .Configuration
import .ExpressionExplorer: is_joined_funcname

Base.push!(x::Set{Cell}) = x

"""
Run given cells and all the cells that depend on them, based on the topology information before and after the changes.
"""
Expand Down Expand Up @@ -77,31 +75,18 @@ function run_reactive_core!(
roots = vcat(roots, removed_cells)

# by setting the reactive node and expression caches of deleted cells to "empty", we are essentially pretending that those cells still exist, but now have empty code. this makes our algorithm simpler.
new_topology = NotebookTopology(
nodes = merge(
new_topology.nodes,
Dict(cell => ReactiveNode() for cell in removed_cells),
),
codes = merge(
new_topology.codes,
Dict(cell => ExprAnalysisCache() for cell in removed_cells)
),
unresolved_cells = new_topology.unresolved_cells,
cell_order = new_topology.cell_order,
disabled_cells=new_topology.disabled_cells,
)


new_topology = exclude_roots(new_topology, removed_cells)

# find (indirectly) deactivated cells and update their status
indirectly_deactivated = collect(topological_order(new_topology, collect(new_topology.disabled_cells); allow_multiple_defs=true, skip_at_partial_multiple_defs=true))

for cell in indirectly_deactivated
cell.running = false
cell.queued = false
cell.depends_on_disabled_cells = true
end

new_topology = exclude_roots(new_topology, indirectly_deactivated)
new_topology = exclude_roots(new_topology, indirectly_deactivated)

# save the old topological order - we'll delete variables assigned from its
# and re-evalutate its cells unless the cells have already run previously in the reactive run
Expand All @@ -110,13 +95,13 @@ function run_reactive_core!(
old_runnable = setdiff(old_order.runnable, already_run, indirectly_deactivated)
to_delete_vars = union!(Set{Symbol}(), defined_variables(old_topology, old_runnable)...)
to_delete_funcs = union!(Set{Tuple{UUID,FunctionName}}(), defined_functions(old_topology, old_runnable)...)
new_roots = setdiff(union(roots, keys(old_order.errable)), indirectly_deactivated)


new_roots = setdiff(union(roots, keys(old_order.errable)), indirectly_deactivated)
# get the new topological order
new_order = topological_order(new_topology, new_roots)
new_runnable = setdiff(new_order.runnable, already_run)
to_run = setdiff(union(new_runnable, old_runnable), keys(new_order.errable))::Vector{Cell} # TODO: think if old error cell order matters
to_run = setdiff!(union(new_runnable, old_runnable), keys(new_order.errable))::Vector{Cell} # TODO: think if old error cell order matters


# change the bar on the sides of cells to "queued"
Expand Down Expand Up @@ -159,9 +144,15 @@ function run_reactive_core!(

cells_to_macro_invalidate = Set{UUID}(c.cell_id for c in cells_with_deleted_macros(old_topology, new_topology))

to_reimport = union!(Set{Expr}(), (
new_topology.codes[c].module_usings_imports.usings for c in notebook.cells if c to_run
)...)
to_reimport = reduce(all_cells(new_topology); init=Set{Expr}()) do to_reimport, c
c to_run && return to_reimport
usings_imports = new_topology.codes[c].module_usings_imports
for (using_, isglobal) in zip(usings_imports.usings, usings_imports.usings_isglobal)
isglobal || continue
push!(to_reimport, using_)
end
to_reimport
end

if will_run_code(notebook)
to_delete_funcs_simple = Set{Tuple{UUID,Tuple{Vararg{Symbol}}}}((id, name.parts) for (id,name) in to_delete_funcs)
Expand Down
2 changes: 1 addition & 1 deletion src/runner/PlutoRunner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1683,7 +1683,7 @@ const integrations = Integration[
code = quote
@assert v"1.0.0" <= AbstractPlutoDingetjes.MY_VERSION < v"2.0.0"

supported!(xs...) = push!(supported_integration_features, xs...)
supported!(xs...) = append!(supported_integration_features, xs)

# don't need feature checks for these because they existed in every version of AbstractPlutoDingetjes:
supported!(
Expand Down
25 changes: 25 additions & 0 deletions test/React.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,31 @@ import Pluto.Configuration: Options, EvaluationOptions
WorkspaceManager.unmake_workspace((🍭, notebook); verbose=false)
end

@testset "Using package from module" begin
notebook = Notebook([
Cell("""module A
using Dates
end"""),
Cell(""),
Cell("December"),
])

update_run!(🍭, notebook, notebook.cells)

@test notebook.cells[begin] |> noerror
@test occursinerror("UndefVarError", notebook.cells[end])

setcode!(notebook.cells[2], "using Dates")

update_run!(🍭, notebook, [notebook.cells[2]])

@test notebook.cells[1] |> noerror
@test notebook.cells[2] |> noerror
@test notebook.cells[3] |> noerror

WorkspaceManager.unmake_workspace((🍭, notebook); verbose=false)
end

@testset "Function wrapping" begin
notebook = Notebook([
Cell("false && jlaksdfjalskdfj"),
Expand Down

0 comments on commit ffc1bc0

Please sign in to comment.