Fix incorrect record types

- Access record elements starting from 1 when creating record type.
- Add record tests for the expression compiler.

Closes: https://github.com/dart-lang/sdk/issues/51197
Change-Id: I02af94a1f09cbcb9801b6b3a5b0effdfd33aab2b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280204
Commit-Queue: Anna Gringauze <annagrin@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
Anna Gringauze 2023-02-01 01:56:38 +00:00 committed by Commit Queue
parent 101738ee72
commit 6387f7345a
2 changed files with 108 additions and 2 deletions

View file

@ -64,6 +64,112 @@ main() {
// TODO(nshahan) Merge with [runAgnosticSharedTests] after we no longer need to
// test support for evaluation in legacy (pre-null safety) code.
void runNullSafeSharedTests(SetupCompilerOptions setup, TestDriver driver) {
group('Records', () {
const recordsSource = '''
void main() {
var r = (true, 3);
var cr = (true, {'a':1, 'b': 2});
var nr = (true, (false, 3));
// Breakpoint: bp
print('hello world');
}
''';
setUpAll(() async {
await driver
.initSource(setup, recordsSource, experiments: {'records': true});
});
tearDownAll(() async {
await driver.cleanupTest();
});
test('simple record', () async {
await driver.check(
breakpointId: 'bp',
expression: 'r.toString()',
expectedResult: '(true, 3)');
});
test('simple record type', () async {
await driver.check(
breakpointId: 'bp',
expression: 'r.runtimeType.toString()',
expectedResult: 'RecordType(bool, int)');
});
test('simple record field one', () async {
await driver.check(
breakpointId: 'bp',
expression: 'r.\$1.toString()',
expectedResult: 'true');
});
test('simple record field two', () async {
await driver.check(
breakpointId: 'bp',
expression: 'r.\$2.toString()',
expectedResult: '3');
});
test('complex record', () async {
await driver.check(
breakpointId: 'bp',
expression: 'cr.toString()',
expectedResult: '(true, {a: 1, b: 2})');
});
test('complex record type', () async {
await driver.check(
breakpointId: 'bp',
expression: 'cr.runtimeType.toString()',
expectedResult: 'RecordType(bool, IdentityMap<String, int>)');
});
test('complex record field one', () async {
await driver.check(
breakpointId: 'bp',
expression: 'cr.\$1.toString()',
expectedResult: 'true');
});
test('complex record field two', () async {
await driver.check(
breakpointId: 'bp',
expression: 'cr.\$2.toString()',
expectedResult: '{a: 1, b: 2}');
});
test('nested record', () async {
await driver.check(
breakpointId: 'bp',
expression: 'nr.toString()',
expectedResult: '(true, (false, 3))');
});
test('nested record type', () async {
await driver.check(
breakpointId: 'bp',
expression: 'nr.runtimeType.toString()',
expectedResult: 'RecordType(bool, RecordType(bool, int))');
});
test('nested record field one', () async {
await driver.check(
breakpointId: 'bp',
expression: 'nr.\$1.toString()',
expectedResult: 'true');
});
test('nested record field two', () async {
await driver.check(
breakpointId: 'bp',
expression: 'nr.\$2.toString()',
expectedResult: '(false, 3)');
});
});
group('Correct null safety mode used', () {
var source = '''
const soundNullSafety = !(<Null>[] is List<int>);

View file

@ -91,8 +91,8 @@ RecordType getRecordType(_RecordImpl obj) {
var named = shape.named;
var positionals = shape.positionals;
var types = [];
var count = 0;
while (count < positionals) {
var count = 1;
while (count <= positionals) {
var name = '\$$count';
var field = JS('', '#[#]', obj, name);
types.add(getReifiedType(field));