diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart index 574fcf2140b..1b77bf24ca0 100644 --- a/pkg/analyzer/lib/src/summary2/element_builder.dart +++ b/pkg/analyzer/lib/src/summary2/element_builder.dart @@ -908,6 +908,33 @@ class ElementBuilder extends ThrowingAstVisitor { } } + @override + void visitRecordTypeAnnotation(RecordTypeAnnotation node) { + node.positionalFields.accept(this); + node.namedFields?.accept(this); + } + + @override + void visitRecordTypeAnnotationNamedField( + RecordTypeAnnotationNamedField node, + ) { + node.type.accept(this); + } + + @override + void visitRecordTypeAnnotationNamedFields( + RecordTypeAnnotationNamedFields node, + ) { + node.fields.accept(this); + } + + @override + void visitRecordTypeAnnotationPositionalField( + RecordTypeAnnotationPositionalField node, + ) { + node.type.accept(this); + } + @override void visitSimpleFormalParameter( covariant SimpleFormalParameterImpl node, diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart index 23b407b1b6e..1d1d0c5d04f 100644 --- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart +++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart @@ -387,6 +387,34 @@ class ReferenceResolver extends ThrowingAstVisitor { node.superclassConstraints.accept(this); } + @override + void visitRecordTypeAnnotation(RecordTypeAnnotation node) { + nodesToBuildType.addDeclaration(node); + node.positionalFields.accept(this); + node.namedFields?.accept(this); + } + + @override + void visitRecordTypeAnnotationNamedField( + RecordTypeAnnotationNamedField node, + ) { + node.type.accept(this); + } + + @override + void visitRecordTypeAnnotationNamedFields( + RecordTypeAnnotationNamedFields node, + ) { + node.fields.accept(this); + } + + @override + void visitRecordTypeAnnotationPositionalField( + RecordTypeAnnotationPositionalField node, + ) { + node.type.accept(this); + } + @override void visitSimpleFormalParameter(SimpleFormalParameter node) { node.type?.accept(this); diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart index b573cf4cd24..06c100cd34c 100644 --- a/pkg/analyzer/lib/src/summary2/types_builder.dart +++ b/pkg/analyzer/lib/src/summary2/types_builder.dart @@ -204,6 +204,8 @@ class TypesBuilder { element.returnType = returnType; } else if (node is MixinDeclaration) { _mixinDeclaration(node); + } else if (node is RecordTypeAnnotationImpl) { + _recordTypeAnnotation(node); } else if (node is SimpleFormalParameter) { var element = node.declaredElement as ParameterElementImpl; element.type = node.type?.type ?? _dynamicType; @@ -325,6 +327,33 @@ class TypesBuilder { } } + void _recordTypeAnnotation(RecordTypeAnnotationImpl node) { + final positionalFields = node.positionalFields.map((field) { + return RecordPositionalFieldElementImpl( + name: field.name?.lexeme, + nameOffset: -1, + type: field.type.typeOrThrow, + ); + }).toList(); + + final namedFields = node.namedFields?.fields.map((field) { + return RecordNamedFieldElementImpl( + name: field.name.lexeme, + nameOffset: -1, + type: field.type.typeOrThrow, + ); + }).toList(); + + node.type = RecordElementImpl( + positionalFields: positionalFields, + namedFields: namedFields ?? const [], + ).instantiate( + nullabilitySuffix: node.question != null + ? NullabilitySuffix.question + : NullabilitySuffix.none, + ); + } + void _superFormalParameter(SuperFormalParameter node) { var element = node.declaredElement as SuperFormalParameterElementImpl; var parameterList = node.parameters; diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart index 677765c2107..176a4b68c3d 100644 --- a/pkg/analyzer/test/src/summary/elements_test.dart +++ b/pkg/analyzer/test/src/summary/elements_test.dart @@ -34752,7 +34752,29 @@ library '''); } - test_recordType_classField_fromLiteral() async { + test_recordType_class_field() async { + var library = await buildLibrary(''' +class A { + final (int, String) x; +} +'''); + checkElementText(library, r''' +library + definingUnit + classes + class A @6 + fields + final x @32 + type: (int, String) + constructors + synthetic @-1 + accessors + synthetic get x @-1 + returnType: (int, String) +'''); + } + + test_recordType_class_field_fromLiteral() async { var library = await buildLibrary(''' class A { final x = (0, true); @@ -34774,6 +34796,131 @@ library '''); } + test_recordType_class_method_formalParameter() async { + var library = await buildLibrary(''' +class A { + void foo((int, String) a) {} +} +'''); + checkElementText(library, r''' +library + definingUnit + classes + class A @6 + constructors + synthetic @-1 + methods + foo @17 + parameters + requiredPositional a @35 + type: (int, String) + returnType: void +'''); + } + + test_recordType_class_method_returnType() async { + var library = await buildLibrary(''' +class A { + (int, String) foo() {} +} +'''); + checkElementText(library, r''' +library + definingUnit + classes + class A @6 + constructors + synthetic @-1 + methods + foo @26 + returnType: (int, String) +'''); + } + + test_recordType_topFunction_formalParameter() async { + var library = await buildLibrary(''' +void f((int, String) a) {} +'''); + checkElementText(library, r''' +library + definingUnit + functions + f @5 + parameters + requiredPositional a @21 + type: (int, String) + returnType: void +'''); + } + + test_recordType_topFunction_returnType_mixed() async { + var library = await buildLibrary(''' +(int, String, {bool c}) f() {} +'''); + checkElementText(library, r''' +library + definingUnit + functions + f @24 + returnType: (int, String, {bool c}) +'''); + } + + test_recordType_topFunction_returnType_named() async { + var library = await buildLibrary(''' +({int a, String b}) f() {} +'''); + checkElementText(library, r''' +library + definingUnit + functions + f @20 + returnType: ({int a, String b}) +'''); + } + + test_recordType_topFunction_returnType_nullable() async { + var library = await buildLibrary(''' +(int, String)? f() {} +'''); + checkElementText(library, r''' +library + definingUnit + functions + f @15 + returnType: (int, String)? +'''); + } + + test_recordType_topFunction_returnType_positional() async { + var library = await buildLibrary(''' +(int, String) f() {} +'''); + checkElementText(library, r''' +library + definingUnit + functions + f @14 + returnType: (int, String) +'''); + } + + test_recordType_topVariable() async { + var library = await buildLibrary(''' +final (int, String) x; +'''); + checkElementText(library, r''' +library + definingUnit + topLevelVariables + static final x @20 + type: (int, String) + accessors + synthetic static get x @-1 + returnType: (int, String) +'''); + } + test_recordType_topVariable_fromLiteral() async { var library = await buildLibrary(''' final x = (0, true);