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

Unified Diff: pkg/analyzer/test/generated/strong_mode_test.dart

Issue 2655273008: fix #28526 and fix #28527 FutureOr<T> in await and subtype (Closed)
Patch Set: fix Created 3 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/generated/strong_mode_test.dart
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index d0042cdf8fd220cef5fcabe2e09148ae09022427..a90fe1430549a2c0190d8412d9f5976e9f0c2fdd 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -14,6 +14,7 @@ import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:front_end/src/base/errors.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -38,6 +39,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
Asserter<DartType> _isDynamic;
Asserter<InterfaceType> _isFutureOfDynamic;
Asserter<InterfaceType> _isFutureOfInt;
+ Asserter<InterfaceType> _isFutureOrOfInt;
Asserter<DartType> _isInt;
Asserter<DartType> _isNum;
Asserter<DartType> _isObject;
@@ -46,6 +48,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
_isFunction2Of;
AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
+ AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOrOf;
AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
_isInstantiationOf;
AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
@@ -75,8 +78,11 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
_isFunction2Of = _assertions.isFunction2Of;
_hasElementOf = _assertions.hasElementOf;
_isFutureOf = _isInstantiationOf(_hasElementOf(typeProvider.futureType));
+ _isFutureOrOf =
+ _isInstantiationOf(_hasElementOf(typeProvider.futureOrType));
_isFutureOfDynamic = _isFutureOf([_isDynamic]);
_isFutureOfInt = _isFutureOf([_isInt]);
+ _isFutureOrOfInt = _isFutureOrOf([_isInt]);
_isStreamOf = _isInstantiationOf(_hasElementOf(typeProvider.streamType));
}
return result;
@@ -135,19 +141,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
// when instantiating type variables.
// TODO(leafp): I think this should pass once the inference changes
// that jmesserly is adding are landed.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
T mk<T extends int>(T x) => null;
FutureOr<int> test() => mk(new Future.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
_isFutureOfInt(invoke.argumentList.arguments[0].staticType);
}
@@ -157,19 +154,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
// when instantiating type variables.
// TODO(leafp): I think this should pass once the inference changes
// that jmesserly is adding are landed.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
T mk<T extends Future<Object>>(T x) => null;
FutureOr<int> test() => mk(new Future.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
_isFutureOfInt(invoke.argumentList.arguments[0].staticType);
}
@@ -970,57 +958,30 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
test_futureOr_downwards1() async {
// Test that downwards inference interacts correctly with FutureOr
// parameters.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
Future<T> mk<T>(FutureOr<T> x) => null;
Future<int> test() => mk(new Future<int>.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
}
test_futureOr_downwards2() async {
// Test that downwards inference interacts correctly with FutureOr
// parameters when the downwards context is FutureOr
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
Future<T> mk<T>(FutureOr<T> x) => null;
FutureOr<int> test() => mk(new Future<int>.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
}
test_futureOr_downwards3() async {
// Test that downwards inference correctly propogates into
// arguments.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
Future<T> mk<T>(FutureOr<T> x) => null;
Future<int> test() => mk(new Future.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
_isFutureOfInt(invoke.argumentList.arguments[0].staticType);
}
@@ -1028,19 +989,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
test_futureOr_downwards4() async {
// Test that downwards inference interacts correctly with FutureOr
// parameters when the downwards context is FutureOr
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
Future<T> mk<T>(FutureOr<T> x) => null;
FutureOr<int> test() => mk(new Future.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
_isFutureOfInt(invoke.argumentList.arguments[0].staticType);
}
@@ -1048,19 +1000,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
test_futureOr_downwards5() async {
// Test that downwards inference correctly pins the type when it
// comes from a FutureOr
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
Future<T> mk<T>(FutureOr<T> x) => null;
FutureOr<num> test() => mk(new Future.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOf([_isNum])(invoke.staticType);
_isFutureOf([_isNum])(invoke.argumentList.arguments[0].staticType);
}
@@ -1068,19 +1011,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
test_futureOr_downwards6() async {
// Test that downwards inference doesn't decompose FutureOr
// when instantiating type variables.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
T mk<T>(T x) => null;
FutureOr<int> test() => mk(new Future.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
_isFutureOfInt(invoke.argumentList.arguments[0].staticType);
}
@@ -1088,129 +1022,119 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
test_futureOr_downwards9() async {
// Test that downwards inference decomposes correctly with
// other composite types
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
List<T> mk<T>(T x) => null;
FutureOr<List<int>> test() => mk(3);
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isListOf(_isInt)(invoke.staticType);
_isInt(invoke.argumentList.arguments[0].staticType);
}
test_futureOr_methods1() async {
// Test that FutureOr has the Object methods
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
dynamic test(FutureOr<int> x) => x.toString();
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isString(invoke.staticType);
}
test_futureOr_methods2() async {
// Test that FutureOr does not have the constituent type methods
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(
+ r'''
dynamic test(FutureOr<int> x) => x.abs();
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''',
+ errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
_isDynamic(invoke.staticType);
}
test_futureOr_methods3() async {
// Test that FutureOr does not have the Future type methods
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(
+ r'''
dynamic test(FutureOr<int> x) => x.then((x) => x);
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''',
+ errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
_isDynamic(invoke.staticType);
}
test_futureOr_methods4() async {
// Test that FutureOr<dynamic> does not have all methods
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(
+ r'''
dynamic test(FutureOr<dynamic> x) => x.abs();
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''',
+ errors: [StaticTypeWarningCode.UNDEFINED_METHOD]);
_isDynamic(invoke.staticType);
}
test_futureOr_upwards1() async {
// Test that upwards inference correctly prefers to instantiate type
// variables with the "smaller" solution when both are possible.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(r'''
Future<T> mk<T>(FutureOr<T> x) => null;
dynamic test() => mk(new Future<int>.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''');
_isFutureOfInt(invoke.staticType);
}
test_futureOr_upwards2() async {
// Test that upwards inference fails when the solution doesn't
// match the bound.
- String code = r'''
- import "dart:async";
+ MethodInvocation invoke = await _testFutureOr(
+ r'''
Future<T> mk<T extends Future<Object>>(FutureOr<T> x) => null;
dynamic test() => mk(new Future<int>.value(42));
- ''';
- Source source = addSource(code);
- TestAnalysisResult analysisResult = await computeAnalysisResult(source);
- assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
- verify([source]);
- CompilationUnit unit = analysisResult.unit;
- FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test");
- ExpressionFunctionBody body = test.functionExpression.body;
- MethodInvocation invoke = body.expression;
+ ''',
+ errors: [StrongModeCode.COULD_NOT_INFER]);
_isFutureOf([_isObject])(invoke.staticType);
}
+ test_futureOr_assignFromValue() async {
+ // Test a T can be assigned to FutureOr<T>.
+ MethodInvocation invoke = await _testFutureOr(r'''
+ FutureOr<T> mk<T>(T x) => x;
+ test() => mk(42);
+ ''');
+ _isFutureOrOfInt(invoke.staticType);
+ }
+
+ test_futureOr_assignFromFuture() async {
+ // Test a Future<T> can be assigned to FutureOr<T>.
+ MethodInvocation invoke = await _testFutureOr(r'''
+ FutureOr<T> mk<T>(Future<T> x) => x;
+ test() => mk(new Future<int>.value(42));
+ ''');
+ _isFutureOrOfInt(invoke.staticType);
+ }
+
+ test_futureOr_await() async {
+ // Test a FutureOr<T> can be awaited.
+ MethodInvocation invoke = await _testFutureOr(r'''
+ Future<T> mk<T>(FutureOr<T> x) async => await x;
+ test() => mk(42);
+ ''');
+ _isFutureOfInt(invoke.staticType);
+ }
+
+ test_futureOr_asyncExpressionBody() async {
+ // A FutureOr<T> can be used as the expression body for an async function
+ MethodInvocation invoke = await _testFutureOr(r'''
+ Future<T> mk<T>(FutureOr<T> x) async => x;
+ test() => mk(42);
+ ''');
+ _isFutureOfInt(invoke.staticType);
+ }
+
+ test_futureOr_asyncReturn() async {
+ // A FutureOr<T> can be used as the return value for an async function
+ MethodInvocation invoke = await _testFutureOr(r'''
+ Future<T> mk<T>(FutureOr<T> x) async { return x; }
+ test() => mk(42);
+ ''');
+ _isFutureOfInt(invoke.staticType);
+ }
+
test_inference_hints() async {
Source source = addSource(r'''
void main () {
@@ -2073,6 +1997,30 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
check("f2", _isListOf(_isInt));
check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
}
+
+ /// Helper method for testing `FutureOr<T>`.
+ ///
+ /// Validates that [code] produces [errors]. It should define a function
+ /// "test", whose body is an expression that invokes a method. Returns that
+ /// invocation.
+ Future<MethodInvocation> _testFutureOr(String code,
+ {List<ErrorCode> errors}) async {
+ Source source = addSource("""
+ import "dart:async";
+ $code""");
+ TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+
+ if (errors == null) {
+ assertNoErrors(source);
+ } else {
+ assertErrors(source, errors);
+ }
+ verify([source]);
+ FunctionDeclaration test =
+ AstFinder.getTopLevelFunction(analysisResult.unit, "test");
+ ExpressionFunctionBody body = test.functionExpression.body;
+ return body.expression;
+ }
}
/**

Powered by Google App Engine
This is Rietveld 408576698