Repository: JuliaLang/julia
File: JuliaLowering/src/ast.jl (Julia)

Code before:
    for v in vals
        _push_nodeid!(graph, ids, v)
    end
end
function _append_nodeids!(graph::SyntaxGraph, ids::Vector{NodeId}, vals::SyntaxList)
    check_compatible_graph(graph, vals)
    append!(ids, vals.ids)
end

function makeleaf(graph::SyntaxGraph, srcref, proto::Union{Kind, SyntaxTree})
    id = newnode!(graph)
    ex = SyntaxTree(graph, id)
    copy_attrs!(ex, proto, true)
    ex.source = _unpack_srcref(graph, srcref)
    return ex
end

function makeleaf(ctx::AbstractLoweringContext, srcref, proto)
    makeleaf(syntax_graph(ctx), srcref, proto)
end

function makeleaf(ctx, srcref, proto, @nospecialize(attrs::AbstractVector))
    graph = syntax_graph(ctx)
    ex = makeleaf(graph, srcref, proto)
    for (k, v) in attrs
        setattr!(graph, ex._id, k, v)
    end
    return ex
end

function makenode(ctx, srcref, proto, children, attrs=nothing)
    graph = syntax_graph(ctx)
    ex = isnothing(attrs) ? makeleaf(graph, srcref, proto) :
        makeleaf(graph, srcref, proto, attrs)
    setchildren!(graph, ex._id, children isa SyntaxList ? children.ids : children)
    return ex
end

function newleaf(ctx, srcref, k::Kind, @nospecialize(value))
    leaf = makeleaf(ctx, srcref, k)
    if k == K"Identifier" || k == K"core" || k == K"top" || k == K"Symbol" ||
            k == K"globalref" || k == K"Placeholder" ||
            k == K"StrMacroName" || k == K"CmdMacroName"
        setattr!(leaf._graph, leaf._id, :name_val, value)
    elseif k == K"BindingId"
        setattr!(leaf._graph, leaf._id, :var_id, value)
    elseif k == K"label"
        setattr!(leaf._graph, leaf._id, :id, value)
    elseif k == K"symbolic_label"
        setattr!(leaf._graph, leaf._id, :name_val, value)
    elseif k in KSet"TOMBSTONE SourceLocation latestworld latestworld_if_toplevel"

Review comment (refactor):
Another normalization trick you might consider trying out at some point is:
```julia
@noinline function _makeleaf(..., attrs::Vector{Any})
    # ... (complicated function)
end
@inline function makeleaf(..., @nospecialize(attrs::AbstractVector))
    return _makeleaf(..., convert(Vector{Any}, attrs))
end
```

This preserves "good" codegen, while trying to limit specialized code to the caller side. Ofc, it's even better if we can avoid the `Vector` type explosion to begin with.


Code after:
    for v in vals
        _push_nodeid!(graph, ids, v)
    end
end
function _append_nodeids!(graph::SyntaxGraph, ids::Vector{NodeId}, vals::SyntaxList)
    check_compatible_graph(graph, vals)
    append!(ids, vals.ids)
end

# TODO: "proto", if SyntaxTree, is rarely different from srcref. reorganize to:
# newnode/newleaf(ctx, srcref, k::Kind[, attrs])
# makenode/makeleaf(ctx, old::SyntaxTree[, attrs])

function makeleaf(graph::SyntaxGraph, srcref, proto::Union{Kind, SyntaxTree})
    id = newnode!(graph)
    ex = SyntaxTree(graph, id)
    copy_attrs!(ex, proto, true)
    ex.source = _unpack_srcref(graph, srcref)
    return ex
end

function makeleaf(ctx::AbstractLoweringContext, srcref, proto)
    makeleaf(syntax_graph(ctx), srcref, proto)
end

function makeleaf(ctx, srcref, proto, @nospecialize(attrs::AbstractVector))
    graph = syntax_graph(ctx)
    ex = makeleaf(graph, srcref, proto)
    for (k, v) in attrs
        setattr!(graph, ex._id, k, v)
    end
    return ex
end

function makenode(ctx, srcref, proto, children, attrs=nothing)
    graph = syntax_graph(ctx)
    ex = isnothing(attrs) ? makeleaf(graph, srcref, proto) :
        makeleaf(graph, srcref, proto, attrs)
    setchildren!(graph, ex._id, children isa SyntaxList ? children.ids : children)
    return ex
end

function newleaf(ctx, srcref, k::Kind, @nospecialize(value))
    leaf = makeleaf(ctx, srcref, k)
    if k == K"Identifier" || k == K"core" || k == K"top" || k == K"Symbol" ||
            k == K"globalref" || k == K"Placeholder" ||
            k == K"StrMacroName" || k == K"CmdMacroName"
        setattr!(leaf._graph, leaf._id, :name_val, value)
    elseif k == K"BindingId"
        setattr!(leaf._graph, leaf._id, :var_id, value)
    elseif k == K"label"