Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.test.generated.strong_mode_test; | 5 library analyzer.test.generated.strong_mode_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; | 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; |
| 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 |