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

Code before:
        if isnothing(st_k)
            setattr!(newnode(graph, old_src, K"unknown_head", cs), :name_val, head_s)
        else
            newnode(graph, old_src, st_k, cs)
        end
    # elseif e isa GlobalRef
        # TODO: Better-behaved as K"globalref", but lowering doesn't know this
    else
        # We may want additional special cases for other types where
        # `Base.isa_ast_node(e)`, but `K"Value"` should be fine for most, since
        # most are produced in or after lowering
        if e isa LineNumberNode
            # linenode oustside of block or toplevel
            src = e
        end
        setattr!(newleaf(graph, src, K"Value"), :value, e)
    end
    @assert isa_lowering_ast_node(e) || is_expr_value(st)

    return st._id, src
end

function est_to_expr(st::SyntaxTree, suppress_linenodes=false)
    k = kind(st)
    return if k === K"core" && numchildren(st) === 0 && st.name_val === "nothing"
        nothing
    elseif is_leaf(st) && hasattr(st, :name_val)
        n = Symbol(st.name_val)
        hasattr(st, :scope_layer) ? Expr(:scope_layer, n, st.scope_layer) : n
    elseif is_leaf(st) && is_expr_value(st)
        v = st.value
        # Let `st.value isa Symbol` (or other AST node).  Since we enforce that
        # this is never produced by the reverse Expr->SyntaxTree transformation,
        # there is no lonely Expr for which `st` is the only SyntaxTree
        # representation.  This means we can pick some other expr this
        # represents, namely Expr(`(inert ,st.value)) rather than
        # Expr(st.value).
        isa_lowering_ast_node(v) ? QuoteNode(v) : v
    elseif k === K"inert"
        QuoteNode(est_to_expr(st[1]))
    else
        # TODO: should handle post-lowering forms as well
        @assert !is_leaf(st) "est_to_expr should only be used pre-desugaring"
        # In a partially-expanded or quoted AST, there may be heads with no
        # corresponding kind
        head = Symbol(k === K"unknown_head" ? st.name_val : untokenize(k))
        out = Expr(head)

        # (Move the following assumptions to the docs if they turn out accurate)
        # The only mandatory LineNumberNode is the second macrocall argument.
        # Other than that, optional linenodes may show up anywhere within:

Review comment (suggestion):
```suggestion
function est_to_expr(st::SyntaxTree; suppress_linenodes=false)
```
just a suggestion, for clarity

Code after:
        if isnothing(st_k)
            setattr!(newnode(graph, old_src, K"unknown_head", cs), :name_val, head_s)
        else
            newnode(graph, old_src, st_k, cs)
        end
    # elseif e isa GlobalRef
        # TODO: Better-behaved as K"globalref", but lowering doesn't know this
    else
        # We may want additional special cases for other types where
        # `Base.isa_ast_node(e)`, but `K"Value"` should be fine for most, since
        # most are produced in or after lowering
        if e isa LineNumberNode
            # linenode oustside of block or toplevel
            src = e
        end
        setattr!(newleaf(graph, src, K"Value"), :value, e)
    end
    @assert isa_lowering_ast_node(e) || is_expr_value(st)

    return st._id, src
end

# `suppress_linenodes` is true if `st`'s parent knows `st` is an exception to
# normal linenode rules.  It only applies to `st`, and not transitively to its
# children.
function est_to_expr(st::SyntaxTree, suppress_linenodes=false)
    k = kind(st)
    return if k === K"core" && numchildren(st) === 0 && st.name_val === "nothing"
        nothing
    elseif is_leaf(st) && hasattr(st, :name_val)
        n = Symbol(st.name_val)
        hasattr(st, :scope_layer) ? Expr(:scope_layer, n, st.scope_layer) : n
    elseif is_leaf(st) && is_expr_value(st)
        v = st.value
        # Let `st.value isa Symbol` (or other AST node).  Since we enforce that
        # this is never produced by the reverse Expr->SyntaxTree transformation,
        # there is no lonely Expr for which `st` is the only SyntaxTree
        # representation.  This means we can pick some other expr this
        # represents, namely Expr(`(inert ,st.value)) rather than
        # Expr(st.value).
        isa_lowering_ast_node(v) ? QuoteNode(v) : v
    elseif k === K"inert"
        QuoteNode(est_to_expr(st[1]))
    else
        # TODO: should handle post-lowering forms as well
        @assert !is_leaf(st) "est_to_expr should only be used pre-desugaring"
        # In a partially-expanded or quoted AST, there may be heads with no
        # corresponding kind
        head = Symbol(k === K"unknown_head" ? st.name_val : untokenize(k))
        out = Expr(head)