f8086c81ae
Collects files from `package:async_helper` and `tests/language` that are generally useful, so that all test-related helpers are in `package:expect`. Moves the two libraries from `package:async_helper` into `package:expect`, and the `tests/language/static_type_helper.dart` file too. Deprecates `async_minitest.dart`, to follow `minitest.dart`, expecting the Flutter use of it to have been fixed to not break on deprecation (I believe Flutter no longer breaks builds on deprecations at all). Patch 1 is the actual change. Patch 2+4+8 is changing all existing references to the files. Patch 6 ignores deprecation in files still using `async_minitest.dart`. 3+5+7+9 are updating this text to make the numbers match. Then it's just test-expectations and small tweaks from there. Change-Id: I1b665135b5fef9b9a0c3b340ffe9daf874d0174c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373120 Reviewed-by: Nate Bosch <nbosch@google.com> Reviewed-by: Devon Carew <devoncarew@google.com> Commit-Queue: Lasse Nielsen <lrn@google.com>
341 lines
11 KiB
Dart
341 lines
11 KiB
Dart
// Copyright (c) 2020, 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.
|
|
|
|
import 'package:expect/static_type_helper.dart';
|
|
|
|
/// Test that the type of a local variable is treated as a "type of interest"
|
|
/// for the variable, and that for non-final variables, the initialization (if
|
|
/// any) is treated as an assignment for the purposes of promotion.
|
|
|
|
/// Verify that the declared type of a local variable is a type of interest.
|
|
void declaredTypeIsATypeOfInterest() {
|
|
// Check that a variable declared with a non-nullable type can be assignment
|
|
// demoted back to its declared type after being promoted.
|
|
{
|
|
num x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
|
|
// Check that a variable declared with a nullable type can be assignment
|
|
// promoted to the non-nullable variant of its type, and demoted back to both
|
|
// the non-nullable variant and the declared type after being promoted.
|
|
{
|
|
num? x = (3 as num?);
|
|
x.expectStaticType<Exactly<num?>>();
|
|
// This should promote to num, since num and num? should both be types of
|
|
// interest.
|
|
x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Verify that demotion back to num? works
|
|
x = null;
|
|
x.expectStaticType<Exactly<num?>>();
|
|
}
|
|
|
|
// Check that a late variable declared with a non-nullable type can be
|
|
// assignment demoted back to its declared type after being promoted.
|
|
{
|
|
late num x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
|
|
// Check that a late variable declared with a nullable type can be assignment
|
|
// promoted to the non-nullable variant of its type, and demoted back to both
|
|
// the non-nullable variant and the declared type after being promoted.
|
|
{
|
|
late num? x = (3 as num?);
|
|
x.expectStaticType<Exactly<num?>>();
|
|
// This should promote to num, since num and num? should both be types of
|
|
// interest.
|
|
x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Verify that demotion back to num? works
|
|
x = null;
|
|
x.expectStaticType<Exactly<num?>>();
|
|
}
|
|
|
|
// Final variables are not re-assignable, but can still be subject to
|
|
// to assignment based promotion and demotion in a few situations.
|
|
|
|
// Check that a late final variable declared with a non-nullable type can be
|
|
// assignment demoted back to its declared type after being promoted.
|
|
{
|
|
late final num x;
|
|
// Make x potentially assigned, and initialize it
|
|
if (num == num) {
|
|
x = 3.5;
|
|
}
|
|
// Branch will not be taken to avoid a double initialization error
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
x = 3.5; // Demote to num.
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
}
|
|
|
|
// Check that a final variable declared with a non-nullable type can be
|
|
// assignment promoted to the non-nullable variant of its type.
|
|
{
|
|
final num? x;
|
|
// Promote to num, since num is a type of interest
|
|
x = 3;
|
|
// Verify that we have promoted to num
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
|
|
// Check that a late final variable declared with a non-nullable type can be
|
|
// assignment promoted to the non-nullable variant of its type.
|
|
{
|
|
late final num? x;
|
|
// Promote to num, since num is a type of interest
|
|
x = 3;
|
|
// Verify that we have promoted to num
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
}
|
|
|
|
/// Verify that the inferred type of a local variable is a type of interest.
|
|
void inferredTypeIsATypeOfInterest() {
|
|
// Check that a variable inferred with a non-nullable type can be
|
|
// assignment demoted back to its declared type after being promoted.
|
|
{
|
|
var x = (3 as num);
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
|
|
// Check that a variable inferred to have a nullable type can be assignment
|
|
// promoted to the non-nullable variant of its type, and demoted back to both
|
|
// the non-nullable variant and the declared type after being promoted.
|
|
{
|
|
var x = (3 as num?);
|
|
x.expectStaticType<Exactly<num?>>();
|
|
// This should promote to num, since num and num? should both be types of
|
|
// interest.
|
|
x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Verify that demotion back to num? works
|
|
x = null;
|
|
x.expectStaticType<Exactly<num?>>();
|
|
}
|
|
|
|
// Check that a variable inferred with a non-nullable type can be
|
|
// assignment demoted back to its declared type after being promoted.
|
|
{
|
|
late var x = (3 as num);
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
|
|
// Check that a late variable inferred to have a nullable type can be
|
|
// assignment promoted to the non-nullable variant of its type, and demoted
|
|
// back to both the non-nullable variant and the declared type after being
|
|
// promoted.
|
|
{
|
|
late var x = (3 as num?);
|
|
x.expectStaticType<Exactly<num?>>();
|
|
// This should promote to num, since num and num? should both be types of
|
|
// interest.
|
|
x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Promote x to int
|
|
if (x is int) {
|
|
x.expectStaticType<Exactly<int>>();
|
|
// Verify that demotion back to num works
|
|
x = 3.5;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Verify that demotion back to num? works
|
|
x = null;
|
|
x.expectStaticType<Exactly<num?>>();
|
|
}
|
|
}
|
|
|
|
/// Verify that the initializer on a mutable variable is treated as if it were
|
|
/// an assignment for the purposes of promotion, and therefore assigning a
|
|
/// non-nullable value can promote to a non-nullable variant of the declared
|
|
/// type.
|
|
void initializersOnVarPromote() {
|
|
// Check that a variable declared to have a nullable type can be promoted on
|
|
// initialization to the non-nullable variant of its type, demoted back to the
|
|
// declared type, and assignment promoted to the non-nullable variant of the
|
|
// declared type.
|
|
{
|
|
num? x = 3;
|
|
// Verify that we have promoted to num
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Verify that num? is a type of interest by demoting to it
|
|
x = null;
|
|
x.expectStaticType<Exactly<num?>>();
|
|
// Verify that num is a type of interest by promoting to it.
|
|
x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
|
|
// Check that a late variable declared to have a nullable type can be promoted
|
|
// on initialization to the non-nullable variant of its type, demoted back to
|
|
// the declared type, and assignment promoted to the non-nullable variant of
|
|
// the declared type.
|
|
{
|
|
late num? x = 3;
|
|
// Verify that we have promoted to num
|
|
x.expectStaticType<Exactly<num>>();
|
|
// Verify that num? is a type of interest by demoting to it
|
|
x = null;
|
|
x.expectStaticType<Exactly<num?>>();
|
|
// Verify that num is a type of interest by promoting to it.
|
|
x = 3;
|
|
x.expectStaticType<Exactly<num>>();
|
|
}
|
|
}
|
|
|
|
/// Verify that the initializer on a final variable is not treated as if it were
|
|
/// an assignment for the purposes of promotion, and therefore assigning a
|
|
/// non-nullable value does not promote to a non-nullable variant of the
|
|
/// declared type.
|
|
void initializersOnFinalDoNotPromote() {
|
|
// Check that a final nullable variable initialized with a non-nullable value
|
|
// does not get promoted by the initializer to the non-nullable variant of the
|
|
// type.
|
|
{
|
|
final num? x = 3;
|
|
// Verify that we have not promoted to num
|
|
x.expectStaticType<Exactly<num?>>();
|
|
}
|
|
|
|
// Check that a late final nullable variable initialized with a non-nullable
|
|
// value does not get promoted by the initializer to the non-nullable variant
|
|
// of the type.
|
|
{
|
|
late final num? x = 3;
|
|
// Verify that we have not promoted to num
|
|
x.expectStaticType<Exactly<num?>>();
|
|
}
|
|
}
|
|
|
|
/// Check that when an initializer is a promoted type variable `X & T`, the
|
|
/// inferred type of the variable is `X`, but that the variable is immediately
|
|
/// promoted to `X & T`.
|
|
void typeVariableTypedVariableInferencePromotes<T>(T x0, T x1, bool b) {
|
|
if (x0 is num) {
|
|
// Promote `x0` to T & num
|
|
|
|
{
|
|
// Declare y, which should have inferred type T, and be promoted to T &
|
|
// num
|
|
var y = x0;
|
|
// Check that y is assignable to z, and hence that y is still promoted to
|
|
// T & num
|
|
num z = y;
|
|
// Check that y can be demoted to T, but do it conditionally so that T &
|
|
// num remains a type of interest.
|
|
if (b) y = x1;
|
|
// T & num is still a type of interest, and hence this assignment should
|
|
// promote to T & num.
|
|
y = x0;
|
|
// Check that y is assignable to z, and hence that y has been promoted T &
|
|
// num
|
|
z = y;
|
|
}
|
|
|
|
{
|
|
// Declare y, which should have inferred type T, and be promoted to T &
|
|
// num
|
|
late var y = x0;
|
|
// Check that y is assignable to z, and hence that y is still promoted to
|
|
// T & num
|
|
num z = y;
|
|
// Check that y can be demoted to T, but do it conditionally so that T &
|
|
// num remains a type of interest.
|
|
if (b) y = x1;
|
|
// T & num is still a type of interest, and hence this assignment should
|
|
// promote to T & num.
|
|
y = x0;
|
|
// Check that y is assignable to z, and hence that y has been promoted T &
|
|
// num
|
|
z = y;
|
|
}
|
|
|
|
{
|
|
// Declare y, which should have inferred type T, and be promoted to T &
|
|
// num
|
|
final y = x0;
|
|
// Check that y is assignable to z, and hence that y is still promoted to
|
|
// T & num
|
|
num z = y;
|
|
}
|
|
|
|
{
|
|
// Declare y, which should have inferred type T, and be promoted to T &
|
|
// num
|
|
late final y = x0;
|
|
// Check that y is assignable to z, and hence that y is still promoted to
|
|
// T & num
|
|
num z = y;
|
|
}
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
declaredTypeIsATypeOfInterest();
|
|
inferredTypeIsATypeOfInterest();
|
|
initializersOnVarPromote();
|
|
initializersOnFinalDoNotPromote();
|
|
typeVariableTypedVariableInferencePromotes<num>(3, 3.5, true);
|
|
}
|