diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart index 3a8935e9bd8..5a9b012866b 100644 --- a/pkg/analyzer/lib/src/dart/constant/value.dart +++ b/pkg/analyzer/lib/src/dart/constant/value.dart @@ -11,6 +11,7 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/type_provider.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/src/dart/constant/has_type_parameter_reference.dart'; +import 'package:analyzer/src/dart/element/extensions.dart'; import 'package:analyzer/src/dart/element/type_system.dart'; import 'package:analyzer/src/error/codes.dart'; import 'package:meta/meta.dart'; @@ -447,6 +448,8 @@ class DartObjectImpl implements DartObject { InstanceState state = _state; if (state is GenericState) { return state.fields[name]; + } else if (state is RecordState) { + return state.getField(name); } return null; } @@ -2578,6 +2581,16 @@ class RecordState extends InstanceState { return BoolState.TRUE_STATE; } + /// Returns the value of the field with the given [name]. + DartObject? getField(String name) { + final index = RecordTypeExtension.positionalFieldIndex(name); + if (index != null && index < positionalFields.length) { + return positionalFields[index]; + } else { + return namedFields[name]; + } + } + @override BoolState isIdentical(TypeSystemImpl typeSystem, InstanceState rightOperand) { var equal = equalEqual(typeSystem, rightOperand); diff --git a/pkg/analyzer/lib/src/dart/element/extensions.dart b/pkg/analyzer/lib/src/dart/element/extensions.dart index 44b0888b69e..1dc44352870 100644 --- a/pkg/analyzer/lib/src/dart/element/extensions.dart +++ b/pkg/analyzer/lib/src/dart/element/extensions.dart @@ -156,12 +156,18 @@ extension RecordTypeExtension on RecordType { } RecordTypePositionalField? positionalField(String name) { + final index = positionalFieldIndex(name); + if (index != null && index < positionalFields.length) { + return positionalFields[index]; + } + return null; + } + + /// Attempt to parse `$0`, `$1`, etc. + static int? positionalFieldIndex(String name) { final match = _positionalName.firstMatch(name); if (match != null) { - final index = int.tryParse(match.group(1)!); - if (index != null && index < positionalFields.length) { - return positionalFields[index]; - } + return int.tryParse(match.group(1)!); } return null; } diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart index 08999f7ff00..eac71ce9583 100644 --- a/pkg/analyzer/test/src/dart/constant/value_test.dart +++ b/pkg/analyzer/test/src/dart/constant/value_test.dart @@ -473,6 +473,25 @@ class DartObjectImplTest { expect(_symbolValue("a"), _symbolValue("a")); } + void test_getField_record() { + final record = _recordValue([ + _intValue(0), + _intValue(1), + ], { + 'a': _intValue(2), + 'b': _intValue(3), + }); + + expect(record.getField(r'$0'), _intValue(0)); + expect(record.getField(r'$1'), _intValue(1)); + expect(record.getField(r'$2'), isNull); + expect(record.getField(r'$-2'), isNull); + + expect(record.getField(r'a'), _intValue(2)); + expect(record.getField(r'b'), _intValue(3)); + expect(record.getField(r'c'), isNull); + } + void test_getValue_bool_false() { expect(_boolValue(false).toBoolValue(), false); }