@@ -43,15 +43,11 @@ static ArrayRef<Syntax> getSyntaxNodes(ArrayRef<RawSyntaxInfo> RawNodes,
43
43
return Scratch;
44
44
}
45
45
46
- static unsigned countTokens (ArrayRef<RawSyntaxInfo> AllNodes) {
47
- return std::accumulate (AllNodes.begin (), AllNodes.end (), 0 ,
48
- [](unsigned Sum, const RawSyntaxInfo &Info) { return Sum + Info.TokCount ; });
49
- }
50
46
} // End of anonymous namespace
51
47
52
- RawSyntaxInfo::RawSyntaxInfo (SourceLoc StartLoc, unsigned TokCount ,
53
- RC<RawSyntax> RawNode): StartLoc(StartLoc), TokCount(TokCount ), RawNode(RawNode) {
54
- assert (StartLoc.isValid ());
48
+ RawSyntaxInfo::RawSyntaxInfo (SourceLoc StartLoc, SourceLoc EndLoc ,
49
+ RC<RawSyntax> RawNode): StartLoc(StartLoc), EndLoc(EndLoc ), RawNode(RawNode) {
50
+ assert (StartLoc. isValid () == EndLoc .isValid ());
55
51
}
56
52
57
53
struct SyntaxParsingContext ::ContextInfo {
@@ -66,7 +62,7 @@ struct SyntaxParsingContext::ContextInfo {
66
62
67
63
ArrayRef<RawSyntaxInfo>::const_iterator findTokenAt (SourceLoc Loc) {
68
64
for (auto It = Tokens.begin (); It != Tokens.end (); It ++) {
69
- assert (It->TokCount == 1 );
65
+ assert (It->StartLoc == It-> EndLoc );
70
66
if (It->StartLoc == Loc)
71
67
return It;
72
68
}
@@ -98,8 +94,9 @@ struct SyntaxParsingContext::ContextInfo {
98
94
ArrayRef<RawSyntaxInfo> getPendingSyntax () const { return PendingSyntax; };
99
95
100
96
void addPendingSyntax (RawSyntaxInfo Info) {
101
- assert (PendingSyntax.empty () || PendingSyntax.back ().StartLoc .
102
- getOpaquePointerValue () < Info.StartLoc .getOpaquePointerValue ());
97
+ assert (Info.isImplicit () || PendingSyntax.empty () ||
98
+ PendingSyntax.back ().StartLoc .getOpaquePointerValue () <
99
+ Info.StartLoc .getOpaquePointerValue ());
103
100
PendingSyntax.push_back (Info);
104
101
}
105
102
@@ -139,10 +136,15 @@ SyntaxParsingContext::ContextInfo::collectAllSyntax() {
139
136
// If no remaining syntax nodes, add the token.
140
137
Results.emplace_back (Tok);
141
138
It ++;
139
+ } else if (CurSyntax->isImplicit ()) {
140
+ // Skip implicit syntax node.
141
+ CurSyntax ++;
142
142
} else if (CurSyntax->StartLoc == Tok.StartLoc ) {
143
143
// Prefer syntax nodes to tokens.
144
144
Results.emplace_back (*CurSyntax);
145
- It += CurSyntax->TokCount ;
145
+ while (It->EndLoc != CurSyntax->EndLoc ) It++;
146
+ assert (It < Tokens.end () && It->EndLoc == CurSyntax->EndLoc );
147
+ It ++;
146
148
CurSyntax ++;
147
149
} else {
148
150
// We have to add token in this case since the next syntax node has not
@@ -178,7 +180,7 @@ SyntaxParsingContext::ContextInfo::createFromBack(SyntaxKind Kind, unsigned N) {
178
180
Result.emplace (makeUnknownSyntax (SyntaxFactory::getUnknownKind (Kind),
179
181
SyntaxParts));
180
182
}
181
- RawSyntaxInfo NewSyntaxNode (Parts.front ().StartLoc , countTokens ( Parts) ,
183
+ RawSyntaxInfo NewSyntaxNode (Parts.front ().StartLoc , Parts. back (). EndLoc ,
182
184
Result->getRaw ());
183
185
// Remove the building bricks and re-append the result.
184
186
for (unsigned I = 0 ; I < N; I ++)
@@ -209,26 +211,9 @@ SyntaxParsingContextRoot::~SyntaxParsingContextRoot() {
209
211
}
210
212
}
211
213
for (auto Info: ContextData.getPendingSyntax ()) {
212
- std::vector<StmtSyntax> AllStmts;
213
- auto S = Info.makeSyntax <Syntax>();
214
- if (S.isDecl ()) {
215
- AllStmts.push_back (SyntaxFactory::makeDeclarationStmt (
216
- S.getAs <DeclSyntax>().getValue (), None));
217
- } else if (S.isExpr ()) {
218
- AllStmts.push_back (SyntaxFactory::makeExpressionStmt (
219
- S.getAs <ExprSyntax>().getValue (), None));
220
- } else if (S.isStmt ()) {
221
- AllStmts.push_back (S.getAs <StmtSyntax>().getValue ());
222
- } else {
223
- // If this is a standalone token, we create an unknown expression wrapper
224
- // for it.
225
- AllStmts.push_back (SyntaxFactory::makeExpressionStmt (
226
- *makeUnknownSyntax (SyntaxKind::UnknownExpr,
227
- { *S.getAs <TokenSyntax>() }).getAs <ExprSyntax>(),
228
- None));
229
- }
214
+ assert (Info.RawNode ->Kind == SyntaxKind::StmtList);
230
215
AllTopLevel.push_back (SyntaxFactory::makeTopLevelCodeDecl (
231
- SyntaxFactory::makeStmtList (AllStmts )));
216
+ Info. makeSyntax <StmtListSyntax>( )));
232
217
}
233
218
234
219
File.setSyntaxRoot (
@@ -248,14 +233,16 @@ SyntaxParsingContextRoot &SyntaxParsingContextChild::getRoot() {
248
233
249
234
SyntaxParsingContextChild::
250
235
SyntaxParsingContextChild (SyntaxParsingContext *&ContextHolder,
251
- SyntaxContextKind Kind):
236
+ Optional< SyntaxContextKind> Kind, Optional<SyntaxKind> KnownSyntax ):
252
237
SyntaxParsingContext(*ContextHolder), Parent(ContextHolder),
253
- ContextHolder(ContextHolder), Kind(Kind) {
238
+ ContextHolder(ContextHolder), Kind(Kind), KnownSyntax(KnownSyntax) {
239
+ assert (Kind.hasValue () != KnownSyntax.hasValue ());
254
240
ContextHolder = this ;
255
241
if (ContextData.Enabled )
256
242
ContextData.setContextStart (Tok.getLoc ());
257
243
}
258
244
245
+
259
246
void SyntaxParsingContextChild::addTokenSyntax (SourceLoc Loc) {
260
247
if (ContextData.Enabled )
261
248
ContextData.promoteTokenAt (Loc);
@@ -281,6 +268,48 @@ void SyntaxParsingContextChild::makeNode(SyntaxKind Kind) {
281
268
}
282
269
283
270
default :
271
+ llvm_unreachable (" Unrecognized node kind." );
272
+ }
273
+ }
274
+
275
+ void SyntaxParsingContextChild::makeNodeWhole (SyntaxKind Kind) {
276
+ assert (ContextData.Enabled );
277
+ switch (Kind) {
278
+ case SyntaxKind::CodeBlock: {
279
+ ContextData.createFromBack (Kind);
280
+ break ;
281
+ }
282
+ case SyntaxKind::StmtList: {
283
+ if (ContextData.getPendingSyntax ().empty ()) {
284
+ // Create an empty statement list if no statement is in the context.
285
+ ContextData.addPendingSyntax ({SyntaxFactory::makeBlankStmtList ().getRaw ()});
286
+ } else {
287
+ ContextData.createFromBack (Kind);
288
+ }
289
+ break ;
290
+ }
291
+ default :
292
+ llvm_unreachable (" Unrecognized node kind." );
293
+ }
294
+ }
295
+
296
+ void RawSyntaxInfo::brigeWithContext (SyntaxContextKind Kind) {
297
+ switch (Kind) {
298
+ case SyntaxContextKind::Stmt: {
299
+ if (RawNode->isDecl ()) {
300
+ // Wrap a declaration with a declaration statement
301
+ RawNode = SyntaxFactory::createSyntax (SyntaxKind::DeclarationStmt,
302
+ { makeSyntax<Syntax>() })->getRaw ();
303
+ } else if (RawNode->isExpr ()) {
304
+ // Wrap an expression with an expression statement
305
+ RawNode = SyntaxFactory::createSyntax (SyntaxKind::ExpressionStmt,
306
+ { makeSyntax<Syntax>() })->getRaw ();
307
+ }
308
+ assert (RawNode->isStmt ());
309
+ break ;
310
+ }
311
+ case SyntaxContextKind::Decl:
312
+ case SyntaxContextKind::Expr:
284
313
break ;
285
314
}
286
315
}
@@ -295,32 +324,51 @@ SyntaxParsingContextChild::~SyntaxParsingContextChild() {
295
324
296
325
// Set the end of the context.
297
326
ContextData.setContextEnd (Tok.getLoc ());
327
+ if (KnownSyntax) {
328
+ // If the entire context should be created to a known syntax kind, create
329
+ // all pending syntax nodes into that node.
330
+ makeNodeWhole (*KnownSyntax);
331
+ assert (ContextData.getPendingSyntax ().size () == 1 );
332
+ auto AllNodes = ContextData.collectAllSyntax ();
333
+ assert (AllNodes.size () == 1 );
334
+ Parent->ContextData .addPendingSyntax (AllNodes.front ());
335
+ return ;
336
+ }
298
337
auto AllNodes = ContextData.collectAllSyntax ();
299
- assert (countTokens (AllNodes) == ContextData.allTokens ().size ());
300
338
RC<RawSyntax> FinalResult;
301
339
if (AllNodes.empty ())
302
340
return ;
303
341
342
+ // Make sure we used all tokens.
343
+ assert (AllNodes.front ().StartLoc == ContextData.allTokens ().front ().StartLoc );
344
+ assert (AllNodes.back ().EndLoc == ContextData.allTokens ().back ().StartLoc );
345
+
304
346
if (AllNodes.size () == 1 ) {
305
- // FIXME: Check kind
306
- Parent->ContextData .addPendingSyntax (AllNodes.front ());
347
+ // If we have only one syntax node remaining, we are done.
348
+ auto Result = AllNodes.front ();
349
+ // Bridge the syntax node to the expected context kind.
350
+ Result.brigeWithContext (*Kind);
351
+ Parent->ContextData .addPendingSyntax (Result);
307
352
return ;
308
353
}
309
354
310
355
llvm::SmallVector<Syntax, 8 > Scratch;
311
356
auto SyntaxNodes = getSyntaxNodes (AllNodes, Scratch);
312
357
SourceLoc Start = AllNodes.front ().StartLoc ;
313
- unsigned TokCount = countTokens ( AllNodes) ;
358
+ SourceLoc End = AllNodes. back (). EndLoc ;
314
359
SyntaxKind UnknownKind;
315
- switch (Kind) {
360
+ switch (* Kind) {
316
361
case SyntaxContextKind::Expr:
317
362
UnknownKind = SyntaxKind::UnknownExpr;
318
363
break ;
319
364
case SyntaxContextKind::Decl:
320
365
UnknownKind = SyntaxKind::UnknownDecl;
321
366
break ;
367
+ case SyntaxContextKind::Stmt:
368
+ UnknownKind = SyntaxKind::UnknownStmt;
369
+ break ;
322
370
}
323
371
// Create an unknown node and give it to the parent context.
324
- Parent->ContextData .addPendingSyntax ({Start, TokCount ,
372
+ Parent->ContextData .addPendingSyntax ({Start, End ,
325
373
makeUnknownSyntax (UnknownKind, SyntaxNodes).getRaw ()});
326
374
}
0 commit comments