API

ExprTools.splitdefFunction
splitdef(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

source
ExprTools.combinedefFunction
combinedef(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.

source
ExprTools.signatureFunction
signature(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 to true this forces name-hygiene on the TypeVars in UnionAlls, regenerating each with a unique name via gensym. 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.
source
signature(sig::Type{<:Tuple})

Like ExprTools.signature(::Method) but on the underlying signature type-tuple, rather than the Method. Forsigbeing a tuple-type representing a methods type signature, this generates a dictionary that can be passes toExprTools.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 to true this forces name-hygine on the TypeVars in UnionAlls, regenerating each with a unique name via gensym. 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.
source