@@ -53,15 +53,15 @@ RC<RawSyntax> createSyntaxAs(SyntaxKind Kind, ArrayRef<RC<RawSyntax>> Parts) {
53
53
SyntaxParsingContext::SyntaxParsingContext (SyntaxParsingContext *&CtxtHolder,
54
54
SourceFile &SF,
55
55
DiagnosticEngine &Diags)
56
- : RootDataOrParent(new RootContextData(SF, Diags)),
57
- CtxtHolder(CtxtHolder ), Mode(AccumulationMode::Root),
56
+ : RootDataOrParent(new RootContextData(SF, Diags)), CtxtHolder(CtxtHolder),
57
+ Storage(getRootData().Storage), Offset( 0 ), Mode(AccumulationMode::Root),
58
58
Enabled(SF.shouldKeepSyntaxInfo()) {
59
59
CtxtHolder = this ;
60
60
}
61
61
62
62
// / Add RawSyntax to the parts.
63
63
void SyntaxParsingContext::addRawSyntax (RC<RawSyntax> Raw) {
64
- Parts .emplace_back (Raw);
64
+ Storage .emplace_back (Raw);
65
65
}
66
66
67
67
SyntaxParsingContext *SyntaxParsingContext::getRoot () {
@@ -90,14 +90,17 @@ void SyntaxParsingContext::addSyntax(Syntax Node) {
90
90
}
91
91
92
92
void SyntaxParsingContext::createNodeInPlace (SyntaxKind Kind, size_t N) {
93
- assert (N >= 1 );
93
+ if (N == 0 ) {
94
+ Storage.push_back (createSyntaxAs (Kind, {}));
95
+ return ;
96
+ }
94
97
95
- auto I = Parts .end () - N;
96
- *I = createSyntaxAs (Kind, llvm::makeArrayRef (Parts ).take_back (N));
98
+ auto I = Storage .end () - N;
99
+ *I = createSyntaxAs (Kind, getParts ( ).take_back (N));
97
100
98
- // Remove used parts.
101
+ // Remove consumed parts.
99
102
if (N != 1 )
100
- Parts .erase (I + 1 , Parts .end ());
103
+ Storage .erase (I + 1 , Storage .end ());
101
104
}
102
105
103
106
void SyntaxParsingContext::createNodeInPlace (SyntaxKind Kind) {
@@ -123,7 +126,7 @@ void SyntaxParsingContext::createNodeInPlace(SyntaxKind Kind) {
123
126
case SyntaxKind::FunctionCallExpr:
124
127
case SyntaxKind::SubscriptExpr:
125
128
case SyntaxKind::ExprList: {
126
- createNodeInPlace (Kind, Parts .size ());
129
+ createNodeInPlace (Kind, getParts () .size ());
127
130
break ;
128
131
}
129
132
default :
@@ -136,14 +139,16 @@ void SyntaxParsingContext::collectNodesInPlace(SyntaxKind ColletionKind) {
136
139
assert (isTopOfContextStack ());
137
140
if (!Enabled)
138
141
return ;
139
- auto Count = std::count_if (Parts. rbegin (), Parts. rend (),
140
- [&]( const RC<RawSyntax> &Raw) {
141
- return SyntaxFactory::canServeAsCollectionMember (ColletionKind,
142
- make<Syntax>(Raw));
143
- });
144
- if (Count) {
145
- createNodeInPlace (ColletionKind, Count) ;
142
+ auto Parts = getParts ();
143
+ auto Count = 0 ;
144
+ for ( auto I = Parts. rbegin (), End = Parts. rend (); I != End; ++I) {
145
+ if (! SyntaxFactory::canServeAsCollectionMember (ColletionKind,
146
+ make<Syntax>(*I)))
147
+ break ;
148
+ ++ Count;
146
149
}
150
+ if (Count)
151
+ createNodeInPlace (ColletionKind, Count);
147
152
}
148
153
149
154
namespace {
@@ -257,28 +262,39 @@ SyntaxParsingContext::~SyntaxParsingContext() {
257
262
switch (Mode) {
258
263
// Create specified Syntax node from the parts and add it to the parent.
259
264
case AccumulationMode::CreateSyntax:
260
- getParent ()->addRawSyntax (createSyntaxAs (SynKind, Parts));
265
+ assert (!isRoot ());
266
+ createNodeInPlace (SynKind, Storage.size () - Offset);
261
267
break ;
262
268
263
269
// Ensure the result is specified Syntax category and add it to the parent.
264
- case AccumulationMode::CoerceKind:
265
- getParent ()->addRawSyntax (bridgeAs (CtxtKind, Parts));
270
+ case AccumulationMode::CoerceKind: {
271
+ assert (!isRoot ());
272
+ if (Storage.size () == Offset) {
273
+ Storage.push_back (bridgeAs (CtxtKind, {}));
274
+ } else {
275
+ auto I = Storage.begin () + Offset;
276
+ *I = bridgeAs (CtxtKind, getParts ());
277
+ // Remove used parts.
278
+ if (Storage.size () > Offset + 1 )
279
+ Storage.erase (Storage.begin () + (Offset + 1 ), Storage.end ());
280
+ }
266
281
break ;
282
+ }
267
283
268
- // Just move the parts to the tail of the parent .
284
+ // Do nothing .
269
285
case AccumulationMode::Transparent:
270
- std::move (Parts. begin (), Parts. end (), std::back_inserter ( getParent ()-> Parts ));
286
+ assert (! isRoot ( ));
271
287
break ;
272
288
273
- // Do nothing. Just let it discarded .
289
+ // Remove all parts in this context .
274
290
case AccumulationMode::Discard:
275
- assert (! isRoot () );
291
+ Storage. resize (Offset );
276
292
break ;
277
293
278
294
// Accumulate parsed toplevel syntax onto the SourceFile.
279
295
case AccumulationMode::Root:
280
296
assert (isRoot () && " AccumulationMode::Root is only for root context" );
281
- finalizeSourceFile (getRootData ().SF , Parts );
297
+ finalizeSourceFile (getRootData ().SF , getParts () );
282
298
break ;
283
299
284
300
// Never.
0 commit comments