Skip to content

Commit 749e450

Browse files
authored
#1399. [Records] Type annotations and record expressions tests updated (#1415)
* #1399. [Records] Type annotations and record expressions tests updated to the current spec * #1399. [Records] More type annotations and record expressions tests added
1 parent efd1d26 commit 749e450

40 files changed

+1369
-93
lines changed

LanguageFeatures/Records/record_expressions_A01_t01.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// literal ::= record
88
/// | // Existing literal productions...
9-
/// record ::= '(' recordField ( ',' recordField )* ','? ')'
9+
/// record ::= 'const'? (' recordField ( ',' recordField )* ','? ')'
1010
/// recordField ::= (identifier ':' )? expression
1111
///
1212
/// This is identical to the grammar for a function call argument list. There
@@ -15,13 +15,16 @@
1515
///
1616
/// The same field name more than once.
1717
///
18-
/// No named fields and only one positional field. This avoids ambiguity with
19-
/// parenthesized expressions.
18+
/// Only one positional field and no trailing comma.
2019
///
2120
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
2221
///
2322
/// A field name that starts with an underscore.
2423
///
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
2528
/// @description Checks that it is a compile-time error if a record has the same
2629
/// field name more than once
2730
/// @author [email protected]

LanguageFeatures/Records/record_expressions_A01_t02.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// literal ::= record
88
/// | // Existing literal productions...
9-
/// record ::= '(' recordField ( ',' recordField )* ','? ')'
9+
/// record ::= 'const'? '(' recordField ( ',' recordField )* ','? ')'
1010
/// recordField ::= (identifier ':' )? expression
1111
///
1212
/// This is identical to the grammar for a function call argument list. There
@@ -15,13 +15,16 @@
1515
///
1616
/// The same field name more than once.
1717
///
18-
/// No named fields and only one positional field. This avoids ambiguity with
19-
/// parenthesized expressions.
18+
/// Only one positional field and no trailing comma.
2019
///
2120
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
2221
///
2322
/// A field name that starts with an underscore.
2423
///
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
2528
/// @description Checks that it is a compile-time error if a record has the same
2629
/// field name more than once
2730
/// @author [email protected]

LanguageFeatures/Records/record_expressions_A02_t01.dart

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// literal ::= record
88
/// | // Existing literal productions...
9-
/// record ::= '(' recordField ( ',' recordField )* ','? ')'
9+
/// record ::= 'const'? '(' recordField ( ',' recordField )* ','? ')'
1010
/// recordField ::= (identifier ':' )? expression
1111
///
1212
/// This is identical to the grammar for a function call argument list. There
@@ -15,19 +15,34 @@
1515
///
1616
/// The same field name more than once.
1717
///
18-
/// No named fields and only one positional field. This avoids ambiguity with
19-
/// parenthesized expressions.
18+
/// Only one positional field and no trailing comma.
2019
///
2120
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
2221
///
2322
/// A field name that starts with an underscore.
2423
///
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
2528
/// @description Checks that it is a compile-time error if a record has no named
26-
/// fields and only one positional field
29+
/// fields and only one positional field with no trailing comma
2730
/// @author [email protected]
2831
2932
// SharedOptions=--enable-experiment=records
3033

34+
Record foo1() => (42);
35+
// ^^^^
36+
// [analyzer] unspecified
37+
// [cfe] unspecified
38+
39+
Record foo2() => ((42));
40+
// ^^^^^^
41+
// [analyzer] unspecified
42+
// [cfe] unspecified
43+
44+
void bar(Record r) {}
45+
3146
main() {
3247
Record r1 = (42);
3348
// ^^
@@ -37,5 +52,15 @@ main() {
3752
Record r2 = ((42));
3853
// ^^^^
3954
// [analyzer] unspecified
55+
// [cfe] unspecified
56+
57+
bar(("Hello"));
58+
// ^^^^^^^^^
59+
// [analyzer] unspecified
60+
// [cfe] unspecified
61+
62+
bar((("Hello")));
63+
// ^^^^^^^^^^^
64+
// [analyzer] unspecified
4065
// [cfe] unspecified
4166
}

LanguageFeatures/Records/record_expressions_A02_t02.dart

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// literal ::= record
88
/// | // Existing literal productions...
9-
/// record ::= '(' recordField ( ',' recordField )* ','? ')'
9+
/// record ::= 'const'? '(' recordField ( ',' recordField )* ','? ')'
1010
/// recordField ::= (identifier ':' )? expression
1111
///
1212
/// This is identical to the grammar for a function call argument list. There
@@ -15,39 +15,44 @@
1515
///
1616
/// The same field name more than once.
1717
///
18-
/// No named fields and only one positional field. This avoids ambiguity with
19-
/// parenthesized expressions.
18+
/// Only one positional field and no trailing comma.
2019
///
2120
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
2221
///
2322
/// A field name that starts with an underscore.
2423
///
25-
/// @description Checks that it is a compile-time error if a record has no named
26-
/// fields and only one positional field
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
28+
/// @description Checks that it is no error if a record has no named fields and
29+
/// only one positional field but with a trailing comma
2730
/// @author [email protected]
2831
2932
// SharedOptions=--enable-experiment=records
3033

31-
Record foo1() => (42);
32-
// ^^^^
33-
// [analyzer] unspecified
34-
// [cfe] unspecified
34+
import "../../Utils/expect.dart";
35+
36+
Record foo1() => (1,);
37+
38+
Record foo2() => ((2),);
3539

36-
Record foo2() => ((42));
37-
// ^^^^^^
38-
// [analyzer] unspecified
39-
// [cfe] unspecified
40+
Record foo3() => ((3,),);
4041

41-
void bar(Record r) {}
42+
dynamic bar(Record r) => r
4243

4344
main() {
44-
bar(("Hello"));
45-
// ^^^^^^^^^
46-
// [analyzer] unspecified
47-
// [cfe] unspecified
48-
49-
bar((("Hello")));
50-
// ^^^^^^^^^^^
51-
// [analyzer] unspecified
52-
// [cfe] unspecified
45+
var r1 = (1,);
46+
var r2 = ((2),);
47+
var r3 = ((3,),);
48+
49+
Expect.equals(1, r1.$0);
50+
Expect.equals(2, r2.$0);
51+
Expect.equals(3, r2.$0.$0);
52+
53+
Expect.equals(1, foo1().$0);
54+
Expect.equals(2, foo2().$0);
55+
Expect.equals((3,), foo3().$0);
56+
Expect.equals(("Hello",), bar(("Hello",)));
57+
Expect.equals(("Hello",), bar((("Hello"),)));
5358
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion A record is created using a record expression. The grammar is:
6+
///
7+
/// literal ::= record
8+
/// | // Existing literal productions...
9+
/// record ::= 'const'? '(' recordField ( ',' recordField )* ','? ')'
10+
/// recordField ::= (identifier ':' )? expression
11+
///
12+
/// This is identical to the grammar for a function call argument list. There
13+
/// are a couple of syntactic restrictions not captured by the grammar. It is a
14+
/// compile-time error if a record has any of:
15+
///
16+
/// The same field name more than once.
17+
///
18+
/// Only one positional field and no trailing comma.
19+
///
20+
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
21+
///
22+
/// A field name that starts with an underscore.
23+
///
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
28+
/// @description Checks that it is no error if a record has trailing commas
29+
/// @author [email protected]
30+
31+
// SharedOptions=--enable-experiment=records
32+
33+
import "../../Utils/expect.dart";
34+
35+
Record foo1() => (1, 2,);
36+
37+
Record foo2() => ((2), (3),);
38+
39+
Record foo3() => ((3, n: 4,), n2: "", true,);
40+
41+
dynamic bar(Record r) => r
42+
43+
main() {
44+
var r1 = (1, n: "n",);
45+
var r2 = ((2), 3,);
46+
var r3 = ((3,), n: Record.empty, (4),);
47+
48+
Expect.equals(1, r1.$0);
49+
Expect.equals("n", r1.n);
50+
Expect.equals(2, r2.$0);
51+
Expect.equals(3, r2.$1);
52+
Expect.equals(3, r3.$0.$0);
53+
Expect.equals(4, r3.$1);
54+
Expect.equals(Record.empty, r3.n);
55+
56+
Expect.equals((1, 2), foo1());
57+
Expect.equals((2, 3), foo2());
58+
Expect.equals(((3, n: 4), n2: "", true), foo3());
59+
Expect.equals(("Hello", 1), bar(("Hello", 1,)));
60+
Expect.equals((n1: "n1", n2: "n2"), bar((n1: "n1", n2: "n2",));
61+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
/// @assertion A record is created using a record expression. The grammar is:
6+
///
7+
/// literal ::= record
8+
/// | // Existing literal productions...
9+
/// record ::= 'const'? '(' recordField ( ',' recordField )* ','? ')'
10+
/// recordField ::= (identifier ':' )? expression
11+
///
12+
/// This is identical to the grammar for a function call argument list. There
13+
/// are a couple of syntactic restrictions not captured by the grammar. It is a
14+
/// compile-time error if a record has any of:
15+
///
16+
/// The same field name more than once.
17+
///
18+
/// Only one positional field and no trailing comma.
19+
///
20+
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
21+
///
22+
/// A field name that starts with an underscore.
23+
///
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
28+
/// @description Checks that it is a compile-time error if a record has more
29+
/// than one trailing comma
30+
/// @author [email protected]
31+
32+
// SharedOptions=--enable-experiment=records
33+
34+
Record foo1() => (1,,);
35+
// ^
36+
// [analyzer] unspecified
37+
// [cfe] unspecified
38+
39+
Record foo2() => ((2),,);
40+
// ^
41+
// [analyzer] unspecified
42+
// [cfe] unspecified
43+
44+
Record foo3() => ((3,,),);
45+
// ^
46+
// [analyzer] unspecified
47+
// [cfe] unspecified
48+
49+
Record foo4() => ((3,),,);
50+
// ^
51+
// [analyzer] unspecified
52+
// [cfe] unspecified
53+
54+
Record foo5() => (n1: 1,,);
55+
// ^
56+
// [analyzer] unspecified
57+
// [cfe] unspecified
58+
59+
Record foo6() => ((2), n: 3,,);
60+
// ^
61+
// [analyzer] unspecified
62+
// [cfe] unspecified
63+
64+
Record foo7() => (1, 2, n: 3, 4,,);
65+
// ^
66+
// [analyzer] unspecified
67+
// [cfe] unspecified
68+
69+
dynamic bar(Record r) => r
70+
71+
main() {
72+
var r1 = (1,,);
73+
// ^
74+
// [analyzer] unspecified
75+
// [cfe] unspecified
76+
77+
var r2 = ((2),,);
78+
// ^
79+
// [analyzer] unspecified
80+
// [cfe] unspecified
81+
82+
var r3 = ((3,),,);
83+
// ^
84+
// [analyzer] unspecified
85+
// [cfe] unspecified
86+
87+
var r4 = (n1: 1,,);
88+
// ^
89+
// [analyzer] unspecified
90+
// [cfe] unspecified
91+
92+
var r5 = (1, 2, n: "n", 3,,);
93+
// ^
94+
// [analyzer] unspecified
95+
// [cfe] unspecified
96+
}

LanguageFeatures/Records/record_expressions_A03_t01.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
///
77
/// literal ::= record
88
/// | // Existing literal productions...
9-
/// record ::= '(' recordField ( ',' recordField )* ','? ')'
9+
/// record ::= 'const'? '(' recordField ( ',' recordField )* ','? ')'
1010
/// recordField ::= (identifier ':' )? expression
1111
///
1212
/// This is identical to the grammar for a function call argument list. There
@@ -15,13 +15,16 @@
1515
///
1616
/// The same field name more than once.
1717
///
18-
/// No named fields and only one positional field. This avoids ambiguity with
19-
/// parenthesized expressions.
18+
/// Only one positional field and no trailing comma.
2019
///
2120
/// A field named hashCode, runtimeType, noSuchMethod, or toString.
2221
///
2322
/// A field name that starts with an underscore.
2423
///
24+
/// A field name that collides with the synthesized getter name of a positional
25+
/// field. For example: ('pos', $0: 'named') since the named field '$0' collides
26+
/// with the getter for the first positional field.
27+
///
2528
/// @description Checks that it is a compile-time error if a record has a field
2629
/// named `hashCode`, `runtimeType`, `noSuchMethod`, or `toString`
2730
/// @author [email protected]

0 commit comments

Comments
 (0)