21
21
22
22
#include " swift/Basic/LLVM.h"
23
23
#include " swift/Parse/ParsedRawSyntaxNode.h"
24
+ #include " swift/Parse/SyntaxParseActions.h"
25
+ #include " swift/SyntaxParse/SyntaxTreeCreator.h"
24
26
#include < memory>
25
27
28
+ // / Define a macro that creates a \c ParsedRawSyntaxNode. If \c
29
+ // / PARSEDRAWSYNTAXNODE_VERIFY_RANGES is defined, it passes the \c Range
30
+ // / parameter, otherwise it ignores it at the pre-processor level, which means
31
+ // / that \c Range can be an invalid expression.
32
+ #ifdef PARSEDRAWSYNTAXNODE_VERIFY_RANGES
33
+ #define makeParsedRawSyntaxNode (Opaque, SynKind, TokKind, DataKind, IsMissing, \
34
+ Range) \
35
+ ParsedRawSyntaxNode (Opaque, SynKind, TokKind, DataKind, IsMissing, Range)
36
+ #else
37
+ #define makeParsedRawSyntaxNode (Opaque, SynKind, TokKind, DataKind, IsMissing, \
38
+ Range) \
39
+ ParsedRawSyntaxNode (Opaque, SynKind, TokKind, DataKind, IsMissing)
40
+ #endif
41
+
26
42
namespace swift {
27
43
28
44
class CharSourceRange ;
@@ -57,18 +73,50 @@ class ParsedRawSyntaxRecorder final {
57
73
// / return the recorded node.
58
74
// / This consumes the data from \c node, which is unusable after it has been
59
75
// / recorded. The returned node should be used afterwards instead.
60
- ParsedRawSyntaxNode recordDeferredNode (ParsedRawSyntaxNode &node);
76
+ ParsedRawSyntaxNode recordDeferredNode (ParsedRawSyntaxNode &node) {
77
+ switch (node.getDataKind ()) {
78
+ case RecordedOrDeferredNode::Kind::Null:
79
+ case RecordedOrDeferredNode::Kind::Recorded:
80
+ llvm_unreachable (" Not deferred" );
81
+ case RecordedOrDeferredNode::Kind::DeferredLayout: {
82
+ OpaqueSyntaxNode Data = SPActions->recordDeferredLayout (node.takeData ());
83
+ return makeParsedRawSyntaxNode (Data, node.getKind (), node.getTokenKind (),
84
+ ParsedRawSyntaxNode::DataKind::Recorded,
85
+ node.isMissing (), node.getRange ());
86
+ }
87
+ case RecordedOrDeferredNode::Kind::DeferredToken: {
88
+ OpaqueSyntaxNode Data = SPActions->recordDeferredToken (node.takeData ());
89
+ return makeParsedRawSyntaxNode (Data, node.getKind (), node.getTokenKind (),
90
+ ParsedRawSyntaxNode::DataKind::Recorded,
91
+ node.isMissing (), node.getRange ());
92
+ }
93
+ }
94
+ }
61
95
62
96
public:
63
97
explicit ParsedRawSyntaxRecorder (std::shared_ptr<SyntaxParseActions> spActions)
64
98
: SPActions(std::move(spActions)) {}
65
99
66
100
ParsedRawSyntaxNode recordToken (const Token &tok, StringRef leadingTrivia,
67
- StringRef trailingTrivia);
101
+ StringRef trailingTrivia) {
102
+ return recordToken (tok.getKind (), tok.getRange (), leadingTrivia,
103
+ trailingTrivia);
104
+ }
68
105
69
106
ParsedRawSyntaxNode recordToken (tok tokenKind, CharSourceRange tokenRange,
70
107
StringRef leadingTrivia,
71
- StringRef trailingTrivia);
108
+ StringRef trailingTrivia) {
109
+ SourceLoc offset =
110
+ tokenRange.getStart ().getAdvancedLoc (-leadingTrivia.size ());
111
+ unsigned length = leadingTrivia.size () + tokenRange.getByteLength () +
112
+ trailingTrivia.size ();
113
+ CharSourceRange range (offset, length);
114
+ OpaqueSyntaxNode n =
115
+ SPActions->recordToken (tokenKind, leadingTrivia, trailingTrivia, range);
116
+ return makeParsedRawSyntaxNode (n, syntax::SyntaxKind::Token, tokenKind,
117
+ ParsedRawSyntaxNode::DataKind::Recorded,
118
+ /* IsMissing=*/ false , range);
119
+ }
72
120
73
121
// / Record a missing token. \p loc can be invalid or an approximate location
74
122
// / of where the token would be if not missing.
@@ -77,8 +125,39 @@ class ParsedRawSyntaxRecorder final {
77
125
// / The provided \p elements are an exact layout appropriate for the syntax
78
126
// / \p kind. Missing optional elements are represented with a null
79
127
// / ParsedRawSyntaxNode object.
80
- ParsedRawSyntaxNode recordRawSyntax (syntax::SyntaxKind kind,
81
- MutableArrayRef<ParsedRawSyntaxNode> elements);
128
+ ParsedRawSyntaxNode
129
+ recordRawSyntax (syntax::SyntaxKind kind,
130
+ MutableArrayRef<ParsedRawSyntaxNode> elements) {
131
+ assert (kind != syntax::SyntaxKind::Token &&
132
+ " Use recordToken to record a token" );
133
+ #ifdef PARSEDRAWSYNTAXNODE_VERIFY_RANGES
134
+ auto range = ParsedRawSyntaxRecorder::verifyElementRanges (elements);
135
+ #endif
136
+
137
+ SmallVector<OpaqueSyntaxNode, 16 > subnodes;
138
+ if (!elements.empty ()) {
139
+ for (auto &subnode : elements) {
140
+ switch (subnode.getDataKind ()) {
141
+ case RecordedOrDeferredNode::Kind::Null:
142
+ subnodes.push_back (nullptr );
143
+ break ;
144
+ case RecordedOrDeferredNode::Kind::Recorded:
145
+ subnodes.push_back (subnode.takeData ());
146
+ break ;
147
+ case RecordedOrDeferredNode::Kind::DeferredLayout:
148
+ case RecordedOrDeferredNode::Kind::DeferredToken: {
149
+ auto recorded = recordDeferredNode (subnode);
150
+ subnodes.push_back (recorded.takeData ());
151
+ break ;
152
+ }
153
+ }
154
+ }
155
+ }
156
+ OpaqueSyntaxNode n = SPActions->recordRawSyntax (kind, subnodes);
157
+ return makeParsedRawSyntaxNode (n, kind, tok::NUM_TOKENS,
158
+ ParsedRawSyntaxNode::DataKind::Recorded,
159
+ /* IsMissing=*/ false , range);
160
+ }
82
161
83
162
// / Record a raw syntax collecton without eny elements. \p loc can be invalid
84
163
// / or an approximate location of where an element of the collection would be
@@ -94,11 +173,38 @@ class ParsedRawSyntaxRecorder final {
94
173
ParsedRawSyntaxNode
95
174
makeDeferred (syntax::SyntaxKind k,
96
175
MutableArrayRef<ParsedRawSyntaxNode> deferredNodes,
97
- SyntaxParsingContext &ctx);
176
+ SyntaxParsingContext &ctx) {
177
+ #ifdef PARSEDRAWSYNTAXNODE_VERIFY_RANGES
178
+ auto range = ParsedRawSyntaxRecorder::verifyElementRanges (deferredNodes);
179
+ #endif
180
+
181
+ assert (llvm::none_of (deferredNodes, [](const ParsedRawSyntaxNode &node) {
182
+ return node.isRecorded ();
183
+ }) && " Cannot create a deferred layout node that has recorded children" );
184
+
185
+ auto data =
186
+ SPActions->makeDeferredLayout (k, /* IsMissing=*/ false , deferredNodes);
187
+ return makeParsedRawSyntaxNode (
188
+ data, k, tok::NUM_TOKENS, ParsedRawSyntaxNode::DataKind::DeferredLayout,
189
+ /* IsMissing=*/ false , range);
190
+ }
98
191
99
192
// / Form a deferred token node.
100
193
ParsedRawSyntaxNode makeDeferred (Token tok, StringRef leadingTrivia,
101
- StringRef trailingTrivia);
194
+ StringRef trailingTrivia) {
195
+ CharSourceRange tokRange = tok.getRange ();
196
+ CharSourceRange RangeWithTrivia = CharSourceRange (
197
+ tokRange.getStart ().getAdvancedLoc (-leadingTrivia.size ()),
198
+ (unsigned )leadingTrivia.size () + tokRange.getByteLength () +
199
+ (unsigned )trailingTrivia.size ());
200
+ auto Data = SPActions->makeDeferredToken (tok.getKind (), leadingTrivia,
201
+ trailingTrivia, RangeWithTrivia,
202
+ /* IsMissing=*/ false );
203
+ return makeParsedRawSyntaxNode (Data, syntax::SyntaxKind::Token,
204
+ tok.getKind (),
205
+ ParsedRawSyntaxNode::DataKind::DeferredToken,
206
+ /* IsMissing=*/ false , RangeWithTrivia);
207
+ }
102
208
103
209
// / Form a deferred missing token node.
104
210
ParsedRawSyntaxNode makeDeferredMissing (tok tokKind, SourceLoc loc);
0 commit comments