Skip to content

Commit e618ae5

Browse files
authored
Merge pull request #13412 from rintaro/syntax-type-tuple
[Syntax] Parse: add support for TupleType and FunctionType
2 parents d2aa82d + fc5f31c commit e618ae5

File tree

10 files changed

+159
-142
lines changed

10 files changed

+159
-142
lines changed

include/swift/Syntax/SyntaxBuilders.h.gyb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ class ${node.name}Builder {
3838

3939
public:
4040
% for child in node.children:
41+
${node.name}Builder &use${child.name}(${child.type_name} ${child.name});
4142
% child_node = NODE_MAP.get(child.syntax_kind)
4243
% if child_node and child_node.is_syntax_collection():
4344
% child_elt = child_node.collection_element_name
4445
% child_elt_type = child_node.collection_element_type
4546
${node.name}Builder &add${child_elt}(${child_elt_type} ${child_elt});
46-
% else:
47-
${node.name}Builder &use${child.name}(${child.type_name} ${child.name});
4847
% end
4948
% end
5049

lib/Parse/ParseType.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,8 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
427427
diag::rethrowing_function_type : diag::throw_in_function_type;
428428
diagnose(Tok.getLoc(), DiagID)
429429
.fixItReplace(Tok.getLoc(), "throws");
430+
if (Tok.is(tok::kw_throw))
431+
Tok.setKind(tok::kw_throws);
430432
}
431433
throwsLoc = consumeToken();
432434
}
@@ -440,6 +442,27 @@ ParserResult<TypeRepr> Parser::parseType(Diag<> MessageID,
440442
return makeParserCodeCompletionResult<TypeRepr>();
441443
if (SecondHalf.isNull())
442444
return nullptr;
445+
446+
if (SyntaxContext->isEnabled()) {
447+
FunctionTypeSyntaxBuilder Builder;
448+
Builder.useReturnType(SyntaxContext->popIf<TypeSyntax>().getValue());
449+
Builder.useArrow(SyntaxContext->popToken());
450+
if (throwsLoc.isValid())
451+
Builder.useThrowsOrRethrowsKeyword(SyntaxContext->popToken());
452+
453+
auto InputNode = SyntaxContext->popIf<TypeSyntax>().getValue();
454+
if (auto TupleTypeNode = InputNode.getAs<TupleTypeSyntax>()) {
455+
// Decompose TupleTypeSyntax and repack into FunctionType.
456+
Builder
457+
.useLeftParen(TupleTypeNode->getLeftParen())
458+
.useArguments(TupleTypeNode->getElements())
459+
.useRightParen(TupleTypeNode->getRightParen());
460+
} else {
461+
Builder
462+
.addTupleTypeElement(SyntaxFactory::makeTupleTypeElement(InputNode));
463+
}
464+
SyntaxContext->addSyntax(Builder.build());
465+
}
443466
tyR = new (Context) FunctionTypeRepr(generics, tyR, throwsLoc, arrowLoc,
444467
SecondHalf.get());
445468
} else if (generics) {
@@ -719,7 +742,6 @@ Parser::parseAnyType() {
719742
/// type-identifier
720743
/// type-composition-list-deprecated ',' type-identifier
721744
ParserResult<TypeRepr> Parser::parseOldStyleProtocolComposition() {
722-
SyntaxParsingContext TypeContext(SyntaxContext, SyntaxContextKind::Type);
723745
assert(Tok.is(tok::kw_protocol) && startsWithLess(peekToken()));
724746

725747
// Start a context for creating type syntax.
@@ -829,7 +851,7 @@ ParserResult<TypeRepr> Parser::parseOldStyleProtocolComposition() {
829851
/// identifier ':' type
830852
/// type
831853
ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
832-
SyntaxParsingContext TypeContext(SyntaxContext, SyntaxContextKind::Type);
854+
SyntaxParsingContext TypeContext(SyntaxContext, SyntaxKind::TupleType);
833855
Parser::StructureMarkerRAII ParsingTypeTuple(*this, Tok);
834856
SourceLoc RPLoc, LPLoc = consumeToken(tok::l_paren);
835857
SourceLoc EllipsisLoc;
@@ -839,7 +861,7 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
839861
ParserStatus Status = parseList(tok::r_paren, LPLoc, RPLoc,
840862
/*AllowSepAfterLast=*/false,
841863
diag::expected_rparen_tuple_type_list,
842-
SyntaxKind::Unknown,
864+
SyntaxKind::TupleTypeElementList,
843865
[&] () -> ParserStatus {
844866
TupleTypeReprElement element;
845867

@@ -877,8 +899,9 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
877899
// Consume the ':'.
878900
if (!consumeIf(tok::colon, element.ColonLoc))
879901
diagnose(Tok, diag::expected_parameter_colon);
902+
880903
} else if (Backtracking) {
881-
// If we don't have labels, 'inout' is not a deprecated use.
904+
// If we don't have labels, 'inout' is not a obsoleted use.
882905
ObsoletedInOutLoc = SourceLoc();
883906
}
884907
Backtracking.reset();
@@ -925,6 +948,7 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
925948
// Parse '= expr' here so we can complain about it directly, rather
926949
// than dying when we see it.
927950
if (Tok.is(tok::equal)) {
951+
SyntaxParsingContext InitContext(SyntaxContext, SyntaxKind::Initializer);
928952
SourceLoc equalLoc = consumeToken(tok::equal);
929953
auto init = parseExpr(diag::expected_init_value);
930954
auto inFlight = diagnose(equalLoc, diag::tuple_type_init);
@@ -943,12 +967,11 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
943967
if (EllipsisLoc.isInvalid())
944968
EllipsisIdx = ElementsR.size();
945969

946-
// If there were any labels, figure out which labels should go into the type
947-
// representation.
948-
949970
bool isFunctionType = Tok.isAny(tok::arrow, tok::kw_throws,
950971
tok::kw_rethrows);
951972

973+
// If there were any labels, figure out which labels should go into the type
974+
// representation.
952975
for (auto &element : ElementsR) {
953976
// True tuples have labels.
954977
if (!isFunctionType) {
@@ -981,11 +1004,11 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
9811004
diag.fixItReplace(SourceRange(element.NameLoc), "_");
9821005
}
9831006

984-
if (element.NameLoc.isValid() || element.SecondNameLoc.isValid()) {
1007+
if (element.SecondNameLoc.isValid()) {
9851008
// Form the named parameter type representation.
1009+
element.UnderscoreLoc = element.NameLoc;
9861010
element.Name = element.SecondName;
9871011
element.NameLoc = element.SecondNameLoc;
988-
element.UnderscoreLoc = element.NameLoc;
9891012
}
9901013
}
9911014

lib/Parse/Parser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,8 @@ static SyntaxKind getListElementKind(SyntaxKind ListKind) {
843843
return SyntaxKind::TupleElement;
844844
case SyntaxKind::FunctionParameterList:
845845
return SyntaxKind::FunctionParameter;
846+
case SyntaxKind::TupleTypeElementList:
847+
return SyntaxKind::TupleTypeElement;
846848
default:
847849
return SyntaxKind::Unknown;
848850
}
@@ -858,6 +860,7 @@ Parser::parseList(tok RightK, SourceLoc LeftLoc, SourceLoc &RightLoc,
858860
SyntaxKind ElementKind = getListElementKind(Kind);
859861

860862
if (Tok.is(RightK)) {
863+
ListContext.reset();
861864
RightLoc = consumeToken(RightK);
862865
return makeParserSuccess();
863866
}

lib/Syntax/SyntaxBuilders.cpp.gyb

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ using namespace swift::syntax;
2828
% for node in SYNTAX_NODES:
2929
% if node.is_buildable():
3030
% for child in node.children:
31+
${node.name}Builder &
32+
${node.name}Builder::use${child.name}(${child.type_name} ${child.name}) {
33+
Layout[cursorIndex(${node.name}::Cursor::${child.name})] =
34+
${child.name}.getRaw();
35+
return *this;
36+
}
3137
% child_node = NODE_MAP.get(child.syntax_kind)
3238
% if child_node and child_node.is_syntax_collection():
3339
% child_elt = child_node.collection_element_name
@@ -38,13 +44,6 @@ ${node.name}Builder::add${child_elt}(${child_elt_type} ${child_elt}) {
3844
raw = raw->append(${child_elt}.getRaw());
3945
return *this;
4046
}
41-
% else:
42-
${node.name}Builder &
43-
${node.name}Builder::use${child.name}(${child.type_name} ${child.name}) {
44-
Layout[cursorIndex(${node.name}::Cursor::${child.name})] =
45-
${child.name}.getRaw();
46-
return *this;
47-
}
4847
% end
4948
% end
5049
${node.name}
@@ -55,4 +54,4 @@ ${node.name}Builder::build() {
5554
}
5655

5756
% end
58-
% end
57+
% end

lib/Syntax/SyntaxFactory.cpp.gyb

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,10 @@ SyntaxFactory::getUnknownKind(SyntaxKind Kind) {
215215
% Result = 'SyntaxKind::UnknownDecl'
216216
% elif node.syntax_kind.endswith('Token'):
217217
% Result = 'SyntaxKind::UnknownToken'
218+
% elif node.syntax_kind.endswith('Type'):
219+
% Result = 'SyntaxKind::UnknownType'
220+
% elif node.syntax_kind.endswith('Pattern'):
221+
% Result = 'SyntaxKind::UnknownPattern'
218222
% else:
219223
% Result = 'SyntaxKind::Unknown'
220224
% end
@@ -307,17 +311,20 @@ TupleTypeSyntax SyntaxFactory::makeVoidTupleType() {
307311
makeRightParenToken({}, {}));
308312
}
309313

310-
TupleTypeElementSyntax SyntaxFactory::makeTupleTypeElement(
311-
llvm::Optional<TokenSyntax> Label,
312-
llvm::Optional<TokenSyntax> Colon, TypeSyntax Type,
313-
llvm::Optional<TokenSyntax> TrailingComma) {
314-
auto annotation = makeTypeAnnotation(makeBlankAttributeList(), None, Type);
315-
return makeTupleTypeElement(Label, Colon, annotation, TrailingComma);
314+
TupleTypeElementSyntax
315+
SyntaxFactory::makeTupleTypeElement(llvm::Optional<TokenSyntax> Label,
316+
llvm::Optional<TokenSyntax> Colon,
317+
TypeSyntax Type,
318+
llvm::Optional<TokenSyntax> TrailingComma) {
319+
return makeTupleTypeElement(None, Label, None, Colon, Type, None, None,
320+
TrailingComma);
316321
}
317322

318-
TupleTypeElementSyntax SyntaxFactory::makeTupleTypeElement(TypeSyntax Type,
319-
llvm::Optional<TokenSyntax> TrailingComma) {
320-
return makeTupleTypeElement(None, None, Type, TrailingComma);
323+
TupleTypeElementSyntax
324+
SyntaxFactory::makeTupleTypeElement(TypeSyntax Type,
325+
llvm::Optional<TokenSyntax> TrailingComma) {
326+
return makeTupleTypeElement(None, None, None, None, Type, None, None,
327+
TrailingComma);
321328
}
322329

323330
GenericParameterSyntax

test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ class C {<FunctionDecl>
6060
}
6161

6262
typealias A = <SimpleTypeIdentifier>Any</SimpleTypeIdentifier>
63-
typealias B = (<MemberTypeIdentifier><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Any</SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier>.Element</MemberTypeIdentifier>)
63+
typealias B = <TupleType>(<TupleTypeElement><MemberTypeIdentifier><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Array<GenericArgumentClause><<GenericArgument><SimpleTypeIdentifier>Any</SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier></GenericArgument>></GenericArgumentClause></SimpleTypeIdentifier>.Element</MemberTypeIdentifier>, </TupleTypeElement><TupleTypeElement>x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier></TupleTypeElement>)</TupleType>
6464
typealias C = <ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>]</ArrayType>
6565
typealias D = <DictionaryType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>: <SimpleTypeIdentifier>String</SimpleTypeIdentifier>]</DictionaryType>
6666
typealias E = <MetatypeType><OptionalType><SimpleTypeIdentifier>Int</SimpleTypeIdentifier>?</OptionalType>.Protocol</MetatypeType>
67-
typealias F = <MetatypeType><ImplicitlyUnwrappedOptionalType><ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>]</ArrayType>!</ImplicitlyUnwrappedOptionalType>.Type</MetatypeType><StructDecl>
67+
typealias F = <MetatypeType><ImplicitlyUnwrappedOptionalType><ArrayType>[<SimpleTypeIdentifier>Int</SimpleTypeIdentifier>]</ArrayType>!</ImplicitlyUnwrappedOptionalType>.Type</MetatypeType>
68+
typealias G = <FunctionType>(<TupleTypeElement>a x: <SimpleTypeIdentifier>Int</SimpleTypeIdentifier>, </TupleTypeElement><TupleTypeElement>_ y: <SimpleTypeIdentifier>Int </SimpleTypeIdentifier>... <Initializer>= <IntegerLiteralExpr>1</IntegerLiteralExpr></Initializer></TupleTypeElement>) throw -> <FunctionType>() -> <TupleType>()</TupleType></FunctionType></FunctionType>
69+
typealias H = <FunctionType>() rethrows -> <TupleType>()</TupleType></FunctionType><StructDecl>
6870

6971
struct foo <MemberDeclBlock>{<StructDecl>
7072
struct foo <MemberDeclBlock>{<StructDecl>

test/Syntax/round_trip_parse_gen.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,13 @@ class C {
6060
}
6161

6262
typealias A = Any
63-
typealias B = (Array<Array<Any>>.Element)
63+
typealias B = (Array<Array<Any>>.Element, x: Int)
6464
typealias C = [Int]
6565
typealias D = [Int: String]
6666
typealias E = Int?.Protocol
6767
typealias F = [Int]!.Type
68+
typealias G = (a x: Int, _ y: Int ... = 1) throw -> () -> ()
69+
typealias H = () rethrows -> ()
6870

6971
struct foo {
7072
struct foo {

tools/SwiftSyntax/SyntaxFactory.swift.gyb

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -120,21 +120,18 @@ public enum SyntaxFactory {
120120
rightParen: makeRightParenToken())
121121
}
122122

123-
public static func makeTupleTypeElement(label: TokenSyntax?,
123+
public static func makeTupleTypeElement(name: TokenSyntax?,
124124
colon: TokenSyntax?, type: TypeSyntax,
125-
comma: TokenSyntax?) -> TupleTypeElementSyntax {
126-
let annotation = makeTypeAnnotation(attributes: makeBlankAttributeList(),
127-
inOutKeyword: nil,
128-
type: type)
129-
return makeTupleTypeElement(label: label, colon: colon,
130-
typeAnnotation: annotation,
131-
comma: comma)
125+
trailingComma: TokenSyntax?) -> TupleTypeElementSyntax {
126+
return makeTupleTypeElement(inOut: nil, name: name, secondName: nil,
127+
colon: colon, type: type, ellipsis: nil,
128+
initializer: nil, trailingComma: trailingComma)
132129
}
133130

134131
public static func makeTupleTypeElement(type: TypeSyntax,
135-
comma: TokenSyntax?) -> TupleTypeElementSyntax {
136-
return makeTupleTypeElement(label: nil, colon: nil,
137-
type: type, comma: comma)
132+
trailingComma: TokenSyntax?) -> TupleTypeElementSyntax {
133+
return makeTupleTypeElement(name: nil, colon: nil,
134+
type: type, trailingComma: trailingComma)
138135
}
139136

140137
public static func makeGenericParameter(name: TokenSyntax,

0 commit comments

Comments
 (0)