| Index: pkg/analyzer/test/src/task/strong/inferred_type_test.dart
|
| diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
|
| index d823b20b49e2c3a02b3b4282a5d0c75c06a6e924..04f643b44a0d01af707b97701e800c0993871ee7 100644
|
| --- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
|
| +++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
|
| @@ -13,55 +13,67 @@ import 'strong_test_helper.dart';
|
|
|
| void main() {
|
| // Error also expected when declared type is `int`.
|
| - testChecker('infer type on var', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer type on var',
|
| + () => {
|
| + '/main.dart': '''
|
| test1() {
|
| int x = 3;
|
| x = /*severe:STATIC_TYPE_ERROR*/"hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| // If inferred type is `int`, error is also reported
|
| - testChecker('infer type on var 2', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer type on var 2',
|
| + () => {
|
| + '/main.dart': '''
|
| test2() {
|
| var x = 3;
|
| x = /*severe:STATIC_TYPE_ERROR*/"hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('No error when declared type is `num` and assigned null.', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'No error when declared type is `num` and assigned null.',
|
| + () => {
|
| + '/main.dart': '''
|
| test1() {
|
| num x = 3;
|
| x = null;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('do not infer type on dynamic', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'do not infer type on dynamic',
|
| + () => {
|
| + '/main.dart': '''
|
| test() {
|
| dynamic x = 3;
|
| x = "hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('do not infer type when initializer is null', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'do not infer type when initializer is null',
|
| + () => {
|
| + '/main.dart': '''
|
| test() {
|
| var x = null;
|
| x = "hi";
|
| x = 3;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer type on var from field', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer type on var from field',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 0;
|
|
|
| @@ -81,10 +93,12 @@ void main() {
|
| final z = 42; // should infer `int`
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer type on var from top-level', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer type on var from top-level',
|
| + () => {
|
| + '/main.dart': '''
|
| int x = 0;
|
|
|
| test1() {
|
| @@ -102,10 +116,12 @@ void main() {
|
| int y = 0; // field def after use
|
| final z = 42; // should infer `int`
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('do not infer field type when initializer is null', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'do not infer field type when initializer is null',
|
| + () => {
|
| + '/main.dart': '''
|
| var x = null;
|
| var y = 3;
|
| class A {
|
| @@ -125,13 +141,15 @@ void main() {
|
| new A().y2 = /*severe:STATIC_TYPE_ERROR*/"hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer from variables in non-cycle imports with flag', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer from variables in non-cycle imports with flag',
|
| + () => {
|
| + '/a.dart': '''
|
| var x = 2;
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| var y = x;
|
|
|
| @@ -140,13 +158,15 @@ void main() {
|
| y = /*severe:STATIC_TYPE_ERROR*/"hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer from variables in non-cycle imports with flag 2', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer from variables in non-cycle imports with flag 2',
|
| + () => {
|
| + '/a.dart': '''
|
| class A { static var x = 2; }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| class B { static var y = A.x; }
|
|
|
| @@ -155,14 +175,16 @@ void main() {
|
| B.y = /*severe:STATIC_TYPE_ERROR*/"hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer from variables in cycle libs when flag is on', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer from variables in cycle libs when flag is on',
|
| + () => {
|
| + '/a.dart': '''
|
| import 'main.dart';
|
| var x = 2; // ok to infer
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| var y = x; // now ok :)
|
|
|
| @@ -172,14 +194,16 @@ void main() {
|
| t = y;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer from variables in cycle libs when flag is on 2', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer from variables in cycle libs when flag is on 2',
|
| + () => {
|
| + '/a.dart': '''
|
| import 'main.dart';
|
| class A { static var x = 2; }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| class B { static var y = A.x; }
|
|
|
| @@ -189,23 +213,25 @@ void main() {
|
| t = B.y;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('can infer also from static and instance fields (flag on)', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'can infer also from static and instance fields (flag on)',
|
| + () => {
|
| + '/a.dart': '''
|
| import 'b.dart';
|
| class A {
|
| static final a1 = B.b1;
|
| final a2 = new B().b2;
|
| }
|
| ''',
|
| - '/b.dart': '''
|
| + '/b.dart': '''
|
| class B {
|
| static final b1 = 1;
|
| final b2 = 1;
|
| }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import "a.dart";
|
|
|
| test1() {
|
| @@ -215,23 +241,25 @@ void main() {
|
| x = new A().a2;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('inference in cycles is deterministic', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'inference in cycles is deterministic',
|
| + () => {
|
| + '/a.dart': '''
|
| import 'b.dart';
|
| class A {
|
| static final a1 = B.b1;
|
| final a2 = new B().b2;
|
| }
|
| ''',
|
| - '/b.dart': '''
|
| + '/b.dart': '''
|
| class B {
|
| static final b1 = 1;
|
| final b2 = 1;
|
| }
|
| ''',
|
| - '/c.dart': '''
|
| + '/c.dart': '''
|
| import "main.dart"; // creates a cycle
|
|
|
| class C {
|
| @@ -239,7 +267,7 @@ void main() {
|
| final c2 = 1;
|
| }
|
| ''',
|
| - '/e.dart': '''
|
| + '/e.dart': '''
|
| import 'a.dart';
|
| part 'e2.dart';
|
|
|
| @@ -252,16 +280,16 @@ void main() {
|
| final e6 = new A().a2;
|
| }
|
| ''',
|
| - '/f.dart': '''
|
| + '/f.dart': '''
|
| part 'f2.dart';
|
| ''',
|
| - '/e2.dart': '''
|
| + '/e2.dart': '''
|
| class F {
|
| static final f1 = 1;
|
| final f2 = 1;
|
| }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import "a.dart";
|
| import "c.dart";
|
| import "e.dart";
|
| @@ -300,11 +328,12 @@ void main() {
|
| x = new F().f2;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| testChecker(
|
| - 'infer from complex expressions if the outer-most value is precise', {
|
| - '/main.dart': '''
|
| + 'infer from complex expressions if the outer-most value is precise',
|
| + () => {
|
| + '/main.dart': '''
|
| class A { int x; B operator+(other) {} }
|
| class B extends A { B(ignore); }
|
| var a = new A();
|
| @@ -347,10 +376,12 @@ void main() {
|
| j = /*severe:STATIC_TYPE_ERROR*/[];
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer list literal nested in map literal', {
|
| - '/main.dart': r'''
|
| + testChecker(
|
| + 'infer list literal nested in map literal',
|
| + () => {
|
| + '/main.dart': r'''
|
| class Resource {}
|
| class Folder extends Resource {}
|
|
|
| @@ -377,16 +408,18 @@ main() {
|
| );
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| // but flags can enable this behavior.
|
| - testChecker('infer if complex expressions read possibly inferred field', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer if complex expressions read possibly inferred field',
|
| + () => {
|
| + '/a.dart': '''
|
| class A {
|
| var x = 3;
|
| }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| class B {
|
| var y = 3;
|
| @@ -407,11 +440,13 @@ main() {
|
| i = new B().y; // B.y was inferred though
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| group('infer types on loop indices', () {
|
| - testChecker('foreach loop', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'foreach loop',
|
| + () => {
|
| + '/main.dart': '''
|
| class Foo {
|
| int bar = 42;
|
| }
|
| @@ -475,21 +510,25 @@ main() {
|
| }
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('for loop, with inference', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'for loop, with inference',
|
| + () => {
|
| + '/main.dart': '''
|
| test() {
|
| for (var i = 0; i < 10; i++) {
|
| int j = i + 1;
|
| }
|
| }
|
| '''
|
| - });
|
| + });
|
| });
|
|
|
| - testChecker('propagate inference to field in class', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'propagate inference to field in class',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 2;
|
| }
|
| @@ -501,10 +540,12 @@ main() {
|
| print(a.x + 2); // ok to use in bigger expression
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('propagate inference to field in class dynamic warnings', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'propagate inference to field in class dynamic warnings',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 2;
|
| }
|
| @@ -516,10 +557,12 @@ main() {
|
| print(/*info:DYNAMIC_INVOKE*/(/*info:DYNAMIC_INVOKE*/a.x) + 2);
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('propagate inference transitively', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'propagate inference transitively',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 2;
|
| }
|
| @@ -532,10 +575,12 @@ main() {
|
| a2.x = /*severe:STATIC_TYPE_ERROR*/"hi";
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('propagate inference transitively 2', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'propagate inference transitively 2',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 42;
|
| }
|
| @@ -560,11 +605,13 @@ main() {
|
| print(d2.c.b.a.x);
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| group('infer type on overridden fields', () {
|
| - testChecker('2', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + '2',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 2;
|
| }
|
| @@ -578,10 +625,12 @@ main() {
|
| int z = new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('4', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + '4',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 2;
|
| }
|
| @@ -595,12 +644,14 @@ main() {
|
| int z = new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
| });
|
|
|
| group('infer types on generic instantiations', () {
|
| - testChecker('infer', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer',
|
| + () => {
|
| + '/main.dart': '''
|
| class A<T> {
|
| T x;
|
| }
|
| @@ -614,10 +665,12 @@ main() {
|
| int z = /*info:DYNAMIC_CAST*/new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('3', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + '3',
|
| + () => {
|
| + '/main.dart': '''
|
| class A<T> {
|
| T x;
|
| T w;
|
| @@ -633,10 +686,12 @@ main() {
|
| int z = new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('4', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + '4',
|
| + () => {
|
| + '/main.dart': '''
|
| class A<T> {
|
| T x;
|
| }
|
| @@ -651,10 +706,12 @@ main() {
|
| String z = new B<String>().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('5', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + '5',
|
| + () => {
|
| + '/main.dart': '''
|
| abstract class I<E> {
|
| String m(a, String f(v, T e));
|
| }
|
| @@ -680,16 +737,18 @@ main() {
|
| String z = new B().m(null, null);
|
| }
|
| '''
|
| - });
|
| + });
|
| });
|
|
|
| - testChecker('infer type regardless of declaration order or cycles', {
|
| - '/b.dart': '''
|
| + testChecker(
|
| + 'infer type regardless of declaration order or cycles',
|
| + () => {
|
| + '/b.dart': '''
|
| import 'main.dart';
|
|
|
| class B extends A { }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'b.dart';
|
| class C extends B {
|
| get x;
|
| @@ -702,19 +761,21 @@ main() {
|
| String y = /*severe:STATIC_TYPE_ERROR*/new C().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| // Note: this is a regression test for a non-deterministic behavior we used to
|
| // have with inference in library cycles. If you see this test flake out,
|
| // change `test` to `skip_test` and reopen bug #48.
|
| - testChecker('infer types on generic instantiations in library cycle', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer types on generic instantiations in library cycle',
|
| + () => {
|
| + '/a.dart': '''
|
| import 'main.dart';
|
| abstract class I<E> {
|
| A<E> m(a, String f(v, int e));
|
| }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
|
|
| abstract class A<E> implements I<E> {
|
| @@ -739,11 +800,13 @@ main() {
|
| String z = new B<String>().m(null, null).value;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| group('do not infer overridden fields that explicitly say dynamic', () {
|
| - testChecker('infer', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| int x = 2;
|
| }
|
| @@ -757,11 +820,13 @@ main() {
|
| int z = /*info:DYNAMIC_CAST*/new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
| });
|
|
|
| - testChecker('conflicts can happen', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'conflicts can happen',
|
| + () => {
|
| + '/main.dart': '''
|
| class I1 {
|
| int x;
|
| }
|
| @@ -786,10 +851,12 @@ main() {
|
| /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('conflicts can happen 2', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'conflicts can happen 2',
|
| + () => {
|
| + '/main.dart': '''
|
| class I1 {
|
| int x;
|
| }
|
| @@ -818,11 +885,12 @@ main() {
|
| /*severe:INVALID_METHOD_OVERRIDE*/get a => null;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| testChecker(
|
| - 'infer from RHS only if it wont conflict with overridden fields', {
|
| - '/main.dart': '''
|
| + 'infer from RHS only if it wont conflict with overridden fields',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| var x;
|
| }
|
| @@ -836,11 +904,12 @@ main() {
|
| int z = /*info:DYNAMIC_CAST*/new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| testChecker(
|
| - 'infer from RHS only if it wont conflict with overridden fields 2', {
|
| - '/main.dart': '''
|
| + 'infer from RHS only if it wont conflict with overridden fields 2',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| final x;
|
| }
|
| @@ -854,10 +923,12 @@ main() {
|
| int z = new B().x;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer correctly on multiple variables declared together', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer correctly on multiple variables declared together',
|
| + () => {
|
| + '/main.dart': '''
|
| class A {
|
| var x, y = 2, z = "hi";
|
| }
|
| @@ -881,19 +952,21 @@ main() {
|
| i = new B().w;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer consts transitively', {
|
| - '/b.dart': '''
|
| + testChecker(
|
| + 'infer consts transitively',
|
| + () => {
|
| + '/b.dart': '''
|
| const b1 = 2;
|
| ''',
|
| - '/a.dart': '''
|
| + '/a.dart': '''
|
| import 'main.dart';
|
| import 'b.dart';
|
| const a1 = m2;
|
| const a2 = b1;
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| const m1 = a1;
|
| const m2 = a2;
|
| @@ -903,13 +976,15 @@ main() {
|
| i = m1;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer statics transitively', {
|
| - '/b.dart': '''
|
| + testChecker(
|
| + 'infer statics transitively',
|
| + () => {
|
| + '/b.dart': '''
|
| final b1 = 2;
|
| ''',
|
| - '/a.dart': '''
|
| + '/a.dart': '''
|
| import 'main.dart';
|
| import 'b.dart';
|
| final a1 = m2;
|
| @@ -917,7 +992,7 @@ main() {
|
| static final a2 = b1;
|
| }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| final m1 = a1;
|
| final m2 = A.a2;
|
| @@ -927,10 +1002,12 @@ main() {
|
| i = m1;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer statics transitively 2', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'infer statics transitively 2',
|
| + () => {
|
| + '/main.dart': '''
|
| const x1 = 1;
|
| final x2 = 1;
|
| final y1 = x1;
|
| @@ -942,17 +1019,19 @@ main() {
|
| i = y2;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer statics transitively 3', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer statics transitively 3',
|
| + () => {
|
| + '/a.dart': '''
|
| const a1 = 3;
|
| const a2 = 4;
|
| class A {
|
| a3;
|
| }
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart' show a1, A;
|
| import 'a.dart' as p show a2, A;
|
| const t1 = 1;
|
| @@ -970,13 +1049,15 @@ main() {
|
| i = t4;
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('infer statics with method invocations', {
|
| - '/a.dart': '''
|
| + testChecker(
|
| + 'infer statics with method invocations',
|
| + () => {
|
| + '/a.dart': '''
|
| m3(String a, String b, [a1,a2]) {}
|
| ''',
|
| - '/main.dart': '''
|
| + '/main.dart': '''
|
| import 'a.dart';
|
| class T {
|
| static final T foo = m1(m2(m3('', '')));
|
| @@ -986,10 +1067,12 @@ main() {
|
|
|
|
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference: miscellaneous', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference: miscellaneous',
|
| + () => {
|
| + '/main.dart': '''
|
| typedef T Function2<S, T>(S x);
|
| class A<T> {
|
| Function2<T, T> x;
|
| @@ -1008,7 +1091,7 @@ main() {
|
| }
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| group('downwards inference on instance creations', () {
|
| String info = 'info:INFERRED_TYPE_ALLOCATION';
|
| @@ -1106,7 +1189,7 @@ main() {
|
| }
|
| }
|
| ''';
|
| - testChecker('infer downwards', {'/main.dart': code});
|
| + testChecker('infer downwards', () => {'/main.dart': code});
|
| });
|
|
|
| group('downwards inference on list literals', () {
|
| @@ -1149,9 +1232,12 @@ main() {
|
| }
|
| }
|
| ''';
|
| - testChecker('infer downwards', {'/main.dart': code});
|
| + testChecker('infer downwards', () => {'/main.dart': code});
|
|
|
| - testChecker('infer if value types match context', {'/main.dart': r'''
|
| + testChecker(
|
| + 'infer if value types match context',
|
| + () => {
|
| + '/main.dart': r'''
|
| class DartType {}
|
| typedef void Asserter<T>(T type);
|
| typedef Asserter<T> AsserterBuilder<S, T>(S arg);
|
| @@ -1206,7 +1292,8 @@ main() {
|
| g.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
|
| g.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
|
| }
|
| - '''});
|
| + '''
|
| + });
|
| });
|
|
|
| group('downwards inference on function arguments', () {
|
| @@ -1244,7 +1331,7 @@ main() {
|
| f4(a: /*$info*/[/*$info*/[/*severe:STATIC_TYPE_ERROR*/"hello"], /*$info*/[3]]);
|
| }
|
| ''';
|
| - testChecker('infer downwards', {'/main.dart': code});
|
| + testChecker('infer downwards', () => {'/main.dart': code});
|
| });
|
|
|
| group('downwards inference on constructor arguments', () {
|
| @@ -1295,7 +1382,7 @@ main() {
|
| /*$info*/[3]]);
|
| }
|
| ''';
|
| - testChecker('infer downwards', {'/main.dart': code});
|
| + testChecker('infer downwards', () => {'/main.dart': code});
|
| });
|
|
|
| group('downwards inference on generic constructor arguments', () {
|
| @@ -1356,7 +1443,7 @@ main() {
|
| new F4(a: /*$info*/[["hello"], [3]]);
|
| }
|
| ''';
|
| - testChecker('infer downwards', {'/main.dart': code});
|
| + testChecker('infer downwards', () => {'/main.dart': code});
|
| });
|
|
|
| group('downwards inference on map literals', () {
|
| @@ -1408,11 +1495,13 @@ main() {
|
| }
|
| }
|
| ''';
|
| - testChecker('infer downwards', {'/main.dart': code});
|
| + testChecker('infer downwards', () => {'/main.dart': code});
|
| });
|
|
|
| - testChecker('downwards inference on function expressions', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference on function expressions',
|
| + () => {
|
| + '/main.dart': '''
|
| typedef T Function2<S, T>(S x);
|
|
|
| void main () {
|
| @@ -1446,10 +1535,12 @@ main() {
|
| }
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference initializing formal, default formal', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference initializing formal, default formal',
|
| + () => {
|
| + '/main.dart': '''
|
| typedef T Function2<S, T>([S x]);
|
| class Foo {
|
| List<int> x;
|
| @@ -1460,19 +1551,23 @@ main() {
|
| // We do this inference in an early task but don't preserve the infos.
|
| Function2<List<int>, String> g = /*pass should be info:INFERRED_TYPE_CLOSURE*/([llll = /*info:INFERRED_TYPE_LITERAL*/const [1]]) => "hello";
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference async/await', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference async/await',
|
| + () => {
|
| + '/main.dart': '''
|
| import 'dart:async';
|
| Future<int> test() async {
|
| List<int> l0 = /*warning:DOWN_CAST_COMPOSITE should be pass*/await /*pass should be info:INFERRED_TYPE_LITERAL*/[3];
|
| List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[3]);
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference foreach', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference foreach',
|
| + () => {
|
| + '/main.dart': '''
|
| import 'dart:async';
|
| void main() {
|
| for(int x in /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3]) {
|
| @@ -1481,10 +1576,12 @@ main() {
|
| }
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference yield/yield*', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference yield/yield*',
|
| + () => {
|
| + '/main.dart': '''
|
| import 'dart:async';
|
| Stream<List<int>> foo() async* {
|
| yield /*info:INFERRED_TYPE_LITERAL*/[];
|
| @@ -1500,10 +1597,12 @@ main() {
|
| yield* /*info:INFERRED_TYPE_ALLOCATION*/new List();
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference, annotations', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference, annotations',
|
| + () => {
|
| + '/main.dart': '''
|
| class Foo {
|
| const Foo(List<String> l);
|
| const Foo.named(List<String> l);
|
| @@ -1513,29 +1612,35 @@ main() {
|
| @Foo.named(/*info:INFERRED_TYPE_LITERAL*/const [])
|
| class Baz {}
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('downwards inference, assignment statements', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'downwards inference, assignment statements',
|
| + () => {
|
| + '/main.dart': '''
|
| void main() {
|
| List<int> l;
|
| l = /*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/"hello"];
|
| l = (l = /*info:INFERRED_TYPE_LITERAL*/[1]);
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('inferred initializing formal checks default value', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'inferred initializing formal checks default value',
|
| + () => {
|
| + '/main.dart': '''
|
| class Foo {
|
| var x = 1;
|
| Foo([this.x = /*severe:STATIC_TYPE_ERROR*/"1"]);
|
| }'''
|
| - });
|
| + });
|
|
|
| group('generic methods', () {
|
| - testChecker('dart:math min/max', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'dart:math min/max',
|
| + () => {
|
| + '/main.dart': '''
|
| import 'dart:math';
|
|
|
| void printInt(int x) => print(x);
|
| @@ -1567,10 +1672,12 @@ main() {
|
| /*severe:STATIC_TYPE_ERROR*/"there"));
|
| }
|
| '''
|
| - });
|
| + });
|
|
|
| - testChecker('Iterable and Future', {
|
| - '/main.dart': '''
|
| + testChecker(
|
| + 'Iterable and Future',
|
| + () => {
|
| + '/main.dart': '''
|
| import 'dart:async';
|
|
|
| Future<int> make(int x) => (/*info:INFERRED_TYPE_ALLOCATION*/new Future(() => x));
|
| @@ -1578,10 +1685,10 @@ main() {
|
| main() {
|
| Iterable<Future<int>> list = <int>[1, 2, 3].map(make);
|
| Future<List<int>> results = Future.wait(list);
|
| - Future<String> results2 = results.then((List<int> list)
|
| + Future<String> results2 = results.then((List<int> list)
|
| => list.fold('', (String x, int y) => x + y.toString()));
|
| }
|
| '''
|
| - });
|
| + });
|
| });
|
| }
|
|
|