Chromium Code Reviews| 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..e34df8a34787720facda4ef65aa98567b15dff75 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 Future<T> can be assigned to FutureOr<T>. |
|
Leaf
2017/01/27 21:34:54
Comment is wrong? Tests that await FutureOr<T> wo
Jennifer Messerly
2017/01/27 22:39:19
I thought so too. It was from Bob's CL. Happy to f
|
| + 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; |
| + } |
| } |
| /** |