Repository: JuliaLang/julia
File: stdlib/InteractiveUtils/src/macros.jl (Julia)

Code before:
"""
    @less

Evaluates the arguments to the function or macro call, determines their types, and calls the [`less`](@ref)
function on the resulting expression.

See also: [`@edit`](@ref), [`@which`](@ref), [`@code_lowered`](@ref).
"""
:@less

"""
    @edit

Evaluates the arguments to the function or macro call, determines their types, and calls the [`edit`](@ref)
function on the resulting expression.

See also: [`@less`](@ref), [`@which`](@ref).
"""
:@edit

"""
    @code_typed

Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_typed`](@ref) on the resulting expression. Use the optional argument `optimize` with

    @code_typed optimize=true foo(x)

to control whether additional optimizations, such as inlining, are also applied.

See also: [`code_typed`](@ref), [`@code_warntype`](@ref), [`@code_lowered`](@ref), [`@code_llvm`](@ref), [`@code_native`](@ref).
"""
:@code_typed

"""
    @code_lowered

Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_lowered`](@ref) on the resulting expression.

See also: [`code_lowered`](@ref), [`@code_warntype`](@ref), [`@code_typed`](@ref), [`@code_llvm`](@ref), [`@code_native`](@ref).
"""
:@code_lowered

"""
    @code_warntype

Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_warntype`](@ref) on the resulting expression.

See also: [`code_warntype`](@ref), [`@code_typed`](@ref), [`@code_lowered`](@ref), [`@code_llvm`](@ref), [`@code_native`](@ref).

Review comment (bug):
same comment about `Ref.()` being problematic here (because it shouldn't affect behavior and because is is the wrong way to map to an Any array)

Code after:
                lens = map(length, rows)
                args = Any[Expr(:tuple, lens...); vcat(rows...)]
                ex0.head === :typed_vcat && pushfirst!(args, ex0.args[1])
                return gen_call(fcn, Any[hf, args...], where_params, kws; use_signature_tuple)
            else
                return gen_call(fcn, Any[f, ex0.args...], where_params, kws; use_signature_tuple)
            end
        elseif ex0.head === :ref
            return expand_ref_begin_end!(ex0, __module__) do ex
                gen_call(fcn, Any[getindex, ex.args...], where_params, kws; use_signature_tuple)
            end
        else
            for (head, f) in Any[:hcat => Base.hcat,
                                 :(.) => Base.getproperty,
                                 :vect => Base.vect,
                                 Symbol("'") => Base.adjoint,
                                 :typed_hcat => Base.typed_hcat,
                                 :string => string]
                ex0.head === head || continue
                return gen_call(fcn, Any[f, ex0.args...], where_params, kws; use_signature_tuple)
            end
        end
    end
    if isa(ex0, Expr) && ex0.head === :macrocall # Make @edit @time 1+2 edit the macro by using the types of the *expressions*
        args = [#=__source__::=#LineNumberNode, #=__module__::=#Module, Core.Typeof.(ex0.args[3:end])...]
        return gen_call(fcn, Any[ex0.args[1], Ref.(args)...], where_params, kws; use_signature_tuple)
    end

    ex = Meta.lower(__module__, ex0)
    isa(ex, Expr) || return Expr(:call, :error, "expression is not a function call or symbol")

    return Expr(:call, :error, "expression is not a function call, \
                                    or is too complex for @$fcn to analyze; \
                                    break it down to simpler parts if possible. \
                                    In some cases, you may want to use Meta.@lower.")
end

"""
Same behaviour as `gen_call_with_extracted_types` except that keyword arguments
of the form "foo=bar" are passed on to the called function as well.
The keyword arguments must be given before the mandatory argument.
"""
function gen_call_with_extracted_types_and_kwargs(__module__, fcn, ex0; is_source_reflection = !is_code_macro(fcn), supports_binding_reflection = false, use_signature_tuple = false)
    kws = Expr[]
    arg = ex0[end] # Mandatory argument
    for i in 1:length(ex0)-1
        x = ex0[i]
        if x isa Expr && x.head === :(=) # Keyword given of the form "foo=bar"
            if length(x.args) != 2
                return Expr(:call, :error, "Invalid keyword argument: $x")
            end