Skip to content

Commit 3d5c995

Browse files
committed
Parse @_implements(Proto, DeclName)
1 parent 4d9ea18 commit 3d5c995

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,10 @@ ERROR(attr_specialize_parameter_already_defined,none,
13521352
ERROR(attr_specialize_expected_partial_or_full,none,
13531353
"expected 'partial' or 'full' as values of the 'kind' parameter in '_specialize' attribute", ())
13541354

1355+
// _implements
1356+
ERROR(attr_implements_expected_member_name,PointsToFirstBadToken,
1357+
"expected a member name as second parameter in '_implements' attribute", ())
1358+
13551359
//------------------------------------------------------------------------------
13561360
// Generics parsing diagnostics
13571361
//------------------------------------------------------------------------------

include/swift/Parse/Parser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,11 @@ class Parser {
730730
bool parseSpecializeAttribute(swift::tok ClosingBrace, SourceLoc AtLoc,
731731
SourceLoc Loc, SpecializeAttr *&Attr);
732732

733+
/// Parse the @_implements attribute.
734+
/// \p Attr is where to store the parsed attribute
735+
ParserResult<ImplementsAttr> parseImplementsAttribute(SourceLoc AtLoc,
736+
SourceLoc Loc);
737+
733738
/// Parse a specific attribute.
734739
bool parseDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc);
735740

lib/Parse/ParseDecl.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,62 @@ bool Parser::parseSpecializeAttribute(swift::tok ClosingBrace, SourceLoc AtLoc,
437437
return true;
438438
}
439439

440+
ParserResult<ImplementsAttr>
441+
Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
442+
StringRef AttrName = "_implements";
443+
ParserStatus Status;
444+
445+
if (Tok.isNot(tok::l_paren)) {
446+
diagnose(Loc, diag::attr_expected_lparen, AttrName,
447+
/*DeclModifier=*/false);
448+
Status.setIsParseError();
449+
return Status;
450+
}
451+
452+
SourceLoc lParenLoc = consumeToken();
453+
454+
ParserResult<TypeRepr> ProtocolType = parseType();
455+
Status |= ProtocolType;
456+
457+
if (!(Status.shouldStopParsing() || consumeIf(tok::comma))) {
458+
diagnose(Tok.getLoc(), diag::attr_expected_comma, AttrName,
459+
/*DeclModifier=*/false);
460+
Status.setIsParseError();
461+
}
462+
463+
DeclNameLoc MemberNameLoc;
464+
DeclName MemberName;
465+
if (!Status.shouldStopParsing()) {
466+
MemberName =
467+
parseUnqualifiedDeclName(/*afterDot=*/false, MemberNameLoc,
468+
diag::attr_implements_expected_member_name,
469+
/*allowOperators=*/true,
470+
/*allowZeroArgCompoundNames=*/true);
471+
if (!MemberName) {
472+
Status.setIsParseError();
473+
}
474+
}
475+
476+
if (Status.isError()) {
477+
skipUntil(tok::r_paren);
478+
}
479+
480+
SourceLoc rParenLoc;
481+
if (!consumeIf(tok::r_paren, rParenLoc)) {
482+
diagnose(lParenLoc, diag::attr_expected_rparen, AttrName,
483+
/*DeclModifier=*/false);
484+
Status.setIsParseError();
485+
}
486+
487+
if (Status.isError()) {
488+
return Status;
489+
}
490+
491+
return ParserResult<ImplementsAttr>(
492+
ImplementsAttr::create(Context, AtLoc, SourceRange(Loc, rParenLoc),
493+
ProtocolType.get(), MemberName, MemberNameLoc));
494+
}
495+
440496
bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
441497
DeclAttrKind DK) {
442498
// Ok, it is a valid attribute, eat it, and then process it.
@@ -1258,6 +1314,14 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
12581314
Attributes.add(Attr);
12591315
break;
12601316
}
1317+
1318+
case DAK_Implements: {
1319+
ParserResult<ImplementsAttr> Attr = parseImplementsAttribute(AtLoc, Loc);
1320+
if (Attr.isNonNull()) {
1321+
Attributes.add(Attr.get());
1322+
}
1323+
break;
1324+
}
12611325
}
12621326

12631327
if (DuplicateAttribute) {

0 commit comments

Comments
 (0)