From 114f91a464f82e17a5bcda8dfde35d499e329735 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sat, 7 Oct 2023 18:05:11 -0400 Subject: [PATCH] check that the file being precompiled contains a module --- base/loading.jl | 32 ++++++++++++++++++++++ test/loading.jl | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/base/loading.jl b/base/loading.jl index 4dd829ea8042ab..bd6ca229a24651 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -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) diff --git a/test/loading.jl b/test/loading.jl index 72a07835dd3390..e5ee5cd3124657 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -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 check_src_module_wrap(p, fpath) + + write(fpath, """ + baremodule Foo + using Bar + end + """) + @test check_src_module_wrap(p, fpath) + + write(fpath, """ + \"\"\" + Foo + using Foo + \"\"\" + module Foo + using Bar + end + """) + @test check_src_module_wrap(p, fpath) + + write(fpath, """ + # using foo + module Foo + using Bar + end + """) + @test check_src_module_wrap(p, fpath) + + write(fpath, """ + # using foo + module Foo + using Bar + end + """) + @test check_src_module_wrap(p, fpath) + end + @testset "invalid" begin + write(fpath, """ + # module Foo + using Bar + # end + """) + @test_throws ErrorException check_src_module_wrap(p, fpath) + + write(fpath, """ + using Bar + module Foo + end + """) + @test_throws ErrorException check_src_module_wrap(p, fpath) + + write(fpath, """ + using Bar + """) + @test_throws ErrorException check_src_module_wrap(p, fpath) + + write(fpath, """ + x = 1 + """) + @test_throws ErrorException check_src_module_wrap(p, fpath) + end +end