diff --git a/Project.toml b/Project.toml index a720d1a..3c242d4 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "GPUToolbox" uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "1.0.0" +version = "1.1.0" [deps] LLVM = "929cbde3-209d-540e-8aea-75f648917ca0" diff --git a/src/enum.jl b/src/enum.jl index 1efd14d..4f3b93a 100644 --- a/src/enum.jl +++ b/src/enum.jl @@ -5,7 +5,31 @@ export @enum_without_prefix # this is useful when enum values from an underlying C library, typically prefixed for the # lack of namespacing in C, are to be used in Julia where we do have module namespacing. -macro enum_without_prefix(enum, prefix) +macro enum_without_prefix(ex...) + # destructure keyword arguments + call = ex[end-1:end] + kwargs = map(ex[1:end-2]) do kwarg + if kwarg isa Symbol + :($kwarg = $kwarg) + elseif Meta.isexpr(kwarg, :(=)) + kwarg + else + throw(ArgumentError("Invalid keyword argument '$kwarg'")) + end + end + + visibility = nothing + for kwarg in kwargs + key, val = kwarg.args + if key == :visibility + val isa QuoteNode && (val = val.value) + visibility = val::Symbol + else + throw(ArgumentError("Invalid keyword argument '$key'")) + end + end + + enum, prefix = call if isa(enum, Symbol) mod = __module__ elseif Meta.isexpr(enum, :(.)) @@ -21,7 +45,13 @@ macro enum_without_prefix(enum, prefix) for instance in instances(enum) name = String(Symbol(instance)) @assert startswith(name, prefix) - push!(ex.args, :(const $(Symbol(name[length(prefix)+1:end])) = $(mod).$(Symbol(name)))) + short = Symbol(name[length(prefix)+1:end]) + push!(ex.args, :(const $short = $(mod).$(Symbol(name)))) + if visibility == :export + push!(ex.args, :(export $short)) + elseif visibility == :public + push!(ex.args, Expr(:public, short)) + end end return esc(ex) diff --git a/test/runtests.jl b/test/runtests.jl index 3c37a44..fa2669b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -86,6 +86,32 @@ using IOCapture end @test mod.ENUM_VALUE == mod.MY_ENUM_VALUE + + # test with visibility=:export + mod_export = @eval module $(gensym()) + using GPUToolbox + @enum MY_ENUM MY_ENUM_A MY_ENUM_B + @enum_without_prefix visibility=:export MY_ENUM MY_ENUM_ + end + @test mod_export.A == mod_export.MY_ENUM_A + @test mod_export.B == mod_export.MY_ENUM_B + exported = names(mod_export) + @test :A in exported + @test :B in exported + + # test with visibility=:public + @static if VERSION >= v"1.11" + mod_public = @eval module $(gensym()) + using GPUToolbox + @enum MY_ENUM MY_ENUM_P MY_ENUM_Q + @enum_without_prefix visibility=:public MY_ENUM MY_ENUM_ + end + @test mod_public.P == mod_public.MY_ENUM_P + @test mod_public.Q == mod_public.MY_ENUM_Q + # public but not exported + @test :P in names(mod_public) + @test !Base.isexported(mod_public, :P) + end end @testset "LazyInitialized" begin