Skip to content

Commit 523a9bc

Browse files
committed
[incrParse] Skip missing node in getNextNode()
Taking Missing node into account confuses reusability checking in incremental parsing. rdar://problem/45215049 https://bugs.swift.org/browse/SR-8976 rdar://problem/45287031 https://bugs.swift.org/browse/SR-9006
1 parent 8027356 commit 523a9bc

File tree

5 files changed

+44
-16
lines changed

5 files changed

+44
-16
lines changed

include/swift/Syntax/SyntaxData.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,16 @@ class SyntaxData final
133133
}
134134

135135
public:
136-
/// Get the node immediately before this current node. Return 0 if we cannot
137-
/// find such node.
136+
/// Get the node immediately before this current node that does contain a
137+
/// non-missing token. Return nullptr if we cannot find such node.
138138
RC<SyntaxData> getPreviousNode() const;
139139

140-
/// Get the node immediately after this current node. Return 0 if we cannot
141-
/// find such node.
140+
/// Get the node immediately after this current node that does contain a
141+
/// non-missing token. Return nullptr if we cannot find such node.
142142
RC<SyntaxData> getNextNode() const;
143143

144-
/// Get the first token node in this tree
144+
/// Get the first non-missing token node in this tree. Return nullptr if this
145+
/// node does not contain non-missing tokens.
145146
RC<SyntaxData> getFirstToken() const;
146147

147148
~SyntaxData() {

lib/Parse/SyntaxParsingCache.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t NodeStart,
4444
if (auto NextNode = Node.getData().getNextNode()) {
4545
auto NextLeafNode = NextNode->getFirstToken();
4646
auto NextRawNode = NextLeafNode->getRaw();
47+
assert(NextRawNode->isPresent());
4748
NextLeafNodeLength += NextRawNode->getTokenText().size();
4849
for (auto TriviaPiece : NextRawNode->getLeadingTrivia()) {
4950
NextLeafNodeLength += TriviaPiece.getTextLength();
@@ -73,7 +74,7 @@ llvm::Optional<Syntax> SyntaxParsingCache::lookUpFrom(const Syntax &Node,
7374
size_t ChildStart = NodeStart;
7475
for (size_t I = 0, E = Node.getNumChildren(); I < E; ++I) {
7576
llvm::Optional<Syntax> Child = Node.getChild(I);
76-
if (!Child.hasValue()) {
77+
if (!Child.hasValue() || Child->isMissing()) {
7778
continue;
7879
}
7980
auto ChildEnd = ChildStart + Child->getTextLength();

lib/Syntax/SyntaxData.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ RC<SyntaxData> SyntaxData::getPreviousNode() const {
5959
if (hasParent()) {
6060
for (size_t I = N - 1; ; I--) {
6161
if (auto C = getParent()->getChild(I)) {
62-
return C;
62+
if (C->getRaw()->isPresent() && C->getFirstToken())
63+
return C;
6364
}
6465
if (I == 0)
6566
break;
@@ -73,27 +74,35 @@ RC<SyntaxData> SyntaxData::getNextNode() const {
7374
if (hasParent()) {
7475
for (size_t I = getIndexInParent() + 1, N = Parent->getNumChildren();
7576
I != N; I++) {
76-
if (auto C = getParent()->getChild(I))
77-
return C;
77+
if (auto C = getParent()->getChild(I)) {
78+
if (C->getRaw()->isPresent() && C->getFirstToken())
79+
return C;
80+
}
7881
}
7982
return Parent->getNextNode();
8083
}
8184
return nullptr;
8285
}
8386

8487
RC<SyntaxData> SyntaxData::getFirstToken() const {
88+
if (getRaw()->isToken()) {
89+
// Get a reference counted version of this
90+
assert(hasParent() && "The syntax tree should not conisist only of the root");
91+
return getParent()->getChild(getIndexInParent());
92+
}
93+
8594
for (size_t I = 0, E = getNumChildren(); I < E; ++I) {
8695
if (auto Child = getChild(I)) {
87-
if (!Child->getRaw()->isMissing()) {
88-
return Child->getFirstToken();
96+
if (Child->getRaw()->isMissing())
97+
continue;
98+
if (Child->getRaw()->isToken()) {
99+
return Child;
100+
} else if (auto Token = Child->getFirstToken()) {
101+
return Token;
89102
}
90103
}
91104
}
92-
93-
// Get a reference counted version of this
94-
assert(getRaw()->isToken() && "Leaf node that is no token?");
95-
assert(hasParent() && "The syntax tree should not conisist only of the root");
96-
return getParent()->getChild(getIndexInParent());
105+
return nullptr;
97106
}
98107

99108
AbsolutePosition SyntaxData::getAbsolutePositionBeforeLeadingTrivia() const {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %validate-incrparse %s --test-case ADD_ELSE
3+
4+
func container() {
5+
#if false
6+
<<ADD_ELSE<|||#else>>>
7+
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %validate-incrparse %s --test-case INSERT_SPACE
3+
4+
class AnimationType {
5+
func foo(x: Blah) {
6+
switch x {
7+
case (.
8+
9+
extension AnimationType {
10+
public<<INSERT_SPACE<||| >>>

0 commit comments

Comments
 (0)