Skip to content

Commit c6b7ad7

Browse files
committed
[SyntaxParse] Eagarly cache deferred range for deferred layout node
1 parent 1f47fa2 commit c6b7ad7

File tree

4 files changed

+29
-29
lines changed

4 files changed

+29
-29
lines changed

include/swift/Parse/ParsedRawSyntaxNode.h

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class ParsedRawSyntaxNode {
5252
};
5353
struct DeferredLayoutNode {
5454
MutableArrayRef<ParsedRawSyntaxNode> Children;
55+
CharSourceRange Range;
5556
};
5657
struct DeferredTokenNode {
5758
const ParsedTriviaPiece *TriviaPieces;
@@ -72,9 +73,9 @@ class ParsedRawSyntaxNode {
7273
/// Primary used for capturing a deferred missing token.
7374
bool IsMissing = false;
7475

75-
ParsedRawSyntaxNode(syntax::SyntaxKind k,
76+
ParsedRawSyntaxNode(syntax::SyntaxKind k, CharSourceRange r,
7677
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes)
77-
: DeferredLayout({deferredNodes}),
78+
: DeferredLayout({deferredNodes, r}),
7879
SynKind(uint16_t(k)), TokKind(uint16_t(tok::unknown)),
7980
DK(DataKind::DeferredLayout) {
8081
assert(getKind() == k && "Syntax kind with too large value!");
@@ -211,14 +212,12 @@ class ParsedRawSyntaxNode {
211212
return copy;
212213
}
213214

214-
CharSourceRange getDeferredRange(bool includeTrivia) const {
215+
CharSourceRange getDeferredRange() const {
215216
switch (DK) {
216217
case DataKind::DeferredLayout:
217-
return getDeferredLayoutRange(includeTrivia);
218+
return getDeferredLayoutRange();
218219
case DataKind::DeferredToken:
219-
return includeTrivia
220-
? getDeferredTokenRangeWithTrivia()
221-
: getDeferredTokenRange();
220+
return getDeferredTokenRangeWithTrivia();
222221
default:
223222
llvm_unreachable("node not deferred");
224223
}
@@ -243,20 +242,9 @@ class ParsedRawSyntaxNode {
243242

244243
// Deferred Layout Data ====================================================//
245244

246-
CharSourceRange getDeferredLayoutRange(bool includeTrivia) const {
245+
CharSourceRange getDeferredLayoutRange() const {
247246
assert(DK == DataKind::DeferredLayout);
248-
auto HasValidRange = [includeTrivia](const ParsedRawSyntaxNode &Child) {
249-
return !Child.isNull() && !Child.isMissing() &&
250-
Child.getDeferredRange(includeTrivia).isValid();
251-
};
252-
auto first = llvm::find_if(getDeferredChildren(), HasValidRange);
253-
if (first == getDeferredChildren().end())
254-
return CharSourceRange();
255-
auto last = llvm::find_if(llvm::reverse(getDeferredChildren()),
256-
HasValidRange);
257-
auto firstRange = first->getDeferredRange(includeTrivia);
258-
firstRange.widen(last->getDeferredRange(includeTrivia));
259-
return firstRange;
247+
return DeferredLayout.Range;
260248
}
261249
ArrayRef<ParsedRawSyntaxNode> getDeferredChildren() const {
262250
assert(DK == DataKind::DeferredLayout);

lib/Parse/ParseType.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -899,9 +899,8 @@ Parser::parseOldStyleProtocolComposition() {
899899
replacement = "Any";
900900
} else {
901901
auto extractText = [&](ParsedTypeSyntax &Type) -> StringRef {
902-
auto SourceRange = Type.getRaw()
903-
.getDeferredRange(/*includeTrivia=*/false);
904-
return SourceMgr.extractText(SourceRange);
902+
auto SourceRange = Type.getRaw().getDeferredRange();
903+
return SourceMgr.extractText(SourceRange).trim();
905904
};
906905
auto Begin = Protocols.begin();
907906
replacement += extractText(*Begin);

lib/Parse/ParsedRawSyntaxNode.cpp

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,31 @@ ParsedRawSyntaxNode
2121
ParsedRawSyntaxNode::makeDeferred(SyntaxKind k,
2222
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
2323
SyntaxParsingContext &ctx) {
24+
CharSourceRange range;
2425
if (deferredNodes.empty()) {
25-
return ParsedRawSyntaxNode(k, {});
26+
return ParsedRawSyntaxNode(k, range, {});
2627
}
2728
ParsedRawSyntaxNode *newPtr =
2829
ctx.getScratchAlloc().Allocate<ParsedRawSyntaxNode>(deferredNodes.size());
2930

30-
// uninitialized move;
3131
auto ptr = newPtr;
32-
for (auto &node : deferredNodes)
33-
:: new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
32+
for (auto &node : deferredNodes) {
33+
// Cached range.
34+
if (!node.isNull() && !node.isMissing()) {
35+
auto nodeRange = node.getDeferredRange();
36+
if (nodeRange.isValid()) {
37+
if (range.isInvalid())
38+
range = nodeRange;
39+
else
40+
range.widen(nodeRange);
41+
}
42+
}
3443

35-
return ParsedRawSyntaxNode(k, makeMutableArrayRef(newPtr, deferredNodes.size()));
44+
// uninitialized move;
45+
:: new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
46+
}
47+
return ParsedRawSyntaxNode(k, range,
48+
makeMutableArrayRef(newPtr, deferredNodes.size()));
3649
}
3750

3851
ParsedRawSyntaxNode

lib/Parse/ParsedRawSyntaxRecorder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void ParsedRawSyntaxRecorder::verifyElementRanges(ArrayRef<ParsedRawSyntaxNode>
138138
continue;
139139
CharSourceRange range = elem.isRecorded()
140140
? elem.getRecordedRange()
141-
: elem.getDeferredRange(/*includeTrivia=*/true);
141+
: elem.getDeferredRange();
142142
if (range.isValid()) {
143143
assert((prevEndLoc.isInvalid() || range.getStart() == prevEndLoc)
144144
&& "Non-contiguous child ranges?");

0 commit comments

Comments
 (0)