Skip to content

Commit 2193a7b

Browse files
committed
[incrParse] Compute NodeStart on the fly when looking up nodes
This is faster than invoking getAbsolutePosition which needs to walk the tree again.
1 parent 3121af2 commit 2193a7b

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

include/swift/Parse/SyntaxParsingCache.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ class SyntaxParsingCache {
9090
getReusedRegions(const SourceFileSyntax &SyntaxTree) const;
9191

9292
private:
93-
llvm::Optional<Syntax> lookUpFrom(const Syntax &Node, size_t Position,
94-
SyntaxKind Kind);
93+
llvm::Optional<Syntax> lookUpFrom(const Syntax &Node, size_t NodeStart,
94+
size_t Position, SyntaxKind Kind);
9595

96-
bool nodeCanBeReused(const Syntax &Node, size_t Position,
96+
bool nodeCanBeReused(const Syntax &Node, size_t Position, size_t NodeStart,
9797
SyntaxKind Kind) const;
9898
};
9999

lib/Parse/SyntaxParsingCache.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,14 @@
1616
using namespace swift;
1717
using namespace swift::syntax;
1818

19-
bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t Position,
19+
bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t NodeStart,
20+
size_t Position,
2021
SyntaxKind Kind) const {
21-
auto NodeStart = Node.getAbsolutePositionBeforeLeadingTrivia().getOffset();
22+
// Computing the value of NodeStart on the fly is faster than determining a
23+
// node's absolute position, but make sure the values match in an assertion
24+
// build
25+
assert(NodeStart == Node.getAbsolutePositionBeforeLeadingTrivia().getOffset());
26+
2227
if (NodeStart != Position)
2328
return false;
2429
if (Node.getKind() != Kind)
@@ -50,23 +55,26 @@ bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t Position,
5055
}
5156

5257
llvm::Optional<Syntax> SyntaxParsingCache::lookUpFrom(const Syntax &Node,
58+
size_t NodeStart,
5359
size_t Position,
5460
SyntaxKind Kind) {
55-
if (nodeCanBeReused(Node, Position, Kind)) {
61+
if (nodeCanBeReused(Node, NodeStart, Position, Kind)) {
5662
return Node;
5763
}
5864

65+
// Compute the child's position on the fly
66+
size_t ChildStart = NodeStart;
5967
for (size_t I = 0, E = Node.getNumChildren(); I < E; ++I) {
6068
llvm::Optional<Syntax> Child = Node.getChild(I);
6169
if (!Child.hasValue()) {
6270
continue;
6371
}
64-
auto ChildStart =
65-
Child->getAbsolutePositionBeforeLeadingTrivia().getOffset();
6672
auto ChildEnd = ChildStart + Child->getTextLength();
6773
if (ChildStart <= Position && Position < ChildEnd) {
68-
return lookUpFrom(Child.getValue(), Position, Kind);
74+
return lookUpFrom(Child.getValue(), ChildStart, Position, Kind);
6975
}
76+
// The next child starts where the previous child ended
77+
ChildStart = ChildEnd;
7078
}
7179
return llvm::None;
7280
}
@@ -83,7 +91,7 @@ llvm::Optional<Syntax> SyntaxParsingCache::lookUp(size_t NewPosition,
8391
}
8492
}
8593

86-
auto Node = lookUpFrom(OldSyntaxTree, OldPosition, Kind);
94+
auto Node = lookUpFrom(OldSyntaxTree, /*NodeStart=*/0, OldPosition, Kind);
8795
if (Node.hasValue()) {
8896
ReusedNodeIds.insert(Node->getId());
8997
}

0 commit comments

Comments
 (0)