Skip to content

Commit ef485d4

Browse files
committed
[libSyntax] Create deferred nodes in the ParsedRawSyntaxRecorder
This is a multi-commit effort to push the responsibility of deferred node handling to the SyntaxParseActions which have more detailed knowledge of their requirements on deferred nodes and might perform additional optimisations. For example, the SyntaxTreeCreator can always create RawSyntax nodes (even for deferred nodes) and decide to simply not use them, should the deferred nodes not get recorded.
1 parent 68877f9 commit ef485d4

File tree

7 files changed

+84
-77
lines changed

7 files changed

+84
-77
lines changed

include/swift/Parse/ParsedRawSyntaxNode.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class SyntaxParsingContext;
4040
/// there are instances that it's not clear what will be the final syntax node
4141
/// in the current parsing context.
4242
class ParsedRawSyntaxNode {
43+
friend class ParsedRawSyntaxRecorder;
4344
enum class DataKind: uint8_t {
4445
Null,
4546
Recorded,
@@ -292,25 +293,6 @@ class ParsedRawSyntaxNode {
292293

293294
//==========================================================================//
294295

295-
/// Form a deferred syntax layout node.
296-
static ParsedRawSyntaxNode makeDeferred(syntax::SyntaxKind k,
297-
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
298-
SyntaxParsingContext &ctx);
299-
300-
/// Form a deferred token node.
301-
static ParsedRawSyntaxNode makeDeferred(Token tok, StringRef leadingTrivia,
302-
StringRef trailingTrivia,
303-
SyntaxParsingContext &ctx);
304-
305-
/// Form a deferred missing token node.
306-
static ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc) {
307-
auto raw = ParsedRawSyntaxNode(tokKind, loc, /*tokLength=*/0,
308-
/*leadingTrivia=*/StringRef(),
309-
/*trailingTrivia=*/StringRef());
310-
raw.IsMissing = true;
311-
return raw;
312-
}
313-
314296
/// Dump this piece of syntax recursively for debugging or testing.
315297
SWIFT_DEBUG_DUMP;
316298

include/swift/Parse/ParsedRawSyntaxRecorder.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class ParsedRawSyntaxNode;
2929
struct ParsedTrivia;
3030
class ParsedTriviaPiece;
3131
class SyntaxParseActions;
32+
class SyntaxParsingContext;
3233
class SourceLoc;
3334
class Token;
3435
enum class tok;
@@ -67,6 +68,19 @@ class ParsedRawSyntaxRecorder final {
6768
ParsedRawSyntaxNode recordEmptyRawSyntaxCollection(syntax::SyntaxKind kind,
6869
SourceLoc loc);
6970

71+
/// Form a deferred syntax layout node.
72+
ParsedRawSyntaxNode
73+
makeDeferred(syntax::SyntaxKind k,
74+
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
75+
SyntaxParsingContext &ctx);
76+
77+
/// Form a deferred token node.
78+
ParsedRawSyntaxNode makeDeferred(Token tok, StringRef leadingTrivia,
79+
StringRef trailingTrivia);
80+
81+
/// Form a deferred missing token node.
82+
ParsedRawSyntaxNode makeDeferredMissing(tok tokKind, SourceLoc loc);
83+
7084
/// Used for incremental re-parsing.
7185
ParsedRawSyntaxNode lookupNode(size_t lexerOffset, SourceLoc loc,
7286
syntax::SyntaxKind kind);

lib/Parse/ParsedRawSyntaxNode.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,50 +17,6 @@ using namespace swift;
1717
using namespace swift::syntax;
1818
using namespace llvm;
1919

20-
ParsedRawSyntaxNode
21-
ParsedRawSyntaxNode::makeDeferred(SyntaxKind k,
22-
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
23-
SyntaxParsingContext &ctx) {
24-
CharSourceRange range;
25-
if (deferredNodes.empty()) {
26-
return ParsedRawSyntaxNode(k, range, {});
27-
}
28-
ParsedRawSyntaxNode *newPtr =
29-
ctx.getScratchAlloc().Allocate<ParsedRawSyntaxNode>(deferredNodes.size());
30-
31-
#ifndef NDEBUG
32-
ParsedRawSyntaxRecorder::verifyElementRanges(deferredNodes);
33-
#endif
34-
auto ptr = newPtr;
35-
for (auto &node : deferredNodes) {
36-
// Cached range.
37-
if (!node.isNull() && !node.isMissing()) {
38-
auto nodeRange = node.getDeferredRange();
39-
if (nodeRange.isValid()) {
40-
if (range.isInvalid())
41-
range = nodeRange;
42-
else
43-
range.widen(nodeRange);
44-
}
45-
}
46-
47-
// uninitialized move;
48-
:: new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
49-
}
50-
return ParsedRawSyntaxNode(k, range,
51-
makeMutableArrayRef(newPtr, deferredNodes.size()));
52-
}
53-
54-
ParsedRawSyntaxNode
55-
ParsedRawSyntaxNode::makeDeferred(Token tok, StringRef leadingTrivia,
56-
StringRef trailingTrivia,
57-
SyntaxParsingContext &ctx) {
58-
CharSourceRange tokRange = tok.getRange();
59-
return ParsedRawSyntaxNode(tok.getKind(), tokRange.getStart(),
60-
tokRange.getByteLength(), leadingTrivia,
61-
trailingTrivia);
62-
}
63-
6420
void ParsedRawSyntaxNode::dump() const {
6521
dump(llvm::errs(), /*Indent*/ 0);
6622
llvm::errs() << '\n';

lib/Parse/ParsedRawSyntaxRecorder.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/Parse/ParsedRawSyntaxNode.h"
2121
#include "swift/Parse/ParsedTrivia.h"
2222
#include "swift/Parse/SyntaxParseActions.h"
23+
#include "swift/Parse/SyntaxParsingContext.h"
2324
#include "swift/Parse/Token.h"
2425
#include "swift/Syntax/SyntaxKind.h"
2526

@@ -112,6 +113,59 @@ ParsedRawSyntaxRecorder::recordEmptyRawSyntaxCollection(SyntaxKind kind,
112113
return ParsedRawSyntaxNode{kind, tok::unknown, range, n};
113114
}
114115

116+
/// Create a deferred layout node.
117+
ParsedRawSyntaxNode ParsedRawSyntaxRecorder::makeDeferred(
118+
syntax::SyntaxKind k, MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
119+
SyntaxParsingContext &ctx) {
120+
CharSourceRange range;
121+
if (deferredNodes.empty()) {
122+
return ParsedRawSyntaxNode(k, range, {});
123+
}
124+
ParsedRawSyntaxNode *newPtr =
125+
ctx.getScratchAlloc().Allocate<ParsedRawSyntaxNode>(deferredNodes.size());
126+
127+
#ifndef NDEBUG
128+
ParsedRawSyntaxRecorder::verifyElementRanges(deferredNodes);
129+
#endif
130+
auto ptr = newPtr;
131+
for (auto &node : deferredNodes) {
132+
// Cached range.
133+
if (!node.isNull() && !node.isMissing()) {
134+
auto nodeRange = node.getDeferredRange();
135+
if (nodeRange.isValid()) {
136+
if (range.isInvalid())
137+
range = nodeRange;
138+
else
139+
range.widen(nodeRange);
140+
}
141+
}
142+
143+
// uninitialized move;
144+
::new (static_cast<void *>(ptr++)) ParsedRawSyntaxNode(std::move(node));
145+
}
146+
return ParsedRawSyntaxNode(
147+
k, range, llvm::makeMutableArrayRef(newPtr, deferredNodes.size()));
148+
}
149+
150+
/// Create a deferred token node.
151+
ParsedRawSyntaxNode
152+
ParsedRawSyntaxRecorder::makeDeferred(Token tok, StringRef leadingTrivia,
153+
StringRef trailingTrivia) {
154+
CharSourceRange tokRange = tok.getRange();
155+
return ParsedRawSyntaxNode(tok.getKind(), tokRange.getStart(),
156+
tokRange.getByteLength(), leadingTrivia,
157+
trailingTrivia);
158+
}
159+
160+
ParsedRawSyntaxNode
161+
ParsedRawSyntaxRecorder::makeDeferredMissing(tok tokKind, SourceLoc loc) {
162+
auto raw = ParsedRawSyntaxNode(tokKind, loc, /*tokLength=*/0,
163+
/*leadingTrivia=*/StringRef(),
164+
/*trailingTrivia=*/StringRef());
165+
raw.IsMissing = true;
166+
return raw;
167+
}
168+
115169
ParsedRawSyntaxNode
116170
ParsedRawSyntaxRecorder::lookupNode(size_t lexerOffset, SourceLoc loc,
117171
SyntaxKind kind) {

lib/Parse/ParsedSyntaxBuilders.cpp.gyb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ Parsed${node.name}Builder::record() {
6767
Parsed${node.name}
6868
Parsed${node.name}Builder::makeDeferred() {
6969
finishLayout(/*deferred=*/true);
70-
auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind},
71-
Layout, SPCtx);
70+
auto raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind},
71+
Layout, SPCtx);
7272
return Parsed${node.name}(std::move(raw));
7373
}
7474

@@ -91,7 +91,7 @@ void Parsed${node.name}Builder::finishLayout(bool deferred) {
9191
% if child_elt:
9292
if (!${child_elt_name}s.empty()) {
9393
if (deferred) {
94-
Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind},
94+
Layout[${idx}] = Rec.makeDeferred(SyntaxKind::${child_node.syntax_kind},
9595
${child_elt_name}s, SPCtx);
9696
} else {
9797
Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, ${child_elt_name}s);
@@ -104,13 +104,13 @@ void Parsed${node.name}Builder::finishLayout(bool deferred) {
104104
% token = child.main_token()
105105
% tok_kind = token.kind if token else "unknown"
106106
if (deferred) {
107-
Layout[${idx}] = ParsedRawSyntaxNode::makeDeferredMissing(tok::${tok_kind}, SourceLoc());
107+
Layout[${idx}] = Rec.makeDeferredMissing(tok::${tok_kind}, SourceLoc());
108108
} else {
109109
Layout[${idx}] = Rec.recordMissingToken(tok::${tok_kind}, SourceLoc());
110110
}
111111
% elif child_elt:
112112
if (deferred) {
113-
Layout[${idx}] = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${child_node.syntax_kind}, {}, SPCtx);
113+
Layout[${idx}] = Rec.makeDeferred(SyntaxKind::${child_node.syntax_kind}, {}, SPCtx);
114114
} else {
115115
Layout[${idx}] = Rec.recordRawSyntax(SyntaxKind::${child_node.syntax_kind}, {});
116116
}

lib/Parse/ParsedSyntaxRecorder.cpp.gyb

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ ParsedSyntaxRecorder::record${node.syntax_kind}(MutableArrayRef<ParsedRawSyntaxN
9898

9999
Parsed${node.name}
100100
ParsedSyntaxRecorder::defer${node.syntax_kind}(MutableArrayRef<ParsedRawSyntaxNode> layout, SyntaxParsingContext &SPCtx) {
101-
auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, layout, SPCtx);
101+
auto raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind},
102+
layout, SPCtx);
102103
return Parsed${node.name}(std::move(raw));
103104
}
104105

@@ -132,8 +133,8 @@ Parsed${node.name}
132133
ParsedSyntaxRecorder::defer${node.syntax_kind}(
133134
MutableArrayRef<ParsedRawSyntaxNode> layout,
134135
SyntaxParsingContext &SPCtx) {
135-
auto raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind},
136-
layout, SPCtx);
136+
auto raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind},
137+
layout, SPCtx);
137138
return Parsed${node.name}(std::move(raw));
138139
}
139140

@@ -157,7 +158,8 @@ ParsedSyntaxRecorder::makeBlank${node.syntax_kind}(SourceLoc loc,
157158
ParsedRawSyntaxNode raw;
158159
if (SPCtx.shouldDefer()) {
159160
// FIXME: 'loc' is not preserved when capturing a deferred layout.
160-
raw = ParsedRawSyntaxNode::makeDeferred(SyntaxKind::${node.syntax_kind}, {}, SPCtx);
161+
raw = SPCtx.getRecorder().makeDeferred(SyntaxKind::${node.syntax_kind},
162+
{}, SPCtx);
161163
} else {
162164
raw = SPCtx.getRecorder().recordEmptyRawSyntaxCollection(SyntaxKind::${node.syntax_kind}, loc);
163165
}

lib/Parse/SyntaxParsingContext.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ SyntaxParsingContext::makeUnknownSyntax(SyntaxKind Kind,
9898
MutableArrayRef<ParsedRawSyntaxNode> Parts) {
9999
assert(isUnknownKind(Kind));
100100
if (shouldDefer())
101-
return ParsedRawSyntaxNode::makeDeferred(Kind, Parts, *this);
101+
return getRecorder().makeDeferred(Kind, Parts, *this);
102102
else
103103
return getRecorder().recordRawSyntax(Kind, Parts);
104104
}
@@ -112,7 +112,7 @@ SyntaxParsingContext::createSyntaxAs(SyntaxKind Kind,
112112
auto &rec = getRecorder();
113113
auto formNode = [&](SyntaxKind kind, MutableArrayRef<ParsedRawSyntaxNode> layout) {
114114
if (nodeCreateK == SyntaxNodeCreationKind::Deferred || shouldDefer()) {
115-
rawNode = ParsedRawSyntaxNode::makeDeferred(kind, layout, *this);
115+
rawNode = getRecorder().makeDeferred(kind, layout, *this);
116116
} else {
117117
rawNode = rec.recordRawSyntax(kind, layout);
118118
}
@@ -210,8 +210,7 @@ void SyntaxParsingContext::addToken(Token &Tok, StringRef LeadingTrivia,
210210

211211
ParsedRawSyntaxNode raw;
212212
if (shouldDefer()) {
213-
raw = ParsedRawSyntaxNode::makeDeferred(Tok, LeadingTrivia, TrailingTrivia,
214-
*this);
213+
raw = getRecorder().makeDeferred(Tok, LeadingTrivia, TrailingTrivia);
215214
} else {
216215
raw = getRecorder().recordToken(Tok, LeadingTrivia, TrailingTrivia);
217216
}
@@ -339,7 +338,7 @@ void SyntaxParsingContext::synthesize(tok Kind, SourceLoc Loc) {
339338

340339
ParsedRawSyntaxNode raw;
341340
if (shouldDefer())
342-
raw = ParsedRawSyntaxNode::makeDeferredMissing(Kind, Loc);
341+
raw = getRecorder().makeDeferredMissing(Kind, Loc);
343342
else
344343
raw = getRecorder().recordMissingToken(Kind, Loc);
345344
getStorage().push_back(std::move(raw));

0 commit comments

Comments
 (0)