Skip to content

Commit

Permalink
#2142. Change static analysis member invocation tests to be extension…
Browse files Browse the repository at this point in the history
… type tests (#2150)

Change static analysis member invocation tests to be extension type tests.
  • Loading branch information
sgrekhov authored Aug 9, 2023
1 parent 7e980e1 commit d31a3b6
Show file tree
Hide file tree
Showing 11 changed files with 265 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,24 @@
// BSD-style license that can be found in the LICENSE file.

/// @assertion If the name of m is a name in the interface of Object (that is,
/// toString, ==, etc.), the static analysis of the invocation is treated as an
/// ordinary instance member invocation on a receiver of type Object and with
/// the same args, if any.
/// toString, ==, hashCode, runtimeType, or noSuchMethod), the static analysis
/// of the invocation is treated as an ordinary instance member invocation on a
/// receiver of type Object? and with the same args or typeArgs, if any.
///
/// @description Checks that members of an `Object` class can be called
/// @author [email protected]
// SharedOptions=--enable-experiment=inline-class

inline class IC {
final int id;
IC(this.id);
}
extension type ET(int id) {}

main() {
IC ic = IC(42);
ic.toString();
ic.runtimeType;
ic.hashCode;
ic == ic;
ET et = ET(42);
et.toString();
et.runtimeType;
et.hashCode;
et == et;
try {
ic.noSuchMethod(Invocation.method(Symbol("test"), []));
et.noSuchMethod(Invocation.method(Symbol("test"), []));
} catch (_) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,43 @@
/// @assertion A compile-time error occurs if V does not have a member named m.
///
/// @description Checks that it is a compile-time error to call a not-existing
/// member of an `inline` class
/// member of an extension type
/// @author [email protected]
// SharedOptions=--enable-experiment=inline-class

inline class BaseIC {
final int id;
BaseIC(this.id);
extension type ET0(int id) {
foo() {}
}

inline class IC implements BaseIC {
final int id;
IC(this.id);
extension type ET(int id) implements ET0 {
foo() {}
bar() {}
}

main() {
IC ic = IC(42);
ic.noGetter;
ET et = ET(42);
et.noGetter;
// ^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

ic.noSetter = 0;
et.noSetter = 0;
// ^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

ic.noMethod();
et.noMethod();
// ^^^^^^^^
// [analyzer] unspecified
// [cfe] unspecified

ic + 1;
et + 1;
// ^
// [analyzer] unspecified
// [cfe] unspecified

ic.id;
ic.foo();
ic.bar();
et.id;
et.foo();
et.bar();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,40 @@
// 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 Dm is a getter declaration with return type R then the static
/// type of the invocation is [T1/X1 .. Ts/Xs]R.
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with the
/// actual type arguments T1, ..., Ts.
/// ...
/// V has an extension type member m with a uniquely determined declaration Dm
/// ...
/// If Dm is a getter declaration with return type R then the static type of the
/// invocation is R
///
/// @description Checks static type of a getter of an `inline` class
/// @description Checks static type of a getter of an extension type
/// @author [email protected]
// SharedOptions=--enable-experiment=inline-class

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

inline class IC1 {
final num id;
IC1(this.id);

extension type ET1(num id) {
int get asInt => id.toInt();
}

inline class IC2<T extends num> {
final T id;
IC2(this.id);

extension type ET2<T extends num>(T id) {
double get asDouble => id.toDouble();
}

main() {
IC1 ic1 = IC1(42);
ic1.asInt.expectStaticType<Exactly<int>>();
ic1.id.expectStaticType<Exactly<num>>();
ET1 et1 = ET1(42);
et1.asInt.expectStaticType<Exactly<int>>();
et1.id.expectStaticType<Exactly<num>>();

IC2<num> ic2 = IC2<double>(3.14);
ic2.asDouble.expectStaticType<Exactly<double>>();
ic2.id.expectStaticType<Exactly<num>>();
ET2<num> et2 = ET2<double>(3.14);
et2.asDouble.expectStaticType<Exactly<double>>();
et2.id.expectStaticType<Exactly<num>>();

IC2<double> ic3 = IC2(3.14);
ic3.asDouble.expectStaticType<Exactly<double>>();
ic3.id.expectStaticType<Exactly<double>>();
ET2<double> et3 = ET2(3.14);
et3.asDouble.expectStaticType<Exactly<double>>();
et3.id.expectStaticType<Exactly<double>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,47 @@
// 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 Dm is a method with function type F, and args is omitted, the
/// invocation has static type [T1/X1 .. Ts/Xs]F.
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with the
/// actual type arguments T1, ..., Ts.
/// ...
/// V has an extension type member m with a uniquely determined declaration Dm
/// ...
/// If Dm is a method with function type F, and args is omitted, the invocation
/// has static type F
///
/// @description Checks static type of a method tear-off with omitted type
/// arguments of an `inline` class
/// arguments of an extension type
/// @author [email protected]
// SharedOptions=--enable-experiment=inline-class

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

inline class IC1 {
final int id;
IC1(this.id);

extension type ET1(int id) {
int foo<T1, T2 extends num>() => 42;
}

inline class IC2<T extends num> {
final T id;
IC2(this.id);

extension type ET2<T extends num>(T id) {
T foo<T1, T2 extends T>() => id;
}

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

extension type ET3<T>(T id) {
Map<K, V> asMap<K, V extends T>(K key) => {key: this.id as V};
}

main() {
IC1 ic1 = IC1(42);
ic1.foo.expectStaticType<Exactly<int Function<T1, T2 extends num>()>>();
ET1 et1 = ET1(42);
et1.foo.expectStaticType<Exactly<int Function<T1, T2 extends num>()>>();

IC2<num> ic2 = IC2<double>(3.14);
ic2.foo.expectStaticType<Exactly<num Function<T1, T2 extends num>()>>();
ET2<num> et2 = ET2<double>(3.14);
et2.foo.expectStaticType<Exactly<num Function<T1, T2 extends num>()>>();

IC2<double> ic2_2 = IC2(3.14);
ic2_2.foo
ET2<double> et2_2 = ET2(3.14);
et2_2.foo
.expectStaticType<Exactly<double Function<T1, T2 extends double>()>>();

IC3<int> ic3 = IC3(0);
ic3.asMap
ET3<int> et3 = ET3(0);
et3.asMap
.expectStaticType<Exactly<Map<K, V> Function<K, V extends int>(K)>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,17 @@
// 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 Dm is a method with function type F, and args exists, the
/// static analysis of the inline member invocation is the same as that of an
/// invocation with argument part args of a function with type [T1/X1 .. Ts/Xs]F
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with the
/// actual type arguments T1, ..., Ts.
/// ...
/// V has an extension type member m with a uniquely determined declaration Dm
/// ...
/// Assume that Dm is a method with function type F, and typeArgs is provided. A
/// compile-time error occurs if F is not a generic function type where typeArgs
/// is a list of actual type arguments that conform to the declared bounds. If
/// no error occurred, the invocation has the static type which is a non-generic
/// function type where typeArgs are substituted into the function type.
///
/// @description Checks static type of a method tear-off with type arguments
/// specified
Expand All @@ -14,40 +22,31 @@

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

inline class IC1 {
final int id;
IC1(this.id);

extension type ET1(int id) {
int foo<T1, T2 extends num>() => 42;
}

inline class IC2<T extends num> {
final T id;
IC2(this.id);

extension type ET2<T extends num>(T id) {
T foo<T1, T2 extends T>() => id;
}

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

extension type ET3<T>(T id) {
Map<K, V> asMap<K, V extends T>(K key) => {key: this.id as V};
}

main() {
IC1 ic1 = IC1(42);
ic1.foo<String, double>.expectStaticType<Exactly<int Function()>>();
ET1 et1 = ET1(42);
et1.foo<String, double>.expectStaticType<Exactly<int Function()>>();

IC2<num> ic2_1 = IC2<double>(3.14);
ic2_1.foo<String, double>.expectStaticType<Exactly<num Function()>>();
ET2<num> et2_1 = ET2<double>(3.14);
et2_1.foo<String, double>.expectStaticType<Exactly<num Function()>>();

IC2<double> ic2_2 = IC2(3.14);
ic2_2.foo<String, double>.expectStaticType<Exactly<double Function()>>();
ET2<double> et2_2 = ET2(3.14);
et2_2.foo<String, double>.expectStaticType<Exactly<double Function()>>();

IC3<num> ic3 = IC3(0);
ic3.asMap<String, double>
ET3<num> et3 = ET3(0);
et3.asMap<String, double>
.expectStaticType<Exactly<Map<String, double> Function(String)>>();
ic3.asMap<String, int>
et3.asMap<String, int>
.expectStaticType<Exactly<Map<String, int> Function(String)>>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@
// 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 Dm is a method with function type F, and args exists, the
/// static analysis of the inline member invocation is the same as that of an
/// invocation with argument part args of a function with type [T1/X1 .. Ts/Xs]F
/// @assertion Consider an invocation of the extension type member m on the
/// receiver expression e according to the extension type declaration V with the
/// actual type arguments T1, ..., Ts.
/// ...
/// V has an extension type member m with a uniquely determined declaration Dm
/// ...
/// Assume that Dm is a method with function type F, and typeArgs is provided. A
/// compile-time error occurs if F is not a generic function type where typeArgs
/// is a list of actual type arguments that conform to the declared bounds. If
/// no error occurred, the invocation has the static type which is a non-generic
/// function type where typeArgs are substituted into the function type.
///
/// @description Checks that it is a compile-time error to specify a wrong
/// type argument of a torn-off method
/// @author [email protected]
// SharedOptions=--enable-experiment=inline-class

inline class IC1 {
final int id;
IC1(this.id);

extension type ET1(int id) {
int foo<T1, T2 extends num>() => 42;
}

main() {
IC1 ic1 = IC1(42);
ic1.foo<String, String>;
ET1 et1 = ET1(42);
et1.foo<String, String>;
// ^^^^^^
// [analyzer] unspecified
// [cfe] unspecified
Expand Down
Loading

0 comments on commit d31a3b6

Please sign in to comment.