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'; |
11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
12 import 'package:analyzer/dart/element/type.dart'; | 12 import 'package:analyzer/dart/element/type.dart'; |
13 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
14 import 'package:analyzer/src/error/codes.dart'; | 14 import 'package:analyzer/src/error/codes.dart'; |
15 import 'package:analyzer/src/generated/engine.dart'; | 15 import 'package:analyzer/src/generated/engine.dart'; |
16 import 'package:analyzer/src/generated/source_io.dart'; | 16 import 'package:analyzer/src/generated/source_io.dart'; |
17 import 'package:test/test.dart'; | 17 import 'package:test/test.dart'; |
18 import 'package:test_reflective_loader/test_reflective_loader.dart'; | 18 import 'package:test_reflective_loader/test_reflective_loader.dart'; |
19 | 19 |
20 import '../utils.dart'; | 20 import '../utils.dart'; |
21 import 'resolver_test_case.dart'; | 21 import 'resolver_test_case.dart'; |
22 | 22 |
23 main() { | 23 main() { |
24 defineReflectiveSuite(() { | 24 defineReflectiveSuite(() { |
25 defineReflectiveTests(StrongModeDownwardsInferenceTest); | 25 defineReflectiveTests(StrongModeLocalInferenceTest); |
26 defineReflectiveTests(StrongModeStaticTypeAnalyzer2Test); | 26 defineReflectiveTests(StrongModeStaticTypeAnalyzer2Test); |
27 defineReflectiveTests(StrongModeTypePropagationTest); | 27 defineReflectiveTests(StrongModeTypePropagationTest); |
28 }); | 28 }); |
29 } | 29 } |
30 | 30 |
31 /** | 31 /** |
32 * Strong mode static analyzer downwards inference tests | 32 * Strong mode static analyzer local type inference tests |
33 */ | 33 */ |
34 @reflectiveTest | 34 @reflectiveTest |
35 class StrongModeDownwardsInferenceTest extends ResolverTestCase { | 35 class StrongModeLocalInferenceTest extends ResolverTestCase { |
36 TypeAssertions _assertions; | 36 TypeAssertions _assertions; |
37 | 37 |
38 Asserter<DartType> _isDynamic; | 38 Asserter<DartType> _isDynamic; |
39 Asserter<InterfaceType> _isFutureOfDynamic; | 39 Asserter<InterfaceType> _isFutureOfDynamic; |
40 Asserter<InterfaceType> _isFutureOfInt; | 40 Asserter<InterfaceType> _isFutureOfInt; |
41 Asserter<DartType> _isInt; | 41 Asserter<DartType> _isInt; |
42 Asserter<DartType> _isNum; | 42 Asserter<DartType> _isNum; |
43 Asserter<DartType> _isObject; | |
43 Asserter<DartType> _isString; | 44 Asserter<DartType> _isString; |
44 | 45 |
45 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType> | 46 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType> |
46 _isFunction2Of; | 47 _isFunction2Of; |
47 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf; | 48 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isFutureOf; |
48 AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType> | 49 AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType> |
49 _isInstantiationOf; | 50 _isInstantiationOf; |
50 AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf; | 51 AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf; |
51 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType> | 52 AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType> |
52 _isMapOf; | 53 _isMapOf; |
53 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf; | 54 AsserterBuilder<List<Asserter<DartType>>, InterfaceType> _isStreamOf; |
54 AsserterBuilder<DartType, DartType> _isType; | 55 AsserterBuilder<DartType, DartType> _isType; |
55 | 56 |
56 AsserterBuilder<Element, DartType> _hasElement; | 57 AsserterBuilder<Element, DartType> _hasElement; |
57 AsserterBuilder<DartType, DartType> _hasElementOf; | 58 AsserterBuilder<DartType, DartType> _hasElementOf; |
58 | 59 |
59 @override | 60 @override |
60 Future<TestAnalysisResult> computeAnalysisResult(Source source) async { | 61 Future<TestAnalysisResult> computeAnalysisResult(Source source) async { |
61 TestAnalysisResult result = await super.computeAnalysisResult(source); | 62 TestAnalysisResult result = await super.computeAnalysisResult(source); |
62 if (_assertions == null) { | 63 if (_assertions == null) { |
63 _assertions = new TypeAssertions(typeProvider); | 64 _assertions = new TypeAssertions(typeProvider); |
64 _isType = _assertions.isType; | 65 _isType = _assertions.isType; |
65 _hasElement = _assertions.hasElement; | 66 _hasElement = _assertions.hasElement; |
66 _isInstantiationOf = _assertions.isInstantiationOf; | 67 _isInstantiationOf = _assertions.isInstantiationOf; |
67 _isInt = _assertions.isInt; | 68 _isInt = _assertions.isInt; |
68 _isNum = _assertions.isNum; | 69 _isNum = _assertions.isNum; |
70 _isObject = _assertions.isObject; | |
69 _isString = _assertions.isString; | 71 _isString = _assertions.isString; |
70 _isDynamic = _assertions.isDynamic; | 72 _isDynamic = _assertions.isDynamic; |
71 _isListOf = _assertions.isListOf; | 73 _isListOf = _assertions.isListOf; |
72 _isMapOf = _assertions.isMapOf; | 74 _isMapOf = _assertions.isMapOf; |
73 _isFunction2Of = _assertions.isFunction2Of; | 75 _isFunction2Of = _assertions.isFunction2Of; |
74 _hasElementOf = _assertions.hasElementOf; | 76 _hasElementOf = _assertions.hasElementOf; |
75 _isFutureOf = _isInstantiationOf(_hasElementOf(typeProvider.futureType)); | 77 _isFutureOf = _isInstantiationOf(_hasElementOf(typeProvider.futureType)); |
76 _isFutureOfDynamic = _isFutureOf([_isDynamic]); | 78 _isFutureOfDynamic = _isFutureOf([_isDynamic]); |
77 _isFutureOfInt = _isFutureOf([_isInt]); | 79 _isFutureOfInt = _isFutureOf([_isInt]); |
78 _isStreamOf = _isInstantiationOf(_hasElementOf(typeProvider.streamType)); | 80 _isStreamOf = _isInstantiationOf(_hasElementOf(typeProvider.streamType)); |
79 } | 81 } |
80 return result; | 82 return result; |
81 } | 83 } |
82 | 84 |
85 fail_constrainedByBounds3() async { | |
86 // Test that upwards inference with two type variables does | |
87 // not propogate from the constrained variable to the unconstrained | |
88 // variable if they are ordered right to left, and that if the result | |
89 // is not a valid instantiation an error is issued | |
90 String code = r''' | |
91 T f<T extends S, S extends int>(S x) => null; | |
92 void test() { var x = f(3); } | |
93 '''; | |
94 Source source = addSource(code); | |
95 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
96 assertErrors( | |
97 source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]); | |
Jennifer Messerly
2017/01/24 19:03:35
might be worth a comment that the error is what we
Leaf
2017/01/24 19:23:30
I think that's already in the comment, and in the
| |
98 verify([source]); | |
99 CompilationUnit unit = analysisResult.unit; | |
100 List<Statement> statements = | |
101 AstFinder.getStatementsInTopLevelFunction(unit, "test"); | |
102 VariableDeclarationStatement stmt = statements[0]; | |
103 VariableDeclaration decl = stmt.variables.variables[0]; | |
104 Expression call = decl.initializer; | |
105 _isDynamic(call.staticType); | |
106 } | |
107 | |
108 fail_constrainedByBounds5() async { | |
109 // Test that upwards inference with two type variables does not | |
110 // propogate from the constrained variable to the unconstrained | |
111 // variable if they are ordered right to left, when the variable | |
112 // appears co and contra variantly, and that an error is issued | |
113 // for the non-matching bound. | |
114 String code = r''' | |
115 typedef To Func1<From, To>(From x); | |
116 T f<T extends Func1<S, S>, S>(S x) => null; | |
117 void test() { var x = f(3)(4); } | |
118 '''; | |
119 Source source = addSource(code); | |
120 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
121 assertErrors( | |
122 source, [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]); | |
123 verify([source]); | |
124 CompilationUnit unit = analysisResult.unit; | |
125 List<Statement> statements = | |
126 AstFinder.getStatementsInTopLevelFunction(unit, "test"); | |
127 VariableDeclarationStatement stmt = statements[0]; | |
128 VariableDeclaration decl = stmt.variables.variables[0]; | |
129 Expression call = decl.initializer; | |
130 _isInt(call.staticType); | |
131 } | |
132 | |
133 fail_pinning_multipleConstraints1() async { | |
134 // Test that downwards inference with two different downwards covariant | |
135 // constraints on the same parameter correctly fails to infer when | |
136 // the types do not share a common subtype | |
137 String code = r''' | |
138 class A<S, T> { | |
139 S s; | |
140 T t; | |
141 } | |
142 class B<S> extends A<S, S> { B(S s); } | |
143 A<int, String> test() => new B(3); | |
144 '''; | |
145 Source source = addSource(code); | |
146 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
147 assertErrors(source, [StrongModeCode.COULD_NOT_INFER]); | |
148 verify([source]); | |
149 CompilationUnit unit = analysisResult.unit; | |
150 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
151 ExpressionFunctionBody body = test.functionExpression.body; | |
152 DartType type = body.expression.staticType; | |
153 | |
154 Element elementB = AstFinder.getClass(unit, "B").element; | |
155 | |
156 _isInstantiationOf(_hasElement(elementB))([_isDynamic])(type); | |
Jennifer Messerly
2017/01/24 19:03:35
FYI: we don't pick "dynamic" in case of inference
Leaf
2017/01/24 19:23:30
Are you saying the expectation of B<dynamic> is wr
| |
157 } | |
158 | |
159 fail_pinning_multipleConstraints2() async { | |
160 // Test that downwards inference with two identical downwards covariant | |
161 // constraints on the same parameter correctly infers and pins the type | |
162 String code = r''' | |
163 class A<S, T> { | |
164 S s; | |
165 T t; | |
166 } | |
167 class B<S> extends A<S, S> { B(S s); } | |
168 A<num, num> test() => new B(3); | |
169 '''; | |
170 Source source = addSource(code); | |
171 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
172 assertNoErrors(source); | |
173 verify([source]); | |
174 CompilationUnit unit = analysisResult.unit; | |
175 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
176 ExpressionFunctionBody body = test.functionExpression.body; | |
177 DartType type = body.expression.staticType; | |
178 | |
179 Element elementB = AstFinder.getClass(unit, "B").element; | |
180 | |
181 _isInstantiationOf(_hasElement(elementB))([_isNum])(type); | |
182 } | |
183 | |
184 fail_pinning_multipleConstraints3() async { | |
185 // Test that downwards inference with two different downwards covariant | |
186 // constraints on the same parameter correctly fails to infer when | |
187 // the types do not share a common subtype, but do share a common supertype | |
188 String code = r''' | |
189 class A<S, T> { | |
190 S s; | |
191 T t; | |
192 } | |
193 class B<S> extends A<S, S> { B(S s); } | |
194 A<int, double> test() => new B(3); | |
195 '''; | |
196 Source source = addSource(code); | |
197 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
198 assertErrors(source, [ | |
199 StrongModeCode.COULD_NOT_INFER, | |
200 StaticTypeWarningCode.RETURN_OF_INVALID_TYPE | |
201 ]); | |
202 verify([source]); | |
203 CompilationUnit unit = analysisResult.unit; | |
204 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
205 ExpressionFunctionBody body = test.functionExpression.body; | |
206 DartType type = body.expression.staticType; | |
207 | |
208 Element elementB = AstFinder.getClass(unit, "B").element; | |
209 | |
210 _isInstantiationOf(_hasElement(elementB))([_isDynamic])(type); | |
211 } | |
212 | |
213 fail_returnType_variance2() async { | |
214 // Check that downwards inference correctly pins a type parameter | |
215 // when the parameter is constrained in a covariant position | |
216 String code = r''' | |
217 typedef To Func1<From, To>(From x); | |
218 Func1<String, T> f<T>(T x) => null; | |
219 Func1<String, num> test() => f(42); | |
220 '''; | |
221 Source source = addSource(code); | |
222 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
223 assertNoErrors(source); | |
224 verify([source]); | |
225 CompilationUnit unit = analysisResult.unit; | |
226 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
227 ExpressionFunctionBody body = test.functionExpression.body; | |
228 MethodInvocation invoke = body.expression; | |
229 _isFunction2Of(_isNum, _isFunction2Of(_isString, _isNum))( | |
230 invoke.staticInvokeType); | |
231 } | |
232 | |
233 fail_returnType_variance6() async { | |
234 // Check that pinning works correctly with a partial type | |
235 // when the return type uses the variable in a covariant position | |
236 String code = r''' | |
237 typedef To Func1<From, To>(From x); | |
238 Func1<String, T> f<T>(T x) => null; | |
239 T g<T, S>(Func1<S, T> f) => null; | |
240 num test() => g(f(3)); | |
241 '''; | |
242 Source source = addSource(code); | |
243 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
244 assertNoErrors(source); | |
245 verify([source]); | |
246 CompilationUnit unit = analysisResult.unit; | |
247 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
248 ExpressionFunctionBody body = test.functionExpression.body; | |
249 MethodInvocation call = body.expression; | |
250 _isNum(call.staticType); | |
251 _isFunction2Of(_isFunction2Of(_isString, _isNum), _isNum)( | |
252 call.staticInvokeType); | |
253 } | |
254 | |
83 @override | 255 @override |
84 void setUp() { | 256 void setUp() { |
85 super.setUp(); | 257 super.setUp(); |
86 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); | 258 AnalysisOptionsImpl options = new AnalysisOptionsImpl(); |
87 options.strongMode = true; | 259 options.strongMode = true; |
88 resetWith(options: options); | 260 resetWith(options: options); |
89 } | 261 } |
90 | 262 |
91 test_async_method_propagation() async { | 263 test_async_method_propagation() async { |
92 String code = r''' | 264 String code = r''' |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 | 452 |
281 CascadeExpression cascade = fetch(0); | 453 CascadeExpression cascade = fetch(0); |
282 _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType); | 454 _isInstantiationOf(_hasElement(elementA))([_isInt])(cascade.staticType); |
283 MethodInvocation invoke = cascade.cascadeSections[0]; | 455 MethodInvocation invoke = cascade.cascadeSections[0]; |
284 FunctionExpression function = invoke.argumentList.arguments[1]; | 456 FunctionExpression function = invoke.argumentList.arguments[1]; |
285 ExecutableElement f0 = function.element; | 457 ExecutableElement f0 = function.element; |
286 _isListOf(_isInt)(f0.type.returnType); | 458 _isListOf(_isInt)(f0.type.returnType); |
287 expect(f0.type.normalParameterTypes[0], typeProvider.intType); | 459 expect(f0.type.normalParameterTypes[0], typeProvider.intType); |
288 } | 460 } |
289 | 461 |
462 test_constrainedByBounds1() async { | |
463 // Test that upwards inference with two type variables correctly | |
464 // propogates from the constrained variable to the unconstrained | |
465 // variable if they are ordered left to right. | |
466 String code = r''' | |
467 T f<S, T extends S>(S x) => null; | |
468 void test() { var x = f(3); } | |
469 '''; | |
470 Source source = addSource(code); | |
471 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
472 assertNoErrors(source); | |
473 verify([source]); | |
474 CompilationUnit unit = analysisResult.unit; | |
475 List<Statement> statements = | |
476 AstFinder.getStatementsInTopLevelFunction(unit, "test"); | |
477 VariableDeclarationStatement stmt = statements[0]; | |
478 VariableDeclaration decl = stmt.variables.variables[0]; | |
479 Expression call = decl.initializer; | |
480 _isInt(call.staticType); | |
481 } | |
482 | |
483 test_constrainedByBounds2() async { | |
484 // Test that upwards inference with two type variables does | |
485 // not propogate from the constrained variable to the unconstrained | |
486 // variable if they are ordered right to left. | |
487 String code = r''' | |
488 T f<T extends S, S>(S x) => null; | |
489 void test() { var x = f(3); } | |
490 '''; | |
491 Source source = addSource(code); | |
492 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
493 assertNoErrors(source); | |
494 verify([source]); | |
495 CompilationUnit unit = analysisResult.unit; | |
496 List<Statement> statements = | |
497 AstFinder.getStatementsInTopLevelFunction(unit, "test"); | |
498 VariableDeclarationStatement stmt = statements[0]; | |
499 VariableDeclaration decl = stmt.variables.variables[0]; | |
500 Expression call = decl.initializer; | |
501 _isDynamic(call.staticType); | |
502 } | |
503 | |
504 test_constrainedByBounds4() async { | |
505 // Test that upwards inference with two type variables correctly | |
506 // propogates from the constrained variable to the unconstrained | |
507 // variable if they are ordered left to right, when the variable | |
508 // appears co and contra variantly | |
509 String code = r''' | |
510 typedef To Func1<From, To>(From x); | |
511 T f<S, T extends Func1<S, S>>(S x) => null; | |
512 void test() { var x = f(3)(4); } | |
513 '''; | |
514 Source source = addSource(code); | |
515 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
516 assertNoErrors(source); | |
517 verify([source]); | |
518 CompilationUnit unit = analysisResult.unit; | |
519 List<Statement> statements = | |
520 AstFinder.getStatementsInTopLevelFunction(unit, "test"); | |
521 VariableDeclarationStatement stmt = statements[0]; | |
522 VariableDeclaration decl = stmt.variables.variables[0]; | |
523 Expression call = decl.initializer; | |
524 _isInt(call.staticType); | |
525 } | |
526 | |
290 test_constructorInitializer_propagation() async { | 527 test_constructorInitializer_propagation() async { |
291 String code = r''' | 528 String code = r''' |
292 class A { | 529 class A { |
293 List<String> x; | 530 List<String> x; |
294 A() : this.x = []; | 531 A() : this.x = []; |
295 } | 532 } |
296 '''; | 533 '''; |
297 CompilationUnit unit = await resolveSource(code); | 534 CompilationUnit unit = await resolveSource(code); |
298 ConstructorDeclaration constructor = | 535 ConstructorDeclaration constructor = |
299 AstFinder.getConstructorInClass(unit, "A", null); | 536 AstFinder.getConstructorInClass(unit, "A", null); |
(...skipping 905 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1205 Statement stmt = (body as BlockFunctionBody).block.statements[0]; | 1442 Statement stmt = (body as BlockFunctionBody).block.statements[0]; |
1206 return (stmt as ReturnStatement).expression; | 1443 return (stmt as ReturnStatement).expression; |
1207 } | 1444 } |
1208 } | 1445 } |
1209 | 1446 |
1210 Asserter<InterfaceType> assertListOfString = _isListOf(_isString); | 1447 Asserter<InterfaceType> assertListOfString = _isListOf(_isString); |
1211 assertListOfString(methodReturnValue("m0").staticType); | 1448 assertListOfString(methodReturnValue("m0").staticType); |
1212 assertListOfString(methodReturnValue("m1").staticType); | 1449 assertListOfString(methodReturnValue("m1").staticType); |
1213 } | 1450 } |
1214 | 1451 |
1452 test_partialTypes1() async { | |
1453 // Test that downwards inference with a partial type | |
1454 // correctly uses the partial information to fill in subterm | |
1455 // types | |
1456 String code = r''' | |
1457 typedef To Func1<From, To>(From x); | |
1458 S f<S, T>(Func1<S, T> g) => null; | |
1459 String test() => f((l) => l.length); | |
1460 '''; | |
1461 Source source = addSource(code); | |
1462 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1463 assertNoErrors(source); | |
1464 verify([source]); | |
1465 CompilationUnit unit = analysisResult.unit; | |
1466 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1467 ExpressionFunctionBody body = test.functionExpression.body; | |
1468 _isString(body.expression.staticType); | |
1469 MethodInvocation invoke = body.expression; | |
1470 FunctionExpression function = invoke.argumentList.arguments[0]; | |
1471 ExecutableElement f0 = function.element; | |
1472 FunctionType type = f0.type; | |
1473 _isFunction2Of(_isString, _isInt)(type); | |
1474 } | |
1475 | |
1476 test_pinning_multipleConstraints4() async { | |
1477 // Test that downwards inference with two subtype related downwards | |
1478 // covariant constraints on the same parameter correctly infers and pins | |
1479 // the type | |
1480 String code = r''' | |
1481 class A<S, T> { | |
1482 S s; | |
1483 T t; | |
1484 } | |
1485 class B<S> extends A<S, S> {} | |
1486 A<int, num> test() => new B(); | |
1487 '''; | |
1488 Source source = addSource(code); | |
1489 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1490 assertNoErrors(source); | |
1491 verify([source]); | |
1492 CompilationUnit unit = analysisResult.unit; | |
1493 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1494 ExpressionFunctionBody body = test.functionExpression.body; | |
1495 DartType type = body.expression.staticType; | |
1496 | |
1497 Element elementB = AstFinder.getClass(unit, "B").element; | |
1498 | |
1499 _isInstantiationOf(_hasElement(elementB))([_isInt])(type); | |
1500 } | |
1501 | |
1502 test_pinning_multipleConstraints_contravariant1() async { | |
1503 // Test that downwards inference with two different downwards contravariant | |
1504 // constraints on the same parameter chooses the upper bound | |
1505 // when the only supertype is Object | |
1506 String code = r''' | |
1507 class A<S, T> { | |
1508 S s; | |
1509 T t; | |
1510 } | |
1511 class B<S> extends A<S, S> {} | |
1512 typedef void Contra1<T>(T x); | |
1513 Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {}; | |
1514 Contra1<A<int, String>> test() => mkA(); | |
1515 '''; | |
1516 Source source = addSource(code); | |
1517 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1518 assertNoErrors(source); | |
1519 verify([source]); | |
1520 CompilationUnit unit = analysisResult.unit; | |
1521 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1522 ExpressionFunctionBody body = test.functionExpression.body; | |
1523 FunctionType functionType = body.expression.staticType; | |
1524 DartType type = functionType.normalParameterTypes[0]; | |
1525 | |
1526 Element elementA = AstFinder.getClass(unit, "A").element; | |
1527 | |
1528 _isInstantiationOf(_hasElement(elementA))([_isObject, _isObject])(type); | |
1529 } | |
1530 | |
1531 test_pinning_multipleConstraints_contravariant2() async { | |
1532 // Test that downwards inference with two identical downwards contravariant | |
1533 // constraints on the same parameter correctly pins the type | |
1534 String code = r''' | |
1535 class A<S, T> { | |
1536 S s; | |
1537 T t; | |
1538 } | |
1539 class B<S> extends A<S, S> {} | |
1540 typedef void Contra1<T>(T x); | |
1541 Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {}; | |
1542 Contra1<A<num, num>> test() => mkA(); | |
1543 '''; | |
1544 Source source = addSource(code); | |
1545 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1546 assertNoErrors(source); | |
1547 verify([source]); | |
1548 CompilationUnit unit = analysisResult.unit; | |
1549 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1550 ExpressionFunctionBody body = test.functionExpression.body; | |
1551 FunctionType functionType = body.expression.staticType; | |
1552 DartType type = functionType.normalParameterTypes[0]; | |
1553 | |
1554 Element elementA = AstFinder.getClass(unit, "A").element; | |
1555 | |
1556 _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type); | |
1557 } | |
1558 | |
1559 test_pinning_multipleConstraints_contravariant3() async { | |
1560 // Test that downwards inference with two different downwards contravariant | |
1561 // constraints on the same parameter correctly choose the least upper bound | |
1562 // when they share a common supertype | |
1563 String code = r''' | |
1564 class A<S, T> { | |
1565 S s; | |
1566 T t; | |
1567 } | |
1568 class B<S> extends A<S, S> {} | |
1569 typedef void Contra1<T>(T x); | |
1570 Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {}; | |
1571 Contra1<A<int, double>> test() => mkA(); | |
1572 '''; | |
1573 Source source = addSource(code); | |
1574 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1575 assertNoErrors(source); | |
1576 verify([source]); | |
1577 CompilationUnit unit = analysisResult.unit; | |
1578 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1579 ExpressionFunctionBody body = test.functionExpression.body; | |
1580 FunctionType functionType = body.expression.staticType; | |
1581 DartType type = functionType.normalParameterTypes[0]; | |
1582 | |
1583 Element elementA = AstFinder.getClass(unit, "A").element; | |
1584 | |
1585 _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type); | |
1586 } | |
1587 | |
1588 test_pinning_multipleConstraints_contravariant4() async { | |
1589 // Test that downwards inference with two different downwards contravariant | |
1590 // constraints on the same parameter correctly choose the least upper bound | |
1591 // when one is a subtype of the other | |
1592 String code = r''' | |
1593 class A<S, T> { | |
1594 S s; | |
1595 T t; | |
1596 } | |
1597 class B<S> extends A<S, S> {} | |
1598 typedef void Contra1<T>(T x); | |
1599 Contra1<A<S, S>> mkA<S>() => (A<S, S> x) {}; | |
1600 Contra1<A<int, num>> test() => mkA(); | |
1601 '''; | |
1602 Source source = addSource(code); | |
1603 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1604 assertNoErrors(source); | |
1605 verify([source]); | |
1606 CompilationUnit unit = analysisResult.unit; | |
1607 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1608 ExpressionFunctionBody body = test.functionExpression.body; | |
1609 FunctionType functionType = body.expression.staticType; | |
1610 DartType type = functionType.normalParameterTypes[0]; | |
1611 | |
1612 Element elementA = AstFinder.getClass(unit, "A").element; | |
1613 | |
1614 _isInstantiationOf(_hasElement(elementA))([_isNum, _isNum])(type); | |
1615 } | |
1616 | |
1215 test_redirectingConstructor_propagation() async { | 1617 test_redirectingConstructor_propagation() async { |
1216 String code = r''' | 1618 String code = r''' |
1217 class A { | 1619 class A { |
1218 A() : this.named([]); | 1620 A() : this.named([]); |
1219 A.named(List<String> x); | 1621 A.named(List<String> x); |
1220 } | 1622 } |
1221 '''; | 1623 '''; |
1222 CompilationUnit unit = await resolveSource(code); | 1624 CompilationUnit unit = await resolveSource(code); |
1223 | 1625 |
1224 ConstructorDeclaration constructor = | 1626 ConstructorDeclaration constructor = |
1225 AstFinder.getConstructorInClass(unit, "A", null); | 1627 AstFinder.getConstructorInClass(unit, "A", null); |
1226 RedirectingConstructorInvocation invocation = constructor.initializers[0]; | 1628 RedirectingConstructorInvocation invocation = constructor.initializers[0]; |
1227 Expression exp = invocation.argumentList.arguments[0]; | 1629 Expression exp = invocation.argumentList.arguments[0]; |
1228 _isListOf(_isString)(exp.staticType); | 1630 _isListOf(_isString)(exp.staticType); |
1229 } | 1631 } |
1230 | 1632 |
1633 test_returnType_variance1() async { | |
1634 // Check that downwards inference correctly pins a type parameter | |
1635 // when the parameter is constrained in a contravariant position | |
1636 String code = r''' | |
1637 typedef To Func1<From, To>(From x); | |
1638 Func1<T, String> f<T>(T x) => null; | |
1639 Func1<num, String> test() => f(42); | |
1640 '''; | |
1641 Source source = addSource(code); | |
1642 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1643 assertNoErrors(source); | |
1644 verify([source]); | |
1645 CompilationUnit unit = analysisResult.unit; | |
1646 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1647 ExpressionFunctionBody body = test.functionExpression.body; | |
1648 MethodInvocation invoke = body.expression; | |
1649 _isFunction2Of(_isNum, _isFunction2Of(_isNum, _isString))( | |
1650 invoke.staticInvokeType); | |
1651 } | |
1652 | |
1653 test_returnType_variance3() async { | |
1654 // Check that the variance heuristic chooses the less precise type | |
1655 // when the return type uses the variable in a contravariant position | |
1656 // and there is no downwards constraint. | |
1657 String code = r''' | |
1658 typedef To Func1<From, To>(From x); | |
1659 Func1<T, String> f<T>(T x, g(T x)) => null; | |
1660 dynamic test() => f(42, (num x) => x); | |
1661 '''; | |
1662 Source source = addSource(code); | |
1663 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1664 assertNoErrors(source); | |
1665 verify([source]); | |
1666 CompilationUnit unit = analysisResult.unit; | |
1667 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1668 ExpressionFunctionBody body = test.functionExpression.body; | |
1669 FunctionType functionType = body.expression.staticType; | |
1670 DartType type = functionType.normalParameterTypes[0]; | |
1671 _isNum(type); | |
1672 } | |
1673 | |
1674 test_returnType_variance4() async { | |
1675 // Check that the variance heuristic chooses the more precise type | |
1676 // when the return type uses the variable in a covariant position | |
1677 // and there is no downwards constraint | |
1678 String code = r''' | |
1679 typedef To Func1<From, To>(From x); | |
1680 Func1<String, T> f<T>(T x, g(T x)) => null; | |
1681 dynamic test() => f(42, (num x) => x); | |
1682 '''; | |
1683 Source source = addSource(code); | |
1684 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1685 assertNoErrors(source); | |
1686 verify([source]); | |
1687 CompilationUnit unit = analysisResult.unit; | |
1688 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1689 ExpressionFunctionBody body = test.functionExpression.body; | |
1690 FunctionType functionType = body.expression.staticType; | |
1691 DartType type = functionType.returnType; | |
1692 _isInt(type); | |
1693 } | |
1694 | |
1695 test_returnType_variance5() async { | |
1696 // Check that pinning works correctly with a partial type | |
1697 // when the return type uses the variable in a contravariant position | |
1698 String code = r''' | |
1699 typedef To Func1<From, To>(From x); | |
1700 Func1<T, String> f<T>(T x) => null; | |
1701 T g<T, S>(Func1<T, S> f) => null; | |
1702 num test() => g(f(3)); | |
1703 '''; | |
1704 Source source = addSource(code); | |
1705 TestAnalysisResult analysisResult = await computeAnalysisResult(source); | |
1706 assertNoErrors(source); | |
1707 verify([source]); | |
1708 CompilationUnit unit = analysisResult.unit; | |
1709 FunctionDeclaration test = AstFinder.getTopLevelFunction(unit, "test"); | |
1710 ExpressionFunctionBody body = test.functionExpression.body; | |
1711 MethodInvocation call = body.expression; | |
1712 _isNum(call.staticType); | |
1713 _isFunction2Of(_isFunction2Of(_isNum, _isString), _isNum)( | |
1714 call.staticInvokeType); | |
1715 } | |
1716 | |
1231 test_superConstructorInvocation_propagation() async { | 1717 test_superConstructorInvocation_propagation() async { |
1232 String code = r''' | 1718 String code = r''' |
1233 class B { | 1719 class B { |
1234 B(List<String>); | 1720 B(List<String>); |
1235 } | 1721 } |
1236 class A extends B { | 1722 class A extends B { |
1237 A() : super([]); | 1723 A() : super([]); |
1238 } | 1724 } |
1239 '''; | 1725 '''; |
1240 CompilationUnit unit = await resolveSource(code); | 1726 CompilationUnit unit = await resolveSource(code); |
(...skipping 1361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2602 var v = x; | 3088 var v = x; |
2603 v; // marker | 3089 v; // marker |
2604 } | 3090 } |
2605 int x = 3; | 3091 int x = 3; |
2606 '''; | 3092 '''; |
2607 CompilationUnit unit = await resolveSource(code); | 3093 CompilationUnit unit = await resolveSource(code); |
2608 assertPropagatedAssignedType(code, unit, typeProvider.intType, null); | 3094 assertPropagatedAssignedType(code, unit, typeProvider.intType, null); |
2609 assertTypeOfMarkedExpression(code, unit, typeProvider.intType, null); | 3095 assertTypeOfMarkedExpression(code, unit, typeProvider.intType, null); |
2610 } | 3096 } |
2611 } | 3097 } |
OLD | NEW |