Skip to content

Commit

Permalink
dart-lang#1400. More static analysis of the inline class tests (dart-…
Browse files Browse the repository at this point in the history
…lang#2068)

More static analysis of the inline class tests
  • Loading branch information
sgrekhov authored Jun 2, 2023
1 parent 736b818 commit e43ef65
Show file tree
Hide file tree
Showing 17 changed files with 781 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// 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 T1, .. Ts are types, and V resolves to an inline
/// class declaration of the following form:
///
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
/// final T id;
/// V(this.id);
///
/// ... // Other members.
/// }
/// ...
/// When s is zero, V<T1, .. Ts> simply stands for V, a non-generic inline type.
/// When s is greater than zero, a raw occurrence V is treated like a raw type:
/// Instantiation to bound is used to obtain the omitted type arguments
///
/// @description Checks that instantiation to bound is used to obtain the
/// omitted type arguments
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/static_type_helper.dart";

inline class V1<T extends num> {
final int id;
V1(this.id);
}

inline class V2<T extends Object> {
final int id;
V2(this.id);
}

inline class V3<T extends Object?> {
final int id;
V3(this.id);
}

main() {
var v1 = V1(42);
v1.expectStaticType<Exactly<V1<num>>>();

var v2 = V2(42);
v2.expectStaticType<Exactly<V2<Object>>>();

var v3 = V3(42);
v3.expectStaticType<Exactly<V3<Object?>>>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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 T1, .. Ts are types, and V resolves to an inline
/// class declaration of the following form:
///
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
/// final T id;
/// V(this.id);
///
/// ... // Other members.
/// }
/// ...
/// When s is zero, V<T1, .. Ts> simply stands for V, a non-generic inline type.
/// When s is greater than zero, a raw occurrence V is treated like a raw type:
/// Instantiation to bound is used to obtain the omitted type arguments
///
/// @description Checks that instantiation to bound is used to obtain the
/// omitted type arguments. Test default bound
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/expect.dart";

inline class V1<T> {
final int id;
V1(this.id);

Type get type => T;
}

main() {
var v1 = V1(42);
Expect.equals(dynamic, v1.type);
}
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 Assume that T1, .. Ts are types, and V resolves to an inline
/// class declaration of the following form:
///
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
/// final T id;
/// V(this.id);
///
/// ... // Other members.
/// }
/// ...
/// When s is zero, V<T1, .. Ts> simply stands for V, a non-generic inline type.
/// When s is greater than zero, a raw occurrence V is treated like a raw type:
/// Instantiation to bound is used to obtain the omitted type arguments
///
/// @description Checks that instantiation to bound is used to obtain the
/// omitted type arguments. Test a super-bounded type
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/expect.dart";

class A<T extends A<T>> {}
class B extends A<B> {}

inline class V<T extends A<T>> {
final int id;
V(this.id);

Type get type => T;
}

main() {
var v1 = V<Never>(42);
Expect.equals(Never, v1.type);

var v2 = V<B>(42);
Expect.equals(B, v2.type);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 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 T1, .. Ts are types, and V resolves to an inline
/// class declaration of the following form:
///
/// inline class V<X1 extends B1, .. Xs extends Bs> ... {
/// final T id;
/// V(this.id);
///
/// ... // Other members.
/// }
/// ...
/// When s is zero, V<T1, .. Ts> simply stands for V, a non-generic inline type.
/// When s is greater than zero, a raw occurrence V is treated like a raw type:
/// Instantiation to bound is used to obtain the omitted type arguments
///
/// @description Checks that it is a compile-time error to use super-bounded
/// inline type with wrong type arguments
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

class A<T extends A<T>> {}

inline class V<T extends A<T>> {
final int id;
V(this.id);

Type get type => T;
}

main() {
var v1 = V<void>(42);
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v2 = V<Object?>(42);
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v3 = V<dynamic>(42);
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v4 = V<Null>(42);
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v5 = V<A>(42);
// ^
// [analyzer] unspecified
// [cfe] unspecified

var v6 = V<A<Object?>>(42);
// ^^^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v7 = V<A<void>>(42);
// ^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v8 = V<A<Null>>(42);
// ^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

var v9 = V<A<dynamic>>(42);
// ^^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@

inline class V1 {
final int id;
V(this.id);
V1(this.id);
}

inline class V2<T> {
final T id;
V(this.id);
V2(this.id);
}

inline class V3<T extends num> {
final T id;
V(this.id);
V3(this.id);
}

main() async {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 If e is an expression whose static type V is the inline type
/// Inline<T1, .. Ts> and m is the name of a member that V has, a member access
/// like e.m(args) is treated as an invocation of the inline member m on the
/// receiver e according to the inline type Inline and with the actual type
/// arguments T1, ..., Ts, with the actual argument part args.
///
/// @description Checks that a member access `e.m(args)` is treated as an
/// invocation of the inline member m on the receiver `e` according to the
/// inline type `Inline` and with the actual type arguments `T1, ..., Ts`, with
/// the actual argument part `args`.
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/static_type_helper.dart";

inline class V1<T> {
final T id;
V1(this.id);

(Map<K, V>, T) asMap<K, V>() => (<K, V>{}, id);
}

main() {
V1<num> v1 = V1(42);
v1.asMap<String, bool>()
.expectStaticType<Exactly<(Map<String, bool>, num)>>();

V1<String> v2 = V1("42");
v2.asMap<String, String>()
.expectStaticType<Exactly<(Map<String, String>, String)>>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// 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 Similarly, e.m is treated an invocation of the inline member m on
/// the receiver e according to the inline type Inline and with the actual type
/// arguments T1, ..., Ts and no actual argument part.
///
/// @description Checks that a member access `e.m` is treated as an invocation
/// of the inline member `m` on the receiver `e` according to the inline type
/// `Inline` and with the actual type arguments `T1, ..., Ts` and no actual
/// argument part
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/static_type_helper.dart";

inline class V1<T, K, V> {
final T id;
V1(this.id);

(Map<K, V>, T) get asMap => (<K, V>{}, id);
}

main() {
V1<num, String, bool> v1 = V1(42);
v1.asMap.expectStaticType<Exactly<(Map<String, bool>, num)>>();

V1<String, String, Null> v2 = V1("42");
v2.asMap.expectStaticType<Exactly<(Map<String, Null>, String)>>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// 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 If e is an expression whose static type V is the inline type
/// Inline<T1, .. Ts> and V has no member whose basename is the basename of m,
/// a member access like e.m(args) may be an extension member access, following
/// the normal rules about applicability and accessibility of extensions, in
/// particular that V must match the on-type of the extension.
///
/// @description Checks that if `V` has no member with the name `m`, but there
/// is an extension member `m` then it is invoked
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

import "../../Utils/expect.dart";

extension Ex1 on V {
String foo() => "Ex1.foo()";
}

extension Ex2 on int {
String bar() => "Ex2.bar()";
}

inline class V {
final int id;
V(this.id);
}

main() {
V v = V(42);
Expect.equals("Ex1.foo()", v.foo());
Expect.equals("Ex2.bar()", v.id.bar());
}
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 If e is an expression whose static type V is the inline type
/// Inline<T1, .. Ts> and V has no member whose basename is the basename of m,
/// a member access like e.m(args) may be an extension member access, following
/// the normal rules about applicability and accessibility of extensions, in
/// particular that V must match the on-type of the extension.
///
/// @description Checks that it is a compile-time error if `V` has no member
/// with name `m` and there is no extension member with the name `m`
/// @author sgrekhov22@gmail.com
// SharedOptions=--enable-experiment=inline-class

extension Ex1 on V {
String foo() => "Ex1.foo()";
}

extension Ex2 on int {
String bar() => "Ex2.bar()";
}

inline class V {
final int id;
V(this.id);
}

main() {
V v = V(42);
v.bar();
// ^^^
// [analyzer] unspecified
// [cfe] unspecified

v.id.foo();
// ^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Loading

0 comments on commit e43ef65

Please sign in to comment.