[parser] Field formal parameter with explicit record type

Fixes https://github.com/dart-lang/sdk/issues/50007

Change-Id: I4cce2fd49db9a71b344d5d3e3ea1e0a941a434ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262200
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Jens Johansen <jensj@google.com>
This commit is contained in:
Jens Johansen 2022-10-03 07:14:26 +00:00 committed by Commit Queue
parent 06847c34fb
commit 92b97fe6fb
6 changed files with 264 additions and 0 deletions

View file

@ -737,6 +737,8 @@ class ComplexTypeInfo implements TypeInfo {
return noType;
}
}
} else if (optional("this", next) && optional(".", next.next!)) {
// E.g. C(({int n, String s}) this.x);
} else {
// Is it e.g. List<(int, int)> or Map<(int, int), (String, String)>?
// or List<List<(int, int)>> or List<List<List<(int, int)>>>.

View file

@ -0,0 +1,7 @@
// https://github.com/dart-lang/sdk/issues/50007
class C {
({num n, String s}) x;
C(({int n, String s}) this.x);
}

View file

@ -0,0 +1,85 @@
beginCompilationUnit(class)
beginMetadataStar(class)
endMetadataStar(0)
beginClassOrMixinOrNamedMixinApplicationPrelude(class)
handleIdentifier(C, classOrMixinDeclaration)
handleNoTypeVariables({)
beginClassDeclaration(class, null, null, null, C)
handleNoType(C)
handleClassExtends(null, 1)
handleClassNoWithClause()
handleImplements(null, 0)
handleClassHeader(class, class, null)
beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
beginMetadataStar(()
endMetadataStar(0)
beginMember()
beginFields(DeclarationKind.Class, null, null, null, null, null, null, null, {)
beginRecordType(()
beginRecordTypeNamedFields({)
beginRecordTypeEntry()
beginMetadataStar(num)
endMetadataStar(0)
handleIdentifier(num, typeReference)
handleNoTypeArguments(n)
handleType(num, null)
handleIdentifier(n, recordFieldDeclaration)
endRecordTypeEntry()
beginRecordTypeEntry()
beginMetadataStar(String)
endMetadataStar(0)
handleIdentifier(String, typeReference)
handleNoTypeArguments(s)
handleType(String, null)
handleIdentifier(s, recordFieldDeclaration)
endRecordTypeEntry()
endRecordTypeNamedFields(2, {)
endRecordType((, null, 1, true)
handleIdentifier(x, fieldDeclaration)
handleNoFieldInitializer(;)
endClassFields(null, null, null, null, null, null, null, 1, (, ;)
endMember()
beginMetadataStar(C)
endMetadataStar(0)
beginMember()
beginMethod(DeclarationKind.Class, null, null, null, null, null, null, C)
handleNoType(;)
handleIdentifier(C, methodDeclaration)
handleNoTypeVariables(()
beginFormalParameters((, MemberKind.NonStaticMethod)
beginMetadataStar(()
endMetadataStar(0)
beginFormalParameter((, MemberKind.NonStaticMethod, null, null, null)
beginRecordType(()
beginRecordTypeNamedFields({)
beginRecordTypeEntry()
beginMetadataStar(int)
endMetadataStar(0)
handleIdentifier(int, typeReference)
handleNoTypeArguments(n)
handleType(int, null)
handleIdentifier(n, recordFieldDeclaration)
endRecordTypeEntry()
beginRecordTypeEntry()
beginMetadataStar(String)
endMetadataStar(0)
handleIdentifier(String, typeReference)
handleNoTypeArguments(s)
handleType(String, null)
handleIdentifier(s, recordFieldDeclaration)
endRecordTypeEntry()
endRecordTypeNamedFields(2, {)
endRecordType((, null, 1, true)
handleIdentifier(x, fieldInitializer)
handleFormalParameterWithoutValue())
endFormalParameter(this, null, ., x, null, null, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
endFormalParameters(1, (, ), MemberKind.NonStaticMethod)
handleNoInitializers()
handleAsyncModifier(null, null)
handleEmptyFunctionBody(;)
endClassConstructor(null, C, (, null, ;)
endMember()
endClassOrMixinOrExtensionBody(DeclarationKind.Class, 2, {, })
endClassDeclaration(class, })
endTopLevelDeclaration()
endCompilationUnit(1, )

View file

@ -0,0 +1,144 @@
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(C, classOrMixinDeclaration)
listener: handleNoTypeVariables({)
listener: beginClassDeclaration(class, null, null, null, C)
parseClass(C, class, class, C)
parseClassHeaderOpt(C, class, class)
parseClassExtendsOpt(C)
listener: handleNoType(C)
listener: handleClassExtends(null, 1)
parseClassWithClauseOpt(C)
listener: handleClassNoWithClause()
parseClassOrMixinOrEnumImplementsOpt(C)
listener: handleImplements(null, 0)
listener: handleClassHeader(class, class, null)
parseClassOrMixinOrExtensionBody(C, DeclarationKind.Class, C)
listener: beginClassOrMixinOrExtensionBody(DeclarationKind.Class, {)
notEofOrValue(}, ()
parseClassOrMixinOrExtensionOrEnumMemberImpl({, DeclarationKind.Class, C)
parseMetadataStar({)
listener: beginMetadataStar(()
listener: endMetadataStar(0)
listener: beginMember()
parseFields({, null, null, null, null, null, null, null, {, Instance of 'ComplexTypeInfo', x, DeclarationKind.Class, C, false)
listener: beginFields(DeclarationKind.Class, null, null, null, null, null, null, null, {)
parseRecordType((, {)
listener: beginRecordType(()
parseRecordTypeNamedFields(()
listener: beginRecordTypeNamedFields({)
parseRecordTypeField({, identifierIsOptional: false)
listener: beginRecordTypeEntry()
parseMetadataStar({)
listener: beginMetadataStar(num)
listener: endMetadataStar(0)
listener: handleIdentifier(num, typeReference)
listener: handleNoTypeArguments(n)
listener: handleType(num, null)
ensureIdentifier(num, recordFieldDeclaration)
listener: handleIdentifier(n, recordFieldDeclaration)
listener: endRecordTypeEntry()
parseRecordTypeField(,, identifierIsOptional: false)
listener: beginRecordTypeEntry()
parseMetadataStar(,)
listener: beginMetadataStar(String)
listener: endMetadataStar(0)
listener: handleIdentifier(String, typeReference)
listener: handleNoTypeArguments(s)
listener: handleType(String, null)
ensureIdentifier(String, recordFieldDeclaration)
listener: handleIdentifier(s, recordFieldDeclaration)
listener: endRecordTypeEntry()
listener: endRecordTypeNamedFields(2, {)
ensureCloseParen(}, ()
listener: endRecordType((, null, 1, true)
ensureIdentifierPotentiallyRecovered(), fieldDeclaration, false)
listener: handleIdentifier(x, fieldDeclaration)
parseFieldInitializerOpt(x, x, null, null, null, null, null, DeclarationKind.Class, C)
listener: handleNoFieldInitializer(;)
listener: endClassFields(null, null, null, null, null, null, null, 1, (, ;)
listener: endMember()
notEofOrValue(}, C)
parseClassOrMixinOrExtensionOrEnumMemberImpl(;, DeclarationKind.Class, C)
parseMetadataStar(;)
listener: beginMetadataStar(C)
listener: endMetadataStar(0)
listener: beginMember()
isReservedKeyword(()
parseMethod(;, null, null, null, null, null, null, null, ;, Instance of 'NoType', null, C, DeclarationKind.Class, C, false)
listener: beginMethod(DeclarationKind.Class, null, null, null, null, null, null, C)
listener: handleNoType(;)
ensureIdentifierPotentiallyRecovered(;, methodDeclaration, false)
listener: handleIdentifier(C, methodDeclaration)
parseQualifiedRestOpt(C, methodDeclarationContinuation)
parseMethodTypeVar(C)
listener: handleNoTypeVariables(()
parseGetterOrFormalParameters(C, C, false, MemberKind.NonStaticMethod)
parseFormalParameters(C, MemberKind.NonStaticMethod)
parseFormalParametersRest((, MemberKind.NonStaticMethod)
listener: beginFormalParameters((, MemberKind.NonStaticMethod)
parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.NonStaticMethod)
parseMetadataStar(()
listener: beginMetadataStar(()
listener: endMetadataStar(0)
listener: beginFormalParameter((, MemberKind.NonStaticMethod, null, null, null)
parseRecordType((, ()
listener: beginRecordType(()
parseRecordTypeNamedFields(()
listener: beginRecordTypeNamedFields({)
parseRecordTypeField({, identifierIsOptional: false)
listener: beginRecordTypeEntry()
parseMetadataStar({)
listener: beginMetadataStar(int)
listener: endMetadataStar(0)
listener: handleIdentifier(int, typeReference)
listener: handleNoTypeArguments(n)
listener: handleType(int, null)
ensureIdentifier(int, recordFieldDeclaration)
listener: handleIdentifier(n, recordFieldDeclaration)
listener: endRecordTypeEntry()
parseRecordTypeField(,, identifierIsOptional: false)
listener: beginRecordTypeEntry()
parseMetadataStar(,)
listener: beginMetadataStar(String)
listener: endMetadataStar(0)
listener: handleIdentifier(String, typeReference)
listener: handleNoTypeArguments(s)
listener: handleType(String, null)
ensureIdentifier(String, recordFieldDeclaration)
listener: handleIdentifier(s, recordFieldDeclaration)
listener: endRecordTypeEntry()
listener: endRecordTypeNamedFields(2, {)
ensureCloseParen(}, ()
listener: endRecordType((, null, 1, true)
ensureIdentifier(., fieldInitializer)
listener: handleIdentifier(x, fieldInitializer)
listener: handleFormalParameterWithoutValue())
listener: endFormalParameter(this, null, ., x, 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: handleEmptyFunctionBody(;)
listener: endClassConstructor(null, C, (, null, ;)
listener: endMember()
notEofOrValue(}, })
listener: endClassOrMixinOrExtensionBody(DeclarationKind.Class, 2, {, })
listener: endClassDeclaration(class, })
listener: endTopLevelDeclaration()
reportAllErrorTokens(class)
listener: endCompilationUnit(1, )

View file

@ -0,0 +1,13 @@
class C {
({num n, String s}) x;
C(({int n, String s}) this.x);
}
class[KeywordToken] C[StringToken] {[BeginToken]
([BeginToken]{[BeginToken]num[StringToken] n[StringToken],[SimpleToken] String[StringToken] s[StringToken]}[SimpleToken])[SimpleToken] x[StringToken];[SimpleToken]
C[StringToken]([BeginToken]([BeginToken]{[BeginToken]int[StringToken] n[StringToken],[SimpleToken] String[StringToken] s[StringToken]}[SimpleToken])[SimpleToken] this[KeywordToken].[SimpleToken]x[StringToken])[SimpleToken];[SimpleToken]
}[SimpleToken]
[SimpleToken]

View file

@ -0,0 +1,13 @@
class C {
({num n, String s}) x;
C(({int n, String s}) this.x);
}
class[KeywordToken] C[StringToken] {[BeginToken]
([BeginToken]{[BeginToken]num[StringToken] n[StringToken],[SimpleToken] String[StringToken] s[StringToken]}[SimpleToken])[SimpleToken] x[StringToken];[SimpleToken]
C[StringToken]([BeginToken]([BeginToken]{[BeginToken]int[StringToken] n[StringToken],[SimpleToken] String[StringToken] s[StringToken]}[SimpleToken])[SimpleToken] this[KeywordToken].[SimpleToken]x[StringToken])[SimpleToken];[SimpleToken]
}[SimpleToken]
[SimpleToken]