Skip to content

fix bug when include statement includes interpolation #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
6 changes: 5 additions & 1 deletion src/parse_utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)]
Expand Down
5 changes: 5 additions & 0 deletions test/DynMod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ get_file() = "hi.jl"

include(get_file())

include("$(get_file())")

hi = "hi"
include("$(hi).jl")

end # DynMod
109 changes: 56 additions & 53 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down