diff --git a/Project.toml b/Project.toml index 038ddf68..d412aeea 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ExplicitImports" uuid = "7d51a73a-1435-4ff3-83d9-f097790105c7" authors = ["Eric P. Hanson"] -version = "1.4.0" +version = "1.4.1" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" diff --git a/src/parse_utilities.jl b/src/parse_utilities.jl index f129c081..9dfa8a81 100644 --- a/src/parse_utilities.jl +++ b/src/parse_utilities.jl @@ -61,8 +61,11 @@ function AbstractTrees.children(wrapper::SyntaxNodeWrapper) end if JuliaSyntax.kind(arg) == K"string" children = JuliaSyntax.children(arg) - # string literals can only have one child (I think...) + # if we have interpolation, there may be >1 child + length(children) == 1 || @goto dynamic c = only(children) + # if we have interpolation, this might not be a string + kind(c) == K"String" || @goto dynamic # The children of a static include statement is the entire file being included new_file = joinpath(dirname(wrapper.file), c.val) if isfile(new_file) @@ -80,6 +83,7 @@ function AbstractTrees.children(wrapper::SyntaxNodeWrapper) return [SkippedFile(location)] end else + @label dynamic @warn "Dynamic `include` found at $location; not recursing" push!(wrapper.bad_locations, location) return [SkippedFile(location)] diff --git a/test/DynMod.jl b/test/DynMod.jl index f7ebb683..e7feb66d 100644 --- a/test/DynMod.jl +++ b/test/DynMod.jl @@ -8,4 +8,9 @@ get_file() = "hi.jl" include(get_file()) +include("$(get_file())") + +hi = "hi" +include("$(hi).jl") + end # DynMod diff --git a/test/runtests.jl b/test/runtests.jl index bca77895..8e1c5047 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -377,71 +377,74 @@ end @test contains(str, "has stale (unused) explicit imports for:") @testset "Tainted modules" begin - log = (:warn, r"Dynamic") - - @test_logs log @test only_name_source(explicit_imports(DynMod, "DynMod.jl")) == - [DynMod => nothing, DynMod.Hidden => nothing] - @test_logs log @test only_name_source(explicit_imports(DynMod, "DynMod.jl"; - strict=false)) == - [DynMod => [(; name=:print_explicit_imports, - source=ExplicitImports)], - # Wrong! Missing explicit export - DynMod.Hidden => []] - - @test_logs log @test explicit_imports_nonrecursive(DynMod, "DynMod.jl") === nothing - - @test_logs log @test only_name_source(explicit_imports_nonrecursive(DynMod, - "DynMod.jl"; - strict=false)) == - [(; name=:print_explicit_imports, source=ExplicitImports)] - @test_logs log @test stale_explicit_imports(DynMod, "DynMod.jl") == - [DynMod => nothing, - DynMod.Hidden => nothing] - - @test_logs log @test stale_explicit_imports_nonrecursive(DynMod, "DynMod.jl") === - nothing - - @test_logs log @test stale_explicit_imports(DynMod, "DynMod.jl"; strict=false) == - [DynMod => [], - # Wrong! Missing stale explicit export - DynMod.Hidden => []] - - @test_logs log @test stale_explicit_imports_nonrecursive(DynMod, "DynMod.jl"; - strict=false) == - [] - @test_logs log str = sprint(print_stale_explicit_imports, DynMod, "DynMod.jl") + # 3 dynamic include statements + l = (:warn, r"Dynamic") + log = (l, l, l) + + @test_logs log... @test only_name_source(explicit_imports(DynMod, "DynMod.jl")) == + [DynMod => nothing, DynMod.Hidden => nothing] + @test_logs log... @test only_name_source(explicit_imports(DynMod, "DynMod.jl"; + strict=false)) == + [DynMod => [(; name=:print_explicit_imports, + source=ExplicitImports)], + # Wrong! Missing explicit export + DynMod.Hidden => []] + + @test_logs log... @test explicit_imports_nonrecursive(DynMod, "DynMod.jl") === + nothing + + @test_logs log... @test only_name_source(explicit_imports_nonrecursive(DynMod, + "DynMod.jl"; + strict=false)) == + [(; name=:print_explicit_imports, source=ExplicitImports)] + @test_logs log... @test stale_explicit_imports(DynMod, "DynMod.jl") == + [DynMod => nothing, + DynMod.Hidden => nothing] + + @test_logs log... @test stale_explicit_imports_nonrecursive(DynMod, "DynMod.jl") === + nothing + + @test_logs log... @test stale_explicit_imports(DynMod, "DynMod.jl"; strict=false) == + [DynMod => [], + # Wrong! Missing stale explicit export + DynMod.Hidden => []] + + @test_logs log... @test stale_explicit_imports_nonrecursive(DynMod, "DynMod.jl"; + strict=false) == + [] + @test_logs log... str = sprint(print_stale_explicit_imports, DynMod, "DynMod.jl") @test contains(str, "DynMod could not be accurately analyzed") - @test_logs log str = sprint(print_explicit_imports, DynMod, "DynMod.jl") + @test_logs log... str = sprint(print_explicit_imports, DynMod, "DynMod.jl") @test contains(str, "DynMod could not be accurately analyzed") - @test_logs log @test check_no_implicit_imports(DynMod, "DynMod.jl"; - allow_unanalyzable=(DynMod, - DynMod.Hidden)) === - nothing + @test_logs log... @test check_no_implicit_imports(DynMod, "DynMod.jl"; + allow_unanalyzable=(DynMod, + DynMod.Hidden)) === + nothing # Ignore also works - @test_logs log @test check_no_implicit_imports(DynMod, "DynMod.jl"; - allow_unanalyzable=(DynMod,), - ignore=(DynMod.Hidden,)) === - nothing + @test_logs log... @test check_no_implicit_imports(DynMod, "DynMod.jl"; + allow_unanalyzable=(DynMod,), + ignore=(DynMod.Hidden,)) === + nothing e = UnanalyzableModuleException - @test_logs log @test_throws e check_no_implicit_imports(DynMod, - "DynMod.jl") + @test_logs log... @test_throws e check_no_implicit_imports(DynMod, + "DynMod.jl") # Missed `Hidden` - @test_logs log @test_throws e check_no_implicit_imports(DynMod, - "DynMod.jl"; - allow_unanalyzable=(DynMod,),) + @test_logs log... @test_throws e check_no_implicit_imports(DynMod, + "DynMod.jl"; + allow_unanalyzable=(DynMod,),) - @test_logs log @test check_no_stale_explicit_imports(DynMod, "DynMod.jl"; - allow_unanalyzable=(DynMod, - DynMod.Hidden)) === - nothing + @test_logs log... @test check_no_stale_explicit_imports(DynMod, "DynMod.jl"; + allow_unanalyzable=(DynMod, + DynMod.Hidden)) === + nothing - @test_logs log @test_throws e check_no_stale_explicit_imports(DynMod, - "DynMod.jl") + @test_logs log... @test_throws e check_no_stale_explicit_imports(DynMod, + "DynMod.jl") str = sprint(Base.showerror, UnanalyzableModuleException(DynMod)) @test contains(str, "was found to be unanalyzable")