Skip to content

Commit

Permalink
Fixes dart-lang#2505. Add more tests for call member
Browse files Browse the repository at this point in the history
  • Loading branch information
sgrekhov committed Jan 25, 2024
1 parent 07ce2fd commit 91b11d7
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@
// 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 A function expression invocation
/// ef(a1, ..., an, xn+1: an+1, ..., xn+k: an+k) is equivalent to
/// ef.call(a1, ..., an, xn+1: an+1, ..., xn+k: an+k).
/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that a function expression invocation ef(...) is indeed
/// equivalent to the ordinary method invocation ef.call(...) and that the result
/// in either case is the same as expected whether ef is a function literal
/// expression or some other kind of expression.
/// equivalent to the ordinary method invocation ef.call(...) and that the
/// result in either case is the same as expected whether ef is a function
/// literal expression or some other kind of expression.
/// @author rodionov
import '../../../../Utils/expect.dart';
Expand All @@ -21,7 +26,6 @@ class C {

main() {
C c = new C();

Expect.equals("call(1, foo)", c(1));
Expect.equals("call(2, bar)", c(2, "bar"));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that an interface containing a `call` method is
/// assignable to the type `Function`
/// @author sgrekhov22@gmail.com
import '../../../../Utils/expect.dart';

class C {
int call() => 1;
}

enum E {
e1, e2;

int call() => 2;
}

mixin M {
int call() => 3;
}

class MA = Object with M;

main() {
Function f1 = C();
Function f2 = E.e1;
Function f3 = MA();

Expect.equals(1, f1());
Expect.equals(2, f2());
Expect.equals(3, f3());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that an interface containing a `call` getter is not
/// assignable to the type `Function`
/// @author sgrekhov22@gmail.com
class C {
int get call => 1;
}

enum E {
e1, e2;

int get call => 2;
}

mixin M {
int get call => 3;
}

class MA = Object with M;

main() {
Function f1 = C();
// ^^^
// [analyzer] unspecified
// [cfe] unspecified
Function f2 = E.e1;
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified
Function f3 = MA();
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that an interface containing a `call` setter is not
/// assignable to the type `Function`
/// @author sgrekhov22@gmail.com
class C {
void set call(int _) {}
}

enum E {
e1, e2;

void set call(int _) {}
}

mixin M {
void set call(int _) {}
}

class MA = Object with M;

main() {
Function f1 = C();
// ^^^
// [analyzer] unspecified
// [cfe] unspecified
Function f2 = E.e1;
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified
Function f3 = MA();
// ^^^^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks an implicit tear off `call` from a receiver whose type
/// is a type variable
/// @author sgrekhov22@gmail.com
import '../../../../Utils/expect.dart';
import '../../../../Utils/static_type_helper.dart';

class A {
int call() => 42;
}

Function f<X extends A>(X x) => x;

void main() {
f(A()).expectStaticType<Exactly<Function>>();
Expect.equals(42, f(A())());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that it is a compile-time error to assign an implicit
/// tear off a `call` getter or setter to the type `Function`
/// @author sgrekhov22@gmail.com
class A {
int get call => 42;
}

class B {
void set call(int _) {}
}

Function f1<X extends A>(X x) => x;
// ^
// [analyzer] unspecified
// [cfe] unspecified
Function f2<X extends B>(X x) => x;
// ^
// [analyzer] unspecified
// [cfe] unspecified

void main() {
print(f1);
print(f2);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that a record with a `call` member is not assignable to
/// the type `Function`
/// @author sgrekhov22@gmail.com
void main() {
var r = (call: () => 42);
Function f = r;
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// 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.

/// @assertion A function expression invocation i has the form
/// ef <A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k),
/// where ef is an expression.
/// ...
/// Let F be the static type of ef . If F is an interface type that has a method
/// named call, i is treated as the ordinary invocation
/// ef .call<A1, . . . , Ar>(a1, . . . , an, xn+1: an+1, . . . , xn+k: an+k)
///
/// @description Checks that it is a compile-time error to call a a `call`
/// member of a record
/// @author sgrekhov22@gmail.com
/// @issue 54616,54651
void main() {
var r = (call: () => 42);
r();
//^^^
// [analyzer] unspecified
// [cfe] unspecified
r.call(); // Ok
}

0 comments on commit 91b11d7

Please sign in to comment.