Lines Matching +full:child +full:- +full:node
1 //===- Tree.cpp -----------------------------------------------*- C++ -*-=====//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
19 static void traverse(const syntax::Node *N, in traverse()
20 llvm::function_ref<void(const syntax::Node *)> Visit) { in traverse()
22 for (const syntax::Node &C : T->getChildren()) in traverse()
27 static void traverse(syntax::Node *N, in traverse()
28 llvm::function_ref<void(syntax::Node *)> Visit) { in traverse()
29 traverse(static_cast<const syntax::Node *>(N), [&](const syntax::Node *N) { in traverse()
30 Visit(const_cast<syntax::Node *>(N)); in traverse()
35 syntax::Leaf::Leaf(syntax::TokenManager::Key K) : Node(NodeKind::Leaf), K(K) {} in Leaf()
37 syntax::Node::Node(NodeKind Kind) in Node() function in syntax::Node
41 this->setRole(NodeRole::Detached); in Node()
44 bool syntax::Node::isDetached() const { in isDetached()
48 void syntax::Node::setRole(NodeRole NR) { in setRole()
49 this->Role = static_cast<unsigned>(NR); in setRole()
52 void syntax::Tree::appendChildLowLevel(Node *Child, NodeRole Role) { in appendChildLowLevel() argument
53 assert(Child->getRole() == NodeRole::Detached); in appendChildLowLevel()
56 Child->setRole(Role); in appendChildLowLevel()
57 appendChildLowLevel(Child); in appendChildLowLevel()
60 void syntax::Tree::appendChildLowLevel(Node *Child) { in appendChildLowLevel() argument
61 assert(Child->Parent == nullptr); in appendChildLowLevel()
62 assert(Child->NextSibling == nullptr); in appendChildLowLevel()
63 assert(Child->PreviousSibling == nullptr); in appendChildLowLevel()
64 assert(Child->getRole() != NodeRole::Detached); in appendChildLowLevel()
66 Child->Parent = this; in appendChildLowLevel()
67 if (this->LastChild) { in appendChildLowLevel()
68 Child->PreviousSibling = this->LastChild; in appendChildLowLevel()
69 this->LastChild->NextSibling = Child; in appendChildLowLevel()
71 this->FirstChild = Child; in appendChildLowLevel()
73 this->LastChild = Child; in appendChildLowLevel()
76 void syntax::Tree::prependChildLowLevel(Node *Child, NodeRole Role) { in prependChildLowLevel() argument
77 assert(Child->getRole() == NodeRole::Detached); in prependChildLowLevel()
80 Child->setRole(Role); in prependChildLowLevel()
81 prependChildLowLevel(Child); in prependChildLowLevel()
84 void syntax::Tree::prependChildLowLevel(Node *Child) { in prependChildLowLevel() argument
85 assert(Child->Parent == nullptr); in prependChildLowLevel()
86 assert(Child->NextSibling == nullptr); in prependChildLowLevel()
87 assert(Child->PreviousSibling == nullptr); in prependChildLowLevel()
88 assert(Child->getRole() != NodeRole::Detached); in prependChildLowLevel()
90 Child->Parent = this; in prependChildLowLevel()
91 if (this->FirstChild) { in prependChildLowLevel()
92 Child->NextSibling = this->FirstChild; in prependChildLowLevel()
93 this->FirstChild->PreviousSibling = Child; in prependChildLowLevel()
95 this->LastChild = Child; in prependChildLowLevel()
97 this->FirstChild = Child; in prependChildLowLevel()
100 void syntax::Tree::replaceChildRangeLowLevel(Node *Begin, Node *End, in replaceChildRangeLowLevel()
101 Node *New) { in replaceChildRangeLowLevel()
102 assert((!Begin || Begin->Parent == this) && in replaceChildRangeLowLevel()
103 "`Begin` is not a child of `this`."); in replaceChildRangeLowLevel()
104 assert((!End || End->Parent == this) && "`End` is not a child of `this`."); in replaceChildRangeLowLevel()
108 for (auto *N = New; N; N = N->NextSibling) { in replaceChildRangeLowLevel()
109 assert(N->Parent == nullptr); in replaceChildRangeLowLevel()
110 assert(N->getRole() != NodeRole::Detached && "Roles must be set"); in replaceChildRangeLowLevel()
114 auto Reachable = [](Node *From, Node *N) { in replaceChildRangeLowLevel()
117 for (auto *It = From; It; It = It->NextSibling) in replaceChildRangeLowLevel()
130 for (auto *T = this; T && T->Original; T = T->Parent) in replaceChildRangeLowLevel()
131 T->Original = false; in replaceChildRangeLowLevel()
133 // Save the node before the range to be removed. Later we insert the `New` in replaceChildRangeLowLevel()
134 // range after this node. in replaceChildRangeLowLevel()
135 auto *BeforeBegin = Begin ? Begin->PreviousSibling : LastChild; in replaceChildRangeLowLevel()
139 auto *Next = N->NextSibling; in replaceChildRangeLowLevel()
141 N->setRole(NodeRole::Detached); in replaceChildRangeLowLevel()
142 N->Parent = nullptr; in replaceChildRangeLowLevel()
143 N->NextSibling = nullptr; in replaceChildRangeLowLevel()
144 N->PreviousSibling = nullptr; in replaceChildRangeLowLevel()
145 if (N->Original) in replaceChildRangeLowLevel()
146 traverse(N, [](Node *C) { C->Original = false; }); in replaceChildRangeLowLevel()
152 auto *&NewFirst = BeforeBegin ? BeforeBegin->NextSibling : FirstChild; in replaceChildRangeLowLevel()
153 auto *&NewLast = End ? End->PreviousSibling : LastChild; in replaceChildRangeLowLevel()
161 New->PreviousSibling = BeforeBegin; in replaceChildRangeLowLevel()
164 Node *LastInNew; in replaceChildRangeLowLevel()
165 for (auto *N = New; N != nullptr; N = N->NextSibling) { in replaceChildRangeLowLevel()
167 N->Parent = this; in replaceChildRangeLowLevel()
169 LastInNew->NextSibling = End; in replaceChildRangeLowLevel()
174 static void dumpNode(raw_ostream &OS, const syntax::Node *N, in dumpNode()
176 auto DumpExtraInfo = [&OS](const syntax::Node *N) { in dumpNode()
177 if (N->getRole() != syntax::NodeRole::Unknown) in dumpNode()
178 OS << " " << N->getRole(); in dumpNode()
179 if (!N->isOriginal()) in dumpNode()
181 if (!N->canModify()) in dumpNode()
188 OS << TM.getText(L->getTokenKey()); in dumpNode()
196 OS << T->getKind(); in dumpNode()
200 for (const syntax::Node &It : T->getChildren()) { in dumpNode()
208 OS << "`-"; in dumpNode()
211 OS << "|-"; in dumpNode()
220 std::string syntax::Node::dump(const TokenManager &TM) const { in dump()
227 std::string syntax::Node::dumpTokens(const TokenManager &TM) const { in dumpTokens()
230 traverse(this, [&](const syntax::Node *N) { in dumpTokens()
232 OS << TM.getText(L->getTokenKey()); in dumpTokens()
239 void syntax::Node::assertInvariants() const { in assertInvariants()
249 for (const Node &C : T->getChildren()) { in assertInvariants()
250 if (T->isOriginal()) in assertInvariants()
255 assert(!Next || &C == Next->getPreviousSibling()); in assertInvariants()
257 assert(&C == T->getLastChild() && in assertInvariants()
258 "Last child is reachable by advancing from the first child."); in assertInvariants()
264 for (const Node &C : T->getChildren()) { in assertInvariants()
269 // FIXME: re-enable it when there is way to retrieve token kind in Leaf. in assertInvariants()
270 // assert(cast<Leaf>(C).getToken()->kind() == L->getDelimiterTokenKind()); in assertInvariants()
277 void syntax::Node::assertInvariantsRecursive() const { in assertInvariantsRecursive()
279 traverse(this, [&](const syntax::Node *N) { N->assertInvariants(); }); in assertInvariantsRecursive()
284 for (const Node &C : getChildren()) { in findFirstLeaf()
294 for (const auto *C = getLastChild(); C; C = C->getPreviousSibling()) { in findLastLeaf()
297 if (const auto *L = cast<syntax::Tree>(C)->findLastLeaf()) in findLastLeaf()
303 const syntax::Node *syntax::Tree::findChild(NodeRole R) const { in findChild()
304 for (const Node &C : getChildren()) { in findChild()
311 std::vector<syntax::List::ElementAndDelimiter<syntax::Node>>
316 std::vector<syntax::List::ElementAndDelimiter<Node>> Children; in getElementsAsNodesAndDelimiters()
317 syntax::Node *ElementWithoutDelimiter = nullptr; in getElementsAsNodesAndDelimiters()
318 for (Node &C : getChildren()) { in getElementsAsNodesAndDelimiters()
357 std::vector<syntax::Node *> syntax::List::getElementsAsNodes() { in getElementsAsNodes()
361 std::vector<syntax::Node *> Children; in getElementsAsNodes()
362 syntax::Node *ElementWithoutDelimiter = nullptr; in getElementsAsNodes()
363 for (Node &C : getChildren()) { in getElementsAsNodes()
400 switch (this->getKind()) { in getDelimiterTokenKind()
414 switch (this->getKind()) { in getTerminationKind()
428 switch (this->getKind()) { in canBeEmpty()