Correct The Parsing of Primary Associated Type Clauses in Protocols

The prior syntax tree did not take into account that the clause itself should own the angle brackets.
This commit is contained in:
Robert Widmann
2022-03-16 17:28:45 -07:00
parent 377cdc16b2
commit cc0bc22dcb
6 changed files with 78 additions and 12 deletions

View File

@@ -1194,6 +1194,8 @@ public:
ParserStatus parsePrimaryAssociatedTypes(
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes);
ParserStatus parsePrimaryAssociatedTypeList(
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes);
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
DeclAttributes &Attributes);

View File

@@ -7905,8 +7905,30 @@ ParserResult<ClassDecl> Parser::parseDeclClass(ParseDeclOptions Flags,
ParserStatus Parser::parsePrimaryAssociatedTypes(
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes) {
SyntaxParsingContext GPSContext(SyntaxContext,
SyntaxKind::PrimaryAssociatedTypeClause);
SourceLoc LAngleLoc = consumeStartingLess();
auto Result = parsePrimaryAssociatedTypeList(AssocTypes);
// Parse the closing '>'.
SourceLoc RAngleLoc;
if (startsWithGreater(Tok)) {
RAngleLoc = consumeStartingGreater();
} else {
diagnose(Tok, diag::expected_rangle_primary_associated_type_list);
diagnose(LAngleLoc, diag::opening_angle);
// Skip until we hit the '>'.
RAngleLoc = skipUntilGreaterInTypeList();
}
return Result;
}
ParserStatus Parser::parsePrimaryAssociatedTypeList(
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes) {
ParserStatus Result;
SyntaxParsingContext PATContext(SyntaxContext,
SyntaxKind::PrimaryAssociatedTypeList);
@@ -7988,18 +8010,6 @@ ParserStatus Parser::parsePrimaryAssociatedTypes(
HasNextParam = consumeIf(tok::comma);
} while (HasNextParam);
// Parse the closing '>'.
SourceLoc RAngleLoc;
if (startsWithGreater(Tok)) {
RAngleLoc = consumeStartingGreater();
} else {
diagnose(Tok, diag::expected_rangle_primary_associated_type_list);
diagnose(LAngleLoc, diag::opening_angle);
// Skip until we hit the '>'.
RAngleLoc = skipUntilGreaterInTypeList();
}
return Result;
}

View File

@@ -633,3 +633,44 @@ TEST(DeclSyntaxTests, FunctionDeclWithAPIs) {
TEST(DeclSyntaxTests, FunctionDeclBuilderAPIs) {
}
#pragma mark - parameterized protocol-decl
TEST(DeclSyntaxTests, ProtocolMakeAPIs) {
RC<SyntaxArena> Arena = SyntaxArena::make();
SyntaxFactory Factory(Arena);
{
SmallString<1> Scratch;
llvm::raw_svector_ostream OS(Scratch);
Factory.makeBlankProtocolDecl().print(OS);
ASSERT_EQ(OS.str().str(), "");
}
{
SmallString<64> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto Protocol = Factory.makeProtocolKeyword("", " ");
auto MyCollection = Factory.makeIdentifier("MyCollection", "", "");
auto ElementName = Factory.makeIdentifier("Element", "", "");
auto ElementParam =
Factory.makePrimaryAssociatedType(None, ElementName, None, None, None, None);
auto LeftAngle = Factory.makeLeftAngleToken("", "");
auto RightAngle = Factory.makeRightAngleToken("", " ");
auto PrimaryAssocs = PrimaryAssociatedTypeClauseSyntaxBuilder(Arena)
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(RightAngle)
.addPrimaryAssociatedType(ElementParam)
.build();
auto LeftBrace = Factory.makeLeftBraceToken("", "");
auto RightBrace = Factory.makeRightBraceToken("", "");
auto Members = MemberDeclBlockSyntaxBuilder(Arena)
.useLeftBrace(LeftBrace)
.useRightBrace(RightBrace)
.build();
Factory
.makeProtocolDecl(None, None, Protocol, MyCollection, PrimaryAssocs, None, None, Members)
.print(OS);
ASSERT_EQ(OS.str().str(),
"protocol MyCollection<Element> {}");
}
}

View File

@@ -257,6 +257,9 @@ DECL_NODES = [
collection_element_name='Modifier', is_optional=True),
Child('ProtocolKeyword', kind='ProtocolToken'),
Child('Identifier', kind='IdentifierToken'),
Child('PrimaryAssociatedTypeClause',
kind='PrimaryAssociatedTypeClause',
is_optional=True),
Child('InheritanceClause', kind='TypeInheritanceClause',
is_optional=True),
Child('GenericWhereClause', kind='GenericWhereClause',

View File

@@ -101,4 +101,13 @@ GENERIC_NODES = [
Child('Colon', kind='ColonToken'),
Child('RightTypeIdentifier', kind='Type'),
]),
# primary-associated-type-clause -> '<' primary-associated-type-list '>'
Node('PrimaryAssociatedTypeClause', kind='Syntax',
children=[
Child('LeftAngleBracket', kind='LeftAngleToken'),
Child('PrimaryAssociatedTypeList', kind='PrimaryAssociatedTypeList',
collection_element_name='PrimaryAssociatedType'),
Child('RightAngleBracket', kind='RightAngleToken'),
]),
]

View File

@@ -257,6 +257,7 @@ SYNTAX_NODE_SERIALIZATION_CODES = {
'RegexLiteralExpr': 253,
'PrimaryAssociatedTypeList' : 254,
'PrimaryAssociatedType' : 255,
'PrimaryAssociatedTypeClause' : 256,
}