Skip to content

Commit 14d0f41

Browse files
committed
[libSyntax] Model parameter modifiers as a ModifierList
This fixes a libSyntax misparse where the first parameter name was parsed as the `isolated` token.
1 parent 8491f52 commit 14d0f41

File tree

3 files changed

+863
-56
lines changed

3 files changed

+863
-56
lines changed

lib/Parse/ParsePattern.cpp

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -254,70 +254,75 @@ Parser::parseParameterClause(SourceLoc &leftParenLoc,
254254
status.setHasCodeCompletionAndIsError();
255255
}
256256
}
257-
258-
// ('inout' | '__shared' | '__owned' | isolated)?
259-
bool hasSpecifier = false;
260-
while (Tok.is(tok::kw_inout) ||
261-
Tok.isContextualKeyword("__shared") ||
262-
Tok.isContextualKeyword("__owned") ||
263-
Tok.isContextualKeyword("isolated") ||
264-
Tok.isContextualKeyword("_const")) {
265-
266-
if (Tok.isContextualKeyword("isolated")) {
267-
// did we already find an 'isolated' type modifier?
268-
if (param.IsolatedLoc.isValid()) {
269-
diagnose(Tok, diag::parameter_specifier_repeated)
257+
258+
{
259+
SyntaxParsingContext ModifiersContext(SyntaxContext, SyntaxKind::ModifierList);
260+
261+
// ('inout' | '__shared' | '__owned' | isolated)?
262+
bool hasSpecifier = false;
263+
while (Tok.is(tok::kw_inout) ||
264+
Tok.isContextualKeyword("__shared") ||
265+
Tok.isContextualKeyword("__owned") ||
266+
Tok.isContextualKeyword("isolated") ||
267+
Tok.isContextualKeyword("_const")) {
268+
SyntaxParsingContext ModContext(SyntaxContext, SyntaxKind::DeclModifier);
269+
270+
if (Tok.isContextualKeyword("isolated")) {
271+
// did we already find an 'isolated' type modifier?
272+
if (param.IsolatedLoc.isValid()) {
273+
diagnose(Tok, diag::parameter_specifier_repeated)
270274
.fixItRemove(Tok.getLoc());
271-
consumeToken();
272-
continue;
273-
}
275+
consumeToken();
276+
continue;
277+
}
274278

275-
// is this 'isolated' token the identifier of an argument label?
276-
bool partOfArgumentLabel = lookahead<bool>(1, [&](CancellableBacktrackingScope &) {
277-
if (Tok.is(tok::colon))
278-
return true; // isolated :
279+
// is this 'isolated' token the identifier of an argument label?
280+
bool partOfArgumentLabel = lookahead<bool>(1, [&](CancellableBacktrackingScope &) {
281+
if (Tok.is(tok::colon))
282+
return true; // isolated :
279283

280-
// isolated x :
281-
return Tok.canBeArgumentLabel() && peekToken().is(tok::colon);
282-
});
284+
// isolated x :
285+
return Tok.canBeArgumentLabel() && peekToken().is(tok::colon);
286+
});
283287

284-
if (partOfArgumentLabel)
285-
break;
288+
if (partOfArgumentLabel)
289+
break;
286290

287-
// consume 'isolated' as type modifier
288-
param.IsolatedLoc = consumeToken();
289-
continue;
290-
}
291+
// consume 'isolated' as type modifier
292+
param.IsolatedLoc = consumeToken();
293+
continue;
294+
}
291295

292-
if (Tok.isContextualKeyword("_const")) {
293-
param.CompileConstLoc = consumeToken();
294-
continue;
295-
}
296+
if (Tok.isContextualKeyword("_const")) {
297+
param.CompileConstLoc = consumeToken();
298+
continue;
299+
}
296300

297-
if (!hasSpecifier) {
298-
if (Tok.is(tok::kw_inout)) {
299-
// This case is handled later when mapping to ParamDecls for
300-
// better fixits.
301-
param.SpecifierKind = ParamDecl::Specifier::InOut;
302-
param.SpecifierLoc = consumeToken();
303-
} else if (Tok.isContextualKeyword("__shared")) {
304-
// This case is handled later when mapping to ParamDecls for
305-
// better fixits.
306-
param.SpecifierKind = ParamDecl::Specifier::Shared;
307-
param.SpecifierLoc = consumeToken();
308-
} else if (Tok.isContextualKeyword("__owned")) {
309-
// This case is handled later when mapping to ParamDecls for
310-
// better fixits.
311-
param.SpecifierKind = ParamDecl::Specifier::Owned;
312-
param.SpecifierLoc = consumeToken();
301+
if (!hasSpecifier) {
302+
if (Tok.is(tok::kw_inout)) {
303+
// This case is handled later when mapping to ParamDecls for
304+
// better fixits.
305+
param.SpecifierKind = ParamDecl::Specifier::InOut;
306+
param.SpecifierLoc = consumeToken();
307+
} else if (Tok.isContextualKeyword("__shared")) {
308+
// This case is handled later when mapping to ParamDecls for
309+
// better fixits.
310+
param.SpecifierKind = ParamDecl::Specifier::Shared;
311+
param.SpecifierLoc = consumeToken();
312+
} else if (Tok.isContextualKeyword("__owned")) {
313+
// This case is handled later when mapping to ParamDecls for
314+
// better fixits.
315+
param.SpecifierKind = ParamDecl::Specifier::Owned;
316+
param.SpecifierLoc = consumeToken();
317+
}
318+
hasSpecifier = true;
319+
} else {
320+
// Redundant specifiers are fairly common, recognize, reject, and
321+
// recover from this gracefully.
322+
diagnose(Tok, diag::parameter_specifier_repeated)
323+
.fixItRemove(Tok.getLoc());
324+
consumeToken();
313325
}
314-
hasSpecifier = true;
315-
} else {
316-
// Redundant specifiers are fairly common, recognize, reject, and
317-
// recover from this gracefully.
318-
diagnose(Tok, diag::parameter_specifier_repeated)
319-
.fixItRemove(Tok.getLoc());
320-
consumeToken();
321326
}
322327
}
323328

0 commit comments

Comments
 (0)