Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(855)

Side by Side Diff: packages/analyzer/test/generated/strong_mode_test.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer.test.generated.strong_mode_test;
6
7 import 'package:analyzer/dart/ast/ast.dart';
8 import 'package:analyzer/dart/element/element.dart';
9 import 'package:analyzer/dart/element/type.dart';
10 import 'package:analyzer/src/dart/element/element.dart';
11 import 'package:analyzer/src/error/codes.dart';
12 import 'package:analyzer/src/generated/engine.dart';
13 import 'package:analyzer/src/generated/source_io.dart';
14 import 'package:test_reflective_loader/test_reflective_loader.dart';
15 import 'package:unittest/unittest.dart';
16
17 import '../utils.dart';
18 import 'resolver_test_case.dart';
19
20 main() {
21 initializeTestEnvironment();
22 defineReflectiveTests(StrongModeDownwardsInferenceTest);
23 defineReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
24 defineReflectiveTests(StrongModeTypePropagationTest);
25 }
26
27 /**
28 * Strong mode static analyzer downwards inference tests
29 */
30 @reflectiveTest
31 class StrongModeDownwardsInferenceTest extends ResolverTestCase {
32 TypeAssertions _assertions;
33
34 Asserter<DartType> _isDynamic;
35 Asserter<InterfaceType> _isFutureOfDynamic;
36 Asserter<InterfaceType> _isFutureOfInt;
37 Asserter<DartType> _isInt;
38 Asserter<DartType> _isNum;
39 Asserter<DartType> _isString;
40
41 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
42 _isFunction2Of;
43 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf;
44 AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
45 _isInstantiationOf;
46 AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
47 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
48 _isMapOf;
49 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf;
50 AsserterBuilder<DartType, DartType> _isType;
51
52 AsserterBuilder<Element, DartType> _hasElement;
53 AsserterBuilder<DartType, DartType> _sameElement;
54
55 @override
56 void setUp() {
57 super.setUp();
58 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
59 options.strongMode = true;
60 resetWithOptions(options);
61 _assertions = new TypeAssertions(typeProvider);
62 _isType = _assertions.isType;
63 _hasElement = _assertions.hasElement;
64 _isInstantiationOf = _assertions.isInstantiationOf;
65 _isInt = _assertions.isInt;
66 _isNum = _assertions.isNum;
67 _isString = _assertions.isString;
68 _isDynamic = _assertions.isDynamic;
69 _isListOf = _assertions.isListOf;
70 _isMapOf = _assertions.isMapOf;
71 _isFunction2Of = _assertions.isFunction2Of;
72 _sameElement = _assertions.sameElement;
73 _isFutureOf = _isInstantiationOf(_sameElement(typeProvider.futureType));
74 _isFutureOfDynamic = _isFutureOf([_isDynamic]);
75 _isFutureOfInt = _isFutureOf([_isInt]);
76 _isStreamOf = _isInstantiationOf(_sameElement(typeProvider.streamType));
77 }
78
79 void test_async_method_propagation() {
80 String code = r'''
81 import "dart:async";
82 class A {
83 Future f0() => new Future.value(3);
84 Future f1() async => new Future.value(3);
85 Future f2() async => await new Future.value(3);
86
87 Future<int> f3() => new Future.value(3);
88 Future<int> f4() async => new Future.value(3);
89 Future<int> f5() async => await new Future.value(3);
90
91 Future g0() { return new Future.value(3); }
92 Future g1() async { return new Future.value(3); }
93 Future g2() async { return await new Future.value(3); }
94
95 Future<int> g3() { return new Future.value(3); }
96 Future<int> g4() async { return new Future.value(3); }
97 Future<int> g5() async { return await new Future.value(3); }
98 }
99 ''';
100 CompilationUnit unit = resolveSource(code);
101
102 void check(String name, Asserter<InterfaceType> typeTest) {
103 MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
104 FunctionBody body = test.body;
105 Expression returnExp;
106 if (body is ExpressionFunctionBody) {
107 returnExp = body.expression;
108 } else {
109 ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
110 returnExp = stmt.expression;
111 }
112 DartType type = returnExp.staticType;
113 if (returnExp is AwaitExpression) {
114 type = returnExp.expression.staticType;
115 }
116 typeTest(type);
117 }
118
119 check("f0", _isFutureOfDynamic);
120 check("f1", _isFutureOfDynamic);
121 check("f2", _isFutureOfDynamic);
122
123 check("f3", _isFutureOfInt);
124 check("f4", _isFutureOfInt);
125 check("f5", _isFutureOfInt);
126
127 check("g0", _isFutureOfDynamic);
128 check("g1", _isFutureOfDynamic);
129 check("g2", _isFutureOfDynamic);
130
131 check("g3", _isFutureOfInt);
132 check("g4", _isFutureOfInt);
133 check("g5", _isFutureOfInt);
134 }
135
136 void test_async_propagation() {
137 String code = r'''
138 import "dart:async";
139
140 Future f0() => new Future.value(3);
141 Future f1() async => new Future.value(3);
142 Future f2() async => await new Future.value(3);
143
144 Future<int> f3() => new Future.value(3);
145 Future<int> f4() async => new Future.value(3);
146 Future<int> f5() async => await new Future.value(3);
147
148 Future g0() { return new Future.value(3); }
149 Future g1() async { return new Future.value(3); }
150 Future g2() async { return await new Future.value(3); }
151
152 Future<int> g3() { return new Future.value(3); }
153 Future<int> g4() async { return new Future.value(3); }
154 Future<int> g5() async { return await new Future.value(3); }
155 ''';
156 CompilationUnit unit = resolveSource(code);
157
158 void check(String name, Asserter<InterfaceType> typeTest) {
159 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
160 FunctionBody body = test.functionExpression.body;
161 Expression returnExp;
162 if (body is ExpressionFunctionBody) {
163 returnExp = body.expression;
164 } else {
165 ReturnStatement stmt = (body as BlockFunctionBody).block.statements[0];
166 returnExp = stmt.expression;
167 }
168 DartType type = returnExp.staticType;
169 if (returnExp is AwaitExpression) {
170 type = returnExp.expression.staticType;
171 }
172 typeTest(type);
173 }
174
175 check("f0", _isFutureOfDynamic);
176 check("f1", _isFutureOfDynamic);
177 check("f2", _isFutureOfDynamic);
178
179 check("f3", _isFutureOfInt);
180 check("f4", _isFutureOfInt);
181 check("f5", _isFutureOfInt);
182
183 check("g0", _isFutureOfDynamic);
184 check("g1", _isFutureOfDynamic);
185 check("g2", _isFutureOfDynamic);
186
187 check("g3", _isFutureOfInt);
188 check("g4", _isFutureOfInt);
189 check("g5", _isFutureOfInt);
190 }
191
192 void test_async_star_method_propagation() {
193 String code = r'''
194 import "dart:async";
195 class A {
196 Stream g0() async* { yield []; }
197 Stream g1() async* { yield* new Stream(); }
198
199 Stream<List<int>> g2() async* { yield []; }
200 Stream<List<int>> g3() async* { yield* new Stream(); }
201 }
202 ''';
203 CompilationUnit unit = resolveSource(code);
204
205 void check(String name, Asserter<InterfaceType> typeTest) {
206 MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
207 BlockFunctionBody body = test.body;
208 YieldStatement stmt = body.block.statements[0];
209 Expression exp = stmt.expression;
210 typeTest(exp.staticType);
211 }
212
213 check("g0", _isListOf(_isDynamic));
214 check("g1", _isStreamOf([_isDynamic]));
215
216 check("g2", _isListOf(_isInt));
217 check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
218 }
219
220 void test_async_star_propagation() {
221 String code = r'''
222 import "dart:async";
223
224 Stream g0() async* { yield []; }
225 Stream g1() async* { yield* new Stream(); }
226
227 Stream<List<int>> g2() async* { yield []; }
228 Stream<List<int>> g3() async* { yield* new Stream(); }
229 ''';
230 CompilationUnit unit = resolveSource(code);
231
232 void check(String name, Asserter<InterfaceType> typeTest) {
233 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
234 BlockFunctionBody body = test.functionExpression.body;
235 YieldStatement stmt = body.block.statements[0];
236 Expression exp = stmt.expression;
237 typeTest(exp.staticType);
238 }
239
240 check("g0", _isListOf(_isDynamic));
241 check("g1", _isStreamOf([_isDynamic]));
242
243 check("g2", _isListOf(_isInt));
244 check("g3", _isStreamOf([(DartType type) => _isListOf(_isInt)(type)]));
245 }
246
247 void test_cascadeExpression() {
248 String code = r'''
249 class A<T> {
250 List<T> map(T a, List<T> mapper(T x)) => mapper(a);
251 }
252
253 void main () {
254 A<int> a = new A()..map(0, (x) => [x]);
255 }
256 ''';
257 CompilationUnit unit = resolveSource(code);
258 List<Statement> statements =
259 AstFinder.getStatementsInTopLevelFunction(unit, "main");
260 CascadeExpression fetch(int i) {
261 VariableDeclarationStatement stmt = statements[i];
262 VariableDeclaration decl = stmt.variables.variables[0];
263 CascadeExpression exp = decl.initializer;
264 return exp;
265 }
266
267 Element elementA = AstFinder.getClass(unit, "A").element;
268
269 CascadeExpression cascade = fetch(0);
270 _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType);
271 MethodInvocation invoke = cascade.cascadeSections[0];
272 FunctionExpression function = invoke.argumentList.arguments[1];
273 ExecutableElement f0 = function.element;
274 _isListOf(_isInt)(f0.type.returnType);
275 expect(f0.type.normalParameterTypes[0], typeProvider.intType);
276 }
277
278 void test_constructorInitializer_propagation() {
279 String code = r'''
280 class A {
281 List<String> x;
282 A() : this.x = [];
283 }
284 ''';
285 CompilationUnit unit = resolveSource(code);
286 ConstructorDeclaration constructor =
287 AstFinder.getConstructorInClass(unit, "A", null);
288 ConstructorFieldInitializer assignment = constructor.initializers[0];
289 Expression exp = assignment.expression;
290 _isListOf(_isString)(exp.staticType);
291 }
292
293 void test_factoryConstructor_propagation() {
294 String code = r'''
295 class A<T> {
296 factory A() { return new B(); }
297 }
298 class B<S> extends A<S> {}
299 ''';
300 CompilationUnit unit = resolveSource(code);
301
302 ConstructorDeclaration constructor =
303 AstFinder.getConstructorInClass(unit, "A", null);
304 BlockFunctionBody body = constructor.body;
305 ReturnStatement stmt = body.block.statements[0];
306 InstanceCreationExpression exp = stmt.expression;
307 ClassElement elementB = AstFinder.getClass(unit, "B").element;
308 ClassElement elementA = AstFinder.getClass(unit, "A").element;
309 expect(exp.constructorName.type.type.element, elementB);
310 _isInstantiationOf(_hasElement(elementB))(
311 [_isType(elementA.typeParameters[0].type)])(exp.staticType);
312 }
313
314 void test_fieldDeclaration_propagation() {
315 String code = r'''
316 class A {
317 List<String> f0 = ["hello"];
318 }
319 ''';
320 CompilationUnit unit = resolveSource(code);
321
322 VariableDeclaration field = AstFinder.getFieldInClass(unit, "A", "f0");
323
324 _isListOf(_isString)(field.initializer.staticType);
325 }
326
327 void test_functionDeclaration_body_propagation() {
328 String code = r'''
329 typedef T Function2<S, T>(S x);
330
331 List<int> test1() => [];
332
333 Function2<int, int> test2 (int x) {
334 Function2<String, int> inner() {
335 return (x) => x.length;
336 }
337 return (x) => x;
338 }
339 ''';
340 CompilationUnit unit = resolveSource(code);
341
342 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
343
344 FunctionDeclaration test1 = AstFinder.getTopLevelFunction(unit, "test1");
345 ExpressionFunctionBody body = test1.functionExpression.body;
346 assertListOfInt(body.expression.staticType);
347
348 List<Statement> statements =
349 AstFinder.getStatementsInTopLevelFunction(unit, "test2");
350
351 FunctionDeclaration inner =
352 (statements[0] as FunctionDeclarationStatement).functionDeclaration;
353 BlockFunctionBody body0 = inner.functionExpression.body;
354 ReturnStatement return0 = body0.block.statements[0];
355 Expression anon0 = return0.expression;
356 FunctionType type0 = anon0.staticType;
357 expect(type0.returnType, typeProvider.intType);
358 expect(type0.normalParameterTypes[0], typeProvider.stringType);
359
360 FunctionExpression anon1 = (statements[1] as ReturnStatement).expression;
361 FunctionType type1 = anon1.element.type;
362 expect(type1.returnType, typeProvider.intType);
363 expect(type1.normalParameterTypes[0], typeProvider.intType);
364 }
365
366 void test_functionLiteral_assignment_typedArguments() {
367 String code = r'''
368 typedef T Function2<S, T>(S x);
369
370 void main () {
371 Function2<int, String> l0 = (int x) => null;
372 Function2<int, String> l1 = (int x) => "hello";
373 Function2<int, String> l2 = (String x) => "hello";
374 Function2<int, String> l3 = (int x) => 3;
375 Function2<int, String> l4 = (int x) {return 3;};
376 }
377 ''';
378 CompilationUnit unit = resolveSource(code);
379 List<Statement> statements =
380 AstFinder.getStatementsInTopLevelFunction(unit, "main");
381 DartType literal(int i) {
382 VariableDeclarationStatement stmt = statements[i];
383 VariableDeclaration decl = stmt.variables.variables[0];
384 FunctionExpression exp = decl.initializer;
385 return exp.element.type;
386 }
387
388 _isFunction2Of(_isInt, _isString)(literal(0));
389 _isFunction2Of(_isInt, _isString)(literal(1));
390 _isFunction2Of(_isString, _isString)(literal(2));
391 _isFunction2Of(_isInt, _isInt)(literal(3));
392 _isFunction2Of(_isInt, _isString)(literal(4));
393 }
394
395 void test_functionLiteral_assignment_unTypedArguments() {
396 String code = r'''
397 typedef T Function2<S, T>(S x);
398
399 void main () {
400 Function2<int, String> l0 = (x) => null;
401 Function2<int, String> l1 = (x) => "hello";
402 Function2<int, String> l2 = (x) => "hello";
403 Function2<int, String> l3 = (x) => 3;
404 Function2<int, String> l4 = (x) {return 3;};
405 }
406 ''';
407 CompilationUnit unit = resolveSource(code);
408 List<Statement> statements =
409 AstFinder.getStatementsInTopLevelFunction(unit, "main");
410 DartType literal(int i) {
411 VariableDeclarationStatement stmt = statements[i];
412 VariableDeclaration decl = stmt.variables.variables[0];
413 FunctionExpression exp = decl.initializer;
414 return exp.element.type;
415 }
416
417 _isFunction2Of(_isInt, _isString)(literal(0));
418 _isFunction2Of(_isInt, _isString)(literal(1));
419 _isFunction2Of(_isInt, _isString)(literal(2));
420 _isFunction2Of(_isInt, _isInt)(literal(3));
421 _isFunction2Of(_isInt, _isString)(literal(4));
422 }
423
424 void test_functionLiteral_body_propagation() {
425 String code = r'''
426 typedef T Function2<S, T>(S x);
427
428 void main () {
429 Function2<int, List<String>> l0 = (int x) => ["hello"];
430 Function2<int, List<String>> l1 = (String x) => ["hello"];
431 Function2<int, List<String>> l2 = (int x) => [3];
432 Function2<int, List<String>> l3 = (int x) {return [3];};
433 }
434 ''';
435 CompilationUnit unit = resolveSource(code);
436 List<Statement> statements =
437 AstFinder.getStatementsInTopLevelFunction(unit, "main");
438 Expression functionReturnValue(int i) {
439 VariableDeclarationStatement stmt = statements[i];
440 VariableDeclaration decl = stmt.variables.variables[0];
441 FunctionExpression exp = decl.initializer;
442 FunctionBody body = exp.body;
443 if (body is ExpressionFunctionBody) {
444 return body.expression;
445 } else {
446 Statement stmt = (body as BlockFunctionBody).block.statements[0];
447 return (stmt as ReturnStatement).expression;
448 }
449 }
450
451 Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
452 assertListOfString(functionReturnValue(0).staticType);
453 assertListOfString(functionReturnValue(1).staticType);
454 assertListOfString(functionReturnValue(2).staticType);
455 assertListOfString(functionReturnValue(3).staticType);
456 }
457
458 void test_functionLiteral_functionExpressionInvocation_typedArguments() {
459 String code = r'''
460 class Mapper<F, T> {
461 T map(T mapper(F x)) => mapper(null);
462 }
463
464 void main () {
465 (new Mapper<int, String>().map)((int x) => null);
466 (new Mapper<int, String>().map)((int x) => "hello");
467 (new Mapper<int, String>().map)((String x) => "hello");
468 (new Mapper<int, String>().map)((int x) => 3);
469 (new Mapper<int, String>().map)((int x) {return 3;});
470 }
471 ''';
472 CompilationUnit unit = resolveSource(code);
473 List<Statement> statements =
474 AstFinder.getStatementsInTopLevelFunction(unit, "main");
475 DartType literal(int i) {
476 ExpressionStatement stmt = statements[i];
477 FunctionExpressionInvocation invk = stmt.expression;
478 FunctionExpression exp = invk.argumentList.arguments[0];
479 return exp.element.type;
480 }
481
482 _isFunction2Of(_isInt, _isString)(literal(0));
483 _isFunction2Of(_isInt, _isString)(literal(1));
484 _isFunction2Of(_isString, _isString)(literal(2));
485 _isFunction2Of(_isInt, _isInt)(literal(3));
486 _isFunction2Of(_isInt, _isString)(literal(4));
487 }
488
489 void test_functionLiteral_functionExpressionInvocation_unTypedArguments() {
490 String code = r'''
491 class Mapper<F, T> {
492 T map(T mapper(F x)) => mapper(null);
493 }
494
495 void main () {
496 (new Mapper<int, String>().map)((x) => null);
497 (new Mapper<int, String>().map)((x) => "hello");
498 (new Mapper<int, String>().map)((x) => "hello");
499 (new Mapper<int, String>().map)((x) => 3);
500 (new Mapper<int, String>().map)((x) {return 3;});
501 }
502 ''';
503 CompilationUnit unit = resolveSource(code);
504 List<Statement> statements =
505 AstFinder.getStatementsInTopLevelFunction(unit, "main");
506 DartType literal(int i) {
507 ExpressionStatement stmt = statements[i];
508 FunctionExpressionInvocation invk = stmt.expression;
509 FunctionExpression exp = invk.argumentList.arguments[0];
510 return exp.element.type;
511 }
512
513 _isFunction2Of(_isInt, _isString)(literal(0));
514 _isFunction2Of(_isInt, _isString)(literal(1));
515 _isFunction2Of(_isInt, _isString)(literal(2));
516 _isFunction2Of(_isInt, _isInt)(literal(3));
517 _isFunction2Of(_isInt, _isString)(literal(4));
518 }
519
520 void test_functionLiteral_functionInvocation_typedArguments() {
521 String code = r'''
522 String map(String mapper(int x)) => mapper(null);
523
524 void main () {
525 map((int x) => null);
526 map((int x) => "hello");
527 map((String x) => "hello");
528 map((int x) => 3);
529 map((int x) {return 3;});
530 }
531 ''';
532 CompilationUnit unit = resolveSource(code);
533 List<Statement> statements =
534 AstFinder.getStatementsInTopLevelFunction(unit, "main");
535 DartType literal(int i) {
536 ExpressionStatement stmt = statements[i];
537 MethodInvocation invk = stmt.expression;
538 FunctionExpression exp = invk.argumentList.arguments[0];
539 return exp.element.type;
540 }
541
542 _isFunction2Of(_isInt, _isString)(literal(0));
543 _isFunction2Of(_isInt, _isString)(literal(1));
544 _isFunction2Of(_isString, _isString)(literal(2));
545 _isFunction2Of(_isInt, _isInt)(literal(3));
546 _isFunction2Of(_isInt, _isString)(literal(4));
547 }
548
549 void test_functionLiteral_functionInvocation_unTypedArguments() {
550 String code = r'''
551 String map(String mapper(int x)) => mapper(null);
552
553 void main () {
554 map((x) => null);
555 map((x) => "hello");
556 map((x) => "hello");
557 map((x) => 3);
558 map((x) {return 3;});
559 }
560 ''';
561 CompilationUnit unit = resolveSource(code);
562 List<Statement> statements =
563 AstFinder.getStatementsInTopLevelFunction(unit, "main");
564 DartType literal(int i) {
565 ExpressionStatement stmt = statements[i];
566 MethodInvocation invk = stmt.expression;
567 FunctionExpression exp = invk.argumentList.arguments[0];
568 return exp.element.type;
569 }
570
571 _isFunction2Of(_isInt, _isString)(literal(0));
572 _isFunction2Of(_isInt, _isString)(literal(1));
573 _isFunction2Of(_isInt, _isString)(literal(2));
574 _isFunction2Of(_isInt, _isInt)(literal(3));
575 _isFunction2Of(_isInt, _isString)(literal(4));
576 }
577
578 void test_functionLiteral_methodInvocation_typedArguments() {
579 String code = r'''
580 class Mapper<F, T> {
581 T map(T mapper(F x)) => mapper(null);
582 }
583
584 void main () {
585 new Mapper<int, String>().map((int x) => null);
586 new Mapper<int, String>().map((int x) => "hello");
587 new Mapper<int, String>().map((String x) => "hello");
588 new Mapper<int, String>().map((int x) => 3);
589 new Mapper<int, String>().map((int x) {return 3;});
590 }
591 ''';
592 CompilationUnit unit = resolveSource(code);
593 List<Statement> statements =
594 AstFinder.getStatementsInTopLevelFunction(unit, "main");
595 DartType literal(int i) {
596 ExpressionStatement stmt = statements[i];
597 MethodInvocation invk = stmt.expression;
598 FunctionExpression exp = invk.argumentList.arguments[0];
599 return exp.element.type;
600 }
601
602 _isFunction2Of(_isInt, _isString)(literal(0));
603 _isFunction2Of(_isInt, _isString)(literal(1));
604 _isFunction2Of(_isString, _isString)(literal(2));
605 _isFunction2Of(_isInt, _isInt)(literal(3));
606 _isFunction2Of(_isInt, _isString)(literal(4));
607 }
608
609 void test_functionLiteral_methodInvocation_unTypedArguments() {
610 String code = r'''
611 class Mapper<F, T> {
612 T map(T mapper(F x)) => mapper(null);
613 }
614
615 void main () {
616 new Mapper<int, String>().map((x) => null);
617 new Mapper<int, String>().map((x) => "hello");
618 new Mapper<int, String>().map((x) => "hello");
619 new Mapper<int, String>().map((x) => 3);
620 new Mapper<int, String>().map((x) {return 3;});
621 }
622 ''';
623 CompilationUnit unit = resolveSource(code);
624 List<Statement> statements =
625 AstFinder.getStatementsInTopLevelFunction(unit, "main");
626 DartType literal(int i) {
627 ExpressionStatement stmt = statements[i];
628 MethodInvocation invk = stmt.expression;
629 FunctionExpression exp = invk.argumentList.arguments[0];
630 return exp.element.type;
631 }
632
633 _isFunction2Of(_isInt, _isString)(literal(0));
634 _isFunction2Of(_isInt, _isString)(literal(1));
635 _isFunction2Of(_isInt, _isString)(literal(2));
636 _isFunction2Of(_isInt, _isInt)(literal(3));
637 _isFunction2Of(_isInt, _isString)(literal(4));
638 }
639
640 void test_functionLiteral_unTypedArgument_propagation() {
641 String code = r'''
642 typedef T Function2<S, T>(S x);
643
644 void main () {
645 Function2<int, int> l0 = (x) => x;
646 Function2<int, int> l1 = (x) => x+1;
647 Function2<int, String> l2 = (x) => x;
648 Function2<int, String> l3 = (x) => x.toLowerCase();
649 Function2<String, String> l4 = (x) => x.toLowerCase();
650 }
651 ''';
652 CompilationUnit unit = resolveSource(code);
653 List<Statement> statements =
654 AstFinder.getStatementsInTopLevelFunction(unit, "main");
655 Expression functionReturnValue(int i) {
656 VariableDeclarationStatement stmt = statements[i];
657 VariableDeclaration decl = stmt.variables.variables[0];
658 FunctionExpression exp = decl.initializer;
659 FunctionBody body = exp.body;
660 if (body is ExpressionFunctionBody) {
661 return body.expression;
662 } else {
663 Statement stmt = (body as BlockFunctionBody).block.statements[0];
664 return (stmt as ReturnStatement).expression;
665 }
666 }
667
668 expect(functionReturnValue(0).staticType, typeProvider.intType);
669 expect(functionReturnValue(1).staticType, typeProvider.intType);
670 expect(functionReturnValue(2).staticType, typeProvider.intType);
671 expect(functionReturnValue(3).staticType, typeProvider.dynamicType);
672 expect(functionReturnValue(4).staticType, typeProvider.stringType);
673 }
674
675 void test_inference_hints() {
676 Source source = addSource(r'''
677 void main () {
678 var x = 3;
679 List<int> l0 = [];
680 }
681 ''');
682 resolve2(source);
683 assertNoErrors(source);
684 verify([source]);
685 }
686
687 void test_inferredFieldDeclaration_propagation() {
688 // Regression test for https://github.com/dart-lang/sdk/issues/25546
689 String code = r'''
690 abstract class A {
691 Map<int, List<int>> get map;
692 }
693 class B extends A {
694 var map = { 42: [] };
695 }
696 class C extends A {
697 get map => { 43: [] };
698 }
699 ''';
700 CompilationUnit unit = resolveSource(code);
701
702 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
703 Asserter<InterfaceType> assertMapOfIntToListOfInt =
704 _isMapOf(_isInt, (DartType type) => assertListOfInt(type));
705
706 VariableDeclaration mapB = AstFinder.getFieldInClass(unit, "B", "map");
707 MethodDeclaration mapC = AstFinder.getMethodInClass(unit, "C", "map");
708 assertMapOfIntToListOfInt(mapB.element.type);
709 assertMapOfIntToListOfInt(mapC.element.returnType);
710
711 MapLiteral mapLiteralB = mapB.initializer;
712 MapLiteral mapLiteralC = (mapC.body as ExpressionFunctionBody).expression;
713 assertMapOfIntToListOfInt(mapLiteralB.staticType);
714 assertMapOfIntToListOfInt(mapLiteralC.staticType);
715
716 ListLiteral listLiteralB = mapLiteralB.entries[0].value;
717 ListLiteral listLiteralC = mapLiteralC.entries[0].value;
718 assertListOfInt(listLiteralB.staticType);
719 assertListOfInt(listLiteralC.staticType);
720 }
721
722 void test_instanceCreation() {
723 String code = r'''
724 class A<S, T> {
725 S x;
726 T y;
727 A(this.x, this.y);
728 A.named(this.x, this.y);
729 }
730
731 class B<S, T> extends A<T, S> {
732 B(S y, T x) : super(x, y);
733 B.named(S y, T x) : super.named(x, y);
734 }
735
736 class C<S> extends B<S, S> {
737 C(S a) : super(a, a);
738 C.named(S a) : super.named(a, a);
739 }
740
741 class D<S, T> extends B<T, int> {
742 D(T a) : super(a, 3);
743 D.named(T a) : super.named(a, 3);
744 }
745
746 class E<S, T> extends A<C<S>, T> {
747 E(T a) : super(null, a);
748 }
749
750 class F<S, T> extends A<S, T> {
751 F(S x, T y, {List<S> a, List<T> b}) : super(x, y);
752 F.named(S x, T y, [S a, T b]) : super(a, b);
753 }
754
755 void test0() {
756 A<int, String> a0 = new A(3, "hello");
757 A<int, String> a1 = new A.named(3, "hello");
758 A<int, String> a2 = new A<int, String>(3, "hello");
759 A<int, String> a3 = new A<int, String>.named(3, "hello");
760 A<int, String> a4 = new A<int, dynamic>(3, "hello");
761 A<int, String> a5 = new A<dynamic, dynamic>.named(3, "hello");
762 }
763 void test1() {
764 A<int, String> a0 = new A("hello", 3);
765 A<int, String> a1 = new A.named("hello", 3);
766 }
767 void test2() {
768 A<int, String> a0 = new B("hello", 3);
769 A<int, String> a1 = new B.named("hello", 3);
770 A<int, String> a2 = new B<String, int>("hello", 3);
771 A<int, String> a3 = new B<String, int>.named("hello", 3);
772 A<int, String> a4 = new B<String, dynamic>("hello", 3);
773 A<int, String> a5 = new B<dynamic, dynamic>.named("hello", 3);
774 }
775 void test3() {
776 A<int, String> a0 = new B(3, "hello");
777 A<int, String> a1 = new B.named(3, "hello");
778 }
779 void test4() {
780 A<int, int> a0 = new C(3);
781 A<int, int> a1 = new C.named(3);
782 A<int, int> a2 = new C<int>(3);
783 A<int, int> a3 = new C<int>.named(3);
784 A<int, int> a4 = new C<dynamic>(3);
785 A<int, int> a5 = new C<dynamic>.named(3);
786 }
787 void test5() {
788 A<int, int> a0 = new C("hello");
789 A<int, int> a1 = new C.named("hello");
790 }
791 void test6() {
792 A<int, String> a0 = new D("hello");
793 A<int, String> a1 = new D.named("hello");
794 A<int, String> a2 = new D<int, String>("hello");
795 A<int, String> a3 = new D<String, String>.named("hello");
796 A<int, String> a4 = new D<num, dynamic>("hello");
797 A<int, String> a5 = new D<dynamic, dynamic>.named("hello");
798 }
799 void test7() {
800 A<int, String> a0 = new D(3);
801 A<int, String> a1 = new D.named(3);
802 }
803 void test8() {
804 A<C<int>, String> a0 = new E("hello");
805 }
806 void test9() { // Check named and optional arguments
807 A<int, String> a0 = new F(3, "hello", a: [3], b: ["hello"]);
808 A<int, String> a1 = new F(3, "hello", a: ["hello"], b:[3]);
809 A<int, String> a2 = new F.named(3, "hello", 3, "hello");
810 A<int, String> a3 = new F.named(3, "hello");
811 A<int, String> a4 = new F.named(3, "hello", "hello", 3);
812 A<int, String> a5 = new F.named(3, "hello", "hello");
813 }
814 }''';
815 CompilationUnit unit = resolveSource(code);
816
817 Expression rhs(VariableDeclarationStatement stmt) {
818 VariableDeclaration decl = stmt.variables.variables[0];
819 Expression exp = decl.initializer;
820 return exp;
821 }
822
823 void hasType(Asserter<DartType> assertion, Expression exp) =>
824 assertion(exp.staticType);
825
826 Element elementA = AstFinder.getClass(unit, "A").element;
827 Element elementB = AstFinder.getClass(unit, "B").element;
828 Element elementC = AstFinder.getClass(unit, "C").element;
829 Element elementD = AstFinder.getClass(unit, "D").element;
830 Element elementE = AstFinder.getClass(unit, "E").element;
831 Element elementF = AstFinder.getClass(unit, "F").element;
832
833 AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf =
834 _isInstantiationOf(_hasElement(elementA));
835 AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf =
836 _isInstantiationOf(_hasElement(elementB));
837 AsserterBuilder<List<Asserter<DartType>>, DartType> assertCOf =
838 _isInstantiationOf(_hasElement(elementC));
839 AsserterBuilder<List<Asserter<DartType>>, DartType> assertDOf =
840 _isInstantiationOf(_hasElement(elementD));
841 AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf =
842 _isInstantiationOf(_hasElement(elementE));
843 AsserterBuilder<List<Asserter<DartType>>, DartType> assertFOf =
844 _isInstantiationOf(_hasElement(elementF));
845
846 {
847 List<Statement> statements =
848 AstFinder.getStatementsInTopLevelFunction(unit, "test0");
849
850 hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
851 hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
852 hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
853 hasType(assertAOf([_isInt, _isString]), rhs(statements[2]));
854 hasType(assertAOf([_isInt, _isString]), rhs(statements[3]));
855 hasType(assertAOf([_isInt, _isDynamic]), rhs(statements[4]));
856 hasType(assertAOf([_isDynamic, _isDynamic]), rhs(statements[5]));
857 }
858
859 {
860 List<Statement> statements =
861 AstFinder.getStatementsInTopLevelFunction(unit, "test1");
862 hasType(assertAOf([_isInt, _isString]), rhs(statements[0]));
863 hasType(assertAOf([_isInt, _isString]), rhs(statements[1]));
864 }
865
866 {
867 List<Statement> statements =
868 AstFinder.getStatementsInTopLevelFunction(unit, "test2");
869 hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
870 hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
871 hasType(assertBOf([_isString, _isInt]), rhs(statements[2]));
872 hasType(assertBOf([_isString, _isInt]), rhs(statements[3]));
873 hasType(assertBOf([_isString, _isDynamic]), rhs(statements[4]));
874 hasType(assertBOf([_isDynamic, _isDynamic]), rhs(statements[5]));
875 }
876
877 {
878 List<Statement> statements =
879 AstFinder.getStatementsInTopLevelFunction(unit, "test3");
880 hasType(assertBOf([_isString, _isInt]), rhs(statements[0]));
881 hasType(assertBOf([_isString, _isInt]), rhs(statements[1]));
882 }
883
884 {
885 List<Statement> statements =
886 AstFinder.getStatementsInTopLevelFunction(unit, "test4");
887 hasType(assertCOf([_isInt]), rhs(statements[0]));
888 hasType(assertCOf([_isInt]), rhs(statements[1]));
889 hasType(assertCOf([_isInt]), rhs(statements[2]));
890 hasType(assertCOf([_isInt]), rhs(statements[3]));
891 hasType(assertCOf([_isDynamic]), rhs(statements[4]));
892 hasType(assertCOf([_isDynamic]), rhs(statements[5]));
893 }
894
895 {
896 List<Statement> statements =
897 AstFinder.getStatementsInTopLevelFunction(unit, "test5");
898 hasType(assertCOf([_isInt]), rhs(statements[0]));
899 hasType(assertCOf([_isInt]), rhs(statements[1]));
900 }
901
902 {
903 // The first type parameter is not constrained by the
904 // context. We could choose a tighter type, but currently
905 // we just use dynamic.
906 List<Statement> statements =
907 AstFinder.getStatementsInTopLevelFunction(unit, "test6");
908 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
909 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
910 hasType(assertDOf([_isInt, _isString]), rhs(statements[2]));
911 hasType(assertDOf([_isString, _isString]), rhs(statements[3]));
912 hasType(assertDOf([_isNum, _isDynamic]), rhs(statements[4]));
913 hasType(assertDOf([_isDynamic, _isDynamic]), rhs(statements[5]));
914 }
915
916 {
917 List<Statement> statements =
918 AstFinder.getStatementsInTopLevelFunction(unit, "test7");
919 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[0]));
920 hasType(assertDOf([_isDynamic, _isString]), rhs(statements[1]));
921 }
922
923 {
924 List<Statement> statements =
925 AstFinder.getStatementsInTopLevelFunction(unit, "test8");
926 hasType(assertEOf([_isInt, _isString]), rhs(statements[0]));
927 }
928
929 {
930 List<Statement> statements =
931 AstFinder.getStatementsInTopLevelFunction(unit, "test9");
932 hasType(assertFOf([_isInt, _isString]), rhs(statements[0]));
933 hasType(assertFOf([_isInt, _isString]), rhs(statements[1]));
934 hasType(assertFOf([_isInt, _isString]), rhs(statements[2]));
935 hasType(assertFOf([_isInt, _isString]), rhs(statements[3]));
936 hasType(assertFOf([_isInt, _isString]), rhs(statements[4]));
937 hasType(assertFOf([_isInt, _isString]), rhs(statements[5]));
938 }
939 }
940
941 void test_listLiteral_nested() {
942 String code = r'''
943 void main () {
944 List<List<int>> l0 = [[]];
945 Iterable<List<int>> l1 = [[3]];
946 Iterable<List<int>> l2 = [[3], [4]];
947 List<List<int>> l3 = [["hello", 3], []];
948 }
949 ''';
950 CompilationUnit unit = resolveSource(code);
951 List<Statement> statements =
952 AstFinder.getStatementsInTopLevelFunction(unit, "main");
953 ListLiteral literal(int i) {
954 VariableDeclarationStatement stmt = statements[i];
955 VariableDeclaration decl = stmt.variables.variables[0];
956 ListLiteral exp = decl.initializer;
957 return exp;
958 }
959
960 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
961 Asserter<InterfaceType> assertListOfListOfInt =
962 _isListOf((DartType type) => assertListOfInt(type));
963
964 assertListOfListOfInt(literal(0).staticType);
965 assertListOfListOfInt(literal(1).staticType);
966 assertListOfListOfInt(literal(2).staticType);
967 assertListOfListOfInt(literal(3).staticType);
968
969 assertListOfInt(literal(1).elements[0].staticType);
970 assertListOfInt(literal(2).elements[0].staticType);
971 assertListOfInt(literal(3).elements[0].staticType);
972 }
973
974 void test_listLiteral_simple() {
975 String code = r'''
976 void main () {
977 List<int> l0 = [];
978 List<int> l1 = [3];
979 List<int> l2 = ["hello"];
980 List<int> l3 = ["hello", 3];
981 }
982 ''';
983 CompilationUnit unit = resolveSource(code);
984 List<Statement> statements =
985 AstFinder.getStatementsInTopLevelFunction(unit, "main");
986 DartType literal(int i) {
987 VariableDeclarationStatement stmt = statements[i];
988 VariableDeclaration decl = stmt.variables.variables[0];
989 ListLiteral exp = decl.initializer;
990 return exp.staticType;
991 }
992
993 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
994
995 assertListOfInt(literal(0));
996 assertListOfInt(literal(1));
997 assertListOfInt(literal(2));
998 assertListOfInt(literal(3));
999 }
1000
1001 void test_listLiteral_simple_const() {
1002 String code = r'''
1003 void main () {
1004 const List<int> c0 = const [];
1005 const List<int> c1 = const [3];
1006 const List<int> c2 = const ["hello"];
1007 const List<int> c3 = const ["hello", 3];
1008 }
1009 ''';
1010 CompilationUnit unit = resolveSource(code);
1011 List<Statement> statements =
1012 AstFinder.getStatementsInTopLevelFunction(unit, "main");
1013 DartType literal(int i) {
1014 VariableDeclarationStatement stmt = statements[i];
1015 VariableDeclaration decl = stmt.variables.variables[0];
1016 ListLiteral exp = decl.initializer;
1017 return exp.staticType;
1018 }
1019
1020 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
1021
1022 assertListOfInt(literal(0));
1023 assertListOfInt(literal(1));
1024 assertListOfInt(literal(2));
1025 assertListOfInt(literal(3));
1026 }
1027
1028 void test_listLiteral_simple_disabled() {
1029 String code = r'''
1030 void main () {
1031 List<int> l0 = <num>[];
1032 List<int> l1 = <num>[3];
1033 List<int> l2 = <String>["hello"];
1034 List<int> l3 = <dynamic>["hello", 3];
1035 }
1036 ''';
1037 CompilationUnit unit = resolveSource(code);
1038 List<Statement> statements =
1039 AstFinder.getStatementsInTopLevelFunction(unit, "main");
1040 DartType literal(int i) {
1041 VariableDeclarationStatement stmt = statements[i];
1042 VariableDeclaration decl = stmt.variables.variables[0];
1043 ListLiteral exp = decl.initializer;
1044 return exp.staticType;
1045 }
1046
1047 _isListOf(_isNum)(literal(0));
1048 _isListOf(_isNum)(literal(1));
1049 _isListOf(_isString)(literal(2));
1050 _isListOf(_isDynamic)(literal(3));
1051 }
1052
1053 void test_listLiteral_simple_subtype() {
1054 String code = r'''
1055 void main () {
1056 Iterable<int> l0 = [];
1057 Iterable<int> l1 = [3];
1058 Iterable<int> l2 = ["hello"];
1059 Iterable<int> l3 = ["hello", 3];
1060 }
1061 ''';
1062 CompilationUnit unit = resolveSource(code);
1063 List<Statement> statements =
1064 AstFinder.getStatementsInTopLevelFunction(unit, "main");
1065 DartType literal(int i) {
1066 VariableDeclarationStatement stmt = statements[i];
1067 VariableDeclaration decl = stmt.variables.variables[0];
1068 ListLiteral exp = decl.initializer;
1069 return exp.staticType;
1070 }
1071
1072 Asserter<InterfaceType> assertListOfInt = _isListOf(_isInt);
1073
1074 assertListOfInt(literal(0));
1075 assertListOfInt(literal(1));
1076 assertListOfInt(literal(2));
1077 assertListOfInt(literal(3));
1078 }
1079
1080 void test_mapLiteral_nested() {
1081 String code = r'''
1082 void main () {
1083 Map<int, List<String>> l0 = {};
1084 Map<int, List<String>> l1 = {3: ["hello"]};
1085 Map<int, List<String>> l2 = {"hello": ["hello"]};
1086 Map<int, List<String>> l3 = {3: [3]};
1087 Map<int, List<String>> l4 = {3:["hello"], "hello": [3]};
1088 }
1089 ''';
1090 CompilationUnit unit = resolveSource(code);
1091 List<Statement> statements =
1092 AstFinder.getStatementsInTopLevelFunction(unit, "main");
1093 MapLiteral literal(int i) {
1094 VariableDeclarationStatement stmt = statements[i];
1095 VariableDeclaration decl = stmt.variables.variables[0];
1096 MapLiteral exp = decl.initializer;
1097 return exp;
1098 }
1099
1100 Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
1101 Asserter<InterfaceType> assertMapOfIntToListOfString =
1102 _isMapOf(_isInt, (DartType type) => assertListOfString(type));
1103
1104 assertMapOfIntToListOfString(literal(0).staticType);
1105 assertMapOfIntToListOfString(literal(1).staticType);
1106 assertMapOfIntToListOfString(literal(2).staticType);
1107 assertMapOfIntToListOfString(literal(3).staticType);
1108 assertMapOfIntToListOfString(literal(4).staticType);
1109
1110 assertListOfString(literal(1).entries[0].value.staticType);
1111 assertListOfString(literal(2).entries[0].value.staticType);
1112 assertListOfString(literal(3).entries[0].value.staticType);
1113 assertListOfString(literal(4).entries[0].value.staticType);
1114 }
1115
1116 void test_mapLiteral_simple() {
1117 String code = r'''
1118 void main () {
1119 Map<int, String> l0 = {};
1120 Map<int, String> l1 = {3: "hello"};
1121 Map<int, String> l2 = {"hello": "hello"};
1122 Map<int, String> l3 = {3: 3};
1123 Map<int, String> l4 = {3:"hello", "hello": 3};
1124 }
1125 ''';
1126 CompilationUnit unit = resolveSource(code);
1127 List<Statement> statements =
1128 AstFinder.getStatementsInTopLevelFunction(unit, "main");
1129 DartType literal(int i) {
1130 VariableDeclarationStatement stmt = statements[i];
1131 VariableDeclaration decl = stmt.variables.variables[0];
1132 MapLiteral exp = decl.initializer;
1133 return exp.staticType;
1134 }
1135
1136 Asserter<InterfaceType> assertMapOfIntToString =
1137 _isMapOf(_isInt, _isString);
1138
1139 assertMapOfIntToString(literal(0));
1140 assertMapOfIntToString(literal(1));
1141 assertMapOfIntToString(literal(2));
1142 assertMapOfIntToString(literal(3));
1143 }
1144
1145 void test_mapLiteral_simple_disabled() {
1146 String code = r'''
1147 void main () {
1148 Map<int, String> l0 = <int, dynamic>{};
1149 Map<int, String> l1 = <int, dynamic>{3: "hello"};
1150 Map<int, String> l2 = <int, dynamic>{"hello": "hello"};
1151 Map<int, String> l3 = <int, dynamic>{3: 3};
1152 }
1153 ''';
1154 CompilationUnit unit = resolveSource(code);
1155 List<Statement> statements =
1156 AstFinder.getStatementsInTopLevelFunction(unit, "main");
1157 DartType literal(int i) {
1158 VariableDeclarationStatement stmt = statements[i];
1159 VariableDeclaration decl = stmt.variables.variables[0];
1160 MapLiteral exp = decl.initializer;
1161 return exp.staticType;
1162 }
1163
1164 Asserter<InterfaceType> assertMapOfIntToDynamic =
1165 _isMapOf(_isInt, _isDynamic);
1166
1167 assertMapOfIntToDynamic(literal(0));
1168 assertMapOfIntToDynamic(literal(1));
1169 assertMapOfIntToDynamic(literal(2));
1170 assertMapOfIntToDynamic(literal(3));
1171 }
1172
1173 void test_methodDeclaration_body_propagation() {
1174 String code = r'''
1175 class A {
1176 List<String> m0(int x) => ["hello"];
1177 List<String> m1(int x) {return [3];};
1178 }
1179 ''';
1180 CompilationUnit unit = resolveSource(code);
1181 Expression methodReturnValue(String methodName) {
1182 MethodDeclaration method =
1183 AstFinder.getMethodInClass(unit, "A", methodName);
1184 FunctionBody body = method.body;
1185 if (body is ExpressionFunctionBody) {
1186 return body.expression;
1187 } else {
1188 Statement stmt = (body as BlockFunctionBody).block.statements[0];
1189 return (stmt as ReturnStatement).expression;
1190 }
1191 }
1192
1193 Asserter<InterfaceType> assertListOfString = _isListOf(_isString);
1194 assertListOfString(methodReturnValue("m0").staticType);
1195 assertListOfString(methodReturnValue("m1").staticType);
1196 }
1197
1198 void test_redirectingConstructor_propagation() {
1199 String code = r'''
1200 class A {
1201 A() : this.named([]);
1202 A.named(List<String> x);
1203 }
1204 ''';
1205 CompilationUnit unit = resolveSource(code);
1206
1207 ConstructorDeclaration constructor =
1208 AstFinder.getConstructorInClass(unit, "A", null);
1209 RedirectingConstructorInvocation invocation = constructor.initializers[0];
1210 Expression exp = invocation.argumentList.arguments[0];
1211 _isListOf(_isString)(exp.staticType);
1212 }
1213
1214 void test_superConstructorInvocation_propagation() {
1215 String code = r'''
1216 class B {
1217 B(List<String>);
1218 }
1219 class A extends B {
1220 A() : super([]);
1221 }
1222 ''';
1223 CompilationUnit unit = resolveSource(code);
1224
1225 ConstructorDeclaration constructor =
1226 AstFinder.getConstructorInClass(unit, "A", null);
1227 SuperConstructorInvocation invocation = constructor.initializers[0];
1228 Expression exp = invocation.argumentList.arguments[0];
1229 _isListOf(_isString)(exp.staticType);
1230 }
1231
1232 void test_sync_star_method_propagation() {
1233 String code = r'''
1234 import "dart:async";
1235 class A {
1236 Iterable f0() sync* { yield []; }
1237 Iterable f1() sync* { yield* new List(); }
1238
1239 Iterable<List<int>> f2() sync* { yield []; }
1240 Iterable<List<int>> f3() sync* { yield* new List(); }
1241 }
1242 ''';
1243 CompilationUnit unit = resolveSource(code);
1244
1245 void check(String name, Asserter<InterfaceType> typeTest) {
1246 MethodDeclaration test = AstFinder.getMethodInClass(unit, "A", name);
1247 BlockFunctionBody body = test.body;
1248 YieldStatement stmt = body.block.statements[0];
1249 Expression exp = stmt.expression;
1250 typeTest(exp.staticType);
1251 }
1252
1253 check("f0", _isListOf(_isDynamic));
1254 check("f1", _isListOf(_isDynamic));
1255
1256 check("f2", _isListOf(_isInt));
1257 check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
1258 }
1259
1260 void test_sync_star_propagation() {
1261 String code = r'''
1262 import "dart:async";
1263
1264 Iterable f0() sync* { yield []; }
1265 Iterable f1() sync* { yield* new List(); }
1266
1267 Iterable<List<int>> f2() sync* { yield []; }
1268 Iterable<List<int>> f3() sync* { yield* new List(); }
1269 ''';
1270 CompilationUnit unit = resolveSource(code);
1271
1272 void check(String name, Asserter<InterfaceType> typeTest) {
1273 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, name);
1274 BlockFunctionBody body = test.functionExpression.body;
1275 YieldStatement stmt = body.block.statements[0];
1276 Expression exp = stmt.expression;
1277 typeTest(exp.staticType);
1278 }
1279
1280 check("f0", _isListOf(_isDynamic));
1281 check("f1", _isListOf(_isDynamic));
1282
1283 check("f2", _isListOf(_isInt));
1284 check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
1285 }
1286 }
1287
1288 /**
1289 * Strong mode static analyzer end to end tests
1290 */
1291 @reflectiveTest
1292 class StrongModeStaticTypeAnalyzer2Test extends StaticTypeAnalyzer2TestShared {
1293 void fail_genericMethod_tearoff_instantiated() {
1294 resolveTestUnit(r'''
1295 class C<E> {
1296 /*=T*/ f/*<T>*/(E e) => null;
1297 static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
1298 static final h = g;
1299 }
1300
1301 /*=T*/ topF/*<T>*/(/*=T*/ e) => null;
1302 var topG = topF;
1303 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
1304 var c = new C<int>();
1305 /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
1306 var methodTearOffInst = c.f/*<int>*/;
1307 var staticTearOffInst = C.g/*<int>*/;
1308 var staticFieldTearOffInst = C.h/*<int>*/;
1309 var topFunTearOffInst = topF/*<int>*/;
1310 var topFieldTearOffInst = topG/*<int>*/;
1311 var localTearOffInst = lf/*<int>*/;
1312 var paramTearOffInst = pf/*<int>*/;
1313 }
1314 ''');
1315 expectIdentifierType('methodTearOffInst', "(int) → int");
1316 expectIdentifierType('staticTearOffInst', "(int) → int");
1317 expectIdentifierType('staticFieldTearOffInst', "(int) → int");
1318 expectIdentifierType('topFunTearOffInst', "(int) → int");
1319 expectIdentifierType('topFieldTearOffInst', "(int) → int");
1320 expectIdentifierType('localTearOffInst', "(int) → int");
1321 expectIdentifierType('paramTearOffInst', "(int) → int");
1322 }
1323
1324 void objectMethodOnFunctions_helper(String code) {
1325 resolveTestUnit(code);
1326 expectIdentifierType('t0', "String");
1327 expectIdentifierType('t1', "() → String");
1328 expectIdentifierType('t2', "int");
1329 expectIdentifierType('t3', "String");
1330 expectIdentifierType('t4', "() → String");
1331 expectIdentifierType('t5', "int");
1332 }
1333
1334 void setUp() {
1335 super.setUp();
1336 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
1337 options.strongMode = true;
1338 resetWithOptions(options);
1339 }
1340
1341 void test_dynamicObjectGetter_hashCode() {
1342 String code = r'''
1343 main() {
1344 dynamic a = null;
1345 var foo = a.hashCode;
1346 }
1347 ''';
1348 resolveTestUnit(code);
1349 expectInitializerType('foo', 'int', isNull);
1350 }
1351
1352 void test_dynamicObjectMethod_toString() {
1353 String code = r'''
1354 main() {
1355 dynamic a = null;
1356 var foo = a.toString();
1357 }
1358 ''';
1359 resolveTestUnit(code);
1360 expectInitializerType('foo', 'String', isNull);
1361 }
1362
1363 void test_genericFunction() {
1364 resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
1365 expectFunctionType('f', '<T>(T) → T',
1366 elementTypeParams: '[T]', typeFormals: '[T]');
1367 SimpleIdentifier f = findIdentifier('f');
1368 FunctionElementImpl e = f.staticElement;
1369 FunctionType ft = e.type.instantiate([typeProvider.stringType]);
1370 expect(ft.toString(), '(String) → String');
1371 }
1372
1373 void test_genericFunction_bounds() {
1374 resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
1375 expectFunctionType('f', '<T extends num>(T) → T',
1376 elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
1377 }
1378
1379 void test_genericFunction_parameter() {
1380 resolveTestUnit(r'''
1381 void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
1382 ''');
1383 expectFunctionType('f', '<T>(T) → T',
1384 elementTypeParams: '[T]', typeFormals: '[T]');
1385 SimpleIdentifier f = findIdentifier('f');
1386 ParameterElementImpl e = f.staticElement;
1387 FunctionType type = e.type;
1388 FunctionType ft = type.instantiate([typeProvider.stringType]);
1389 expect(ft.toString(), '(String) → String');
1390 }
1391
1392 void test_genericFunction_static() {
1393 resolveTestUnit(r'''
1394 class C<E> {
1395 static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
1396 }
1397 ''');
1398 expectFunctionType('f', '<T>(T) → T',
1399 elementTypeParams: '[T]', typeFormals: '[T]');
1400 SimpleIdentifier f = findIdentifier('f');
1401 MethodElementImpl e = f.staticElement;
1402 FunctionType ft = e.type.instantiate([typeProvider.stringType]);
1403 expect(ft.toString(), '(String) → String');
1404 }
1405
1406 void test_genericFunction_typedef() {
1407 String code = r'''
1408 typedef T F<T>(T x);
1409 F f0;
1410
1411 class C {
1412 static F f1;
1413 F f2;
1414 void g(F f3) {
1415 F f4;
1416 f0(3);
1417 f1(3);
1418 f2(3);
1419 f3(3);
1420 f4(3);
1421 }
1422 }
1423
1424 class D<S> {
1425 static F f1;
1426 F f2;
1427 void g(F f3) {
1428 F f4;
1429 f0(3);
1430 f1(3);
1431 f2(3);
1432 f3(3);
1433 f4(3);
1434 }
1435 }
1436 ''';
1437 resolveTestUnit(code);
1438
1439 checkBody(String className) {
1440 List<Statement> statements =
1441 AstFinder.getStatementsInMethod(testUnit, className, "g");
1442
1443 for (int i = 1; i <= 5; i++) {
1444 Expression exp = (statements[i] as ExpressionStatement).expression;
1445 expect(exp.staticType, typeProvider.dynamicType);
1446 }
1447 }
1448
1449 checkBody("C");
1450 checkBody("D");
1451 }
1452
1453 void test_genericFunction_upwardsAndDownwards() {
1454 // Regression tests for https://github.com/dart-lang/sdk/issues/27151.
1455 resolveTestUnit(r'List<num> x = [1, 2];');
1456 expectInitializerType('x', 'List<int>');
1457 }
1458
1459 void test_genericMethod() {
1460 resolveTestUnit(r'''
1461 class C<E> {
1462 List/*<T>*/ f/*<T>*/(E e) => null;
1463 }
1464 main() {
1465 C<String> cOfString;
1466 }
1467 ''');
1468 expectFunctionType('f', '<T>(E) → List<T>',
1469 elementTypeParams: '[T]',
1470 typeParams: '[E]',
1471 typeArgs: '[E]',
1472 typeFormals: '[T]');
1473 SimpleIdentifier c = findIdentifier('cOfString');
1474 FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
1475 expect(ft.toString(), '<T>(String) → List<T>');
1476 ft = ft.instantiate([typeProvider.intType]);
1477 expect(ft.toString(), '(String) → List<int>');
1478 expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
1479 }
1480
1481 void test_genericMethod_explicitTypeParams() {
1482 resolveTestUnit(r'''
1483 class C<E> {
1484 List/*<T>*/ f/*<T>*/(E e) => null;
1485 }
1486 main() {
1487 C<String> cOfString;
1488 var x = cOfString.f/*<int>*/('hi');
1489 }
1490 ''');
1491 MethodInvocation f = findIdentifier('f/*<int>*/').parent;
1492 FunctionType ft = f.staticInvokeType;
1493 expect(ft.toString(), '(String) → List<int>');
1494 expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
1495
1496 SimpleIdentifier x = findIdentifier('x');
1497 expect(x.staticType,
1498 typeProvider.listType.instantiate([typeProvider.intType]));
1499 }
1500
1501 void test_genericMethod_functionExpressionInvocation_explicit() {
1502 resolveTestUnit(r'''
1503 class C<E> {
1504 /*=T*/ f/*<T>*/(/*=T*/ e) => null;
1505 static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
1506 static final h = g;
1507 }
1508
1509 /*=T*/ topF/*<T>*/(/*=T*/ e) => null;
1510 var topG = topF;
1511 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
1512 var c = new C<int>();
1513 /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
1514
1515 var lambdaCall = (/*<E>*/(/*=E*/ e) => e)/*<int>*/(3);
1516 var methodCall = (c.f)/*<int>*/(3);
1517 var staticCall = (C.g)/*<int>*/(3);
1518 var staticFieldCall = (C.h)/*<int>*/(3);
1519 var topFunCall = (topF)/*<int>*/(3);
1520 var topFieldCall = (topG)/*<int>*/(3);
1521 var localCall = (lf)/*<int>*/(3);
1522 var paramCall = (pf)/*<int>*/(3);
1523 }
1524 ''');
1525 expectIdentifierType('methodCall', "int");
1526 expectIdentifierType('staticCall', "int");
1527 expectIdentifierType('staticFieldCall', "int");
1528 expectIdentifierType('topFunCall', "int");
1529 expectIdentifierType('topFieldCall', "int");
1530 expectIdentifierType('localCall', "int");
1531 expectIdentifierType('paramCall', "int");
1532 expectIdentifierType('lambdaCall', "int");
1533 }
1534
1535 void test_genericMethod_functionExpressionInvocation_inferred() {
1536 resolveTestUnit(r'''
1537 class C<E> {
1538 /*=T*/ f/*<T>*/(/*=T*/ e) => null;
1539 static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
1540 static final h = g;
1541 }
1542
1543 /*=T*/ topF/*<T>*/(/*=T*/ e) => null;
1544 var topG = topF;
1545 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
1546 var c = new C<int>();
1547 /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
1548
1549 var lambdaCall = (/*<E>*/(/*=E*/ e) => e)(3);
1550 var methodCall = (c.f)(3);
1551 var staticCall = (C.g)(3);
1552 var staticFieldCall = (C.h)(3);
1553 var topFunCall = (topF)(3);
1554 var topFieldCall = (topG)(3);
1555 var localCall = (lf)(3);
1556 var paramCall = (pf)(3);
1557 }
1558 ''');
1559 expectIdentifierType('methodCall', "int");
1560 expectIdentifierType('staticCall', "int");
1561 expectIdentifierType('staticFieldCall', "int");
1562 expectIdentifierType('topFunCall', "int");
1563 expectIdentifierType('topFieldCall', "int");
1564 expectIdentifierType('localCall', "int");
1565 expectIdentifierType('paramCall', "int");
1566 expectIdentifierType('lambdaCall', "int");
1567 }
1568
1569 void test_genericMethod_functionInvocation_explicit() {
1570 resolveTestUnit(r'''
1571 class C<E> {
1572 /*=T*/ f/*<T>*/(/*=T*/ e) => null;
1573 static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
1574 static final h = g;
1575 }
1576
1577 /*=T*/ topF/*<T>*/(/*=T*/ e) => null;
1578 var topG = topF;
1579 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
1580 var c = new C<int>();
1581 /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
1582 var methodCall = c.f/*<int>*/(3);
1583 var staticCall = C.g/*<int>*/(3);
1584 var staticFieldCall = C.h/*<int>*/(3);
1585 var topFunCall = topF/*<int>*/(3);
1586 var topFieldCall = topG/*<int>*/(3);
1587 var localCall = lf/*<int>*/(3);
1588 var paramCall = pf/*<int>*/(3);
1589 }
1590 ''');
1591 expectIdentifierType('methodCall', "int");
1592 expectIdentifierType('staticCall', "int");
1593 expectIdentifierType('staticFieldCall', "int");
1594 expectIdentifierType('topFunCall', "int");
1595 expectIdentifierType('topFieldCall', "int");
1596 expectIdentifierType('localCall', "int");
1597 expectIdentifierType('paramCall', "int");
1598 }
1599
1600 void test_genericMethod_functionInvocation_inferred() {
1601 resolveTestUnit(r'''
1602 class C<E> {
1603 /*=T*/ f/*<T>*/(/*=T*/ e) => null;
1604 static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
1605 static final h = g;
1606 }
1607
1608 /*=T*/ topF/*<T>*/(/*=T*/ e) => null;
1609 var topG = topF;
1610 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
1611 var c = new C<int>();
1612 /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
1613 var methodCall = c.f(3);
1614 var staticCall = C.g(3);
1615 var staticFieldCall = C.h(3);
1616 var topFunCall = topF(3);
1617 var topFieldCall = topG(3);
1618 var localCall = lf(3);
1619 var paramCall = pf(3);
1620 }
1621 ''');
1622 expectIdentifierType('methodCall', "int");
1623 expectIdentifierType('staticCall', "int");
1624 expectIdentifierType('staticFieldCall', "int");
1625 expectIdentifierType('topFunCall', "int");
1626 expectIdentifierType('topFieldCall', "int");
1627 expectIdentifierType('localCall', "int");
1628 expectIdentifierType('paramCall', "int");
1629 }
1630
1631 void test_genericMethod_functionTypedParameter() {
1632 resolveTestUnit(r'''
1633 class C<E> {
1634 List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
1635 }
1636 main() {
1637 C<String> cOfString;
1638 }
1639 ''');
1640 expectFunctionType('f', '<T>((E) → T) → List<T>',
1641 elementTypeParams: '[T]',
1642 typeParams: '[E]',
1643 typeArgs: '[E]',
1644 typeFormals: '[T]');
1645
1646 SimpleIdentifier c = findIdentifier('cOfString');
1647 FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
1648 expect(ft.toString(), '<T>((String) → T) → List<T>');
1649 ft = ft.instantiate([typeProvider.intType]);
1650 expect(ft.toString(), '((String) → int) → List<int>');
1651 }
1652
1653 void test_genericMethod_implicitDynamic() {
1654 // Regression test for:
1655 // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
1656 // These should not cause any hints or warnings.
1657 resolveTestUnit(r'''
1658 class List<E> {
1659 /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
1660 }
1661 void foo() {
1662 List list = null;
1663 list.map((e) => e);
1664 list.map((e) => 3);
1665 }''');
1666 expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T', isNull);
1667 expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T', isNull);
1668
1669 MethodInvocation m1 = findIdentifier('map((e) => e);').parent;
1670 expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
1671 MethodInvocation m2 = findIdentifier('map((e) => 3);').parent;
1672 expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
1673 }
1674
1675 void test_genericMethod_max_doubleDouble() {
1676 String code = r'''
1677 import 'dart:math';
1678 main() {
1679 var foo = max(1.0, 2.0);
1680 }
1681 ''';
1682 resolveTestUnit(code);
1683 expectInitializerType('foo', 'double', isNull);
1684 }
1685
1686 void test_genericMethod_max_doubleDouble_prefixed() {
1687 String code = r'''
1688 import 'dart:math' as math;
1689 main() {
1690 var foo = math.max(1.0, 2.0);
1691 }
1692 ''';
1693 resolveTestUnit(code);
1694 expectInitializerType('foo', 'double', isNull);
1695 }
1696
1697 void test_genericMethod_max_doubleInt() {
1698 String code = r'''
1699 import 'dart:math';
1700 main() {
1701 var foo = max(1.0, 2);
1702 }
1703 ''';
1704 resolveTestUnit(code);
1705 expectInitializerType('foo', 'num', isNull);
1706 }
1707
1708 void test_genericMethod_max_intDouble() {
1709 String code = r'''
1710 import 'dart:math';
1711 main() {
1712 var foo = max(1, 2.0);
1713 }
1714 ''';
1715 resolveTestUnit(code);
1716 expectInitializerType('foo', 'num', isNull);
1717 }
1718
1719 void test_genericMethod_max_intInt() {
1720 String code = r'''
1721 import 'dart:math';
1722 main() {
1723 var foo = max(1, 2);
1724 }
1725 ''';
1726 resolveTestUnit(code);
1727 expectInitializerType('foo', 'int', isNull);
1728 }
1729
1730 void test_genericMethod_nestedBound() {
1731 String code = r'''
1732 class Foo<T extends num> {
1733 void method/*<U extends T>*/(dynamic/*=U*/ u) {
1734 u.abs();
1735 }
1736 }
1737 ''';
1738 // Just validate that there is no warning on the call to `.abs()`.
1739 resolveTestUnit(code);
1740 }
1741
1742 void test_genericMethod_nestedCapture() {
1743 resolveTestUnit(r'''
1744 class C<T> {
1745 /*=T*/ f/*<S>*/(/*=S*/ x) {
1746 new C<S>().f/*<int>*/(3);
1747 new C<S>().f; // tear-off
1748 return null;
1749 }
1750 }
1751 ''');
1752 MethodInvocation f = findIdentifier('f/*<int>*/(3);').parent;
1753 expect(f.staticInvokeType.toString(), '(int) → S');
1754 FunctionType ft = f.staticInvokeType;
1755 expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
1756
1757 expectIdentifierType('f;', '<S₀>(S₀) → S');
1758 }
1759
1760 void test_genericMethod_nestedFunctions() {
1761 resolveTestUnit(r'''
1762 /*=S*/ f/*<S>*/(/*=S*/ x) {
1763 g/*<S>*/(/*=S*/ x) => f;
1764 return null;
1765 }
1766 ''');
1767 expectIdentifierType('f', '<S>(S) → S');
1768 expectIdentifierType('g', '<S>(S) → <S>(S) → S');
1769 }
1770
1771 void test_genericMethod_override() {
1772 resolveTestUnit(r'''
1773 class C {
1774 /*=T*/ f/*<T>*/(/*=T*/ x) => null;
1775 }
1776 class D extends C {
1777 /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
1778 }
1779 ''');
1780 expectFunctionType('f/*<T>*/(/*=T*/ x) => null; // from D', '<T>(T) → T',
1781 elementTypeParams: '[T]', typeFormals: '[T]');
1782 SimpleIdentifier f =
1783 findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
1784 MethodElementImpl e = f.staticElement;
1785 FunctionType ft = e.type.instantiate([typeProvider.stringType]);
1786 expect(ft.toString(), '(String) → String');
1787 }
1788
1789 void test_genericMethod_override_bounds() {
1790 resolveTestUnit(r'''
1791 class A {}
1792 class B extends A {}
1793 class C {
1794 /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
1795 }
1796 class D extends C {
1797 /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
1798 }
1799 ''');
1800 }
1801
1802 void test_genericMethod_override_invalidReturnType() {
1803 Source source = addSource(r'''
1804 class C {
1805 Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
1806 }
1807 class D extends C {
1808 String f/*<S>*/(/*=S*/ x) => null;
1809 }''');
1810 assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]);
1811 verify([source]);
1812 }
1813
1814 void test_genericMethod_override_invalidTypeParamBounds() {
1815 Source source = addSource(r'''
1816 class A {}
1817 class B extends A {}
1818 class C {
1819 /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
1820 }
1821 class D extends C {
1822 /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
1823 }''');
1824 assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]);
1825 verify([source]);
1826 }
1827
1828 void test_genericMethod_override_invalidTypeParamCount() {
1829 Source source = addSource(r'''
1830 class C {
1831 /*=T*/ f/*<T>*/(/*=T*/ x) => null;
1832 }
1833 class D extends C {
1834 /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
1835 }''');
1836 assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]);
1837 verify([source]);
1838 }
1839
1840 void test_genericMethod_propagatedType_promotion() {
1841 // Regression test for:
1842 // https://github.com/dart-lang/sdk/issues/25340
1843
1844 // Note, after https://github.com/dart-lang/sdk/issues/25486 the original
1845 // example won't work, as we now compute a static type and therefore discard
1846 // the propagated type. So a new test was created that doesn't run under
1847 // strong mode.
1848 resolveTestUnit(r'''
1849 abstract class Iter {
1850 List/*<S>*/ map/*<S>*/(/*=S*/ f(x));
1851 }
1852 class C {}
1853 C toSpan(dynamic element) {
1854 if (element is Iter) {
1855 var y = element.map(toSpan);
1856 }
1857 return null;
1858 }''');
1859 expectIdentifierType('y = ', 'List<C>', isNull);
1860 }
1861
1862 void test_genericMethod_tearoff() {
1863 resolveTestUnit(r'''
1864 class C<E> {
1865 /*=T*/ f/*<T>*/(E e) => null;
1866 static /*=T*/ g/*<T>*/(/*=T*/ e) => null;
1867 static final h = g;
1868 }
1869
1870 /*=T*/ topF/*<T>*/(/*=T*/ e) => null;
1871 var topG = topF;
1872 void test/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {
1873 var c = new C<int>();
1874 /*=T*/ lf/*<T>*/(/*=T*/ e) => null;
1875 var methodTearOff = c.f;
1876 var staticTearOff = C.g;
1877 var staticFieldTearOff = C.h;
1878 var topFunTearOff = topF;
1879 var topFieldTearOff = topG;
1880 var localTearOff = lf;
1881 var paramTearOff = pf;
1882 }
1883 ''');
1884 expectIdentifierType('methodTearOff', "<T>(int) → T");
1885 expectIdentifierType('staticTearOff', "<T>(T) → T");
1886 expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
1887 expectIdentifierType('topFunTearOff', "<T>(T) → T");
1888 expectIdentifierType('topFieldTearOff', "<T>(T) → T");
1889 expectIdentifierType('localTearOff', "<T>(T) → T");
1890 expectIdentifierType('paramTearOff', "<T>(T) → T");
1891 }
1892
1893 void test_genericMethod_then() {
1894 String code = r'''
1895 import 'dart:async';
1896 String toString(int x) => x.toString();
1897 main() {
1898 Future<int> bar = null;
1899 var foo = bar.then(toString);
1900 }
1901 ''';
1902 resolveTestUnit(code);
1903 expectInitializerType('foo', 'Future<String>', isNull);
1904 }
1905
1906 void test_genericMethod_then_prefixed() {
1907 String code = r'''
1908 import 'dart:async' as async;
1909 String toString(int x) => x.toString();
1910 main() {
1911 async.Future<int> bar = null;
1912 var foo = bar.then(toString);
1913 }
1914 ''';
1915 resolveTestUnit(code);
1916 expectInitializerType('foo', 'Future<String>', isNull);
1917 }
1918
1919 void test_genericMethod_then_propagatedType() {
1920 // Regression test for https://github.com/dart-lang/sdk/issues/25482.
1921 String code = r'''
1922 import 'dart:async';
1923 void main() {
1924 Future<String> p;
1925 var foo = p.then((r) => new Future<String>.value(3));
1926 }
1927 ''';
1928 // This should produce no hints or warnings.
1929 resolveTestUnit(code);
1930 expectInitializerType('foo', 'Future<String>', isNull);
1931 }
1932
1933 void test_implicitBounds() {
1934 String code = r'''
1935 class A<T> {}
1936
1937 class B<T extends num> {}
1938
1939 class C<S extends int, T extends B<S>, U extends B> {}
1940
1941 void test() {
1942 //
1943 A ai;
1944 B bi;
1945 C ci;
1946 var aa = new A();
1947 var bb = new B();
1948 var cc = new C();
1949 }
1950 ''';
1951 resolveTestUnit(code);
1952 expectIdentifierType('ai', "A<dynamic>");
1953 expectIdentifierType('bi', "B<num>");
1954 expectIdentifierType('ci', "C<int, B<int>, B<dynamic>>");
1955 expectIdentifierType('aa', "A<dynamic>");
1956 expectIdentifierType('bb', "B<num>");
1957 expectIdentifierType('cc', "C<int, B<int>, B<dynamic>>");
1958 }
1959
1960 void test_objectMethodOnFunctions_Anonymous() {
1961 String code = r'''
1962 void main() {
1963 var f = (x) => 3;
1964 // No errors, correct type
1965 var t0 = f.toString();
1966 var t1 = f.toString;
1967 var t2 = f.hashCode;
1968
1969 // Expressions, no errors, correct type
1970 var t3 = (f).toString();
1971 var t4 = (f).toString;
1972 var t5 = (f).hashCode;
1973
1974 // Cascades, no errors
1975 f..toString();
1976 f..toString;
1977 f..hashCode;
1978
1979 // Expression cascades, no errors
1980 (f)..toString();
1981 (f)..toString;
1982 (f)..hashCode;
1983 }''';
1984 objectMethodOnFunctions_helper(code);
1985 }
1986
1987 void test_objectMethodOnFunctions_Function() {
1988 String code = r'''
1989 void main() {
1990 Function f;
1991 // No errors, correct type
1992 var t0 = f.toString();
1993 var t1 = f.toString;
1994 var t2 = f.hashCode;
1995
1996 // Expressions, no errors, correct type
1997 var t3 = (f).toString();
1998 var t4 = (f).toString;
1999 var t5 = (f).hashCode;
2000
2001 // Cascades, no errors
2002 f..toString();
2003 f..toString;
2004 f..hashCode;
2005
2006 // Expression cascades, no errors
2007 (f)..toString();
2008 (f)..toString;
2009 (f)..hashCode;
2010 }''';
2011 objectMethodOnFunctions_helper(code);
2012 }
2013
2014 void test_objectMethodOnFunctions_Static() {
2015 String code = r'''
2016 int f(int x) => null;
2017 void main() {
2018 // No errors, correct type
2019 var t0 = f.toString();
2020 var t1 = f.toString;
2021 var t2 = f.hashCode;
2022
2023 // Expressions, no errors, correct type
2024 var t3 = (f).toString();
2025 var t4 = (f).toString;
2026 var t5 = (f).hashCode;
2027
2028 // Cascades, no errors
2029 f..toString();
2030 f..toString;
2031 f..hashCode;
2032
2033 // Expression cascades, no errors
2034 (f)..toString();
2035 (f)..toString;
2036 (f)..hashCode;
2037 }''';
2038 objectMethodOnFunctions_helper(code);
2039 }
2040
2041 void test_objectMethodOnFunctions_Typedef() {
2042 String code = r'''
2043 typedef bool Predicate<T>(T object);
2044
2045 void main() {
2046 Predicate<int> f;
2047 // No errors, correct type
2048 var t0 = f.toString();
2049 var t1 = f.toString;
2050 var t2 = f.hashCode;
2051
2052 // Expressions, no errors, correct type
2053 var t3 = (f).toString();
2054 var t4 = (f).toString;
2055 var t5 = (f).hashCode;
2056
2057 // Cascades, no errors
2058 f..toString();
2059 f..toString;
2060 f..hashCode;
2061
2062 // Expression cascades, no errors
2063 (f)..toString();
2064 (f)..toString;
2065 (f)..hashCode;
2066 }''';
2067 objectMethodOnFunctions_helper(code);
2068 }
2069
2070 void test_setterWithDynamicTypeIsError() {
2071 Source source = addSource(r'''
2072 class A {
2073 dynamic set f(String s) => null;
2074 }
2075 dynamic set g(int x) => null;
2076 ''');
2077 computeLibrarySourceErrors(source);
2078 assertErrors(source, [
2079 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
2080 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
2081 ]);
2082 verify([source]);
2083 }
2084
2085 void test_setterWithExplicitVoidType_returningVoid() {
2086 Source source = addSource(r'''
2087 void returnsVoid() {}
2088 class A {
2089 void set f(String s) => returnsVoid();
2090 }
2091 void set g(int x) => returnsVoid();
2092 ''');
2093 computeLibrarySourceErrors(source);
2094 assertNoErrors(source);
2095 verify([source]);
2096 }
2097
2098 void test_setterWithNoVoidType() {
2099 Source source = addSource(r'''
2100 class A {
2101 set f(String s) {
2102 return '42';
2103 }
2104 }
2105 set g(int x) => 42;
2106 ''');
2107 computeLibrarySourceErrors(source);
2108 assertErrors(source, [
2109 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE,
2110 ]);
2111 verify([source]);
2112 }
2113
2114 void test_setterWithNoVoidType_returningVoid() {
2115 Source source = addSource(r'''
2116 void returnsVoid() {}
2117 class A {
2118 set f(String s) => returnsVoid();
2119 }
2120 set g(int x) => returnsVoid();
2121 ''');
2122 computeLibrarySourceErrors(source);
2123 assertNoErrors(source);
2124 verify([source]);
2125 }
2126
2127 void test_setterWithOtherTypeIsError() {
2128 Source source = addSource(r'''
2129 class A {
2130 String set f(String s) => null;
2131 }
2132 Object set g(x) => null;
2133 ''');
2134 computeLibrarySourceErrors(source);
2135 assertErrors(source, [
2136 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER,
2137 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER
2138 ]);
2139 verify([source]);
2140 }
2141
2142 void test_ternaryOperator_null_left() {
2143 String code = r'''
2144 main() {
2145 var foo = (true) ? null : 3;
2146 }
2147 ''';
2148 resolveTestUnit(code);
2149 expectInitializerType('foo', 'int', isNull);
2150 }
2151
2152 void test_ternaryOperator_null_right() {
2153 String code = r'''
2154 main() {
2155 var foo = (true) ? 3 : null;
2156 }
2157 ''';
2158 resolveTestUnit(code);
2159 expectInitializerType('foo', 'int', isNull);
2160 }
2161 }
2162
2163 @reflectiveTest
2164 class StrongModeTypePropagationTest extends ResolverTestCase {
2165 @override
2166 void setUp() {
2167 super.setUp();
2168 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
2169 options.strongMode = true;
2170 resetWithOptions(options);
2171 }
2172
2173 void test_foreachInference_dynamic_disabled() {
2174 String code = r'''
2175 main() {
2176 var list = <int>[];
2177 for (dynamic v in list) {
2178 v; // marker
2179 }
2180 }''';
2181 assertPropagatedIterationType(code, typeProvider.dynamicType, null);
2182 assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
2183 }
2184
2185 void test_foreachInference_reusedVar_disabled() {
2186 String code = r'''
2187 main() {
2188 var list = <int>[];
2189 var v;
2190 for (v in list) {
2191 v; // marker
2192 }
2193 }''';
2194 assertPropagatedIterationType(code, typeProvider.dynamicType, null);
2195 assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
2196 }
2197
2198 void test_foreachInference_var() {
2199 String code = r'''
2200 main() {
2201 var list = <int>[];
2202 for (var v in list) {
2203 v; // marker
2204 }
2205 }''';
2206 assertPropagatedIterationType(code, typeProvider.intType, null);
2207 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2208 }
2209
2210 void test_foreachInference_var_iterable() {
2211 String code = r'''
2212 main() {
2213 Iterable<int> list = <int>[];
2214 for (var v in list) {
2215 v; // marker
2216 }
2217 }''';
2218 assertPropagatedIterationType(code, typeProvider.intType, null);
2219 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2220 }
2221
2222 void test_foreachInference_var_stream() {
2223 String code = r'''
2224 import 'dart:async';
2225 main() async {
2226 Stream<int> stream = null;
2227 await for (var v in stream) {
2228 v; // marker
2229 }
2230 }''';
2231 assertPropagatedIterationType(code, typeProvider.intType, null);
2232 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2233 }
2234
2235 void test_localVariableInference_bottom_disabled() {
2236 String code = r'''
2237 main() {
2238 var v = null;
2239 v; // marker
2240 }''';
2241 assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
2242 assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
2243 }
2244
2245 void test_localVariableInference_constant() {
2246 String code = r'''
2247 main() {
2248 var v = 3;
2249 v; // marker
2250 }''';
2251 assertPropagatedAssignedType(code, typeProvider.intType, null);
2252 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2253 }
2254
2255 void test_localVariableInference_declaredType_disabled() {
2256 String code = r'''
2257 main() {
2258 dynamic v = 3;
2259 v; // marker
2260 }''';
2261 assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
2262 assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
2263 }
2264
2265 void test_localVariableInference_noInitializer_disabled() {
2266 String code = r'''
2267 main() {
2268 var v;
2269 v = 3;
2270 v; // marker
2271 }''';
2272 assertPropagatedAssignedType(code, typeProvider.dynamicType, null);
2273 assertTypeOfMarkedExpression(code, typeProvider.dynamicType, null);
2274 }
2275
2276 void test_localVariableInference_transitive_field_inferred_lexical() {
2277 String code = r'''
2278 class A {
2279 final x = 3;
2280 f() {
2281 var v = x;
2282 return v; // marker
2283 }
2284 }
2285 main() {
2286 }
2287 ''';
2288 assertPropagatedAssignedType(code, typeProvider.intType, null);
2289 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2290 }
2291
2292 void test_localVariableInference_transitive_field_inferred_reversed() {
2293 String code = r'''
2294 class A {
2295 f() {
2296 var v = x;
2297 return v; // marker
2298 }
2299 final x = 3;
2300 }
2301 main() {
2302 }
2303 ''';
2304 assertPropagatedAssignedType(code, typeProvider.intType, null);
2305 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2306 }
2307
2308 void test_localVariableInference_transitive_field_lexical() {
2309 String code = r'''
2310 class A {
2311 int x = 3;
2312 f() {
2313 var v = x;
2314 return v; // marker
2315 }
2316 }
2317 main() {
2318 }
2319 ''';
2320 assertPropagatedAssignedType(code, typeProvider.intType, null);
2321 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2322 }
2323
2324 void test_localVariableInference_transitive_field_reversed() {
2325 String code = r'''
2326 class A {
2327 f() {
2328 var v = x;
2329 return v; // marker
2330 }
2331 int x = 3;
2332 }
2333 main() {
2334 }
2335 ''';
2336 assertPropagatedAssignedType(code, typeProvider.intType, null);
2337 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2338 }
2339
2340 void test_localVariableInference_transitive_list_local() {
2341 String code = r'''
2342 main() {
2343 var x = <int>[3];
2344 var v = x[0];
2345 v; // marker
2346 }''';
2347 assertPropagatedAssignedType(code, typeProvider.intType, null);
2348 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2349 }
2350
2351 void test_localVariableInference_transitive_local() {
2352 String code = r'''
2353 main() {
2354 var x = 3;
2355 var v = x;
2356 v; // marker
2357 }''';
2358 assertPropagatedAssignedType(code, typeProvider.intType, null);
2359 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2360 }
2361
2362 void test_localVariableInference_transitive_toplevel_inferred_lexical() {
2363 String code = r'''
2364 final x = 3;
2365 main() {
2366 var v = x;
2367 v; // marker
2368 }
2369 ''';
2370 assertPropagatedAssignedType(code, typeProvider.intType, null);
2371 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2372 }
2373
2374 void test_localVariableInference_transitive_toplevel_inferred_reversed() {
2375 String code = r'''
2376 main() {
2377 var v = x;
2378 v; // marker
2379 }
2380 final x = 3;
2381 ''';
2382 assertPropagatedAssignedType(code, typeProvider.intType, null);
2383 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2384 }
2385
2386 void test_localVariableInference_transitive_toplevel_lexical() {
2387 String code = r'''
2388 int x = 3;
2389 main() {
2390 var v = x;
2391 v; // marker
2392 }
2393 ''';
2394 assertPropagatedAssignedType(code, typeProvider.intType, null);
2395 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2396 }
2397
2398 void test_localVariableInference_transitive_toplevel_reversed() {
2399 String code = r'''
2400 main() {
2401 var v = x;
2402 v; // marker
2403 }
2404 int x = 3;
2405 ''';
2406 assertPropagatedAssignedType(code, typeProvider.intType, null);
2407 assertTypeOfMarkedExpression(code, typeProvider.intType, null);
2408 }
2409 }
OLDNEW
« no previous file with comments | « packages/analyzer/test/generated/static_warning_code_test.dart ('k') | packages/analyzer/test/generated/test_all.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698