Repository: JuliaLang/julia
File: JuliaSyntax/src/porcelain/syntax_graph.jl (Julia)

Code before:
    (graph1, entrypoints) = (unaliased.graph, unaliased.ids)

    nodes1 = copy(entrypoints)      # Current reachable subset of graph1
    map12 = Dict{NodeId, Int}()     # graph1 => graph2 mapping
    graph2 = ensure_attributes!(SyntaxGraph(); attrdefs(graph1)...)
    while length(graph2.edge_ranges) < length(nodes1)
        n2 = length(graph2.edge_ranges) + 1
        n1 = nodes1[n2]
        map12[n1] = n2
        push!(graph2.edge_ranges, is_leaf(graph1, n1) ?
            (0:-1) : (1:numchildren(graph1, n1)) .+ length(nodes1))
        for c1 in children(graph1, n1)
            push!(nodes1, c1)
        end
    end
    graph2.edges = 1:length(nodes1) # our reward for unaliasing

    for attr in attrnames(graph1)
        attr === :source && continue
        for (n2, n1) in enumerate(nodes1)
            if (begin
                    attrval = get(graph1.attributes[attr], n1, nothing)
                    !isnothing(attrval)
                end)
                graph2.attributes[attr][n2] = attrval
            end
        end
    end

    # Resolve provenance.  Tricky to avoid dangling `.source` references.
    resolved_sources = Dict{NodeId, SourceAttrType}() # graph1 id => graph2 src
    function get_resolved!(id1::NodeId)
        out = get(resolved_sources, id1, nothing)
        if isnothing(out)
            src1 = graph1.source[id1]
            out = if haskey(map12, src1)
                map12[src1]
            elseif src1 isa NodeId
                get_resolved!(src1)
            elseif src1 isa Tuple
                map(get_resolved!, src1)
            else
                src1
            end
            resolved_sources[id1] = out
        end
        return out
    end

    for (n2, n1) in enumerate(nodes1)
        graph2.source[n2] = get_resolved!(n1)

Review comment (suggestion):
```suggestion
            attrval = get(graph1.attributes[attr], n1, nothing)
            if !isnothing(attrval)
                graph2.attributes[attr][n2] = attrval
            end
```

Code after:
        n2 = length(graph2.edge_ranges) + 1
        n1 = nodes1[n2]
        map12[n1] = n2
        push!(graph2.edge_ranges, is_leaf(graph1, n1) ?
            (0:-1) : (1:numchildren(graph1, n1)) .+ length(nodes1))
        for c1 in children(graph1, n1)
            push!(nodes1, c1)
        end
    end
    graph2.edges = 1:length(nodes1) # our reward for unaliasing

    for attr in attrnames(graph1)
        attr === :source && continue
        for (n2, n1) in enumerate(nodes1)
            attrval = get(graph1.attributes[attr], n1, nothing)
            if !isnothing(attrval)
                graph2.attributes[attr][n2] = attrval
            end
        end
    end

    # Resolve provenance.  Tricky to avoid dangling `.source` references.
    resolved_sources = Dict{NodeId, SourceAttrType}() # graph1 id => graph2 src
    function get_resolved!(id1::NodeId)
        out = get(resolved_sources, id1, nothing)
        if isnothing(out)
            src1 = graph1.source[id1]
            out = if haskey(map12, src1)
                map12[src1]
            elseif src1 isa NodeId
                get_resolved!(src1)
            elseif src1 isa Tuple
                map(get_resolved!, src1)
            else
                src1
            end
            resolved_sources[id1] = out
        end
        return out
    end

    for (n2, n1) in enumerate(nodes1)
        graph2.source[n2] = get_resolved!(n1)
    end

    # The first n entries in nodes1 were our entrypoints, unique from unaliasing
    return SyntaxList(graph2, 1:length(entrypoints))
end

"""
Give each descendent of `st` a `parent::NodeId` attribute.