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 ac834e6460a3b44a0ae208e41725c85702cc73cb..4854cee68d3342e813cdc3e054e3a332a71cdb53 100644 |
| --- a/pkg/analyzer/test/generated/strong_mode_test.dart |
| +++ b/pkg/analyzer/test/generated/strong_mode_test.dart |
| @@ -92,19 +92,21 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| return result; |
| } |
| - fail_constrainedByBounds3() async { |
| - // Test that upwards inference with two type variables does |
| - // not propogate from the constrained variable to the unconstrained |
| - // variable if they are ordered right to left, and that if the result |
| - // is not a valid instantiation an error is issued |
| - String code = r''' |
| - T f<T extends S, S extends int>(S x) => null; |
| - void test() { var x = f(3); } |
| - '''; |
| - Source source = addSource(code); |
| + @override |
| + void setUp() { |
| + super.setUp(); |
| + AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| + options.strongMode = true; |
| + resetWith(options: options); |
| + } |
| + |
| + test_constrainedByBounds3() async { |
|
Leaf
2017/03/14 22:37:40
Sort methods in file?
Jennifer Messerly
2017/03/14 23:49:09
I can do that. It will destroy the diff, but that
|
| + Source source = addSource(r''' |
| + T f<T extends S, S extends int>(S x) => null; |
| + void test() { var x = f(3); } |
| + '''); |
| TestAnalysisResult analysisResult = await computeAnalysisResult(source); |
| - assertErrors( |
| - source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]); |
| + assertNoErrors(source); |
| verify([source]); |
| CompilationUnit unit = analysisResult.unit; |
| List<Statement> statements = |
| @@ -112,10 +114,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| VariableDeclarationStatement stmt = statements[0]; |
| VariableDeclaration decl = stmt.variables.variables[0]; |
| Expression call = decl.initializer; |
| - _isDynamic(call.staticType); |
| + _isInt(call.staticType); |
| } |
| - fail_constrainedByBounds5() async { |
| + test_constrainedByBounds5() async { |
| // Test that upwards inference with two type variables does not |
| // propogate from the constrained variable to the unconstrained |
| // variable if they are ordered right to left, when the variable |
| @@ -128,8 +130,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| '''; |
| Source source = addSource(code); |
| TestAnalysisResult analysisResult = await computeAnalysisResult(source); |
| - assertErrors( |
| - source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]); |
| + assertErrors(source, [StrongModeCode.COULD_NOT_INFER]); |
| verify([source]); |
| CompilationUnit unit = analysisResult.unit; |
| List<Statement> statements = |
| @@ -137,23 +138,21 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| VariableDeclarationStatement stmt = statements[0]; |
| VariableDeclaration decl = stmt.variables.variables[0]; |
| Expression call = decl.initializer; |
| - _isInt(call.staticType); |
| + _isDynamic(call.staticType); |
| } |
| - fail_futureOr_downwards7() async { |
| + test_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. |
| MethodInvocation invoke = await _testFutureOr(r''' |
| - T mk<T extends int>(T x) => null; |
| - FutureOr<int> test() => mk(new Future.value(42)); |
| + T mk<T extends Future<int>>(T x) => null; |
| + FutureOr<int> test() => mk(new Future.value(42)); |
| '''); |
| _isFutureOfInt(invoke.staticType); |
| _isFutureOfInt(invoke.argumentList.arguments[0].staticType); |
| } |
| - fail_futureOr_downwards8() async { |
| + test_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 |
| @@ -166,7 +165,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| _isFutureOfInt(invoke.argumentList.arguments[0].staticType); |
| } |
| - fail_pinning_multipleConstraints1() async { |
| + test_pinning_multipleConstraints1() async { |
| // Test that downwards inference with two different downwards covariant |
| // constraints on the same parameter correctly fails to infer when |
| // the types do not share a common subtype |
| @@ -180,7 +179,8 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| '''; |
| Source source = addSource(code); |
| TestAnalysisResult analysisResult = await computeAnalysisResult(source); |
| - assertErrors(source, [StrongModeCode.COULD_NOT_INFER]); |
| + assertErrors(source, |
| + [StrongModeCode.COULD_NOT_INFER, StrongModeCode.INVALID_CAST_LITERAL]); |
| verify([source]); |
| CompilationUnit unit = analysisResult.unit; |
| FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); |
| @@ -189,10 +189,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| Element elementB = AstFinder.getClass(unit, "B").element; |
| - _isInstantiationOf(_hasElement(elementB))([_isDynamic])(type); |
| + _isInstantiationOf(_hasElement(elementB))([_isNull])(type); |
| } |
| - fail_pinning_multipleConstraints2() async { |
| + test_pinning_multipleConstraints2() async { |
| // Test that downwards inference with two identical downwards covariant |
| // constraints on the same parameter correctly infers and pins the type |
| String code = r''' |
| @@ -217,7 +217,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| _isInstantiationOf(_hasElement(elementB))([_isNum])(type); |
| } |
| - fail_pinning_multipleConstraints3() async { |
| + test_pinning_multipleConstraints3() async { |
| // Test that downwards inference with two different downwards covariant |
| // constraints on the same parameter correctly fails to infer when |
| // the types do not share a common subtype, but do share a common supertype |
| @@ -233,7 +233,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| TestAnalysisResult analysisResult = await computeAnalysisResult(source); |
| assertErrors(source, [ |
| StrongModeCode.COULD_NOT_INFER, |
| - StaticTypeWarningCode.RETURN_OF_INVALID_TYPE |
| + StrongModeCode.INVALID_CAST_LITERAL, |
| ]); |
| verify([source]); |
| CompilationUnit unit = analysisResult.unit; |
| @@ -243,10 +243,10 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| Element elementB = AstFinder.getClass(unit, "B").element; |
| - _isInstantiationOf(_hasElement(elementB))([_isDynamic])(type); |
| + _isInstantiationOf(_hasElement(elementB))([_isNull])(type); |
| } |
| - fail_returnType_variance2() async { |
| + test_returnType_variance2() async { |
| // Check that downwards inference correctly pins a type parameter |
| // when the parameter is constrained in a covariant position |
| String code = r''' |
| @@ -266,7 +266,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| invoke.staticInvokeType); |
| } |
| - fail_returnType_variance6() async { |
| + test_returnType_variance6() async { |
| // Check that pinning works correctly with a partial type |
| // when the return type uses the variable in a covariant position |
| String code = r''' |
| @@ -288,14 +288,6 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| call.staticInvokeType); |
| } |
| - @override |
| - void setUp() { |
| - super.setUp(); |
| - AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
| - options.strongMode = true; |
| - resetWith(options: options); |
| - } |
| - |
| test_async_method_propagation() async { |
| String code = r''' |
| import "dart:async"; |
| @@ -534,7 +526,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| VariableDeclarationStatement stmt = statements[0]; |
| VariableDeclaration decl = stmt.variables.variables[0]; |
| Expression call = decl.initializer; |
| - _isDynamic(call.staticType); |
| + _isInt(call.staticType); |
| } |
| test_constrainedByBounds4() async { |
| @@ -1064,7 +1056,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| T mk<T>(T x) => null; |
| FutureOr<int> test() => mk(new Future.value(42)); |
| '''); |
| - _isFutureOfInt(invoke.staticType); |
| + _isFutureOrOfInt(invoke.staticType); |
| _isFutureOfInt(invoke.argumentList.arguments[0].staticType); |
| } |
| @@ -1125,7 +1117,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| '''); |
| _isFunction2Of(_isInt, _isNull)( |
| invoke.argumentList.arguments[0].staticType); |
| - _isFutureOfDynamic(invoke.staticType); |
| + _isFutureOfNull(invoke.staticType); |
| } |
| test_futureOr_no_return_value() async { |
| @@ -1136,7 +1128,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| '''); |
| _isFunction2Of(_isInt, _isNull)( |
| invoke.argumentList.arguments[0].staticType); |
| - _isFutureOfDynamic(invoke.staticType); |
| + _isFutureOfNull(invoke.staticType); |
| } |
| test_futureOr_return_null() async { |
| @@ -1147,7 +1139,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| '''); |
| _isFunction2Of(_isInt, _isNull)( |
| invoke.argumentList.arguments[0].staticType); |
| - _isFutureOfDynamic(invoke.staticType); |
| + _isFutureOfNull(invoke.staticType); |
| } |
| test_futureOr_upwards1() async { |
| @@ -1169,7 +1161,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| dynamic test() => mk(new Future<int>.value(42)); |
| ''', |
| errors: [StrongModeCode.COULD_NOT_INFER]); |
| - _isFutureOf([_isObject])(invoke.staticType); |
| + _isFutureOfInt(invoke.staticType); |
| } |
| test_futureOrNull_no_return() async { |
| @@ -1895,6 +1887,53 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type); |
| } |
| + test_inferConstructor_unknownTypeLowerBound() async { |
| + Source source = addSource(r''' |
| + class C<T> { |
| + C(void callback(List<T> a)); |
| + } |
| + test() { |
| + // downwards inference pushes List<?> and in parameter position this |
| + // becomes inferred as List<Null>. |
| + var c = new C((items) {}); |
| + } |
| + '''); |
| + CompilationUnit unit = (await computeAnalysisResult(source)).unit; |
| + assertNoErrors(source); |
| + verify([source]); |
| + DartType cType = AstFinder |
| + .getTopLevelFunction(unit, "test") |
| + .element |
| + .localVariables[0] |
| + .type; |
| + Element elementC = AstFinder.getClass(unit, "C").element; |
| + |
| + _isInstantiationOf(_hasElement(elementC))([_isNull])(cType); |
| + } |
| + |
| + test_inferConstructor_varianceForCallback2() async { |
| + Source source = addSource(r''' |
| + class C<T> { |
| + C(void callback(List<T> a)); |
| + } |
| + test() { |
| + var c = new C((List items) {}); |
| + } |
| + '''); |
| + CompilationUnit unit = (await computeAnalysisResult(source)).unit; |
| + assertNoErrors(source); |
| + verify([source]); |
| + DartType cType = AstFinder |
| + .getTopLevelFunction(unit, "test") |
| + .element |
| + .localVariables[0] |
| + .type; |
| + Element elementC = AstFinder.getClass(unit, "C").element; |
| + |
| + _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType); |
| + } |
| + |
| + |
| test_redirectingConstructor_propagation() async { |
| String code = r''' |
| class A { |
| @@ -1932,7 +1971,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| } |
| test_returnType_variance3() async { |
| - // Check that the variance heuristic chooses the less precise type |
| + // Check that the variance heuristic chooses the most precise type |
| // when the return type uses the variable in a contravariant position |
| // and there is no downwards constraint. |
| String code = r''' |
| @@ -1949,7 +1988,7 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| ExpressionFunctionBody body = test.functionExpression.body; |
| FunctionType functionType = body.expression.staticType; |
| DartType type = functionType.normalParameterTypes[0]; |
| - _isNum(type); |
| + _isInt(type); |
| } |
| test_returnType_variance4() async { |
| @@ -2301,9 +2340,25 @@ class D<S> { |
| } |
| test_genericFunction_upwardsAndDownwards() async { |
| - // Regression tests for https://github.com/dart-lang/sdk/issues/27151. |
| + // Regression tests for https://github.com/dart-lang/sdk/issues/27586. |
| await resolveTestUnit(r'List<num> x = [1, 2];'); |
| - expectInitializerType('x', 'List<int>'); |
| + expectInitializerType('x', 'List<num>'); |
| + } |
| + |
| + test_genericFunction_upwardsAndDownwards_Object() async { |
| + // Regression tests for https://github.com/dart-lang/sdk/issues/27625. |
| + await resolveTestUnit(r''' |
| +List<Object> aaa = []; |
| +List<Object> bbb = [1, 2, 3]; |
| +List<Object> ccc = [null]; |
| +List<Object> ddd = [1 as dynamic]; |
| +List<Object> eee = [new Object()]; |
| + '''); |
| + expectInitializerType('aaa', 'List<Object>'); |
| + expectInitializerType('bbb', 'List<Object>'); |
| + expectInitializerType('ccc', 'List<Object>'); |
| + expectInitializerType('ddd', 'List<Object>'); |
| + expectInitializerType('eee', 'List<Object>'); |
| } |
| test_genericMethod() async { |
| @@ -3011,7 +3066,22 @@ class C<T> { |
| '''; |
| await resolveTestUnit(code); |
| assertNoErrors(testSource); |
| - expectStaticInvokeType('m(null', '(T, List<T>) → void'); |
| + expectStaticInvokeType('m(null', '(Null, Null) → void'); |
| + } |
| + |
| + test_instantiateToBounds_method_ok_referenceOther_before2() async { |
| + String code = r''' |
| +class C<T> { |
| + Map<S0, S1> m<S0 extends T, S1 extends List<S0>>() => null; |
| + |
| + void main() { |
| + m(); |
| + } |
| +} |
| +'''; |
| + await resolveTestUnit(code); |
| + assertNoErrors(testSource); |
| + expectStaticInvokeType('m();', '() → Map<T, List<T>>'); |
| } |
| test_instantiateToBounds_method_ok_simpleBounds() async { |
| @@ -3026,7 +3096,22 @@ class C<T> { |
| '''; |
| await resolveTestUnit(code); |
| assertNoErrors(testSource); |
| - expectStaticInvokeType('m(null)', '(T) → void'); |
| + expectStaticInvokeType('m(null)', '(Null) → void'); |
| + } |
| + |
| + test_instantiateToBounds_method_ok_simpleBounds2() async { |
| + String code = r''' |
| +class C<T> { |
| + S m<S extends T>() => null; |
| + |
| + void main() { |
| + m(); |
| + } |
| +} |
| +'''; |
| + await resolveTestUnit(code); |
| + assertNoErrors(testSource); |
| + expectStaticInvokeType('m();', '() → T'); |
| } |
| test_notInstantiatedBound_direct_class_class() async { |