API
ExprTools.splitdef
— Functionsplitdef(ex::Expr; throw::Bool=true) -> Union{Dict{Symbol,Any}, Nothing}
Split a function definition expression into its various components including:
:head
: Expression head of the function definition (:function
,:(=)
,:(->)
):name
: Name of the function (not present for anonymous functions):params
: Parametric types defined on constructors:args
: Positional arguments of the function:kwargs
: Keyword arguments of the function:rtype
: Return type of the function:whereparams
: Where parameters:body
: Function body (not present for empty functions)
All components listed may not be present in the returned dictionary with the exception of :head
which will always be present.
If the provided expression is not a function then an exception will be raised when throw=true
. Use throw=false
avoid raising an exception and return nothing
instead.
See also: combinedef
ExprTools.combinedef
— Functioncombinedef(def::Dict{Symbol,Any}) -> Expr
Create a function definition expression from various components. Typically used to construct a function using the result of splitdef
.
If def[:head]
is not provided it will default to :function
.
For more details see the documentation on splitdef
.
ExprTools.signature
— Functionsignature(m::Method) -> Dict{Symbol,Any}
Finds the expression for a method's signature as broken up into its various components including:
:name
: Name of the function:params
: Parametric types defined on constructors:args
: Positional arguments of the function:whereparams
: Where parameters
All components listed above may not be present in the returned dictionary if they are not in the function definition.
Limited support for:
:kwargs
: Keyword arguments of the function. Only the names will be included, not the default values or type constraints.
Unsupported:
:rtype
: Return type of the function:body
: Function body0:head
: Expression head of the function definition (:function
,:(=)
,:(->)
)
For more complete coverage, consider using splitdef
with CodeTracking.definition
.
The dictionary of components returned by signature
match those returned by splitdef
and include all that are required by combinedef
, except for the :body
component.
keywords
extra_hygiene=false
: if set totrue
this forces name-hygiene on theTypeVar
s inUnionAll
s, regenerating each with a unique name viagensym
. This shouldn't actually be required as they are scoped such that they are not supposed to leak. However, there is a long-standing julia bug that means they do leak if they clash with function type-vars.
signature(sig::Type{<:Tuple})
Like ExprTools.signature(::Method)
but on the underlying signature type-tuple, rather than the Method. For
sigbeing a tuple-type representing a methods type signature, this generates a dictionary that can be passes to
ExprTools.combinedefto define that function, Provided that you assign the
:body` key on the dictionary first.
The quality of the output, in terms of matching names etc is not as high as for the signature(::Method)
, but all the key information is present; and the type-tuple is for other purposes generally easier to manipulate.
Examples
julia> signature(Tuple{typeof(identity), Any})
Dict{Symbol, Any} with 2 entries:
:name => :(op::typeof(identity))
:args => Expr[:(x1::Any)]
julia> signature(Tuple{typeof(+), Vector{T}, Vector{T}} where T<:Number)
Dict{Symbol, Any} with 3 entries:
:name => :(op::typeof(+))
:args => Expr[:(x1::Array{var"##T#5492", 1}), :(x2::Array{var"##T#5492", 1})]
:whereparams => Any[:(var"##T#5492" <: Number)]
keywords
extra_hygiene=false
: if set totrue
this forces name-hygine on theTypeVar
s inUnionAll
s, regenerating each with a unique name viagensym
. This shouldn't actually be required as they are scoped such that they are not supposed to leak. However, there is a long-standing julia bug that means they do leak if they clash with function type-vars.