Skip to content

Commit 6da54ce

Browse files
Check that file being precompiled contains a module (#51635)
1 parent 4115c72 commit 6da54ce

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

base/loading.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2246,9 +2246,41 @@ function load_path_setup_code(load_path::Bool=true)
22462246
return code
22472247
end
22482248

2249+
"""
2250+
check_src_module_wrap(srcpath::String)
2251+
2252+
Checks that a package entry file `srcpath` has a module declaration, and that it is before any using/import statements.
2253+
"""
2254+
function check_src_module_wrap(pkg::PkgId, srcpath::String)
2255+
module_rgx = r"^\s*(?:@\w*\s*)*(?:bare)?module\s"
2256+
load_rgx = r"\b(?:using|import)\s"
2257+
load_seen = false
2258+
inside_comment = false
2259+
for s in eachline(srcpath)
2260+
if contains(s, "\"\"\"")
2261+
# ignore module docstrings
2262+
inside_comment = !inside_comment
2263+
end
2264+
inside_comment && continue
2265+
if startswith(s, module_rgx)
2266+
if load_seen
2267+
throw(ErrorException("Package $pkg source file $srcpath has a using/import before a module declaration."))
2268+
end
2269+
return true
2270+
end
2271+
if startswith(s, load_rgx)
2272+
load_seen = true
2273+
end
2274+
end
2275+
throw(ErrorException("Package $pkg source file $srcpath does not contain a module declaration."))
2276+
end
2277+
22492278
# this is called in the external process that generates precompiled package files
22502279
function include_package_for_output(pkg::PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String},
22512280
concrete_deps::typeof(_concrete_dependencies), source::Union{Nothing,String})
2281+
2282+
check_src_module_wrap(pkg, input)
2283+
22522284
append!(empty!(Base.DEPOT_PATH), depot_path)
22532285
append!(empty!(Base.DL_LOAD_PATH), dl_load_path)
22542286
append!(empty!(Base.LOAD_PATH), load_path)

test/loading.jl

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,3 +1184,75 @@ end
11841184
@test success(`$(Base.julia_cmd()) --startup-file=no -e 'using DelimitedFiles'`)
11851185
@test success(`$(Base.julia_cmd()) --startup-file=no -e 'using Statistics'`)
11861186
end
1187+
1188+
@testset "checking srcpath modules" begin
1189+
p = Base.PkgId("Dummy")
1190+
fpath, _ = mktemp()
1191+
@testset "valid" begin
1192+
write(fpath, """
1193+
module Foo
1194+
using Bar
1195+
end
1196+
""")
1197+
@test Base.check_src_module_wrap(p, fpath)
1198+
1199+
write(fpath, """
1200+
baremodule Foo
1201+
using Bar
1202+
end
1203+
""")
1204+
@test Base.check_src_module_wrap(p, fpath)
1205+
1206+
write(fpath, """
1207+
\"\"\"
1208+
Foo
1209+
using Foo
1210+
\"\"\"
1211+
module Foo
1212+
using Bar
1213+
end
1214+
""")
1215+
@test Base.check_src_module_wrap(p, fpath)
1216+
1217+
write(fpath, """
1218+
# using foo
1219+
module Foo
1220+
using Bar
1221+
end
1222+
""")
1223+
@test Base.check_src_module_wrap(p, fpath)
1224+
1225+
write(fpath, """
1226+
# using foo
1227+
module Foo
1228+
using Bar
1229+
end
1230+
""")
1231+
@test Base.check_src_module_wrap(p, fpath)
1232+
end
1233+
@testset "invalid" begin
1234+
write(fpath, """
1235+
# module Foo
1236+
using Bar
1237+
# end
1238+
""")
1239+
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)
1240+
1241+
write(fpath, """
1242+
using Bar
1243+
module Foo
1244+
end
1245+
""")
1246+
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)
1247+
1248+
write(fpath, """
1249+
using Bar
1250+
""")
1251+
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)
1252+
1253+
write(fpath, """
1254+
x = 1
1255+
""")
1256+
@test_throws ErrorException Base.check_src_module_wrap(p, fpath)
1257+
end
1258+
end

test/precompile.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,11 @@ precompile_test_harness(false) do dir
622622
FooBar3_inc = joinpath(dir, "FooBar3_inc.jl")
623623
write(FooBar3_inc, "x=1\n")
624624
for code in ["Core.eval(Base, :(x=1))", "Base.include(Base, \"FooBar3_inc.jl\")"]
625-
write(FooBar3_file, code)
625+
write(FooBar3_file, """
626+
module FooBar3
627+
$code
628+
end
629+
""")
626630
@test_warn "Evaluation into the closed module `Base` breaks incremental compilation" try
627631
Base.require(Main, :FooBar3)
628632
catch exc

0 commit comments

Comments
 (0)