Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.test.generated.strong_mode_test; | 5 library analyzer.test.generated.strong_mode_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| (...skipping 1080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1091 DartType cType = AstFinder | 1091 DartType cType = AstFinder |
| 1092 .getTopLevelFunction(unit, "test") | 1092 .getTopLevelFunction(unit, "test") |
| 1093 .element | 1093 .element |
| 1094 .localVariables[0] | 1094 .localVariables[0] |
| 1095 .type; | 1095 .type; |
| 1096 Element elementC = AstFinder.getClass(unit, "C").element; | 1096 Element elementC = AstFinder.getClass(unit, "C").element; |
| 1097 | 1097 |
| 1098 _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType); | 1098 _isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType); |
| 1099 } | 1099 } |
| 1100 | 1100 |
| 1101 test_inference_error_arguments() async { | |
| 1102 Source source = addSource(r''' | |
| 1103 typedef R F<T, R>(T t); | |
| 1104 | |
| 1105 F<T, T> g<T>(F<T, T> f) => (x) => f(f(x)); | |
| 1106 | |
| 1107 test() { | |
| 1108 var h = g((int x) => 42.0); | |
| 1109 } | |
| 1110 '''); | |
| 1111 await computeAnalysisResult(source); | |
| 1112 _expectInferenceError( | |
| 1113 source, | |
| 1114 [ | |
| 1115 StrongModeCode.COULD_NOT_INFER, | |
| 1116 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1117 ], | |
| 1118 r''' | |
| 1119 Couldn't infer type parameter 'T'. | |
| 1120 | |
| 1121 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.
| |
| 1122 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
| |
| 1123 must be a '(T) → T'. | |
|
Jennifer Messerly
2017/03/20 22:03:27
should we show this as (double) → double?
... it'
| |
| 1124 | |
| 1125 Consider passing explicit type argument(s) to the generic. | |
| 1126 | |
| 1127 '''); | |
| 1128 } | |
| 1129 | |
| 1130 test_inference_error_arguments2() async { | |
| 1131 Source source = addSource(r''' | |
| 1132 typedef R F<T, R>(T t); | |
| 1133 | |
| 1134 F<T, T> g<T>(F<T, T> a, F<T, T> b) => (x) => a(b(x)); | |
| 1135 | |
| 1136 test() { | |
| 1137 var h = g((int x) => 42.0, (double x) => 42); | |
| 1138 } | |
| 1139 '''); | |
| 1140 await computeAnalysisResult(source); | |
| 1141 _expectInferenceError( | |
| 1142 source, | |
| 1143 [ | |
| 1144 StrongModeCode.COULD_NOT_INFER, | |
| 1145 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, | |
| 1146 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1147 ], | |
| 1148 r''' | |
| 1149 Couldn't infer type parameter 'T'. | |
| 1150 | |
| 1151 Tried to infer 'num' for 'T' but it did not work: | |
| 1152 Argument 'a' inferred as '(int) → double' | |
| 1153 must be a '(T) → T'. | |
| 1154 Argument 'b' inferred as '(double) → int' | |
| 1155 must be a '(T) → T'. | |
| 1156 | |
| 1157 Consider passing explicit type argument(s) to the generic. | |
| 1158 | |
| 1159 '''); | |
| 1160 } | |
| 1161 | |
| 1162 test_inference_error_extendsFromReturn() async { | |
| 1163 // This is not an inference error because we successfully infer Null. | |
| 1164 Source source = addSource(r''' | |
| 1165 T max<T extends num>(T x, T y) => x; | |
| 1166 | |
| 1167 test() { | |
| 1168 String hello = max(1, 2); | |
| 1169 } | |
| 1170 '''); | |
| 1171 var analysisResult = await computeAnalysisResult(source); | |
| 1172 assertErrors(source, [ | |
| 1173 StrongModeCode.INVALID_CAST_LITERAL, | |
| 1174 StrongModeCode.INVALID_CAST_LITERAL | |
| 1175 ]); | |
| 1176 var unit = analysisResult.unit; | |
| 1177 var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0] | |
| 1178 as VariableDeclarationStatement) | |
| 1179 .variables | |
| 1180 .variables[0]; | |
| 1181 var call = h.initializer as MethodInvocation; | |
| 1182 expect(call.staticInvokeType.toString(), '(Null, Null) → Null'); | |
| 1183 } | |
| 1184 | |
| 1185 test_inference_error_extendsFromReturn2() async { | |
| 1186 Source source = addSource(r''' | |
| 1187 typedef R F<T, R>(T t); | |
| 1188 F<T, T> g<T extends num>() => (y) => y; | |
| 1189 | |
| 1190 test() { | |
| 1191 F<String, String> hello = g(); | |
| 1192 } | |
| 1193 '''); | |
| 1194 await computeAnalysisResult(source); | |
| 1195 _expectInferenceError( | |
| 1196 source, | |
| 1197 [ | |
| 1198 StrongModeCode.COULD_NOT_INFER, | |
| 1199 ], | |
| 1200 r''' | |
| 1201 Couldn't infer type parameter 'T'. | |
| 1202 | |
| 1203 Tried to infer 'String' for 'T' but it did not work: | |
| 1204 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.
| |
| 1205 The type 'String' was inferred from: | |
| 1206 Return type declared as '(T) → T' | |
| 1207 used where '(String) → String' is required. | |
| 1208 | |
| 1209 Consider passing explicit type argument(s) to the generic. | |
| 1210 | |
| 1211 '''); | |
| 1212 } | |
| 1213 | |
| 1214 | |
| 1215 test_inference_error_genericFunction() async { | |
| 1216 Source source = addSource(r''' | |
| 1217 T max<T extends num>(T x, T y) => x < y ? y : x; | |
| 1218 abstract class Iterable<T> { | |
| 1219 T get first; | |
| 1220 S fold<S>(S s, S f(S s, T t)); | |
| 1221 } | |
| 1222 test(Iterable values) { | |
| 1223 num n = values.fold(values.first as num, max); | |
| 1224 } | |
| 1225 '''); | |
| 1226 await computeAnalysisResult(source); | |
| 1227 _expectInferenceError( | |
| 1228 source, | |
| 1229 [ | |
| 1230 StrongModeCode.COULD_NOT_INFER, | |
| 1231 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE | |
| 1232 ], | |
| 1233 r''' | |
| 1234 Couldn't infer type parameter 'T'. | |
| 1235 | |
| 1236 Tried to infer 'dynamic' for 'T' but it did not work: | |
| 1237 Function type declared as '<T extends num>(T, T) → T' | |
| 1238 used where '(num, dynamic) → num' is required. | |
| 1239 | |
| 1240 Consider passing explicit type argument(s) to the generic. | |
| 1241 | |
| 1242 '''); | |
| 1243 } | |
| 1244 | |
| 1245 test_inference_error_returnContext() async { | |
| 1246 Source source = addSource(r''' | |
| 1247 typedef R F<T, R>(T t); | |
| 1248 | |
| 1249 F<T, T> g<T>(T t) => (x) => t; | |
| 1250 | |
| 1251 test() { | |
| 1252 F<num, int> h = g(42); | |
| 1253 } | |
| 1254 '''); | |
| 1255 await computeAnalysisResult(source); | |
| 1256 _expectInferenceError( | |
| 1257 source, | |
| 1258 [StrongModeCode.COULD_NOT_INFER], | |
| 1259 r''' | |
| 1260 Couldn't infer type parameter 'T'. | |
| 1261 | |
| 1262 Tried to infer 'num' for 'T' but it did not work: | |
| 1263 Return type declared as '(T) → T' | |
| 1264 used where '(num) → int' is required. | |
| 1265 | |
| 1266 Consider passing explicit type argument(s) to the generic. | |
| 1267 | |
| 1268 '''); | |
| 1269 } | |
| 1270 | |
| 1101 test_inference_hints() async { | 1271 test_inference_hints() async { |
| 1102 Source source = addSource(r''' | 1272 Source source = addSource(r''' |
| 1103 void main () { | 1273 void main () { |
| 1104 var x = 3; | 1274 var x = 3; |
| 1105 List<int> l0 = []; | 1275 List<int> l0 = []; |
| 1106 } | 1276 } |
| 1107 '''); | 1277 '''); |
| 1108 await computeAnalysisResult(source); | 1278 await computeAnalysisResult(source); |
| 1109 assertNoErrors(source); | 1279 assertNoErrors(source); |
| 1110 verify([source]); | 1280 verify([source]); |
| (...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2130 typeTest(exp.staticType); | 2300 typeTest(exp.staticType); |
| 2131 } | 2301 } |
| 2132 | 2302 |
| 2133 check("f0", _isListOf(_isDynamic)); | 2303 check("f0", _isListOf(_isDynamic)); |
| 2134 check("f1", _isListOf(_isDynamic)); | 2304 check("f1", _isListOf(_isDynamic)); |
| 2135 | 2305 |
| 2136 check("f2", _isListOf(_isInt)); | 2306 check("f2", _isListOf(_isInt)); |
| 2137 check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type))); | 2307 check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type))); |
| 2138 } | 2308 } |
| 2139 | 2309 |
| 2310 /// Verifies the source has the expected [errorCodes] as well as the | |
| 2311 /// expected [errorMessage]. | |
| 2312 void _expectInferenceError( | |
| 2313 Source source, List<ErrorCode> errorCodes, String errorMessage) { | |
| 2314 assertErrors(source, errorCodes); | |
| 2315 var errors = analysisResults[source] | |
| 2316 .errors | |
| 2317 .where((e) => e.errorCode == StrongModeCode.COULD_NOT_INFER) | |
| 2318 .map((e) => e.message) | |
| 2319 .toList(); | |
| 2320 expect(errors.length, 1); | |
| 2321 var actual = errors[0]; | |
| 2322 expect(actual, | |
| 2323 errorMessage, // Print the literal error message for easy copy+paste: | |
| 2324 reason: 'Actual error did not match expected error:\n$actual'); | |
| 2325 } | |
| 2326 | |
| 2140 /// Helper method for testing `FutureOr<T>`. | 2327 /// Helper method for testing `FutureOr<T>`. |
| 2141 /// | 2328 /// |
| 2142 /// Validates that [code] produces [errors]. It should define a function | 2329 /// Validates that [code] produces [errors]. It should define a function |
| 2143 /// "test", whose body is an expression that invokes a method. Returns that | 2330 /// "test", whose body is an expression that invokes a method. Returns that |
| 2144 /// invocation. | 2331 /// invocation. |
| 2145 Future<MethodInvocation> _testFutureOr(String code, | 2332 Future<MethodInvocation> _testFutureOr(String code, |
| 2146 {List<ErrorCode> errors}) async { | 2333 {List<ErrorCode> errors}) async { |
| 2147 Source source = addSource(""" | 2334 Source source = addSource(""" |
| 2148 import "dart:async"; | 2335 import "dart:async"; |
| 2149 $code"""); | 2336 $code"""); |
| (...skipping 1520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3670 var v = x; | 3857 var v = x; |
| 3671 v; // marker | 3858 v; // marker |
| 3672 } | 3859 } |
| 3673 int x = 3; | 3860 int x = 3; |
| 3674 '''; | 3861 '''; |
| 3675 CompilationUnit unit = await resolveSource(code); | 3862 CompilationUnit unit = await resolveSource(code); |
| 3676 assertPropagatedAssignedType(code, unit, typeProvider.intType, null); | 3863 assertPropagatedAssignedType(code, unit, typeProvider.intType, null); |
| 3677 assertTypeOfMarkedExpression(code, unit, typeProvider.intType, null); | 3864 assertTypeOfMarkedExpression(code, unit, typeProvider.intType, null); |
| 3678 } | 3865 } |
| 3679 } | 3866 } |
| OLD | NEW |