| 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 f2aebcb1d3b4ad2e6cae82fb0543cf8c9bb9ed1c..d0042cdf8fd220cef5fcabe2e09148ae09022427 100644
|
| --- a/pkg/analyzer/test/generated/strong_mode_test.dart
|
| +++ b/pkg/analyzer/test/generated/strong_mode_test.dart
|
| @@ -130,6 +130,50 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
|
| _isInt(call.staticType);
|
| }
|
|
|
| + fail_futureOr_downwards7() async {
|
| + // Test that downwards inference incorporates bounds correctly
|
| + // 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";
|
| + 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);
|
| + }
|
| +
|
| + fail_futureOr_downwards8() async {
|
| + // Test that downwards inference incorporates bounds correctly
|
| + // 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";
|
| + 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);
|
| + }
|
| +
|
| fail_pinning_multipleConstraints1() async {
|
| // Test that downwards inference with two different downwards covariant
|
| // constraints on the same parameter correctly fails to infer when
|
| @@ -923,6 +967,250 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
|
| expect(functionReturnValue(4).staticType, typeProvider.stringType);
|
| }
|
|
|
| + test_futureOr_downwards1() async {
|
| + // Test that downwards inference interacts correctly with FutureOr
|
| + // parameters.
|
| + String code = r'''
|
| + import "dart:async";
|
| + 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";
|
| + 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";
|
| + 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);
|
| + }
|
| +
|
| + 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";
|
| + 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);
|
| + }
|
| +
|
| + test_futureOr_downwards5() async {
|
| + // Test that downwards inference correctly pins the type when it
|
| + // comes from a FutureOr
|
| + String code = r'''
|
| + import "dart:async";
|
| + 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);
|
| + }
|
| +
|
| + test_futureOr_downwards6() async {
|
| + // Test that downwards inference doesn't decompose FutureOr
|
| + // when instantiating type variables.
|
| + String code = r'''
|
| + import "dart:async";
|
| + 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);
|
| + }
|
| +
|
| + test_futureOr_downwards9() async {
|
| + // Test that downwards inference decomposes correctly with
|
| + // other composite types
|
| + String code = r'''
|
| + import "dart:async";
|
| + 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";
|
| + 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";
|
| + 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;
|
| + _isDynamic(invoke.staticType);
|
| + }
|
| +
|
| + test_futureOr_methods3() async {
|
| + // Test that FutureOr does not have the Future type methods
|
| + String code = r'''
|
| + import "dart:async";
|
| + 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;
|
| + _isDynamic(invoke.staticType);
|
| + }
|
| +
|
| + test_futureOr_methods4() async {
|
| + // Test that FutureOr<dynamic> does not have all methods
|
| + String code = r'''
|
| + import "dart:async";
|
| + 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;
|
| + _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";
|
| + 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";
|
| + 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;
|
| + _isFutureOf([_isObject])(invoke.staticType);
|
| + }
|
| +
|
| test_inference_hints() async {
|
| Source source = addSource(r'''
|
| void main () {
|
| @@ -1797,6 +2085,19 @@ class StrongModeStaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
|
| expect(invocation.staticInvokeType.toString(), type);
|
| }
|
|
|
| + fail_futureOr_promotion4() async {
|
| + // Test that promotion from FutureOr<T> to T works for type
|
| + // parameters T
|
| + // TODO(leafp): When the restriction on is checks for generic methods
|
| + // goes away this should pass.
|
| + String code = r'''
|
| + import "dart:async";
|
| + dynamic test<T extends num>(FutureOr<T> x) => (x is T) &&
|
| + (x.abs() == 0);
|
| + ''';
|
| + await resolveTestUnit(code);
|
| + }
|
| +
|
| fail_genericMethod_tearoff_instantiated() async {
|
| await resolveTestUnit(r'''
|
| class C<E> {
|
| @@ -1857,6 +2158,37 @@ main() {
|
| expectInitializerType('foo', 'String', isNull);
|
| }
|
|
|
| + test_futureOr_promotion1() async {
|
| + // Test that promotion from FutureOr<T> to T works for concrete types
|
| + String code = r'''
|
| + import "dart:async";
|
| + dynamic test(FutureOr<int> x) => (x is int) && (x.abs() == 0);
|
| + ''';
|
| + await resolveTestUnit(code);
|
| + }
|
| +
|
| + test_futureOr_promotion2() async {
|
| + // Test that promotion from FutureOr<T> to Future<T> works for concrete
|
| + // types
|
| + String code = r'''
|
| + import "dart:async";
|
| + dynamic test(FutureOr<int> x) => (x is Future<int>) &&
|
| + (x.then((x) => x) == null);
|
| + ''';
|
| + await resolveTestUnit(code);
|
| + }
|
| +
|
| + test_futureOr_promotion4() async {
|
| + // Test that promotion from FutureOr<T> to Future<T> works for type
|
| + // parameters T
|
| + String code = r'''
|
| + import "dart:async";
|
| + dynamic test<T extends num>(FutureOr<T> x) => (x is Future<T>) &&
|
| + (x.then((x) => x) == null);
|
| + ''';
|
| + await resolveTestUnit(code);
|
| + }
|
| +
|
| test_genericFunction() async {
|
| await resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
|
| expectFunctionType('f', '<T>(T) → T',
|
| @@ -2400,6 +2732,7 @@ main() {
|
| }
|
| ''';
|
| await resolveTestUnit(code);
|
| +
|
| expectInitializerType('foo', 'Future<String>', isNull);
|
| }
|
|
|
|
|