[wildcard-variables] More language tests on declarations - classes, enums, extension types.

Bug: https://github.com/dart-lang/sdk/issues/55652
Change-Id: Id1c48c3f6345d13c9c5f88224085a863e30f5aaf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/367985
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
Kallen Tu 2024-06-11 19:44:41 +00:00 committed by Commit Queue
parent cf9623f3d9
commit 549a1b1987
6 changed files with 219 additions and 0 deletions

View file

@ -0,0 +1,35 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Tests using wildcards in class generic type parameters.
// SharedOptions=--enable-experiment=wildcard-variables
import 'package:expect/expect.dart';
typedef _ = BB;
class AA {}
class BB extends AA {}
class A<T, U extends AA> {}
class B<_, _ extends AA> extends A<_, _> {
int foo<_ extends _>([int _ = 2]) => 1;
}
class C<_, _ extends _> extends A<_, _> {
static const int _ = 1;
}
void main() {
var b = B();
Expect.equals(1, b.foo());
Expect.type<A<BB, BB>>(b);
Expect.type<B<Object?, AA>>(b);
Expect.equals(1, C._);
Expect.type<C<dynamic, BB>>(C());
}

View file

@ -0,0 +1,32 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Class methods and getters and setters can still be named `_`.
// SharedOptions=--enable-experiment=wildcard-variables
import 'package:expect/expect.dart';
class A<_> {
int _<_ extends num>([int _ = 2]) => 1;
}
class B {
int x = 1;
int get _ => x;
void set _(int y) {
x = y;
}
}
void main() {
var a = A();
Expect.equals(1, a._());
var b = B();
Expect.equals(1, b._);
b._ = 2;
Expect.equals(2, b._);
}

View file

@ -0,0 +1,24 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Tests the usage of wildcards in enum constructors and fields.
// SharedOptions=--enable-experiment=wildcard-variables
import 'package:expect/expect.dart';
enum A { _ }
enum B {
e(2);
const B(int _) : _ = 1;
final int _;
}
void main() {
A._;
Expect.equals(1, B.e._);
}

View file

@ -0,0 +1,19 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// The representation variable of an extension type can be named `_`, and no
// formal parameter name is introduced into any scopes.
// SharedOptions=--enable-experiment=wildcard-variables
import 'package:expect/expect.dart';
extension type Id(int _) {
operator <(Id other) => _ < other._;
}
void main() {
var id = Id(1);
Expect.isTrue(id < Id(2));
}

View file

@ -0,0 +1,18 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// A local function declaration named `_` is non-binding and cannot be accessed.
// SharedOptions=--enable-experiment=wildcard-variables
void main() {
void _() {}
// ^
// [analyzer] unspecified
/*indent*/ _();
// ^
// [analyzer] unspecified
// [cfe] unspecified
}

View file

@ -0,0 +1,91 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Allow positional record fields named `_` in record types.
// SharedOptions=--enable-experiment=wildcard-variables
import 'dart:async';
import 'package:expect/expect.dart';
typedef R = (String _, String _);
void main() {
(int _, int _) record;
record = (1, 2);
Expect.equals(1, record.$1);
Expect.equals(2, record.$2);
R rType = ('1', '2');
Expect.equals('1', rType.$1);
Expect.equals('2', rType.$2);
// Has a named field (which cannot be `_`).
(int _, int _, {int x}) recordX;
recordX = (1, 2, x: 3);
Expect.equals(1, recordX.$1);
Expect.equals(2, recordX.$2);
// In composite types.
(int _, int _) functionReturn() => (1, 2);
(int _, int _) Function() functionTypeReturn() => functionReturn;
(int _, int _) functionArgument((int _, int _) _) => (1, 2);
(int _, int _)? nullableType;
FutureOr<(int _, int _)> futureOrType = record;
List<(int _, int _)> listOfType = [(1, 2)];
// In type tests, where it promotes.
// True value that promotion cannot recognize.
// Used to prevent promotion from affecting later tests.
bool truth() => DateTime.now().millisecondsSinceEpoch > 0; //
Object? maybeRecord = truth() ? record : "not a record";
if (truth() && maybeRecord is (int _, int _)) {
Expect.equals(1, maybeRecord.$1);
Expect.equals(2, maybeRecord.$2);
} else {
Expect.fail("is check failed");
}
if (truth()) {
maybeRecord as (int _, int _);
Expect.equals(1, maybeRecord.$1);
Expect.equals(2, maybeRecord.$2);
}
if (truth()) {
(int _, int _) implicitDowncast = (maybeRecord as dynamic);
Expect.equals(1, implicitDowncast.$1);
Expect.equals(2, implicitDowncast.$2);
}
try {
throw record;
} on (int _, int _) catch (onClauseTest) {
Expect.equals(1, onClauseTest.$1);
Expect.equals(2, onClauseTest.$2);
}
// Type tests in patterns.
switch (record as dynamic) {
case R(:var $1, :var $2):
Expect.equals(1, $1);
Expect.equals(2, $2);
default:
Expect.fail("Not here!");
}
switch (record as dynamic) {
case (int _, int _) pair:
{
// Occurs as type here, not pattern.
Expect.equals(1, pair.$1);
Expect.equals(2, pair.$2);
}
default:
Expect.fail("Not here!");
}
}