From 92b97fe6fbab22c2f5f5aeda5304dd4fdb5b61b4 Mon Sep 17 00:00:00 2001 From: Jens Johansen Date: Mon, 3 Oct 2022 07:14:26 +0000 Subject: [PATCH] [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 Reviewed-by: Brian Wilkerson Commit-Queue: Jens Johansen --- .../lib/src/parser/type_info_impl.dart | 2 + ...l_parameter_with_explicit_record_type.dart | 7 + ...eter_with_explicit_record_type.dart.expect | 85 +++++++++++ ...plicit_record_type.dart.intertwined.expect | 144 ++++++++++++++++++ ...th_explicit_record_type.dart.parser.expect | 13 ++ ...h_explicit_record_type.dart.scanner.expect | 13 ++ 6 files changed, 264 insertions(+) create mode 100644 pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart create mode 100644 pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.expect create mode 100644 pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.scanner.expect diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart index d6606809d64..932b6601e35 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info_impl.dart @@ -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> or List>>. diff --git a/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart new file mode 100644 index 00000000000..36f7c0831e3 --- /dev/null +++ b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart @@ -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); +} diff --git a/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.expect b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.expect new file mode 100644 index 00000000000..fdac54db9d3 --- /dev/null +++ b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.expect @@ -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, ) diff --git a/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.intertwined.expect b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.intertwined.expect new file mode 100644 index 00000000000..35298e6b2da --- /dev/null +++ b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.intertwined.expect @@ -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, ) diff --git a/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.parser.expect b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.parser.expect new file mode 100644 index 00000000000..109ac23f740 --- /dev/null +++ b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.parser.expect @@ -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] diff --git a/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.scanner.expect b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.scanner.expect new file mode 100644 index 00000000000..109ac23f740 --- /dev/null +++ b/pkg/front_end/parser_testcases/record/field_formal_parameter_with_explicit_record_type.dart.scanner.expect @@ -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]