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 89f75d53d953ebbba2cae6afd82c0355bba92fc3..534655d022fa6fdbaccea7c6dc278937d2ff499e 100644 |
| --- a/pkg/analyzer/test/generated/strong_mode_test.dart |
| +++ b/pkg/analyzer/test/generated/strong_mode_test.dart |
| @@ -1098,6 +1098,176 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
| _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType); |
| } |
| + test_inference_error_arguments() async { |
| + Source source = addSource(r''' |
| +typedef R F<T, R>(T t); |
| + |
| +F<T, T> g<T>(F<T, T> f) => (x) => f(f(x)); |
| + |
| +test() { |
| + var h = g((int x) => 42.0); |
| +} |
| + '''); |
| + await computeAnalysisResult(source); |
| + _expectInferenceError( |
| + source, |
| + [ |
| + StrongModeCode.COULD_NOT_INFER, |
| + StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE |
| + ], |
| + r''' |
| +Couldn't infer type parameter 'T'. |
| + |
| +Tried to infer 'double' for 'T' but it did not work: |
|
Leaf
2017/03/20 22:46:55
<bikeshed>
"it did not work" feels a bit clunky to
Jennifer Messerly
2017/03/21 01:08:08
Done.
|
| + Argument 'f' inferred as '(int) → double' |
|
Leaf
2017/03/20 22:46:55
The key to this section is making it absolutely 10
Jennifer Messerly
2017/03/21 01:08:36
oops! also I did this one too. Forgot to save comm
|
| + must be a '(T) → T'. |
|
Jennifer Messerly
2017/03/20 22:03:27
should we show this as (double) → double?
... it'
|
| + |
| +Consider passing explicit type argument(s) to the generic. |
| + |
| +'''); |
| + } |
| + |
| + test_inference_error_arguments2() async { |
| + Source source = addSource(r''' |
| +typedef R F<T, R>(T t); |
| + |
| +F<T, T> g<T>(F<T, T> a, F<T, T> b) => (x) => a(b(x)); |
| + |
| +test() { |
| + var h = g((int x) => 42.0, (double x) => 42); |
| +} |
| + '''); |
| + await computeAnalysisResult(source); |
| + _expectInferenceError( |
| + source, |
| + [ |
| + StrongModeCode.COULD_NOT_INFER, |
| + StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, |
| + StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE |
| + ], |
| + r''' |
| +Couldn't infer type parameter 'T'. |
| + |
| +Tried to infer 'num' for 'T' but it did not work: |
| + Argument 'a' inferred as '(int) → double' |
| + must be a '(T) → T'. |
| + Argument 'b' inferred as '(double) → int' |
| + must be a '(T) → T'. |
| + |
| +Consider passing explicit type argument(s) to the generic. |
| + |
| +'''); |
| + } |
| + |
| + test_inference_error_extendsFromReturn() async { |
| + // This is not an inference error because we successfully infer Null. |
| + Source source = addSource(r''' |
| +T max<T extends num>(T x, T y) => x; |
| + |
| +test() { |
| + String hello = max(1, 2); |
| +} |
| + '''); |
| + var analysisResult = await computeAnalysisResult(source); |
| + assertErrors(source, [ |
| + StrongModeCode.INVALID_CAST_LITERAL, |
| + StrongModeCode.INVALID_CAST_LITERAL |
| + ]); |
| + var unit = analysisResult.unit; |
| + var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0] |
| + as VariableDeclarationStatement) |
| + .variables |
| + .variables[0]; |
| + var call = h.initializer as MethodInvocation; |
| + expect(call.staticInvokeType.toString(), '(Null, Null) → Null'); |
| + } |
| + |
| + test_inference_error_extendsFromReturn2() async { |
| + Source source = addSource(r''' |
| +typedef R F<T, R>(T t); |
| +F<T, T> g<T extends num>() => (y) => y; |
| + |
| +test() { |
| + F<String, String> hello = g(); |
| +} |
| + '''); |
| + await computeAnalysisResult(source); |
| + _expectInferenceError( |
| + source, |
| + [ |
| + StrongModeCode.COULD_NOT_INFER, |
| + ], |
| + r''' |
| +Couldn't infer type parameter 'T'. |
| + |
| +Tried to infer 'String' for 'T' but it did not work: |
| + Type parameter 'T' declared to extend 'num'. |
|
Jennifer Messerly
2017/03/20 22:03:27
like I feel this one is pretty good, but YMMV
Leaf
2017/03/20 22:46:55
Agreed.
|
| +The type 'String' was inferred from: |
| + Return type declared as '(T) → T' |
| + used where '(String) → String' is required. |
| + |
| +Consider passing explicit type argument(s) to the generic. |
| + |
| +'''); |
| + } |
| + |
| + |
| + test_inference_error_genericFunction() async { |
| + Source source = addSource(r''' |
| +T max<T extends num>(T x, T y) => x < y ? y : x; |
| +abstract class Iterable<T> { |
| + T get first; |
| + S fold<S>(S s, S f(S s, T t)); |
| +} |
| +test(Iterable values) { |
| + num n = values.fold(values.first as num, max); |
| +} |
| + '''); |
| + await computeAnalysisResult(source); |
| + _expectInferenceError( |
| + source, |
| + [ |
| + StrongModeCode.COULD_NOT_INFER, |
| + StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE |
| + ], |
| + r''' |
| +Couldn't infer type parameter 'T'. |
| + |
| +Tried to infer 'dynamic' for 'T' but it did not work: |
| + Function type declared as '<T extends num>(T, T) → T' |
| + used where '(num, dynamic) → num' is required. |
| + |
| +Consider passing explicit type argument(s) to the generic. |
| + |
| +'''); |
| + } |
| + |
| + test_inference_error_returnContext() async { |
| + Source source = addSource(r''' |
| +typedef R F<T, R>(T t); |
| + |
| +F<T, T> g<T>(T t) => (x) => t; |
| + |
| +test() { |
| + F<num, int> h = g(42); |
| +} |
| + '''); |
| + await computeAnalysisResult(source); |
| + _expectInferenceError( |
| + source, |
| + [StrongModeCode.COULD_NOT_INFER], |
| + r''' |
| +Couldn't infer type parameter 'T'. |
| + |
| +Tried to infer 'num' for 'T' but it did not work: |
| + Return type declared as '(T) → T' |
| + used where '(num) → int' is required. |
| + |
| +Consider passing explicit type argument(s) to the generic. |
| + |
| +'''); |
| + } |
| + |
| test_inference_hints() async { |
| Source source = addSource(r''' |
| void main () { |
| @@ -2137,6 +2307,23 @@ num test(Iterable values) => values.fold(values.first as num, max); |
| check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type))); |
| } |
| + /// Verifies the source has the expected [errorCodes] as well as the |
| + /// expected [errorMessage]. |
| + void _expectInferenceError( |
| + Source source, List<ErrorCode> errorCodes, String errorMessage) { |
| + assertErrors(source, errorCodes); |
| + var errors = analysisResults[source] |
| + .errors |
| + .where((e) => e.errorCode == StrongModeCode.COULD_NOT_INFER) |
| + .map((e) => e.message) |
| + .toList(); |
| + expect(errors.length, 1); |
| + var actual = errors[0]; |
| + expect(actual, |
| + errorMessage, // Print the literal error message for easy copy+paste: |
| + reason: 'Actual error did not match expected error:\n$actual'); |
| + } |
| + |
| /// Helper method for testing `FutureOr<T>`. |
| /// |
| /// Validates that [code] produces [errors]. It should define a function |