Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use isglobal for usings
Browse files Browse the repository at this point in the history
Pangoraw committed Nov 16, 2023
1 parent a45427c commit 0c17e6a
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
@@ -130,20 +130,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)
3 changes: 2 additions & 1 deletion src/evaluation/MacroAnalysis.jl
Original file line number Diff line number Diff line change
@@ -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}())
43 changes: 17 additions & 26 deletions src/evaluation/Run.jl
Original file line number Diff line number Diff line change
@@ -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.
"""
@@ -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
@@ -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"
@@ -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)
2 changes: 1 addition & 1 deletion src/runner/PlutoRunner.jl
Original file line number Diff line number Diff line change
@@ -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!(
25 changes: 25 additions & 0 deletions test/React.jl
Original file line number Diff line number Diff line change
@@ -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"),

0 comments on commit 0c17e6a

Please sign in to comment.