-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[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
Conversation
@swift-ci Please smoke test |
Child('Comma', kind='CommaToken', | ||
is_optional=True), | ||
Child('LeftParen', kind='LeftParenToken'), | ||
Child('Arguments', kind='TupleTypeElementList'), |
There was a problem hiding this comment.
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'): |
There was a problem hiding this comment.
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.
There was a problem hiding this 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); |
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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 👍
lib/Parse/ParseType.cpp
Outdated
} | ||
} | ||
|
||
if (isFunctionType) | ||
SyntaxContext->setTransparent(); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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()
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()
.
For now using SyntaxParsingContext.
35f189b
to
fc5f31c
Compare
@swift-ci Please smoke test |
For now, using
SyntaxParsingContext
.CC: @nkcsgexi