[parser] Parse record type return type for operators

Change-Id: I23b5ef38a9bfd58c327303198e59d9b50ace323b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262681
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Jens Johansen 2022-10-07 08:59:39 +00:00 committed by Commit Queue
parent 575ae24207
commit 97cdb043da
6 changed files with 437 additions and 0 deletions

View file

@ -736,6 +736,10 @@ class ComplexTypeInfo implements TypeInfo {
// TODO(jensj): A setter would need parenthesis so technically
// couldn't look like this, but I don't think any other valid thing
// could either. Should we handle that specifically?
} else if (optional("operator", next) &&
afterIdentifier.isUserDefinableOperator) {
// E.g.
// `(int, int) operator [](int foo) {}`
} else {
// This could for instance be `(int x, int y) async {`.
return noType;

View file

@ -0,0 +1,11 @@
class Foo {
(int, int) operator [](int foo) {
return (42, 42);
}
}
class Bar {
(int, int)? operator [](int bar) {
return (42, 42);
}
}

View file

@ -0,0 +1,126 @@
beginCompilationUnit(class)
beginMetadataStar(class)
endMetadataStar(0)
beginClassOrMixinOrNamedMixinApplicationPrelude(class)
handleIdentifier(Foo, classOrMixinDeclaration)
handleNoTypeVariables({)
beginClassDeclaration(class, null, null, null, Foo)
handleNoType(Foo)
handleClassExtends(null, 1)
handleClassNoWithClause()
handleImplements(null, 0)
handleClassHeader(class, class, null)
beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
beginMetadataStar(()
endMetadataStar(0)
beginMember()
beginMethod(DeclarationKind.Class, null, null, null, null, null, null, operator)
beginRecordType(()
beginRecordTypeEntry()
beginMetadataStar(int)
endMetadataStar(0)
handleIdentifier(int, typeReference)
handleNoTypeArguments(,)
handleType(int, null)
handleNoName(,)
endRecordTypeEntry()
beginRecordTypeEntry()
beginMetadataStar(int)
endMetadataStar(0)
handleIdentifier(int, typeReference)
handleNoTypeArguments())
handleType(int, null)
handleNoName())
endRecordTypeEntry()
endRecordType((, null, 2, false)
handleOperatorName(operator, [])
handleNoTypeVariables(()
beginFormalParameters((, MemberKind.NonStaticMethod)
beginMetadataStar(int)
endMetadataStar(0)
beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
handleIdentifier(int, typeReference)
handleNoTypeArguments(foo)
handleType(int, null)
handleIdentifier(foo, formalParameterDeclaration)
handleFormalParameterWithoutValue())
endFormalParameter(null, null, null, foo, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
handleNoInitializers()
handleAsyncModifier(null, null)
beginBlockFunctionBody({)
beginReturnStatement(return)
beginParenthesizedExpressionOrRecordLiteral(()
handleLiteralInt(42)
handleLiteralInt(42)
endRecordLiteral((, 2, null)
endReturnStatement(true, return, ;)
endBlockFunctionBody(1, {, })
endClassMethod(null, (, (, null, })
endMember()
endClassOrMixinOrExtensionBody(DeclarationKind.Class, 1, {, })
endClassDeclaration(class, })
endTopLevelDeclaration(class)
beginMetadataStar(class)
endMetadataStar(0)
beginClassOrMixinOrNamedMixinApplicationPrelude(class)
handleIdentifier(Bar, classOrMixinDeclaration)
handleNoTypeVariables({)
beginClassDeclaration(class, null, null, null, Bar)
handleNoType(Bar)
handleClassExtends(null, 1)
handleClassNoWithClause()
handleImplements(null, 0)
handleClassHeader(class, class, null)
beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
beginMetadataStar(()
endMetadataStar(0)
beginMember()
beginMethod(DeclarationKind.Class, null, null, null, null, null, null, operator)
beginRecordType(()
beginRecordTypeEntry()
beginMetadataStar(int)
endMetadataStar(0)
handleIdentifier(int, typeReference)
handleNoTypeArguments(,)
handleType(int, null)
handleNoName(,)
endRecordTypeEntry()
beginRecordTypeEntry()
beginMetadataStar(int)
endMetadataStar(0)
handleIdentifier(int, typeReference)
handleNoTypeArguments())
handleType(int, null)
handleNoName())
endRecordTypeEntry()
endRecordType((, ?, 2, false)
handleOperatorName(operator, [])
handleNoTypeVariables(()
beginFormalParameters((, MemberKind.NonStaticMethod)
beginMetadataStar(int)
endMetadataStar(0)
beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
handleIdentifier(int, typeReference)
handleNoTypeArguments(bar)
handleType(int, null)
handleIdentifier(bar, formalParameterDeclaration)
handleFormalParameterWithoutValue())
endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
handleNoInitializers()
handleAsyncModifier(null, null)
beginBlockFunctionBody({)
beginReturnStatement(return)
beginParenthesizedExpressionOrRecordLiteral(()
handleLiteralInt(42)
handleLiteralInt(42)
endRecordLiteral((, 2, null)
endReturnStatement(true, return, ;)
endBlockFunctionBody(1, {, })
endClassMethod(null, (, (, null, })
endMember()
endClassOrMixinOrExtensionBody(DeclarationKind.Class, 1, {, })
endClassDeclaration(class, })
endTopLevelDeclaration()
endCompilationUnit(2, )

View file

@ -0,0 +1,246 @@
parseUnit(class)
skipErrorTokens(class)
listener: beginCompilationUnit(class)
syntheticPreviousToken(class)
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
parseMetadataStar()
listener: beginMetadataStar(class)
listener: endMetadataStar(0)
parseTopLevelKeywordDeclaration(, class, null, Instance of 'DirectiveContext')
parseClassOrNamedMixinApplication(null, null, null, class)
listener: beginClassOrMixinOrNamedMixinApplicationPrelude(class)
ensureIdentifier(class, classOrMixinDeclaration)
listener: handleIdentifier(Foo, classOrMixinDeclaration)
listener: handleNoTypeVariables({)
listener: beginClassDeclaration(class, null, null, null, Foo)
parseClass(Foo, class, class, Foo)
parseClassHeaderOpt(Foo, class, class)
parseClassExtendsOpt(Foo)
listener: handleNoType(Foo)
listener: handleClassExtends(null, 1)
parseClassWithClauseOpt(Foo)
listener: handleClassNoWithClause()
parseClassOrMixinOrEnumImplementsOpt(Foo)
listener: handleImplements(null, 0)
listener: handleClassHeader(class, class, null)
parseClassOrMixinOrExtensionBody(Foo, DeclarationKind.Class, Foo)
listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
notEofOrValue(}, ()
parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Foo)
parseMetadataStar({)
listener: beginMetadataStar(()
listener: endMetadataStar(0)
listener: beginMember()
parseMethod({, null, null, null, null, null, null, null, {, Instance of 'ComplexTypeInfo', null, operator, DeclarationKind.Class, Foo, false)
listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, operator)
parseRecordType((, {)
listener: beginRecordType(()
parseRecordTypeField((, identifierIsOptional: true)
listener: beginRecordTypeEntry()
parseMetadataStar(()
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments(,)
listener: handleType(int, null)
listener: handleNoName(,)
listener: endRecordTypeEntry()
parseRecordTypeField(,, identifierIsOptional: true)
listener: beginRecordTypeEntry()
parseMetadataStar(,)
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments())
listener: handleType(int, null)
listener: handleNoName())
listener: endRecordTypeEntry()
listener: endRecordType((, null, 2, false)
parseOperatorName())
listener: handleOperatorName(operator, [])
parseMethodTypeVar([])
listener: handleNoTypeVariables(()
parseGetterOrFormalParameters([], operator, false, MemberKind.NonStaticMethod)
parseFormalParameters([], MemberKind.NonStaticMethod)
parseFormalParametersRest((, MemberKind.NonStaticMethod)
listener: beginFormalParameters((, MemberKind.NonStaticMethod)
parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
parseMetadataStar(()
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments(foo)
listener: handleType(int, null)
ensureIdentifier(int, formalParameterDeclaration)
listener: handleIdentifier(foo, formalParameterDeclaration)
listener: handleFormalParameterWithoutValue())
listener: endFormalParameter(null, null, null, foo, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
parseInitializersOpt())
listener: handleNoInitializers()
parseAsyncModifierOpt())
listener: handleAsyncModifier(null, null)
inPlainSync()
inPlainSync()
parseFunctionBody(), false, true)
listener: beginBlockFunctionBody({)
notEofOrValue(}, return)
parseStatement({)
parseStatementX({)
parseReturnStatement({)
listener: beginReturnStatement(return)
parseExpression(return)
parsePrecedenceExpression(return, 1, true)
parseUnaryExpression(return, true)
parsePrimary(return, expression)
parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
parseParenthesizedExpressionOrRecordLiteral(return, null)
listener: beginParenthesizedExpressionOrRecordLiteral(()
parseExpression(()
parsePrecedenceExpression((, 1, true)
parseUnaryExpression((, true)
parsePrimary((, expression)
parseLiteralInt(()
listener: handleLiteralInt(42)
parseExpression(,)
parsePrecedenceExpression(,, 1, true)
parseUnaryExpression(,, true)
parsePrimary(,, expression)
parseLiteralInt(,)
listener: handleLiteralInt(42)
ensureCloseParen(42, ()
listener: endRecordLiteral((, 2, null)
ensureSemicolon())
listener: endReturnStatement(true, return, ;)
inGenerator()
notEofOrValue(}, })
listener: endBlockFunctionBody(1, {, })
listener: endClassMethod(null, (, (, null, })
listener: endMember()
notEofOrValue(}, })
listener: endClassOrMixinOrExtensionBody(DeclarationKind.Class, 1, {, })
listener: endClassDeclaration(class, })
listener: endTopLevelDeclaration(class)
parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
parseMetadataStar(})
listener: beginMetadataStar(class)
listener: endMetadataStar(0)
parseTopLevelKeywordDeclaration(}, class, null, Instance of 'DirectiveContext')
parseClassOrNamedMixinApplication(null, null, null, class)
listener: beginClassOrMixinOrNamedMixinApplicationPrelude(class)
ensureIdentifier(class, classOrMixinDeclaration)
listener: handleIdentifier(Bar, classOrMixinDeclaration)
listener: handleNoTypeVariables({)
listener: beginClassDeclaration(class, null, null, null, Bar)
parseClass(Bar, class, class, Bar)
parseClassHeaderOpt(Bar, class, class)
parseClassExtendsOpt(Bar)
listener: handleNoType(Bar)
listener: handleClassExtends(null, 1)
parseClassWithClauseOpt(Bar)
listener: handleClassNoWithClause()
parseClassOrMixinOrEnumImplementsOpt(Bar)
listener: handleImplements(null, 0)
listener: handleClassHeader(class, class, null)
parseClassOrMixinOrExtensionBody(Bar, DeclarationKind.Class, Bar)
listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
notEofOrValue(}, ()
parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, Bar)
parseMetadataStar({)
listener: beginMetadataStar(()
listener: endMetadataStar(0)
listener: beginMember()
parseMethod({, null, null, null, null, null, null, null, {, Instance of 'ComplexTypeInfo', null, operator, DeclarationKind.Class, Bar, false)
listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, operator)
parseRecordType((, {)
listener: beginRecordType(()
parseRecordTypeField((, identifierIsOptional: true)
listener: beginRecordTypeEntry()
parseMetadataStar(()
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments(,)
listener: handleType(int, null)
listener: handleNoName(,)
listener: endRecordTypeEntry()
parseRecordTypeField(,, identifierIsOptional: true)
listener: beginRecordTypeEntry()
parseMetadataStar(,)
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments())
listener: handleType(int, null)
listener: handleNoName())
listener: endRecordTypeEntry()
listener: endRecordType((, ?, 2, false)
parseOperatorName(?)
listener: handleOperatorName(operator, [])
parseMethodTypeVar([])
listener: handleNoTypeVariables(()
parseGetterOrFormalParameters([], operator, false, MemberKind.NonStaticMethod)
parseFormalParameters([], MemberKind.NonStaticMethod)
parseFormalParametersRest((, MemberKind.NonStaticMethod)
listener: beginFormalParameters((, MemberKind.NonStaticMethod)
parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
parseMetadataStar(()
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: beginFormalParameter(int, MemberKind.NonStaticMethod, null, null, null)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments(bar)
listener: handleType(int, null)
ensureIdentifier(int, formalParameterDeclaration)
listener: handleIdentifier(bar, formalParameterDeclaration)
listener: handleFormalParameterWithoutValue())
listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
listener: endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
parseInitializersOpt())
listener: handleNoInitializers()
parseAsyncModifierOpt())
listener: handleAsyncModifier(null, null)
inPlainSync()
inPlainSync()
parseFunctionBody(), false, true)
listener: beginBlockFunctionBody({)
notEofOrValue(}, return)
parseStatement({)
parseStatementX({)
parseReturnStatement({)
listener: beginReturnStatement(return)
parseExpression(return)
parsePrecedenceExpression(return, 1, true)
parseUnaryExpression(return, true)
parsePrimary(return, expression)
parseParenthesizedExpressionFunctionLiteralOrRecordLiteral(return)
parseParenthesizedExpressionOrRecordLiteral(return, null)
listener: beginParenthesizedExpressionOrRecordLiteral(()
parseExpression(()
parsePrecedenceExpression((, 1, true)
parseUnaryExpression((, true)
parsePrimary((, expression)
parseLiteralInt(()
listener: handleLiteralInt(42)
parseExpression(,)
parsePrecedenceExpression(,, 1, true)
parseUnaryExpression(,, true)
parsePrimary(,, expression)
parseLiteralInt(,)
listener: handleLiteralInt(42)
ensureCloseParen(42, ()
listener: endRecordLiteral((, 2, null)
ensureSemicolon())
listener: endReturnStatement(true, return, ;)
inGenerator()
notEofOrValue(}, })
listener: endBlockFunctionBody(1, {, })
listener: endClassMethod(null, (, (, null, })
listener: endMember()
notEofOrValue(}, })
listener: endClassOrMixinOrExtensionBody(DeclarationKind.Class, 1, {, })
listener: endClassDeclaration(class, })
listener: endTopLevelDeclaration()
reportAllErrorTokens(class)
listener: endCompilationUnit(2, )

View file

@ -0,0 +1,25 @@
class Foo {
(int, int) operator [](int foo) {
return (42, 42);
}
}
class Bar {
(int, int)? operator [](int bar) {
return (42, 42);
}
}
class[KeywordToken] Foo[StringToken] {[BeginToken]
([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken] operator[KeywordToken] [][SimpleToken]([BeginToken]int[StringToken] foo[StringToken])[SimpleToken] {[BeginToken]
return[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
}[SimpleToken]
}[SimpleToken]
class[KeywordToken] Bar[StringToken] {[BeginToken]
([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]?[SimpleToken] operator[KeywordToken] [][SimpleToken]([BeginToken]int[StringToken] bar[StringToken])[SimpleToken] {[BeginToken]
return[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
}[SimpleToken]
}[SimpleToken]
[SimpleToken]

View file

@ -0,0 +1,25 @@
class Foo {
(int, int) operator [](int foo) {
return (42, 42);
}
}
class Bar {
(int, int)? operator [](int bar) {
return (42, 42);
}
}
class[KeywordToken] Foo[StringToken] {[BeginToken]
([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken] operator[KeywordToken] [][SimpleToken]([BeginToken]int[StringToken] foo[StringToken])[SimpleToken] {[BeginToken]
return[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
}[SimpleToken]
}[SimpleToken]
class[KeywordToken] Bar[StringToken] {[BeginToken]
([BeginToken]int[StringToken],[SimpleToken] int[StringToken])[SimpleToken]?[SimpleToken] operator[KeywordToken] [][SimpleToken]([BeginToken]int[StringToken] bar[StringToken])[SimpleToken] {[BeginToken]
return[KeywordToken] ([BeginToken]42[StringToken],[SimpleToken] 42[StringToken])[SimpleToken];[SimpleToken]
}[SimpleToken]
}[SimpleToken]
[SimpleToken]