mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
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:
@@ -1194,6 +1194,8 @@ public:
|
||||
|
||||
ParserStatus parsePrimaryAssociatedTypes(
|
||||
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes);
|
||||
ParserStatus parsePrimaryAssociatedTypeList(
|
||||
SmallVectorImpl<AssociatedTypeDecl *> &AssocTypes);
|
||||
ParserResult<ProtocolDecl> parseDeclProtocol(ParseDeclOptions Flags,
|
||||
DeclAttributes &Attributes);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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> {}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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'),
|
||||
]),
|
||||
]
|
||||
|
||||
@@ -257,6 +257,7 @@ SYNTAX_NODE_SERIALIZATION_CODES = {
|
||||
'RegexLiteralExpr': 253,
|
||||
'PrimaryAssociatedTypeList' : 254,
|
||||
'PrimaryAssociatedType' : 255,
|
||||
'PrimaryAssociatedTypeClause' : 256,
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user