Skip to content

Commit

Permalink
dart-lang#2145. Add more local variable declaration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed Sep 1, 2023
1 parent af88c17 commit 4beb74f
Show file tree
Hide file tree
Showing 11 changed files with 408 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2023, 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.

/// @assertion The declared type of a local variable with a declaration of one
/// of the forms
/// late? T v = e; late? final T v = e; const T v = e; is T
///
/// @description Checks that the declared type of a local variable with the
/// specified type `T` is `T`
/// @author sgrekhov22@gmail.com
import '../../../Utils/static_type_helper.dart';

main() {
late num v1 = 1;
late final num v2 = 2;
num v3 = 3;
final num? v4 = 4;
const num v5 = 5;

v1.expectStaticType<Exactly<num>>();
v2.expectStaticType<Exactly<num>>();
v3.expectStaticType<Exactly<num>>();
v4.expectStaticType<Exactly<num?>>();
v5.expectStaticType<Exactly<num>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,40 @@
/// as follows:
/// • If the static type of e is Null then the declared type of v is dynamic.
///
/// @description Checks that a variable declaration statement `var id;`
/// introduces a new variable `id` with `dynamic` static type into the innermost
/// enclosing scope.
/// @description Checks that a variable declaration statements
/// `late? var v = e; late? final v = e; const v = e;` introduce a new variable
/// `v` with `dynamic` static type into the innermost enclosing scope.
/// @author vasya
import '../../../Utils/expect.dart';

class C {}

main() {
test1() {
var id;
Expect.throws(() {
id.whatever;
});
id = false;
id = "";
id = 2;
id = new C();
id = C();
id = () {};
}

test2() {
late var id;
Expect.throws(() {
id.whatever;
});
id = false;
id = "";
id = 2;
id = C();
id = () {};
}

main() {
test1();
test2();
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
/// as follows:
/// • If the static type of e is Null then the declared type of v is dynamic.
///
/// @description Checks that a variable declaration statement `var id = null;`
/// introduces a new variable `id` with `dynamic` static type into the innermost
/// enclosing scope.
/// @description Checks that a variable declaration statements
/// `late? var v = null; late? final v = null; const v = null;` introduce a new
/// variable `v` with `dynamic` static type into the innermost enclosing scope.
/// @author vasya
import '../../../Utils/expect.dart';

class C {}

main() {
test1() {
var id = null;
Expect.throws(() {
id.whatever;
Expand All @@ -27,3 +27,34 @@ main() {
id = new C();
id = () {};
}

test2() {
late var id = null;
Expect.throws(() {
id.whatever;
});
id = false;
id = "";
id = 2;
id = new C();
id = () {};
}

main() {
late final v1 = null;
final v2 = null;
const v3 = null;

Expect.throws(() {
v1.whatever;
});
Expect.throws(() {
v2.whatever;
});
Expect.throws(() {
v3.whatever;
});

test1();
test2();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (c) 2023, 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.

/// @assertion The declared type of a local variable with a declaration of one
/// of the forms late? var v = e; late? final v = e; const v = e; is determined
/// as follows:
/// ...
/// • If the static type of e is of the form X & T where X is a type variable,
/// the declared type of v is X. In this case v is immediately promoted to X & T
///
/// @description Checks that static type of a variable declared by the
/// statements `late? var v = e; late? final v = e;` is `X` if the static type
/// of `e` is `X & T` where `X` is a type variable. Also test that `v` is
/// promoted to `X & T`
/// @author sgrekhov22@gmail.com
import '../../../Utils/static_type_helper.dart';

test1<T>(T t) {
if (t is int) {
var v = t;
v.isEven;
v.expectStaticType<Exactly<T>>();
}
var v = t;
v.expectStaticType<Exactly<T>>();
}

test2<T>(T t) {
if (t is int) {
late var v = t;
v.isEven;
v.expectStaticType<Exactly<T>>();
}
late var v = t;
v.expectStaticType<Exactly<T>>();
}

test3<T>(T t) {
if (t is int) {
final v = t;
v.isEven;
v.expectStaticType<Exactly<T>>();
}
final v = t;
v.expectStaticType<Exactly<T>>();
}

test4<T>(T t) {
if (t is int) {
late final v = t;
v.isEven;
v.expectStaticType<Exactly<T>>();
}
late final v = t;
v.expectStaticType<Exactly<T>>();
}

main() {
test1<int>(1);
test2<num>(2);
test3<int>(3);
test4<num>(4);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2023, 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.

/// @assertion The declared type of a local variable with a declaration of one
/// of the forms late? var v = e; late? final v = e; const v = e; is determined
/// as follows:
/// ...
/// • Otherwise, the declared type of v is the static type of e.
///
/// @description Checks that static type of a variable declared by the
/// statements `late? var v = e; late? final v = e; const v = e;` is the static
/// type of `e`
/// @author sgrekhov22@gmail.com
import '../../../Utils/static_type_helper.dart';

test4<T>(T t) {
if (t is int) {
late final v = t;
v.isEven;
v.expectStaticType<Exactly<T>>();
}
late final v = t;
v.expectStaticType<Exactly<T>>();
}

main() {
late var v1 = "1";
v1.expectStaticType<Exactly<String>>();

var v2 = 2;
v2.expectStaticType<Exactly<int>>();

late final v3 = 3 as num;
v3.expectStaticType<Exactly<num>>();

final v4 = 4 as int?;
v4.expectStaticType<Exactly<int?>>();

const v5 = 5 as num?;
v5.expectStaticType<Exactly<num?>>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2023, 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.

/// @assertion Assume that D is a local variable declaration with the modifier
/// late that declares a variable v, which has an initializing expression e. It
/// is a compile-time error if e contains an await expression a, unless there is
/// a function f which is the immediately enclosing function for a, and f is not
/// the immediately enclosing function for D.
///
/// @description Checks that it is a compile-time error if initializing
/// expression of a late local variable contains an `await` expression
/// @author sgrekhov22@gmail.com
import 'dart:async';

Future<T> foo<T>(T t) => Future<T>.value(t);

main() async {
late var v1 = await Future<int>.value(1);
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified

late final v2 = await foo<int>(2);
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified

late String v3 = await foo<String>("3");
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified

late final int v4 = await Future<int>.value(4);
// ^^^^^
// [analyzer] unspecified
// [cfe] unspecified

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) 2023, 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.

/// @assertion Assume that D is a local variable declaration with the modifier
/// late that declares a variable v, which has an initializing expression e. It
/// is a compile-time error if e contains an await expression a, unless there is
/// a function f which is the immediately enclosing function for a, and f is not
/// the immediately enclosing function for D.
///
/// @description Checks that it is not an error if there is a function `f` which
/// is the immediately enclosing function for `a`, and `f` is not the
/// immediately enclosing function for `D`
/// @author sgrekhov22@gmail.com
import 'dart:async';
import '../../../Utils/static_type_helper.dart';

Future<T> foo<T>(T t) => Future<T>.value(t);

main() {
late var v1 = () async => await Future<int>.value(1);
v1.expectStaticType<Exactly<Future<int> Function()>>();

late final v2 = () async {return await foo<int>(2);};
v2.expectStaticType<Exactly<Future<int> Function()>>();

late Future<String> v3 = () async {return await foo<String>("3");}();
print(v3);

late final Future<int> Function() v4 = () async => await Future<int>.value(4);
print(v4);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2023, 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.

/// @assertion Let D be a late and final local variable declaration that
/// declares a variable v. If an object o is assigned to v in a situation where
/// v is unbound then v is bound to o. If an object o is assigned to v in a
/// situation where v is bound to an object o′ then a dynamic error occurs (it
/// does not matter whether o is the same object as o′).
///
/// @description Checks that if an object `o` is assigned to a late final local
/// variable `v` in a situation where `v` is unbound then `v` is bound to `o`
/// @author sgrekhov22@gmail.com
import '../../../Utils/expect.dart';

class C {
int id;
C(this.id);
}

main() {
C c1 = C(1);
late final v1 = c1;
Expect.identical(c1, v1);

C c2 = C(2);
late final v2;
v2 = c2;
Expect.identical(c2, v2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright (c) 2023, 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.

/// @assertion Let D be a late and final local variable declaration that
/// declares a variable v. If an object o is assigned to v in a situation where
/// v is unbound then v is bound to o. If an object o is assigned to v in a
/// situation where v is bound to an object o′ then a dynamic error occurs (it
/// does not matter whether o is the same object as o′).
///
/// @description Checks that it is a dynamic error if an object `o` is assigned
/// to a late final local variable `v` in a situation where `v` is bound to some
/// object
/// @author sgrekhov22@gmail.com
import '../../../Utils/expect.dart';

class C {
int id;
C(this.id);
}

main() {
C c = C(1);
late final v;
if (2 > 1) {
v = c;
}
Expect.throws(() {
v = C(42);
});
Expect.throws(() {
v = c;
});
}

0 comments on commit 4beb74f

Please sign in to comment.