| Index: test/checker/checker_test.dart
 | 
| diff --git a/test/checker/checker_test.dart b/test/checker/checker_test.dart
 | 
| deleted file mode 100644
 | 
| index ba9885292fd16fbc4eb60cefe25c59c150b49a9c..0000000000000000000000000000000000000000
 | 
| --- a/test/checker/checker_test.dart
 | 
| +++ /dev/null
 | 
| @@ -1,2319 +0,0 @@
 | 
| -// Copyright (c) 2015, 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.
 | 
| -
 | 
| -/// General type checking tests
 | 
| -library dev_compiler.test.checker_test;
 | 
| -
 | 
| -import 'package:test/test.dart';
 | 
| -
 | 
| -import '../testing.dart';
 | 
| -
 | 
| -void main() {
 | 
| -  testChecker('ternary operator', {
 | 
| -    '/main.dart': '''
 | 
| -        abstract class Comparable<T> {
 | 
| -          int compareTo(T other);
 | 
| -          static int compare(Comparable a, Comparable b) => a.compareTo(b);
 | 
| -        }
 | 
| -        typedef int Comparator<T>(T a, T b);
 | 
| -
 | 
| -        typedef bool _Predicate<T>(T value);
 | 
| -
 | 
| -        class SplayTreeMap<K, V> {
 | 
| -          Comparator<K> _comparator;
 | 
| -          _Predicate _validKey;
 | 
| -
 | 
| -          // Initializing _comparator needs a cast, since K may not always be
 | 
| -          // Comparable.
 | 
| -          // Initializing _validKey shouldn't need a cast.  Currently
 | 
| -          // it requires inference to work because of dartbug.com/23381
 | 
| -          SplayTreeMap([int compare(K key1, K key2),
 | 
| -                        bool isValidKey(potentialKey)]) {
 | 
| -            : _comparator = /*warning:DownCastComposite*/(compare == null) ? Comparable.compare : compare,
 | 
| -              _validKey = /*info:InferredType should be pass*/(isValidKey != null) ? isValidKey : ((v) => true);
 | 
| -              _Predicate<Object> _v = /*warning:DownCastComposite*/(isValidKey != null) ? isValidKey : ((v) => true);
 | 
| -              _v = /*info:InferredType should be pass*/(isValidKey != null) ? _v : ((v) => true);
 | 
| -          }
 | 
| -        }
 | 
| -        void main() {
 | 
| -          Object obj = 42;
 | 
| -          dynamic dyn = 42;
 | 
| -          int i = 42;
 | 
| -
 | 
| -          // Check the boolean conversion of the condition.
 | 
| -          print((/*severe:StaticTypeError*/i) ? false : true);
 | 
| -          print((/*info:DownCastImplicit*/obj) ? false : true);
 | 
| -          print((/*info:DynamicCast*/dyn) ? false : true);
 | 
| -        }
 | 
| -      '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('if/for/do/while statements use boolean conversion', {
 | 
| -    '/main.dart': '''
 | 
| -      main() {
 | 
| -        dynamic d = 42;
 | 
| -        Object obj = 42;
 | 
| -        int i = 42;
 | 
| -        bool b = false;
 | 
| -
 | 
| -        if (b) {}
 | 
| -        if (/*info:DynamicCast*/dyn) {}
 | 
| -        if (/*info:DownCastImplicit*/obj) {}
 | 
| -        if (/*severe:StaticTypeError*/i) {}
 | 
| -
 | 
| -        while (b) {}
 | 
| -        while (/*info:DynamicCast*/dyn) {}
 | 
| -        while (/*info:DownCastImplicit*/obj) {}
 | 
| -        while (/*severe:StaticTypeError*/i) {}
 | 
| -
 | 
| -        do {} while (b);
 | 
| -        do {} while (/*info:DynamicCast*/dyn);
 | 
| -        do {} while (/*info:DownCastImplicit*/obj);
 | 
| -        do {} while (/*severe:StaticTypeError*/i);
 | 
| -
 | 
| -        for (;b;) {}
 | 
| -        for (;/*info:DynamicCast*/dyn;) {}
 | 
| -        for (;/*info:DownCastImplicit*/obj;) {}
 | 
| -        for (;/*severe:StaticTypeError*/i;) {}
 | 
| -      }
 | 
| -    '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('dynamic invocation', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {
 | 
| -        dynamic call(dynamic x) => x;
 | 
| -      }
 | 
| -      class B extends A {
 | 
| -        int call(int x) => x;
 | 
| -        double col(double x) => x;
 | 
| -      }
 | 
| -      void main() {
 | 
| -        {
 | 
| -          B f = new B();
 | 
| -          int x;
 | 
| -          double y;
 | 
| -          // The analyzer has what I believe is a bug (dartbug.com/23252) which
 | 
| -          // causes the return type of calls to f to be treated as dynamic.
 | 
| -          x = /*info:DynamicCast should be pass*/f(3);
 | 
| -          x = /*severe:StaticTypeError*/f.col(3.0);
 | 
| -          y = /*info:DynamicCast should be severe:StaticTypeError*/f(3);
 | 
| -          y = f.col(3.0);
 | 
| -          f(/*severe:StaticTypeError*/3.0);
 | 
| -          f.col(/*severe:StaticTypeError*/3);
 | 
| -        }
 | 
| -        {
 | 
| -          Function f = new B();
 | 
| -          int x;
 | 
| -          double y;
 | 
| -          x = /*info:DynamicCast, info:DynamicInvoke*/f(3);
 | 
| -          x = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0);
 | 
| -          y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
 | 
| -          y = /*info:DynamicCast, info:DynamicInvoke*/f.col(3.0);
 | 
| -          (/*info:DynamicInvoke*/f(3.0));
 | 
| -          (/*info:DynamicInvoke*/f.col(3));
 | 
| -        }
 | 
| -        {
 | 
| -          A f = new B();
 | 
| -          int x;
 | 
| -          double y;
 | 
| -          x = /*info:DynamicCast, info:DynamicInvoke*/f(3);
 | 
| -          y = /*info:DynamicCast, info:DynamicInvoke*/f(3);
 | 
| -          (/*info:DynamicInvoke*/f(3.0));
 | 
| -        }
 | 
| -      }
 | 
| -    '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('conversion and dynamic invoke', {
 | 
| -    '/helper.dart': '''
 | 
| -      dynamic toString = (int x) => x + 42;
 | 
| -      dynamic hashCode = "hello";
 | 
| -      ''',
 | 
| -    '/main.dart': '''
 | 
| -      import 'helper.dart' as helper;
 | 
| -
 | 
| -      class A {
 | 
| -        String x = "hello world";
 | 
| -
 | 
| -        void baz1(y) => x + /*info:DynamicCast*/y;
 | 
| -        static baz2(y) => /*info:DynamicInvoke*/y + y;
 | 
| -      }
 | 
| -
 | 
| -      void foo(String str) {
 | 
| -        print(str);
 | 
| -      }
 | 
| -
 | 
| -      class B {
 | 
| -        String toString([int arg]) => arg.toString();
 | 
| -      }
 | 
| -
 | 
| -      void bar(a) {
 | 
| -        foo(/*info:DynamicCast,info:DynamicInvoke*/a.x);
 | 
| -      }
 | 
| -
 | 
| -      baz() => new B();
 | 
| -
 | 
| -      typedef DynFun(x);
 | 
| -      typedef StrFun(String x);
 | 
| -
 | 
| -      var bar1 = bar;
 | 
| -
 | 
| -      void main() {
 | 
| -        var a = new A();
 | 
| -        bar(a);
 | 
| -        (/*info:DynamicInvoke*/bar1(a));
 | 
| -        var b = bar;
 | 
| -        (/*info:DynamicInvoke*/b(a));
 | 
| -        var f1 = foo;
 | 
| -        f1("hello");
 | 
| -        dynamic f2 = foo;
 | 
| -        (/*info:DynamicInvoke*/f2("hello"));
 | 
| -        DynFun f3 = foo;
 | 
| -        (/*info:DynamicInvoke*/f3("hello"));
 | 
| -        (/*info:DynamicInvoke*/f3(42));
 | 
| -        StrFun f4 = foo;
 | 
| -        f4("hello");
 | 
| -        a.baz1("hello");
 | 
| -        var b1 = a.baz1;
 | 
| -        (/*info:DynamicInvoke*/b1("hello"));
 | 
| -        A.baz2("hello");
 | 
| -        var b2 = A.baz2;
 | 
| -        (/*info:DynamicInvoke*/b2("hello"));
 | 
| -
 | 
| -        dynamic a1 = new B();
 | 
| -        (/*info:DynamicInvoke*/a1.x);
 | 
| -        a1.toString();
 | 
| -        (/*info:DynamicInvoke*/a1.toString(42));
 | 
| -        var toStringClosure = a1.toString;
 | 
| -        (/*info:DynamicInvoke*/a1.toStringClosure());
 | 
| -        (/*info:DynamicInvoke*/a1.toStringClosure(42));
 | 
| -        (/*info:DynamicInvoke*/a1.toStringClosure("hello"));
 | 
| -        a1.hashCode;
 | 
| -
 | 
| -        dynamic toString = () => null;
 | 
| -        (/*info:DynamicInvoke*/toString());
 | 
| -
 | 
| -        (/*info:DynamicInvoke*/helper.toString());
 | 
| -        var toStringClosure2 = helper.toString;
 | 
| -        (/*info:DynamicInvoke*/toStringClosure2());
 | 
| -        int hashCode = /*info:DynamicCast*/helper.hashCode;
 | 
| -
 | 
| -        baz().toString();
 | 
| -        baz().hashCode;
 | 
| -      }
 | 
| -    '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Constructors', {
 | 
| -    '/main.dart': '''
 | 
| -      const num z = 25;
 | 
| -      Object obj = "world";
 | 
| -
 | 
| -      class A {
 | 
| -        int x;
 | 
| -        String y;
 | 
| -
 | 
| -        A(this.x) : this.y = /*severe:StaticTypeError*/42;
 | 
| -
 | 
| -        A.c1(p): this.x = /*info:DownCastImplicit*/z, this.y = /*info:DynamicCast*/p;
 | 
| -
 | 
| -        A.c2(this.x, this.y);
 | 
| -
 | 
| -        A.c3(/*severe:InvalidParameterDeclaration*/num this.x, String this.y);
 | 
| -      }
 | 
| -
 | 
| -      class B extends A {
 | 
| -        B() : super(/*severe:StaticTypeError*/"hello");
 | 
| -
 | 
| -        B.c2(int x, String y) : super.c2(/*severe:StaticTypeError*/y, 
 | 
| -                                         /*severe:StaticTypeError*/x);
 | 
| -
 | 
| -        B.c3(num x, Object y) : super.c3(x, /*info:DownCastImplicit*/y);
 | 
| -      }
 | 
| -
 | 
| -      void main() {
 | 
| -         A a = new A.c2(/*info:DownCastImplicit*/z, /*severe:StaticTypeError*/z);
 | 
| -         var b = new B.c2(/*severe:StaticTypeError*/"hello", /*info:DownCastImplicit*/obj);
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Unbound variable', {
 | 
| -    '/main.dart': '''
 | 
| -      void main() {
 | 
| -         dynamic y = /*pass should be severe:StaticTypeError*/unboundVariable;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Unbound type name', {
 | 
| -    '/main.dart': '''
 | 
| -      void main() {
 | 
| -         /*pass should be severe:StaticTypeError*/AToB y;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Ground type subtyping: dynamic is top', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      void main() {
 | 
| -         dynamic y;
 | 
| -         Object o;
 | 
| -         int i = 0;
 | 
| -         double d = 0.0;
 | 
| -         num n;
 | 
| -         A a;
 | 
| -         B b;
 | 
| -         y = o;
 | 
| -         y = i;
 | 
| -         y = d;
 | 
| -         y = n;
 | 
| -         y = a;
 | 
| -         y = b;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Ground type subtyping: dynamic downcasts', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      void main() {
 | 
| -         dynamic y;
 | 
| -         Object o;
 | 
| -         int i = 0;
 | 
| -         double d = 0.0;
 | 
| -         num n;
 | 
| -         A a;
 | 
| -         B b;
 | 
| -         o = y;
 | 
| -         i = /*info:DynamicCast*/y;
 | 
| -         d = /*info:DynamicCast*/y;
 | 
| -         n = /*info:DynamicCast*/y;
 | 
| -         a = /*info:DynamicCast*/y;
 | 
| -         b = /*info:DynamicCast*/y;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Ground type subtyping: assigning a class', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      void main() {
 | 
| -         dynamic y;
 | 
| -         Object o;
 | 
| -         int i = 0;
 | 
| -         double d = 0.0;
 | 
| -         num n;
 | 
| -         A a;
 | 
| -         B b;
 | 
| -         y = a;
 | 
| -         o = a;
 | 
| -         i = /*severe:StaticTypeError*/a;
 | 
| -         d = /*severe:StaticTypeError*/a;
 | 
| -         n = /*severe:StaticTypeError*/a;
 | 
| -         a = a;
 | 
| -         b = /*info:DownCastImplicit*/a;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Ground type subtyping: assigning a subclass', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -      class C extends A {}
 | 
| -
 | 
| -      void main() {
 | 
| -         dynamic y;
 | 
| -         Object o;
 | 
| -         int i = 0;
 | 
| -         double d = 0.0;
 | 
| -         num n;
 | 
| -         A a;
 | 
| -         B b;
 | 
| -         C c;
 | 
| -         y = b;
 | 
| -         o = b;
 | 
| -         i = /*severe:StaticTypeError*/b;
 | 
| -         d = /*severe:StaticTypeError*/b;
 | 
| -         n = /*severe:StaticTypeError*/b;
 | 
| -         a = b;
 | 
| -         b = b;
 | 
| -         c = /*severe:StaticTypeError*/b;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Ground type subtyping: interfaces', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -      class C extends A {}
 | 
| -      class D extends B implements C {}
 | 
| -
 | 
| -      void main() {
 | 
| -         A top;
 | 
| -         B left;
 | 
| -         C right;
 | 
| -         D bot;
 | 
| -         {
 | 
| -           top = top;
 | 
| -           top = left;
 | 
| -           top = right;
 | 
| -           top = bot;
 | 
| -         }
 | 
| -         {
 | 
| -           left = /*info:DownCastImplicit*/top;
 | 
| -           left = left;
 | 
| -           left = /*severe:StaticTypeError*/right;
 | 
| -           left = bot;
 | 
| -         }
 | 
| -         {
 | 
| -           right = /*info:DownCastImplicit*/top;
 | 
| -           right = /*severe:StaticTypeError*/left;
 | 
| -           right = right;
 | 
| -           right = bot;
 | 
| -         }
 | 
| -         {
 | 
| -           bot = /*info:DownCastImplicit*/top;
 | 
| -           bot = /*info:DownCastImplicit*/left;
 | 
| -           bot = /*info:DownCastImplicit*/right;
 | 
| -           bot = bot;
 | 
| -         }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: int and object', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      typedef Object Top(int x);      // Top of the lattice
 | 
| -      typedef int Left(int x);        // Left branch
 | 
| -      typedef int Left2(int x);       // Left branch
 | 
| -      typedef Object Right(Object x); // Right branch
 | 
| -      typedef int Bot(Object x);      // Bottom of the lattice
 | 
| -
 | 
| -      Object top(int x) => x;
 | 
| -      int left(int x) => x;
 | 
| -      Object right(Object x) => x;
 | 
| -      int _bot(Object x) => /*info:DownCastImplicit*/x;
 | 
| -      int bot(Object x) => x as int;
 | 
| -
 | 
| -      void main() {
 | 
| -        { // Check typedef equality
 | 
| -          Left f = left;
 | 
| -          Left2 g = f;
 | 
| -        }
 | 
| -        {
 | 
| -          Top f;
 | 
| -          f = top;
 | 
| -          f = left;
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Left f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = left;
 | 
| -          f = /*warning:DownCastComposite*/right; // Should we reject this?
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Right f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left; // Should we reject this?
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Bot f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -          f = /*warning:DownCastComposite*/right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: classes', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      typedef A Top(B x);   // Top of the lattice
 | 
| -      typedef B Left(B x);  // Left branch
 | 
| -      typedef B Left2(B x); // Left branch
 | 
| -      typedef A Right(A x); // Right branch
 | 
| -      typedef B Bot(A x);   // Bottom of the lattice
 | 
| -
 | 
| -      B left(B x) => x;
 | 
| -      B _bot(A x) => /*info:DownCastImplicit*/x;
 | 
| -      B bot(A x) => x as B;
 | 
| -      A top(B x) => x;
 | 
| -      A right(A x) => x;
 | 
| -
 | 
| -      void main() {
 | 
| -        { // Check typedef equality
 | 
| -          Left f = left;
 | 
| -          Left2 g = f;
 | 
| -        }
 | 
| -        {
 | 
| -          Top f;
 | 
| -          f = top;
 | 
| -          f = left;
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Left f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = left;
 | 
| -          f = /*warning:DownCastComposite*/right; // Should we reject this?
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Right f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left; // Should we reject this?
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Bot f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -          f = /*warning:DownCastComposite*/right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: dynamic', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -
 | 
| -      typedef dynamic Top(dynamic x);     // Top of the lattice
 | 
| -      typedef dynamic Left(A x);          // Left branch
 | 
| -      typedef A Right(dynamic x);         // Right branch
 | 
| -      typedef A Bottom(A x);              // Bottom of the lattice
 | 
| -
 | 
| -      dynamic left(A x) => x;
 | 
| -      A bot(A x) => x;
 | 
| -      dynamic top(dynamic x) => x;
 | 
| -      A right(dynamic x) => /*info:DynamicCast*/x;
 | 
| -
 | 
| -      void main() {
 | 
| -        {
 | 
| -          Top f;
 | 
| -          f = top;
 | 
| -          f = left;
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Left f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = left;
 | 
| -          f = /*warning:DownCastComposite*/right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Right f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Bottom f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -          f = /*warning:DownCastComposite*/right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: function literal variance', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      typedef T Function2<S, T>(S z);
 | 
| -
 | 
| -      A top(B x) => x;
 | 
| -      B left(B x) => x;
 | 
| -      A right(A x) => x;
 | 
| -      B bot(A x) => x as B;
 | 
| -
 | 
| -      void main() {
 | 
| -        {
 | 
| -          Function2<B, A> f;
 | 
| -          f = top;
 | 
| -          f = left;
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Function2<B, B> f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = left;
 | 
| -          f = /*warning:DownCastComposite*/right; // Should we reject this?
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Function2<A, A> f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left; // Should we reject this?
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Function2<A, B> f;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -          f = /*warning:DownCastComposite*/right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: function variable variance', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      typedef T Function2<S, T>(S z);
 | 
| -
 | 
| -      void main() {
 | 
| -        {
 | 
| -          Function2<B, A> top;
 | 
| -          Function2<B, B> left;
 | 
| -          Function2<A, A> right;
 | 
| -          Function2<A, B> bot;
 | 
| -
 | 
| -          top = right;
 | 
| -          top = bot;
 | 
| -          top = top;
 | 
| -          top = left;
 | 
| -
 | 
| -          left = /*warning:DownCastComposite*/top;
 | 
| -          left = left;
 | 
| -          left = /*warning:DownCastComposite*/right; // Should we reject this?
 | 
| -          left = bot;
 | 
| -
 | 
| -          right = /*warning:DownCastComposite*/top;
 | 
| -          right = /*warning:DownCastComposite*/left; // Should we reject this?
 | 
| -          right = right;
 | 
| -          right = bot;
 | 
| -
 | 
| -          bot = /*warning:DownCastComposite*/top;
 | 
| -          bot = /*warning:DownCastComposite*/left;
 | 
| -          bot = /*warning:DownCastComposite*/right;
 | 
| -          bot = bot;
 | 
| -        }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: higher order function literals', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -      class B extends A {}
 | 
| -
 | 
| -      typedef T Function2<S, T>(S z);
 | 
| -
 | 
| -      typedef A BToA(B x);  // Top of the base lattice
 | 
| -      typedef B AToB(A x);  // Bot of the base lattice
 | 
| -
 | 
| -      BToA top(AToB f) => f;
 | 
| -      AToB left(AToB f) => f;
 | 
| -      BToA right(BToA f) => f;
 | 
| -      AToB _bot(BToA f) => /*warning:DownCastComposite*/f;
 | 
| -      AToB bot(BToA f) => f as AToB;
 | 
| -
 | 
| -      Function2<B, A> top(AToB f) => f;
 | 
| -      Function2<A, B> left(AToB f) => f;
 | 
| -      Function2<B, A> right(BToA f) => f;
 | 
| -      Function2<A, B> _bot(BToA f) => /*warning:DownCastComposite*/f;
 | 
| -      Function2<A, B> bot(BToA f) => f as Function2<A, B>;
 | 
| -
 | 
| -
 | 
| -      BToA top(Function2<A, B> f) => f;
 | 
| -      AToB left(Function2<A, B> f) => f;
 | 
| -      BToA right(Function2<B, A> f) => f;
 | 
| -      AToB _bot(Function2<B, A> f) => /*warning:DownCastComposite*/f;
 | 
| -      AToB bot(Function2<B, A> f) => f as AToB;
 | 
| -
 | 
| -      void main() {
 | 
| -        {
 | 
| -          Function2<AToB, BToA> f; // Top
 | 
| -          f = top;
 | 
| -          f = left;
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Function2<AToB, AToB> f; // Left
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = left;
 | 
| -          f = /*warning:DownCastComposite*/right; // Should we reject this?
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Function2<BToA, BToA> f; // Right
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left; // Should we reject this?
 | 
| -          f = right;
 | 
| -          f = bot;
 | 
| -        }
 | 
| -        {
 | 
| -          Function2<BToA, AToB> f; // Bot
 | 
| -          f = bot;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -          f = /*warning:DownCastComposite*/top;
 | 
| -          f = /*warning:DownCastComposite*/left;
 | 
| -        }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker(
 | 
| -      'Function typing and subtyping: higher order function variables', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -    class A {}
 | 
| -    class B extends A {}
 | 
| -
 | 
| -    typedef T Function2<S, T>(S z);
 | 
| -
 | 
| -    void main() {
 | 
| -      {
 | 
| -        Function2<Function2<A, B>, Function2<B, A>> top;
 | 
| -        Function2<Function2<B, A>, Function2<B, A>> right;
 | 
| -        Function2<Function2<A, B>, Function2<A, B>> left;
 | 
| -        Function2<Function2<B, A>, Function2<A, B>> bot;
 | 
| -
 | 
| -        top = right;
 | 
| -        top = bot;
 | 
| -        top = top;
 | 
| -        top = left;
 | 
| -
 | 
| -        left = /*warning:DownCastComposite*/top;
 | 
| -        left = left;
 | 
| -        left =
 | 
| -            /*warning:DownCastComposite should be severe:StaticTypeError*/right;
 | 
| -        left = bot;
 | 
| -
 | 
| -        right = /*warning:DownCastComposite*/top;
 | 
| -        right =
 | 
| -            /*warning:DownCastComposite should be severe:StaticTypeError*/left;
 | 
| -        right = right;
 | 
| -        right = bot;
 | 
| -
 | 
| -        bot = /*warning:DownCastComposite*/top;
 | 
| -        bot = /*warning:DownCastComposite*/left;
 | 
| -        bot = /*warning:DownCastComposite*/right;
 | 
| -        bot = bot;
 | 
| -      }
 | 
| -    }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: named and optional parameters', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -
 | 
| -      typedef A FR(A x);
 | 
| -      typedef A FO([A x]);
 | 
| -      typedef A FN({A x});
 | 
| -      typedef A FRR(A x, A y);
 | 
| -      typedef A FRO(A x, [A y]);
 | 
| -      typedef A FRN(A x, {A n});
 | 
| -      typedef A FOO([A x, A y]);
 | 
| -      typedef A FNN({A x, A y});
 | 
| -      typedef A FNNN({A z, A y, A x});
 | 
| -
 | 
| -      void main() {
 | 
| -         FR r;
 | 
| -         FO o;
 | 
| -         FN n;
 | 
| -         FRR rr;
 | 
| -         FRO ro;
 | 
| -         FRN rn;
 | 
| -         FOO oo;
 | 
| -         FNN nn;
 | 
| -         FNNN nnn;
 | 
| -
 | 
| -         r = r;
 | 
| -         r = o;
 | 
| -         r = /*severe:StaticTypeError*/n;
 | 
| -         r = /*severe:StaticTypeError*/rr;
 | 
| -         r = ro;
 | 
| -         r = rn;
 | 
| -         r = oo;
 | 
| -         r = /*severe:StaticTypeError*/nn;
 | 
| -         r = /*severe:StaticTypeError*/nnn;
 | 
| -
 | 
| -         o = /*warning:DownCastComposite*/r;
 | 
| -         o = o;
 | 
| -         o = /*severe:StaticTypeError*/n;
 | 
| -         o = /*severe:StaticTypeError*/rr;
 | 
| -         o = /*severe:StaticTypeError*/ro;
 | 
| -         o = /*severe:StaticTypeError*/rn;
 | 
| -         o = oo;
 | 
| -         o = /*severe:StaticTypeError*/nn
 | 
| -         o = /*severe:StaticTypeError*/nnn;
 | 
| -
 | 
| -         n = /*severe:StaticTypeError*/r;
 | 
| -         n = /*severe:StaticTypeError*/o;
 | 
| -         n = n;
 | 
| -         n = /*severe:StaticTypeError*/rr;
 | 
| -         n = /*severe:StaticTypeError*/ro;
 | 
| -         n = /*severe:StaticTypeError*/rn;
 | 
| -         n = /*severe:StaticTypeError*/oo;
 | 
| -         n = nn;
 | 
| -         n = nnn;
 | 
| -
 | 
| -         rr = /*severe:StaticTypeError*/r;
 | 
| -         rr = /*severe:StaticTypeError*/o;
 | 
| -         rr = /*severe:StaticTypeError*/n;
 | 
| -         rr = rr;
 | 
| -         rr = ro;
 | 
| -         rr = /*severe:StaticTypeError*/rn;
 | 
| -         rr = oo;
 | 
| -         rr = /*severe:StaticTypeError*/nn;
 | 
| -         rr = /*severe:StaticTypeError*/nnn;
 | 
| -
 | 
| -         ro = /*warning:DownCastComposite*/r;
 | 
| -         ro = /*severe:StaticTypeError*/o;
 | 
| -         ro = /*severe:StaticTypeError*/n;
 | 
| -         ro = /*warning:DownCastComposite*/rr;
 | 
| -         ro = ro;
 | 
| -         ro = /*severe:StaticTypeError*/rn;
 | 
| -         ro = oo;
 | 
| -         ro = /*severe:StaticTypeError*/nn;
 | 
| -         ro = /*severe:StaticTypeError*/nnn;
 | 
| -
 | 
| -         rn = /*warning:DownCastComposite*/r;
 | 
| -         rn = /*severe:StaticTypeError*/o;
 | 
| -         rn = /*severe:StaticTypeError*/n;
 | 
| -         rn = /*severe:StaticTypeError*/rr;
 | 
| -         rn = /*severe:StaticTypeError*/ro;
 | 
| -         rn = rn;
 | 
| -         rn = /*severe:StaticTypeError*/oo;
 | 
| -         rn = /*severe:StaticTypeError*/nn;
 | 
| -         rn = /*severe:StaticTypeError*/nnn;
 | 
| -
 | 
| -         oo = /*warning:DownCastComposite*/r;
 | 
| -         oo = /*warning:DownCastComposite*/o;
 | 
| -         oo = /*severe:StaticTypeError*/n;
 | 
| -         oo = /*warning:DownCastComposite*/rr;
 | 
| -         oo = /*warning:DownCastComposite*/ro;
 | 
| -         oo = /*severe:StaticTypeError*/rn;
 | 
| -         oo = oo;
 | 
| -         oo = /*severe:StaticTypeError*/nn;
 | 
| -         oo = /*severe:StaticTypeError*/nnn;
 | 
| -
 | 
| -         nn = /*severe:StaticTypeError*/r;
 | 
| -         nn = /*severe:StaticTypeError*/o;
 | 
| -         nn = /*warning:DownCastComposite*/n;
 | 
| -         nn = /*severe:StaticTypeError*/rr;
 | 
| -         nn = /*severe:StaticTypeError*/ro;
 | 
| -         nn = /*severe:StaticTypeError*/rn;
 | 
| -         nn = /*severe:StaticTypeError*/oo;
 | 
| -         nn = nn;
 | 
| -         nn = nnn;
 | 
| -
 | 
| -         nnn = /*severe:StaticTypeError*/r;
 | 
| -         nnn = /*severe:StaticTypeError*/o;
 | 
| -         nnn = /*warning:DownCastComposite*/n;
 | 
| -         nnn = /*severe:StaticTypeError*/rr;
 | 
| -         nnn = /*severe:StaticTypeError*/ro;
 | 
| -         nnn = /*severe:StaticTypeError*/rn;
 | 
| -         nnn = /*severe:StaticTypeError*/oo;
 | 
| -         nnn = /*warning:DownCastComposite*/nn;
 | 
| -         nnn = nnn;
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function subtyping: objects with call methods', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      typedef int I2I(int x);
 | 
| -      typedef num N2N(num x);
 | 
| -      class A {
 | 
| -         int call(int x) => x;
 | 
| -      }
 | 
| -      class B {
 | 
| -         num call(num x) => x;
 | 
| -      }
 | 
| -      int i2i(int x) => x;
 | 
| -      num n2n(num x) => x;
 | 
| -      void main() {
 | 
| -         {
 | 
| -           I2I f;
 | 
| -           f = new A();
 | 
| -           f = /*severe:StaticTypeError*/new B();
 | 
| -           f = i2i;
 | 
| -           f = /*warning:DownCastComposite*/n2n;
 | 
| -           f = /*warning:DownCastComposite*/i2i as Object;
 | 
| -           f = /*warning:DownCastComposite*/n2n as Function;
 | 
| -         }
 | 
| -         {
 | 
| -           N2N f;
 | 
| -           f = /*severe:StaticTypeError*/new A();
 | 
| -           f = new B();
 | 
| -           f = /*warning:DownCastComposite*/i2i;
 | 
| -           f = n2n;
 | 
| -           f = /*warning:DownCastComposite*/i2i as Object;
 | 
| -           f = /*warning:DownCastComposite*/n2n as Function;
 | 
| -         }
 | 
| -         {
 | 
| -           A f;
 | 
| -           f = new A();
 | 
| -           f = /*severe:StaticTypeError*/new B();
 | 
| -           f = /*severe:StaticTypeError*/i2i;
 | 
| -           f = /*severe:StaticTypeError*/n2n;
 | 
| -           f = /*info:DownCastImplicit*/i2i as Object;
 | 
| -           f = /*info:DownCastImplicit*/n2n as Function;
 | 
| -         }
 | 
| -         {
 | 
| -           B f;
 | 
| -           f = /*severe:StaticTypeError*/new A();
 | 
| -           f = new B();
 | 
| -           f = /*severe:StaticTypeError*/i2i;
 | 
| -           f = /*severe:StaticTypeError*/n2n;
 | 
| -           f = /*info:DownCastImplicit*/i2i as Object;
 | 
| -           f = /*info:DownCastImplicit*/n2n as Function;
 | 
| -         }
 | 
| -         {
 | 
| -           Function f;
 | 
| -           f = new A();
 | 
| -           f = new B();
 | 
| -           f = i2i;
 | 
| -           f = n2n;
 | 
| -           f = /*info:DownCastImplicit*/i2i as Object;
 | 
| -           f = (n2n as Function);
 | 
| -         }
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Function typing and subtyping: void', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {
 | 
| -        void bar() => null;
 | 
| -        void foo() => bar; // allowed
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Relaxed casts', {
 | 
| -    '/main.dart': '''
 | 
| -
 | 
| -      class A {}
 | 
| -
 | 
| -      class L<T> {}
 | 
| -      class M<T> extends L<T> {}
 | 
| -      //     L<dynamic|Object>
 | 
| -      //    /              \
 | 
| -      // M<dynamic|Object>  L<A>
 | 
| -      //    \              /
 | 
| -      //          M<A>
 | 
| -      // In normal Dart, there are additional edges
 | 
| -      //  from M<A> to M<dynamic>
 | 
| -      //  from L<A> to M<dynamic>
 | 
| -      //  from L<A> to L<dynamic>
 | 
| -      void main() {
 | 
| -        L lOfDs;
 | 
| -        L<Object> lOfOs;
 | 
| -        L<A> lOfAs;
 | 
| -
 | 
| -        M mOfDs;
 | 
| -        M<Object> mOfOs;
 | 
| -        M<A> mOfAs;
 | 
| -
 | 
| -        {
 | 
| -          lOfDs = mOfDs;
 | 
| -          lOfDs = mOfOs;
 | 
| -          lOfDs = mOfAs;
 | 
| -          lOfDs = lOfDs;
 | 
| -          lOfDs = lOfOs;
 | 
| -          lOfDs = lOfAs;
 | 
| -        }
 | 
| -        {
 | 
| -          lOfOs = mOfDs;
 | 
| -          lOfOs = mOfOs;
 | 
| -          lOfOs = mOfAs;
 | 
| -          lOfOs = lOfDs;
 | 
| -          lOfOs = lOfOs;
 | 
| -          lOfOs = lOfAs;
 | 
| -        }
 | 
| -        {
 | 
| -          lOfAs = /*warning:DownCastComposite*/mOfDs;
 | 
| -          lOfAs = /*severe:StaticTypeError*/mOfOs;
 | 
| -          lOfAs = mOfAs;
 | 
| -          lOfAs = /*warning:DownCastComposite*/lOfDs;
 | 
| -          lOfAs = /*warning:DownCastComposite*/lOfOs;
 | 
| -          lOfAs = lOfAs;
 | 
| -        }
 | 
| -        {
 | 
| -          mOfDs = mOfDs;
 | 
| -          mOfDs = mOfOs;
 | 
| -          mOfDs = mOfAs;
 | 
| -          mOfDs = /*info:DownCastImplicit*/lOfDs;
 | 
| -          mOfDs = /*info:DownCastImplicit*/lOfOs;
 | 
| -          mOfDs = /*info:DownCastImplicit*/lOfAs;
 | 
| -        }
 | 
| -        {
 | 
| -          mOfOs = mOfDs;
 | 
| -          mOfOs = mOfOs;
 | 
| -          mOfOs = mOfAs;
 | 
| -          mOfOs = /*info:DownCastImplicit*/lOfDs;
 | 
| -          mOfOs = /*info:DownCastImplicit*/lOfOs;
 | 
| -          mOfOs = /*severe:StaticTypeError*/lOfAs;
 | 
| -        }
 | 
| -        {
 | 
| -          mOfAs = /*warning:DownCastComposite*/mOfDs;
 | 
| -          mOfAs = /*warning:DownCastComposite*/mOfOs;
 | 
| -          mOfAs = mOfAs;
 | 
| -          mOfAs = /*warning:DownCastComposite*/lOfDs;
 | 
| -          mOfAs = /*warning:DownCastComposite*/lOfOs;
 | 
| -          mOfAs = /*warning:DownCastComposite*/lOfAs;
 | 
| -        }
 | 
| -
 | 
| -      }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('Type checking literals', {
 | 
| -    '/main.dart': '''
 | 
| -          test() {
 | 
| -            num n = 3;
 | 
| -            int i = 3;
 | 
| -            String s = "hello";
 | 
| -            {
 | 
| -               List<int> l = <int>[i];
 | 
| -               l = <int>[/*severe:StaticTypeError*/s];
 | 
| -               l = <int>[/*info:DownCastImplicit*/n];
 | 
| -               l = <int>[i, /*info:DownCastImplicit*/n, /*severe:StaticTypeError*/s];
 | 
| -            }
 | 
| -            {
 | 
| -               List l = [i];
 | 
| -               l = [s];
 | 
| -               l = [n];
 | 
| -               l = [i, n, s];
 | 
| -            }
 | 
| -            {
 | 
| -               Map<String, int> m = <String, int>{s: i};
 | 
| -               m = <String, int>{s: /*severe:StaticTypeError*/s};
 | 
| -               m = <String, int>{s: /*info:DownCastImplicit*/n};
 | 
| -               m = <String, int>{s: i,
 | 
| -                                 s: /*info:DownCastImplicit*/n,
 | 
| -                                 s: /*severe:StaticTypeError*/s};
 | 
| -            }
 | 
| -           // TODO(leafp): We can't currently test for key errors since the
 | 
| -           // error marker binds to the entire entry.
 | 
| -            {
 | 
| -               Map m = {s: i};
 | 
| -               m = {s: s};
 | 
| -               m = {s: n};
 | 
| -               m = {s: i,
 | 
| -                    s: n,
 | 
| -                    s: s};
 | 
| -               m = {i: s,
 | 
| -                    n: s,
 | 
| -                    s: s};
 | 
| -            }
 | 
| -          }
 | 
| -   '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('casts in constant contexts', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {
 | 
| -            static const num n = 3.0;
 | 
| -            static const int i = /*info:AssignmentCast*/n;
 | 
| -            final int fi;
 | 
| -            const A(num a) : this.fi = /*info:DownCastImplicit*/a;
 | 
| -          }
 | 
| -          class B extends A {
 | 
| -            const B(Object a) : super(/*info:DownCastImplicit*/a);
 | 
| -          }
 | 
| -          void foo(Object o) {
 | 
| -            var a = const A(/*info:DownCastImplicit*/o);
 | 
| -          }
 | 
| -     '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('casts in conditionals', {
 | 
| -    '/main.dart': '''
 | 
| -          main() {
 | 
| -            bool b = true;
 | 
| -            num x = b ? 1 : 2.3;
 | 
| -            int y = /*info:AssignmentCast*/b ? 1 : 2.3;
 | 
| -            String z = !b ? "hello" : null;
 | 
| -            z = b ? null : "hello";
 | 
| -          }
 | 
| -      '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('redirecting constructor', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {
 | 
| -            A(A x) {}
 | 
| -            A.two() : this(/*severe:StaticTypeError*/3);
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('super constructor', {
 | 
| -    '/main.dart': '''
 | 
| -          class A { A(A x) {} }
 | 
| -          class B extends A {
 | 
| -            B() : super(/*severe:StaticTypeError*/3);
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('field/field override', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {}
 | 
| -          class B extends A {}
 | 
| -          class C extends B {}
 | 
| -
 | 
| -          class Base {
 | 
| -            B f1;
 | 
| -            B f2;
 | 
| -            B f3;
 | 
| -            B f4;
 | 
| -          }
 | 
| -
 | 
| -          class Child extends Base {
 | 
| -            /*severe:InvalidMethodOverride*/A f1; // invalid for getter
 | 
| -            /*severe:InvalidMethodOverride*/C f2; // invalid for setter
 | 
| -            var f3;
 | 
| -            /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/dynamic f4;
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('getter/getter override', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {}
 | 
| -          class B extends A {}
 | 
| -          class C extends B {}
 | 
| -
 | 
| -          abstract class Base {
 | 
| -            B get f1;
 | 
| -            B get f2;
 | 
| -            B get f3;
 | 
| -            B get f4;
 | 
| -          }
 | 
| -
 | 
| -          class Child extends Base {
 | 
| -            /*severe:InvalidMethodOverride*/A get f1 => null;
 | 
| -            C get f2 => null;
 | 
| -            get f3 => null;
 | 
| -            /*severe:InvalidMethodOverride*/dynamic get f4 => null;
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('field/getter override', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {}
 | 
| -          class B extends A {}
 | 
| -          class C extends B {}
 | 
| -
 | 
| -          abstract class Base {
 | 
| -            B f1;
 | 
| -            B f2;
 | 
| -            B f3;
 | 
| -            B f4;
 | 
| -          }
 | 
| -
 | 
| -          class Child extends Base {
 | 
| -            /*severe:InvalidMethodOverride*/A get f1 => null;
 | 
| -            C get f2 => null;
 | 
| -            get f3 => null;
 | 
| -            /*severe:InvalidMethodOverride*/dynamic get f4 => null;
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('setter/setter override', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {}
 | 
| -          class B extends A {}
 | 
| -          class C extends B {}
 | 
| -
 | 
| -          abstract class Base {
 | 
| -            void set f1(B value);
 | 
| -            void set f2(B value);
 | 
| -            void set f3(B value);
 | 
| -            void set f4(B value);
 | 
| -            void set f5(B value);
 | 
| -          }
 | 
| -
 | 
| -          class Child extends Base {
 | 
| -            void set f1(A value) {}
 | 
| -            /*severe:InvalidMethodOverride*/void set f2(C value) {}
 | 
| -            void set f3(value) {}
 | 
| -            /*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
 | 
| -            set f5(B value) {}
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('field/setter override', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {}
 | 
| -          class B extends A {}
 | 
| -          class C extends B {}
 | 
| -
 | 
| -          class Base {
 | 
| -            B f1;
 | 
| -            B f2;
 | 
| -            B f3;
 | 
| -            B f4;
 | 
| -            B f5;
 | 
| -          }
 | 
| -
 | 
| -          class Child extends Base {
 | 
| -            B get f1 => null;
 | 
| -            B get f2 => null;
 | 
| -            B get f3 => null;
 | 
| -            B get f4 => null;
 | 
| -            B get f5 => null;
 | 
| -
 | 
| -            void set f1(A value) {}
 | 
| -            /*severe:InvalidMethodOverride*/void set f2(C value) {}
 | 
| -            void set f3(value) {}
 | 
| -            /*severe:InvalidMethodOverride*/void set f4(dynamic value) {}
 | 
| -            set f5(B value) {}
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('method override', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {}
 | 
| -          class B extends A {}
 | 
| -          class C extends B {}
 | 
| -
 | 
| -          class Base {
 | 
| -            B m1(B a);
 | 
| -            B m2(B a);
 | 
| -            B m3(B a);
 | 
| -            B m4(B a);
 | 
| -            B m5(B a);
 | 
| -            B m6(B a);
 | 
| -          }
 | 
| -
 | 
| -          class Child extends Base {
 | 
| -            /*severe:InvalidMethodOverride*/A m1(A value) {}
 | 
| -            /*severe:InvalidMethodOverride*/C m2(C value) {}
 | 
| -            /*severe:InvalidMethodOverride*/A m3(C value) {}
 | 
| -            C m4(A value) {}
 | 
| -            m5(value) {}
 | 
| -            /*severe:InvalidMethodOverride*/dynamic m6(dynamic value) {}
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('unary operators', {
 | 
| -    '/main.dart': '''
 | 
| -      class A {
 | 
| -        A operator ~() {}
 | 
| -        A operator +(int x) {}
 | 
| -        A operator -(int x) {}
 | 
| -        A operator -() {}
 | 
| -      }
 | 
| -
 | 
| -      foo() => new A();
 | 
| -
 | 
| -      test() {
 | 
| -        A a = new A();
 | 
| -        var c = foo();
 | 
| -
 | 
| -        ~a;
 | 
| -        (/*info:DynamicInvoke*/~d);
 | 
| -
 | 
| -        !/*severe:StaticTypeError*/a;
 | 
| -        !/*info:DynamicCast*/d;
 | 
| -
 | 
| -        -a;
 | 
| -        (/*info:DynamicInvoke*/-d);
 | 
| -
 | 
| -        ++a;
 | 
| -        --a;
 | 
| -        (/*info:DynamicInvoke*/++d);
 | 
| -        (/*info:DynamicInvoke*/--d);
 | 
| -
 | 
| -        a++;
 | 
| -        a--;
 | 
| -        (/*info:DynamicInvoke*/d++);
 | 
| -        (/*info:DynamicInvoke*/d--);
 | 
| -      }'''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('binary and index operators', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {
 | 
| -            A operator *(B b) {}
 | 
| -            A operator /(B b) {}
 | 
| -            A operator ~/(B b) {}
 | 
| -            A operator %(B b) {}
 | 
| -            A operator +(B b) {}
 | 
| -            A operator -(B b) {}
 | 
| -            A operator <<(B b) {}
 | 
| -            A operator >>(B b) {}
 | 
| -            A operator &(B b) {}
 | 
| -            A operator ^(B b) {}
 | 
| -            A operator |(B b) {}
 | 
| -            A operator[](B b) {}
 | 
| -          }
 | 
| -
 | 
| -          class B {
 | 
| -            A operator -(B b) {}
 | 
| -          }
 | 
| -
 | 
| -          foo() => new A();
 | 
| -
 | 
| -          test() {
 | 
| -            A a = new A();
 | 
| -            B b = new B();
 | 
| -            var c = foo();
 | 
| -            a = a * b;
 | 
| -            a = a * /*info:DynamicCast*/c;
 | 
| -            a = a / b;
 | 
| -            a = a ~/ b;
 | 
| -            a = a % b;
 | 
| -            a = a + b;
 | 
| -            a = a + /*severe:StaticTypeError*/a;
 | 
| -            a = a - b;
 | 
| -            b = /*severe:StaticTypeError*/b - b;
 | 
| -            a = a << b;
 | 
| -            a = a >> b;
 | 
| -            a = a & b;
 | 
| -            a = a ^ b;
 | 
| -            a = a | b;
 | 
| -            c = (/*info:DynamicInvoke*/c + b);
 | 
| -
 | 
| -            String x = 'hello';
 | 
| -            int y = 42;
 | 
| -            x = x + x;
 | 
| -            x = x + /*info:DynamicCast*/c;
 | 
| -            x = x + /*severe:StaticTypeError*/y;
 | 
| -
 | 
| -            bool p = true;
 | 
| -            p = p && p;
 | 
| -            p = p && /*info:DynamicCast*/c;
 | 
| -            p = (/*info:DynamicCast*/c) && p;
 | 
| -            p = (/*info:DynamicCast*/c) && /*info:DynamicCast*/c;
 | 
| -            p = (/*severe:StaticTypeError*/y) && p;
 | 
| -            p = c == y;
 | 
| -
 | 
| -            a = a[b];
 | 
| -            a = a[/*info:DynamicCast*/c];
 | 
| -            c = (/*info:DynamicInvoke*/c[b]);
 | 
| -            a[/*severe:StaticTypeError*/y];
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('compound assignments', {
 | 
| -    '/main.dart': '''
 | 
| -          class A {
 | 
| -            A operator *(B b) {}
 | 
| -            A operator /(B b) {}
 | 
| -            A operator ~/(B b) {}
 | 
| -            A operator %(B b) {}
 | 
| -            A operator +(B b) {}
 | 
| -            A operator -(B b) {}
 | 
| -            A operator <<(B b) {}
 | 
| -            A operator >>(B b) {}
 | 
| -            A operator &(B b) {}
 | 
| -            A operator ^(B b) {}
 | 
| -            A operator |(B b) {}
 | 
| -            D operator [](B index) {}
 | 
| -            void operator []=(B index, D value) {}
 | 
| -          }
 | 
| -
 | 
| -          class B {
 | 
| -            A operator -(B b) {}
 | 
| -          }
 | 
| -
 | 
| -          class D {
 | 
| -            D operator +(D d) {}
 | 
| -          }
 | 
| -
 | 
| -          foo() => new A();
 | 
| -
 | 
| -          test() {
 | 
| -            int x = 0;
 | 
| -            x += 5;
 | 
| -            (/*severe:StaticTypeError*/x += 3.14);
 | 
| -
 | 
| -            double y = 0.0;
 | 
| -            y += 5;
 | 
| -            y += 3.14;
 | 
| -
 | 
| -            num z = 0;
 | 
| -            z += 5;
 | 
| -            z += 3.14;
 | 
| -
 | 
| -            x = /*info:DownCastImplicit*/x + z;
 | 
| -            x += /*info:DownCastImplicit*/z;
 | 
| -            y = /*info:DownCastImplicit*/y + z;
 | 
| -            y += /*info:DownCastImplicit*/z;
 | 
| -
 | 
| -            dynamic w = 42;
 | 
| -            x += /*info:DynamicCast*/w;
 | 
| -            y += /*info:DynamicCast*/w;
 | 
| -            z += /*info:DynamicCast*/w;
 | 
| -
 | 
| -            A a = new A();
 | 
| -            B b = new B();
 | 
| -            var c = foo();
 | 
| -            a = a * b;
 | 
| -            a *= b;
 | 
| -            a *= /*info:DynamicCast*/c;
 | 
| -            a /= b;
 | 
| -            a ~/= b;
 | 
| -            a %= b;
 | 
| -            a += b;
 | 
| -            a += /*severe:StaticTypeError*/a;
 | 
| -            a -= b;
 | 
| -            (/*severe:StaticTypeError*/b -= b);
 | 
| -            a <<= b;
 | 
| -            a >>= b;
 | 
| -            a &= b;
 | 
| -            a ^= b;
 | 
| -            a |= b;
 | 
| -            (/*info:DynamicInvoke*/c += b);
 | 
| -
 | 
| -            var d = new D();
 | 
| -            a[b] += d;
 | 
| -            a[/*info:DynamicCast*/c] += d;
 | 
| -            a[/*severe:StaticTypeError*/z] += d;
 | 
| -            a[b] += /*info:DynamicCast*/c;
 | 
| -            a[b] += /*severe:StaticTypeError*/z;
 | 
| -            (/*info:DynamicInvoke*/(/*info:DynamicInvoke*/c[b]) += d);
 | 
| -          }
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('super call placement', {
 | 
| -    '/main.dart': '''
 | 
| -          class Base {
 | 
| -            var x;
 | 
| -            Base() : x = print('Base.1') { print('Base.2'); }
 | 
| -          }
 | 
| -
 | 
| -          class Derived extends Base {
 | 
| -            var y, z;
 | 
| -            Derived()
 | 
| -                : y = print('Derived.1'),
 | 
| -                  /*severe:InvalidSuperInvocation*/super(),
 | 
| -                  z = print('Derived.2') {
 | 
| -              print('Derived.3');
 | 
| -            }
 | 
| -          }
 | 
| -
 | 
| -          class Valid extends Base {
 | 
| -            var y, z;
 | 
| -            Valid()
 | 
| -                : y = print('Valid.1'),
 | 
| -                  z = print('Valid.2'),
 | 
| -                  super() {
 | 
| -              print('Valid.3');
 | 
| -            }
 | 
| -          }
 | 
| -
 | 
| -          class AlsoValid extends Base {
 | 
| -            AlsoValid() : super();
 | 
| -          }
 | 
| -
 | 
| -          main() => new Derived();
 | 
| -       '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('for loop variable', {
 | 
| -    '/main.dart': '''
 | 
| -          foo() {
 | 
| -            for (int i = 0; i < 10; i++) {
 | 
| -              i = /*severe:StaticTypeError*/"hi";
 | 
| -            }
 | 
| -          }
 | 
| -          bar() {
 | 
| -            for (var i = 0; i < 10; i++) {
 | 
| -              int j = i + 1;
 | 
| -            }
 | 
| -          }
 | 
| -        '''
 | 
| -  });
 | 
| -
 | 
| -  group('invalid overrides', () {
 | 
| -    testChecker('child override', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Base {
 | 
| -                A f;
 | 
| -            }
 | 
| -
 | 
| -            class T1 extends Base {
 | 
| -              /*severe:InvalidMethodOverride*/B get f => null;
 | 
| -            }
 | 
| -
 | 
| -            class T2 extends Base {
 | 
| -              /*severe:InvalidMethodOverride*/set f(B b) => null;
 | 
| -            }
 | 
| -
 | 
| -            class T3 extends Base {
 | 
| -              /*severe:InvalidMethodOverride*/final B f;
 | 
| -            }
 | 
| -            class T4 extends Base {
 | 
| -              // two: one for the getter one for the setter.
 | 
| -              /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/B f;
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('child override 2', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Base {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class Test extends Base {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -    testChecker('grandchild override', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Grandparent {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -            class Parent extends Grandparent {
 | 
| -            }
 | 
| -
 | 
| -            class Test extends Parent {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('double override', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Grandparent {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -            class Parent extends Grandparent {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class Test extends Parent {
 | 
| -                // Reported only once
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('double override 2', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Grandparent {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -            class Parent extends Grandparent {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class Test extends Parent {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('mixin override to base', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Base {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class M1 {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class M2 {}
 | 
| -
 | 
| -            class T1 extends Base with /*severe:InvalidMethodOverride*/M1 {}
 | 
| -            class T2 extends Base with /*severe:InvalidMethodOverride*/M1, M2 {}
 | 
| -            class T3 extends Base with M2, /*severe:InvalidMethodOverride*/M1 {}
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('mixin override to mixin', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Base {
 | 
| -            }
 | 
| -
 | 
| -            class M1 {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class M2 {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class T1 extends Base with M1, /*severe:InvalidMethodOverride*/M2 {}
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    // This is a regression test for a bug in an earlier implementation were
 | 
| -    // names were hiding errors if the first mixin override looked correct,
 | 
| -    // but subsequent ones did not.
 | 
| -    testChecker('no duplicate mixin override', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Base {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class M1 {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class M2 {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class M3 {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class T1 extends Base
 | 
| -                with M1, /*severe:InvalidMethodOverride*/M2, M3 {}
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('class override of interface', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            abstract class I {
 | 
| -                m(A a);
 | 
| -            }
 | 
| -
 | 
| -            class T1 implements I {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('base class override to child interface', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            abstract class I {
 | 
| -                m(A a);
 | 
| -            }
 | 
| -
 | 
| -            class Base {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -
 | 
| -            class T1 /*severe:InvalidMethodOverride*/extends Base implements I {
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('mixin override of interface', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            abstract class I {
 | 
| -                m(A a);
 | 
| -            }
 | 
| -
 | 
| -            class M {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class T1 extends Object with /*severe:InvalidMethodOverride*/M
 | 
| -               implements I {}
 | 
| -         '''
 | 
| -    });
 | 
| -
 | 
| -    // This is a case were it is incorrect to say that the base class
 | 
| -    // incorrectly overrides the interface.
 | 
| -    testChecker(
 | 
| -        'no errors if subclass correctly overrides base and interface', {
 | 
| -      '/main.dart': '''
 | 
| -            class A {}
 | 
| -            class B {}
 | 
| -
 | 
| -            class Base {
 | 
| -                m(A a) {}
 | 
| -            }
 | 
| -
 | 
| -            class I1 {
 | 
| -                m(B a) {}
 | 
| -            }
 | 
| -
 | 
| -            class T1 /*severe:InvalidMethodOverride*/extends Base
 | 
| -                implements I1 {}
 | 
| -
 | 
| -            class T2 extends Base implements I1 {
 | 
| -                /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a) {}
 | 
| -            }
 | 
| -
 | 
| -            class T3 extends Object with /*severe:InvalidMethodOverride*/Base
 | 
| -                implements I1 {}
 | 
| -
 | 
| -            class T4 extends Object with Base implements I1 {
 | 
| -                /*severe:InvalidMethodOverride,severe:InvalidMethodOverride*/m(a) {}
 | 
| -            }
 | 
| -         '''
 | 
| -    });
 | 
| -  });
 | 
| -
 | 
| -  group('class override of grand interface', () {
 | 
| -    testChecker('interface of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 implements I1 {}
 | 
| -
 | 
| -              class T1 implements I2 {
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('superclass of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 extends I1 {}
 | 
| -
 | 
| -              class T1 implements I2 {
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('mixin of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class M1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 extends Object with M1 {}
 | 
| -
 | 
| -              class T1 implements I2 {
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('interface of abstract superclass', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class Base implements I1 {}
 | 
| -
 | 
| -              class T1 extends Base {
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('interface of concrete superclass', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              // See issue #25
 | 
| -              /*pass should be warning:AnalyzerError*/class Base implements I1 {
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Base {
 | 
| -                  // not reported technically because if the class is concrete,
 | 
| -                  // it should implement all its interfaces and hence it is
 | 
| -                  // sufficient to check overrides against it.
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -  });
 | 
| -
 | 
| -  group('mixin override of grand interface', () {
 | 
| -    testChecker('interface of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 implements I1 {}
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Object with /*severe:InvalidMethodOverride*/M
 | 
| -                  implements I2 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('superclass of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 extends I1 {}
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Object with /*severe:InvalidMethodOverride*/M
 | 
| -                  implements I2 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('mixin of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class M1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 extends Object with M1 {}
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Object with /*severe:InvalidMethodOverride*/M
 | 
| -                  implements I2 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('interface of abstract superclass', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class Base implements I1 {}
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Base with /*severe:InvalidMethodOverride*/M {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('interface of concrete superclass', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              // See issue #25
 | 
| -              /*pass should be warning:AnalyzerError*/class Base implements I1 {
 | 
| -              }
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Base with M {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -  });
 | 
| -
 | 
| -  group('superclass override of grand interface', () {
 | 
| -    testChecker('interface of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 implements I1 {}
 | 
| -
 | 
| -              class Base {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 /*severe:InvalidMethodOverride*/extends Base
 | 
| -                  implements I2 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('superclass of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 extends I1 {}
 | 
| -
 | 
| -              class Base {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 /*severe:InvalidMethodOverride*/extends Base
 | 
| -                  implements I2 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('mixin of interface of child', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class M1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 extends Object with M1 {}
 | 
| -
 | 
| -              class Base {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 /*severe:InvalidMethodOverride*/extends Base
 | 
| -                  implements I2 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('interface of abstract superclass', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              abstract class Base implements I1 {
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Base {
 | 
| -                  // we consider the base class incomplete because it is
 | 
| -                  // abstract, so we report the error here too.
 | 
| -                  // TODO(sigmund): consider tracking overrides in a fine-grain
 | 
| -                  // manner, then this and the double-overrides would not be
 | 
| -                  // reported.
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -    testChecker('interface of concrete superclass', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class Base implements I1 {
 | 
| -                  /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Base {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -  });
 | 
| -
 | 
| -  group('no duplicate reports from overriding interfaces', () {
 | 
| -    testChecker('type overrides same method in multiple interfaces', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -              abstract class I2 implements I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class Base {
 | 
| -              }
 | 
| -
 | 
| -              class T1 implements I2 {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('type and base type override same method in interface', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class Base {
 | 
| -                  m(B a);
 | 
| -              }
 | 
| -
 | 
| -              // Note: no error reported in `extends Base` to avoid duplicating
 | 
| -              // the error in T1.
 | 
| -              class T1 extends Base implements I1 {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              // If there is no error in the class, we do report the error at
 | 
| -              // the base class:
 | 
| -              class T2 /*severe:InvalidMethodOverride*/extends Base
 | 
| -                  implements I1 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('type and mixin override same method in interface', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a);
 | 
| -              }
 | 
| -
 | 
| -              class T1 extends Object with M implements I1 {
 | 
| -                /*severe:InvalidMethodOverride*/m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class T2 extends Object with /*severe:InvalidMethodOverride*/M
 | 
| -                  implements I1 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('two grand types override same method in interface', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class Grandparent {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class Parent1 extends Grandparent {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -              class Parent2 extends Grandparent {
 | 
| -              }
 | 
| -
 | 
| -              // Note: otherwise both errors would be reported on this line
 | 
| -              class T1 /*severe:InvalidMethodOverride*/extends Parent1
 | 
| -                  implements I1 {
 | 
| -              }
 | 
| -              class T2 /*severe:InvalidMethodOverride*/extends Parent2
 | 
| -                  implements I1 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('two mixins override same method in interface', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class M1 {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class M2 {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              // Here we want to report both, because the error location is
 | 
| -              // different.
 | 
| -              // TODO(sigmund): should we merge these as well?
 | 
| -              class T1 extends Object
 | 
| -                  with /*severe:InvalidMethodOverride*/M1
 | 
| -                  with /*severe:InvalidMethodOverride*/M2
 | 
| -                  implements I1 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('base type and mixin override same method in interface', {
 | 
| -      '/main.dart': '''
 | 
| -              class A {}
 | 
| -              class B {}
 | 
| -
 | 
| -              abstract class I1 {
 | 
| -                  m(A a);
 | 
| -              }
 | 
| -
 | 
| -              class Base {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              class M {
 | 
| -                  m(B a) {}
 | 
| -              }
 | 
| -
 | 
| -              // Here we want to report both, because the error location is
 | 
| -              // different.
 | 
| -              // TODO(sigmund): should we merge these as well?
 | 
| -              class T1 /*severe:InvalidMethodOverride*/extends Base
 | 
| -                  with /*severe:InvalidMethodOverride*/M
 | 
| -                  implements I1 {
 | 
| -              }
 | 
| -           '''
 | 
| -    });
 | 
| -  });
 | 
| -
 | 
| -  testChecker('invalid runtime checks', {
 | 
| -    '/main.dart': '''
 | 
| -          typedef int I2I(int x);
 | 
| -          typedef int D2I(x);
 | 
| -          typedef int II2I(int x, int y);
 | 
| -          typedef int DI2I(x, int y);
 | 
| -          typedef int ID2I(int x, y);
 | 
| -          typedef int DD2I(x, y);
 | 
| -
 | 
| -          typedef I2D(int x);
 | 
| -          typedef D2D(x);
 | 
| -          typedef II2D(int x, int y);
 | 
| -          typedef DI2D(x, int y);
 | 
| -          typedef ID2D(int x, y);
 | 
| -          typedef DD2D(x, y);
 | 
| -
 | 
| -          int foo(int x) => x;
 | 
| -          int bar(int x, int y) => x + y;
 | 
| -
 | 
| -          void main() {
 | 
| -            bool b;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/foo is I2I;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/foo is D2I;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/foo is I2D;
 | 
| -            b = foo is D2D;
 | 
| -
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is II2I;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is DI2I;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is ID2I;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is II2D;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is DD2I;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is DI2D;
 | 
| -            b = /*info:NonGroundTypeCheckInfo*/bar is ID2D;
 | 
| -            b = bar is DD2D;
 | 
| -
 | 
| -            // For as, the validity of checks is deferred to runtime.
 | 
| -            Function f;
 | 
| -            f = foo as I2I;
 | 
| -            f = foo as D2I;
 | 
| -            f = foo as I2D;
 | 
| -            f = foo as D2D;
 | 
| -
 | 
| -            f = bar as II2I;
 | 
| -            f = bar as DI2I;
 | 
| -            f = bar as ID2I;
 | 
| -            f = bar as II2D;
 | 
| -            f = bar as DD2I;
 | 
| -            f = bar as DI2D;
 | 
| -            f = bar as ID2D;
 | 
| -            f = bar as DD2D;
 | 
| -          }
 | 
| -      '''
 | 
| -  });
 | 
| -
 | 
| -  testChecker('custom URL mappings', {
 | 
| -    '/main.dart': '''
 | 
| -      import 'dart:foobar' show Baz;
 | 
| -      main() {
 | 
| -        print(Baz.quux);
 | 
| -      }'''
 | 
| -  }, customUrlMappings: {
 | 
| -    'dart:foobar': '$testDirectory/checker/dart_foobar.dart'
 | 
| -  });
 | 
| -
 | 
| -  group('function modifiers', () {
 | 
| -    testChecker('async', {
 | 
| -      '/main.dart': '''
 | 
| -        import 'dart:async';
 | 
| -        import 'dart:math' show Random;
 | 
| -
 | 
| -        dynamic x;
 | 
| -
 | 
| -        foo1() async => x;
 | 
| -        Future foo2() async => x;
 | 
| -        Future<int> foo3() async => (/*info:DynamicCast*/x);
 | 
| -        Future<int> foo4() async => (/*severe:StaticTypeError*/new Future<int>.value(/*info:DynamicCast*/x));
 | 
| -
 | 
| -        bar1() async { return x; }
 | 
| -        Future bar2() async { return x; }
 | 
| -        Future<int> bar3() async { return (/*info:DynamicCast*/x); }
 | 
| -        Future<int> bar4() async { return (/*severe:StaticTypeError*/new Future<int>.value(/*info:DynamicCast*/x)); }
 | 
| -
 | 
| -        int y;
 | 
| -        Future<int> z;
 | 
| -
 | 
| -        void baz() async {
 | 
| -          int a = /*info:DynamicCast*/await x;
 | 
| -          int b = await y;
 | 
| -          int c = await z;
 | 
| -          String d = /*severe:StaticTypeError*/await z;
 | 
| -        }
 | 
| -
 | 
| -        Future<bool> get issue_264 async {
 | 
| -          await 42;
 | 
| -          if (new Random().nextBool()) {
 | 
| -            return true;
 | 
| -          } else {
 | 
| -            return /*severe:StaticTypeError*/new Future<bool>.value(false);
 | 
| -          }
 | 
| -        }
 | 
| -    '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('async*', {
 | 
| -      '/main.dart': '''
 | 
| -        import 'dart:async';
 | 
| -
 | 
| -        dynamic x;
 | 
| -
 | 
| -        bar1() async* { yield x; }
 | 
| -        Stream bar2() async* { yield x; }
 | 
| -        Stream<int> bar3() async* { yield (/*info:DynamicCast*/x); }
 | 
| -        Stream<int> bar4() async* { yield (/*severe:StaticTypeError*/new Stream<int>()); }
 | 
| -
 | 
| -        baz1() async* { yield* (/*info:DynamicCast*/x); }
 | 
| -        Stream baz2() async* { yield* (/*info:DynamicCast*/x); }
 | 
| -        Stream<int> baz3() async* { yield* (/*warning:DownCastComposite*/x); }
 | 
| -        Stream<int> baz4() async* { yield* new Stream<int>(); }
 | 
| -        Stream<int> baz5() async* { yield* (/*info:InferredTypeAllocation*/new Stream()); }
 | 
| -    '''
 | 
| -    });
 | 
| -
 | 
| -    testChecker('sync*', {
 | 
| -      '/main.dart': '''
 | 
| -        import 'dart:async';
 | 
| -
 | 
| -        dynamic x;
 | 
| -
 | 
| -        bar1() sync* { yield x; }
 | 
| -        Iterable bar2() sync* { yield x; }
 | 
| -        Iterable<int> bar3() sync* { yield (/*info:DynamicCast*/x); }
 | 
| -        Iterable<int> bar4() sync* { yield (/*severe:StaticTypeError*/new Iterable<int>()); }
 | 
| -
 | 
| -        baz1() sync* { yield* (/*info:DynamicCast*/x); }
 | 
| -        Iterable baz2() sync* { yield* (/*info:DynamicCast*/x); }
 | 
| -        Iterable<int> baz3() sync* { yield* (/*warning:DownCastComposite*/x); }
 | 
| -        Iterable<int> baz4() sync* { yield* new Iterable<int>(); }
 | 
| -        Iterable<int> baz5() sync* { yield* (/*info:InferredTypeAllocation*/new Iterable()); }
 | 
| -    '''
 | 
| -    });
 | 
| -  });
 | 
| -}
 | 
| 
 |