/* * Copyright (c) 2023, Dan Klishch * * SPDX-License-Identifier: BSD-2-Clause */ #include #include "AST/AST.h" namespace JSSpecCompiler { Tree NodeSubtreePointer::get(Badge) { return m_tree_ptr.visit( [&](NullableTree* nullable_tree) -> Tree { NullableTree copy = *nullable_tree; return copy.release_nonnull(); }, [&](Tree* tree) -> Tree { return *tree; }, [&](VariableRef* tree) -> Tree { return *tree; }); } void NodeSubtreePointer::replace_subtree(Badge, NullableTree replacement) { m_tree_ptr.visit( [&](NullableTree* nullable_tree) { *nullable_tree = replacement; }, [&](Tree* tree) { *tree = replacement.release_nonnull(); }, [&](VariableRef*) { VERIFY_NOT_REACHED(); }); } Vector ControlFlowJump::references() { return { &m_block }; } Vector ControlFlowBranch::references() { return { &m_then, &m_else }; } Vector BinaryOperation::subtrees() { return { { &m_left }, { &m_right } }; } Vector UnaryOperation::subtrees() { return { { &m_operand } }; } Vector IsOneOfOperation::subtrees() { Vector result = { { &m_operand } }; for (auto& child : m_compare_values) result.append({ &child }); return result; } Vector ReturnNode::subtrees() { return { { &m_return_value } }; } Vector AssertExpression::subtrees() { return { { &m_condition } }; } Vector IfBranch::subtrees() { return { { &m_condition }, { &m_branch } }; } Vector ElseIfBranch::subtrees() { if (m_condition) return { { &m_condition }, { &m_branch } }; return { { &m_branch } }; } Vector IfElseIfChain::subtrees() { Vector result; for (size_t i = 0; i < branches_count(); ++i) { result.append({ &m_conditions[i] }); result.append({ &m_branches[i] }); } if (m_else_branch) result.append({ &m_else_branch }); return result; } TreeList::TreeList(Vector&& trees) { for (auto const& tree : trees) { if (tree->is_list()) { for (auto const& nested_tree : as(tree)->m_trees) m_trees.append(nested_tree); } else { m_trees.append(tree); } } } Vector TreeList::subtrees() { Vector result; for (auto& expression : m_trees) result.append({ &expression }); return result; } Vector RecordDirectListInitialization::subtrees() { Vector result { &m_type_reference }; for (auto& argument : m_arguments) { result.append({ &argument.name }); result.append({ &argument.value }); } return result; } Vector FunctionCall::subtrees() { Vector result = { { &m_name } }; for (auto& child : m_arguments) result.append({ &child }); return result; } String Variable::name() const { if (m_ssa) return MUST(String::formatted("{}@{}", m_name->m_name, m_ssa->m_version)); return MUST(String::from_utf8(m_name->m_name)); } Vector List::subtrees() { Vector result; for (auto& element : m_elements) result.append({ &element }); return result; } }