blob: 85a5efbadba37d5b0ae1549c8de8cbb160ffeb6e [file] [log] [blame]
// 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 'dart:async';
// Tests several aspects of the TOP_MERGE algorithm for merging super-interfaces.
// This tests that TOP_MERGE is not applied when a class directly overrides a
// method. Instead, the signature of the overriding method should apply.
class A<T> {
T member() {
throw "Unreachable";
}
}
void takesObject(Object x) {}
class D0 extends A<dynamic> {
Object? member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void`
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class D1 extends A<Object?> {
dynamic member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member returns `dynamic`
}
}
class D2 extends A<void> {
Object? member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void`
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class D3 extends A<Object?> {
void member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object?`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class D4 extends A<void> {
dynamic member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member returns `dynamic`
}
}
class D5 extends A<dynamic> {
void member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object?`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class D6 extends A<void> {
void member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object?`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class D7 extends A<dynamic> {
dynamic member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member returns `dynamic`
}
}
// Test the same examples with top level normalization
class ND0 extends A<FutureOr<dynamic>> {
Object? member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void`
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class ND1 extends A<FutureOr<Object?>> {
dynamic member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member returns `dynamic`
}
}
class ND2 extends A<FutureOr<void>> {
Object? member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void`
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class ND3 extends A<FutureOr<Object?>> {
void member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object?`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class ND4 extends A<FutureOr<void>> {
dynamic member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member returns `dynamic`
}
}
class ND5 extends A<FutureOr<dynamic>> {
void member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object?`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class ND6 extends A<FutureOr<void>> {
void member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member does not return `dynamic`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object?`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class ND7 extends A<FutureOr<dynamic>> {
dynamic member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member();
x.foo; // Check that member returns `dynamic`
}
}
// Test the same examples with deep normalization
class DND0 extends A<FutureOr<dynamic> Function()> {
Object? Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class DND1 extends A<FutureOr<Object?> Function()> {
dynamic Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member returns `dynamic Function()`
}
}
class DND2 extends A<FutureOr<void> Function()> {
Object? Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class DND3 extends A<FutureOr<Object?> Function()> {
void Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object? Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class DND4 extends A<FutureOr<void> Function()> {
dynamic Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member returns `dynamic Function()`
}
}
class DND5 extends A<FutureOr<dynamic> Function()> {
void Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object? Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class DND6 extends A<FutureOr<void> Function()> {
void Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `Object? Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class DND7 extends A<FutureOr<dynamic> Function()> {
dynamic Function() member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member returns `dynamic Function()`
}
}
// Test the same examples with deep normalization + typedefs
// With all override examples, no normalization is specified, and so
// all errors and warnings should look like the `Object?` errors and
// warnings (we don't distinguish between the method sets on `Object?`
// and `FutureOr<T>` for any `T`).
typedef Wrap<T> = FutureOr<T>? Function();
class WND0 extends A<Wrap<FutureOr<dynamic>>> {
Wrap<FutureOr<Object?>> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND1 extends A<Wrap<FutureOr<Object?>>> {
Wrap<dynamic> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND2 extends A<Wrap<FutureOr<void>>> {
Wrap<Object?> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND3 extends A<Wrap<FutureOr<Object?>>> {
Wrap<void> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND4 extends A<Wrap<FutureOr<void>>> {
Wrap<dynamic> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND5 extends A<Wrap<FutureOr<dynamic>>> {
Wrap<void> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND6 extends A<Wrap<FutureOr<void>>> {
Wrap<void> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}
class WND7 extends A<Wrap<FutureOr<dynamic>>> {
Wrap<dynamic> member() {
throw "Unreachable";
}
void test() {
var self = this;
var x = self.member()();
x.foo; // Check that member does not return `dynamic Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
x.toString; // Check that member does not return `void Function()`
takesObject(x); // Check that member does not return `Object Function()`
// ^
// [analyzer] unspecified
// [cfe] unspecified
}
}