Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Unified Diff: pkg/analyzer/test/src/task/strong/inferred_type_test.dart

Issue 1632113002: make checker_test, inferred_type_test easier to debug (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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()));
}
'''
- });
+ });
});
}

Powered by Google App Engine
This is Rietveld 408576698