@@ -2246,9 +2246,41 @@ function load_path_setup_code(load_path::Bool=true)
22462246 return code
22472247end
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
22502279function 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)
0 commit comments