Get the actual type from an Expr representing a type

I think this may be the question being asked here, but it wasn’t resolved.

I am writing a macro that manipulates the signature of a function. I want to know if an argument is annotated with a subtype of a type owned by my package. Basic example:

using Expronicon

macro my_macro(func_expr)
    func = JLFunction(func_expr)
    type_annotation_expr = func.args[1].args[2]
    
     actual_type = # ?? Some logic to turn this into literal Vector{Int}?

    if actual_type <: Array
        print("Got a subtype!")
    end
    return nothing
end
@my_macro function f(x::Vector{Int}) end
# prints "Got a subtype!"

If it was unparameterized, I could use getfield(__module__, type_annotation_expr), but if it is parameterized, then that doesn’t work.

Macros work at the level of expressions and should not be messing with their meaning, e.g., care which types or values an expression represents. They can generate an expression containing an appropriate condition though:

macro my_macro(func_expr)
    func = JLFunction(func_expr)
    type_annotation_expr = func.args[1].args[2]
           
    quote 
        if $(esc(type_annotation_expr)) <: Array
            print("Got a subtype!")
            # Insert expansion suitable for subtypes here ...
        else
            # Insert alternative expansion here ...
            nothing
        end
    end
end
julia> @my_macro function f(x::Vector{Int}) end
Got a subtype!
julia> @my_macro function g(x::Real) end

1 Like

Ah! I feel silly for not thinking of that. Thank you!