Build RecordType(s) for RecordTypeAnnotation(s) in element model.

Change-Id: I4c42ffe10d2f51796d98d4901e04115fc3be6e83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255881
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Konstantin Shcheglov 2022-08-19 21:49:05 +00:00 committed by Commit Bot
parent 162091bd92
commit 2bc155e6e7
4 changed files with 232 additions and 1 deletions

View file

@ -908,6 +908,33 @@ class ElementBuilder extends ThrowingAstVisitor<void> {
}
}
@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,

View file

@ -387,6 +387,34 @@ class ReferenceResolver extends ThrowingAstVisitor<void> {
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);

View file

@ -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;

View file

@ -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);