16
16
using namespace swift ;
17
17
using namespace swift ::syntax;
18
18
19
- bool SyntaxParsingCache::nodeCanBeReused (const Syntax &Node, size_t Position,
19
+ bool SyntaxParsingCache::nodeCanBeReused (const Syntax &Node, size_t NodeStart,
20
+ size_t Position,
20
21
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
+
22
27
if (NodeStart != Position)
23
28
return false ;
24
29
if (Node.getKind () != Kind)
@@ -50,23 +55,26 @@ bool SyntaxParsingCache::nodeCanBeReused(const Syntax &Node, size_t Position,
50
55
}
51
56
52
57
llvm::Optional<Syntax> SyntaxParsingCache::lookUpFrom (const Syntax &Node,
58
+ size_t NodeStart,
53
59
size_t Position,
54
60
SyntaxKind Kind) {
55
- if (nodeCanBeReused (Node, Position, Kind)) {
61
+ if (nodeCanBeReused (Node, NodeStart, Position, Kind)) {
56
62
return Node;
57
63
}
58
64
65
+ // Compute the child's position on the fly
66
+ size_t ChildStart = NodeStart;
59
67
for (size_t I = 0 , E = Node.getNumChildren (); I < E; ++I) {
60
68
llvm::Optional<Syntax> Child = Node.getChild (I);
61
69
if (!Child.hasValue ()) {
62
70
continue ;
63
71
}
64
- auto ChildStart =
65
- Child->getAbsolutePositionBeforeLeadingTrivia ().getOffset ();
66
72
auto ChildEnd = ChildStart + Child->getTextLength ();
67
73
if (ChildStart <= Position && Position < ChildEnd) {
68
- return lookUpFrom (Child.getValue (), Position, Kind);
74
+ return lookUpFrom (Child.getValue (), ChildStart, Position, Kind);
69
75
}
76
+ // The next child starts where the previous child ended
77
+ ChildStart = ChildEnd;
70
78
}
71
79
return llvm::None;
72
80
}
@@ -83,7 +91,7 @@ llvm::Optional<Syntax> SyntaxParsingCache::lookUp(size_t NewPosition,
83
91
}
84
92
}
85
93
86
- auto Node = lookUpFrom (OldSyntaxTree, OldPosition, Kind);
94
+ auto Node = lookUpFrom (OldSyntaxTree, /* NodeStart= */ 0 , OldPosition, Kind);
87
95
if (Node.hasValue ()) {
88
96
ReusedNodeIds.insert (Node->getId ());
89
97
}
0 commit comments