Skip to content

[Syntax] Parse: add support for TupleType and FunctionType #13412

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 14, 2017

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented Dec 13, 2017

For now, using SyntaxParsingContext.
CC: @nkcsgexi

@rintaro
Copy link
Member Author

rintaro commented Dec 13, 2017

@swift-ci Please smoke test

Child('Comma', kind='CommaToken',
is_optional=True),
Child('LeftParen', kind='LeftParenToken'),
Child('Arguments', kind='TupleTypeElementList'),
Copy link
Member Author

@rintaro rintaro Dec 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I declared rich TupleTypeElement, use TupleTypeElementList here instead of FunctionTypeArgumentList.
Removed FunctionTypeArgument(List)

@@ -215,6 +215,10 @@ SyntaxFactory::getUnknownKind(SyntaxKind Kind) {
% Result = 'SyntaxKind::UnknownDecl'
% elif node.syntax_kind.endswith('Token'):
% Result = 'SyntaxKind::UnknownToken'
% elif node.syntax_kind.endswith('Type'):
% Result = 'SyntaxKind::UnknownType'
% elif node.syntax_kind.endswith('Pattern'):
Copy link
Member Author

@rintaro rintaro Dec 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use isTypeKind(Kind) API et al here (instead of name based heuristics).
E.g. SimpleTypeIdentifier is Type kind.
TODO for follow up PR.

Copy link
Contributor

@nkcsgexi nkcsgexi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor comments/questions inline.

@@ -925,6 +926,7 @@ ParserResult<TupleTypeRepr> Parser::parseTypeTupleBody() {
// Parse '= expr' here so we can complain about it directly, rather
// than dying when we see it.
if (Tok.is(tok::equal)) {
SyntaxParsingContext InitContext(SyntaxContext, SyntaxKind::Initializer);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are using Initializer, can we refactor the part in FunctionParameter to initializer too? they are now equal+expr.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing. I'll do that in follow up PR 👍

}
}

if (isFunctionType)
SyntaxContext->setTransparent();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you clarify why do we need this? If a FunctionType node is already created, the parent context will do nothing if the FunctionType is the only node. setTransparent will disallow the creation of an UnknownType wrapper if there are other nodes; is this why we need it here?

Copy link
Member Author

@rintaro rintaro Dec 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The structure here is something like this:

func parseTypeTupleBody() {
  SyntaxContextRAII(SyntaxContext)
  consumeToken(tok::l_paren) // '('
  parseTupleTypeElementList() // tuple-type-element-list
  consumeToken(tok::r_paren) // ')'
   
  isFunctionType = tok.isAny(tok::arrow, tok::throws)
  if isFunctionType {
    // propagate to the parent stack.
    SyntaxContext.setTransparent()
  } else {
    //  '(' tuple-type-element-list ')'
    SyntaxContext.setCreate(SyntaxKind::TupleType)
  }
}

func parseType() {
  SyntaxContextRAII(SyntaxContext)
  parseTypeTupleBody()
   
  isFunctionType = tok.isAny(tok::arrow, tok::throws)
  if (isFunctionType) {
    consumeIf(tok::kw_throws) // 'throws'
    consumeToken(tok::arrow) // '->'
    parseType() // return type

    // '(' tuple-type-element-list ')' 'throws'? '->' type
    Context.setCreateType(SyntaxKind::FunctionType)
  } else {
    // type | unknown-type 
    Context.setCoerce(ContextKind::Type)
  }
}

If we see -> or throws after r_paren, we have to propagate '(' tuple-type-element-list ')' part back to parseType()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Thank you for explaining! could we add some comments there to keep track of this scope-misalignment?

Copy link
Contributor

@nkcsgexi nkcsgexi Dec 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking a little bit more about this, how about we make the first three children of a FunctionType a TupleType? This allows us to get rid of setTransparent and to simplify the structure of FunctionType.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, although that's convenient solution for now, I'd like to avoid that because it's against @CodaFi's efforts of re-modeling function type parameters.
How about to parse just TypeTuple in parseTypeTupleBody, then decompose it to '(' TupleTypeElementList ')' and repack into FunctionType in parseType?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that'll add another operation (decompose) to SyntaxParsingContext, right? If changing function type's structure isn't a good option, i'd say what you have for now is good enough.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that'll add another operation (decompose) to SyntaxParsingContext, right?

Not really. We can SyntaxParsingContext::popIf(), build FunctionType with FunctionTypeSyntaxBuilder, then SyntaxParsingContext::addSyntax().

@rintaro
Copy link
Member Author

rintaro commented Dec 14, 2017

@swift-ci Please smoke test

@rintaro rintaro merged commit e618ae5 into swiftlang:master Dec 14, 2017
@rintaro rintaro deleted the syntax-type-tuple branch December 14, 2017 08:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants