| Index: pkg/analyzer/test/src/task/strong/checker_test.dart
|
| diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
|
| index 2cdb1bf81f7ac9cde4594225e03ebcbb0ab89b3c..e1be1b3a56e5d3a6fea435273949f18b566be0be 100644
|
| --- a/pkg/analyzer/test/src/task/strong/checker_test.dart
|
| +++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
|
| @@ -499,6 +499,112 @@ void main() {
|
| ''');
|
| }
|
|
|
| + void test_covariantOverride() {
|
| + addFile(r'''
|
| +library meta;
|
| +class _Checked { const _Checked(); }
|
| +const Object checked = const _Checked();
|
| + ''', name: '/meta.dart');
|
| +
|
| + checkFile(r'''
|
| +import 'meta.dart';
|
| +class C {
|
| + num f(num x) => x;
|
| +}
|
| +class D extends C {
|
| + int f(@checked int x) => x;
|
| +}
|
| +class E extends D {
|
| + int f(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
|
| +}
|
| +class F extends E {
|
| + int f(@checked int x) => x;
|
| +}
|
| +class G extends E implements D {}
|
| +
|
| +class D_error extends C {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(int x) => x;
|
| +}
|
| +class E_error extends D {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0;
|
| +}
|
| +class F_error extends E {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0;
|
| +}
|
| +class G_error extends E implements D {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(@checked double x) => 0;
|
| +}
|
| + ''');
|
| + }
|
| +
|
| + void test_covariantOverride_leastUpperBound() {
|
| + addFile(r'''
|
| +library meta;
|
| +class _Checked { const _Checked(); }
|
| +const Object checked = const _Checked();
|
| + ''', name: '/meta.dart');
|
| +
|
| + checkFile(r'''
|
| +import "meta.dart";
|
| +abstract class Top {}
|
| +abstract class Left implements Top {}
|
| +abstract class Right implements Top {}
|
| +abstract class Bottom implements Left, Right {}
|
| +
|
| +abstract class TakesLeft {
|
| + m(Left x);
|
| +}
|
| +abstract class TakesRight {
|
| + m(Right x);
|
| +}
|
| +abstract class TakesTop implements TakesLeft, TakesRight {
|
| + m(Top x); // works today
|
| +}
|
| +abstract class TakesBottom implements TakesLeft, TakesRight {
|
| + // LUB(Left, Right) == Top, so this is an implicit cast from Top to Bottom.
|
| + m(@checked Bottom x);
|
| +}
|
| + ''');
|
| + }
|
| +
|
| + void test_covariantOverride_markerIsInherited() {
|
| + addFile(r'''
|
| +library meta;
|
| +class _Checked { const _Checked(); }
|
| +const Object checked = const _Checked();
|
| + ''', name: '/meta.dart');
|
| +
|
| + checkFile(r'''
|
| +import 'meta.dart';
|
| +class C {
|
| + num f(@checked num x) => x;
|
| +}
|
| +class D extends C {
|
| + int f(int x) => x;
|
| +}
|
| +class E extends D {
|
| + int f(Object x) => /*info:DOWN_CAST_IMPLICIT*/x;
|
| +}
|
| +class F extends E {
|
| + int f(int x) => x;
|
| +}
|
| +class G extends E implements D {}
|
| +
|
| +class D_error extends C {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(String x) => 0;
|
| +}
|
| +class E_error extends D {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0;
|
| +}
|
| +class F_error extends E {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0;
|
| +}
|
| +class G_error extends E implements D {
|
| + /*error:INVALID_METHOD_OVERRIDE*/int f(double x) => 0;
|
| +}
|
| + ''');
|
| + }
|
| +
|
| void test_dynamicInvocation() {
|
| checkFile('''
|
| typedef dynamic A(dynamic x);
|
|
|