Skip to content

Commit

Permalink
Check that file being precompiled contains a module (#51635)
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth authored Oct 9, 2023
1 parent 4115c72 commit 6da54ce
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
32 changes: 32 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2246,9 +2246,41 @@ function load_path_setup_code(load_path::Bool=true)
return code
end

"""
check_src_module_wrap(srcpath::String)
Checks that a package entry file `srcpath` has a module declaration, and that it is before any using/import statements.
"""
function check_src_module_wrap(pkg::PkgId, srcpath::String)
module_rgx = r"^\s*(?:@\w*\s*)*(?:bare)?module\s"
load_rgx = r"\b(?:using|import)\s"
load_seen = false
inside_comment = false
for s in eachline(srcpath)
if contains(s, "\"\"\"")
# ignore module docstrings
inside_comment = !inside_comment
end
inside_comment && continue
if startswith(s, module_rgx)
if load_seen
throw(ErrorException("Package $pkg source file $srcpath has a using/import before a module declaration."))
end
return true
end
if startswith(s, load_rgx)
load_seen = true
end
end
throw(ErrorException("Package $pkg source file $srcpath does not contain a module declaration."))
end

# this is called in the external process that generates precompiled package files
function include_package_for_output(pkg::PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String},
concrete_deps::typeof(_concrete_dependencies), source::Union{Nothing,String})

check_src_module_wrap(pkg, input)

append!(empty!(Base.DEPOT_PATH), depot_path)
append!(empty!(Base.DL_LOAD_PATH), dl_load_path)
append!(empty!(Base.LOAD_PATH), load_path)
Expand Down
72 changes: 72 additions & 0 deletions test/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1184,3 +1184,75 @@ end
@test success(`$(Base.julia_cmd()) --startup-file=no -e 'using DelimitedFiles'`)
@test success(`$(Base.julia_cmd()) --startup-file=no -e 'using Statistics'`)
end

@testset "checking srcpath modules" begin
p = Base.PkgId("Dummy")
fpath, _ = mktemp()
@testset "valid" begin
write(fpath, """
module Foo
using Bar
end
""")
@test Base.check_src_module_wrap(p, fpath)

write(fpath, """
baremodule Foo
using Bar
end
""")
@test Base.check_src_module_wrap(p, fpath)

write(fpath, """
\"\"\"
Foo
using Foo
\"\"\"
module Foo
using Bar
end
""")
@test Base.check_src_module_wrap(p, fpath)

write(fpath, """
# using foo
module Foo
using Bar
end
""")
@test Base.check_src_module_wrap(p, fpath)

write(fpath, """
# using foo
module Foo
using Bar
end
""")
@test Base.check_src_module_wrap(p, fpath)
end
@testset "invalid" begin
write(fpath, """
# module Foo
using Bar
# end
""")
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)

write(fpath, """
using Bar
module Foo
end
""")
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)

write(fpath, """
using Bar
""")
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)

write(fpath, """
x = 1
""")
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)
end
end
6 changes: 5 additions & 1 deletion test/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,11 @@ precompile_test_harness(false) do dir
FooBar3_inc = joinpath(dir, "FooBar3_inc.jl")
write(FooBar3_inc, "x=1\n")
for code in ["Core.eval(Base, :(x=1))", "Base.include(Base, \"FooBar3_inc.jl\")"]
write(FooBar3_file, code)
write(FooBar3_file, """
module FooBar3
$code
end
""")
@test_warn "Evaluation into the closed module `Base` breaks incremental compilation" try
Base.require(Main, :FooBar3)
catch exc
Expand Down

0 comments on commit 6da54ce

Please sign in to comment.