Skip to content

Commit

Permalink
Merge pull request #26933 from rintaro/syntaxparse-roundtrip1
Browse files Browse the repository at this point in the history
[SyntaxParse] Fix round-trip issue in function types
  • Loading branch information
rintaro authored Aug 29, 2019
2 parents 3a78945 + 974c9d1 commit 6fcbb40
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
29 changes: 17 additions & 12 deletions lib/Parse/ParseType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ Parser::TypeASTResult Parser::parseType(Diag<> MessageID,
}

if (Tok.is(tok::arrow)) {
auto InputNode = SyntaxContext->popIf<ParsedTypeSyntax>().getValue();
// Handle type-function if we have an arrow.
auto ArrowLoc = Tok.getLoc();
auto Arrow = consumeTokenSyntax();
Expand All @@ -403,23 +404,21 @@ Parser::TypeASTResult Parser::parseType(Diag<> MessageID,
}
ParserResult<TypeRepr> SecondHalf =
parseType(diag::expected_type_function_result);
auto SecondTy = SyntaxContext->popIf<ParsedTypeSyntax>();
if (SecondHalf.isParseError()) {
SyntaxContext->addSyntax(InputNode);
if (Throws)
SyntaxContext->addSyntax(*Throws);
SyntaxContext->addSyntax(Arrow);
if (SecondTy)
SyntaxContext->addSyntax(*SecondTy);
if (SecondHalf.hasCodeCompletion())
return makeParserCodeCompletionResult<TypeRepr>();
if (SecondHalf.isNull())
return nullptr;
}

ParsedFunctionTypeSyntaxBuilder Builder(*SyntaxContext);
Builder.useReturnType(SyntaxContext->popIf<ParsedTypeSyntax>().getValue());
Builder.useArrow(Arrow);
if (Throws)
Builder.useThrowsOrRethrowsKeyword(*Throws);

auto InputNode = SyntaxContext->popIf<ParsedTypeSyntax>().getValue();
bool isVoid = false;
if (auto TupleTypeNode = InputNode.getAs<ParsedTupleTypeSyntax>()) {
// Decompose TupleTypeSyntax and repack into FunctionType.
Expand Down Expand Up @@ -447,6 +446,13 @@ Parser::TypeASTResult Parser::parseType(Diag<> MessageID,
Builder.addArgumentsMember(ParsedSyntaxRecorder::makeTupleTypeElement(
InputNode, /*TrailingComma=*/None, *SyntaxContext));
}

Builder.useReturnType(*SecondTy);
if (Throws)
Builder.useThrowsOrRethrowsKeyword(*Throws);
Builder.useArrow(Arrow);
Builder.useReturnType(*SecondTy);

SyntaxContext->addSyntax(Builder.build());

auto FunctionType = SyntaxContext->topNode<FunctionTypeSyntax>();
Expand Down Expand Up @@ -1107,21 +1113,20 @@ Parser::TypeResult Parser::parseTypeTupleBody() {
// Parse the type annotation.
auto TypeLoc = Tok.getLoc();
auto TypeASTResult = parseType(diag::expected_type);
auto Type = SyntaxContext->popIf<ParsedTypeSyntax>();
if (TypeASTResult.hasCodeCompletion() || TypeASTResult.isNull()) {
Junk.append(LocalJunk.begin(), LocalJunk.end());
if (auto parsedT = SyntaxContext->popIf<ParsedTypeSyntax>())
Junk.push_back(*parsedT);
if (Type)
Junk.push_back(*Type);
skipListUntilDeclRBraceSyntax(Junk, LParenLoc, tok::r_paren, tok::comma);
return TypeASTResult.hasCodeCompletion()
? makeParserCodeCompletionStatus()
: makeParserError();
}

auto Type = *SyntaxContext->popIf<ParsedTypeSyntax>();

if (IsInOutObsoleted) {
bool IsTypeAlreadyAttributed = false;
if (auto AttributedType = Type.getAs<ParsedAttributedTypeSyntax>())
if (auto AttributedType = Type->getAs<ParsedAttributedTypeSyntax>())
IsTypeAlreadyAttributed = AttributedType->getDeferredSpecifier().hasValue();

if (IsTypeAlreadyAttributed) {
Expand Down Expand Up @@ -1167,7 +1172,7 @@ Parser::TypeResult Parser::parseTypeTupleBody() {
Comma = consumeTokenSyntaxIf(tok::comma);

auto Element = ParsedSyntaxRecorder::makeTupleTypeElement(
InOut, Name, SecondName, Colon, Type, ElementEllipsis, Initializer,
InOut, Name, SecondName, Colon, *Type, ElementEllipsis, Initializer,
Comma, *SyntaxContext);

Junk.push_back(Element);
Expand Down
3 changes: 3 additions & 0 deletions test/Syntax/round_trip_misc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ do {
do {
typealias Alias3 = (a b C,
}
do {
typealias Alias3 = () -> @objc func
}

// Orphan '}' at top level
}
Expand Down

0 comments on commit 6fcbb40

Please sign in to comment.