Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 test.src.task.strong_mode_test; | 5 library test.src.task.strong_mode_test; |
| 6 | 6 |
| 7 import 'package:analyzer/src/generated/ast.dart'; | 7 import 'package:analyzer/src/generated/ast.dart'; |
| 8 import 'package:analyzer/src/generated/element.dart'; | |
| 8 import 'package:analyzer/src/generated/source.dart'; | 9 import 'package:analyzer/src/generated/source.dart'; |
| 9 import 'package:analyzer/src/task/strong_mode.dart'; | 10 import 'package:analyzer/src/task/strong_mode.dart'; |
| 10 import 'package:analyzer/task/dart.dart'; | 11 import 'package:analyzer/task/dart.dart'; |
| 11 import 'package:unittest/unittest.dart'; | 12 import 'package:unittest/unittest.dart'; |
| 12 | 13 |
| 13 import '../../reflective_tests.dart'; | 14 import '../../reflective_tests.dart'; |
| 14 import '../../utils.dart'; | 15 import '../../utils.dart'; |
| 15 import '../context/abstract_context.dart'; | 16 import '../context/abstract_context.dart'; |
| 16 | 17 |
| 17 main() { | 18 main() { |
| 18 initializeTestEnvironment(); | 19 initializeTestEnvironment(); |
| 19 runReflectiveTests(InferrenceFinderTest); | 20 runReflectiveTests(InferrenceFinderTest); |
| 21 runReflectiveTests(InstanceMemberInferrerTest); | |
| 20 } | 22 } |
| 21 | 23 |
| 22 @reflectiveTest | 24 @reflectiveTest |
| 23 class InferrenceFinderTest extends AbstractContextTest { | 25 class InferrenceFinderTest extends AbstractContextTest { |
| 24 void test_creation() { | 26 void test_creation() { |
| 25 InferrenceFinder finder = new InferrenceFinder(); | 27 InferrenceFinder finder = new InferrenceFinder(); |
| 26 expect(finder, isNotNull); | 28 expect(finder, isNotNull); |
| 27 expect(finder.classes, isEmpty); | 29 expect(finder.classes, isEmpty); |
| 28 expect(finder.staticVariables, isEmpty); | 30 expect(finder.staticVariables, isEmpty); |
| 29 } | 31 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 50 typedef int F(int x); | 52 typedef int F(int x); |
| 51 '''); | 53 '''); |
| 52 computeResult(source, PARSED_UNIT); | 54 computeResult(source, PARSED_UNIT); |
| 53 CompilationUnit unit = outputs[PARSED_UNIT]; | 55 CompilationUnit unit = outputs[PARSED_UNIT]; |
| 54 InferrenceFinder finder = new InferrenceFinder(); | 56 InferrenceFinder finder = new InferrenceFinder(); |
| 55 unit.accept(finder); | 57 unit.accept(finder); |
| 56 expect(finder.classes, hasLength(3)); | 58 expect(finder.classes, hasLength(3)); |
| 57 expect(finder.staticVariables, hasLength(6)); | 59 expect(finder.staticVariables, hasLength(6)); |
| 58 } | 60 } |
| 59 } | 61 } |
| 62 | |
| 63 @reflectiveTest | |
| 64 class InstanceMemberInferrerTest extends AbstractContextTest { | |
| 65 InstanceMemberInferrer get createInferrer => | |
| 66 new InstanceMemberInferrer(context.typeProvider); | |
| 67 | |
| 68 /** | |
| 69 * Add a source with the given [content] and return the result of resolving | |
| 70 * the source. | |
| 71 */ | |
| 72 CompilationUnitElement resolve(String content) { | |
| 73 Source source = addSource('/test.dart', content); | |
| 74 return context.resolveCompilationUnit2(source, source).element; | |
| 75 } | |
| 76 | |
| 77 void test_creation() { | |
| 78 InstanceMemberInferrer inferrer = createInferrer; | |
| 79 expect(inferrer, isNotNull); | |
| 80 expect(inferrer.typeSystem, isNotNull); | |
| 81 } | |
| 82 | |
| 83 void test_inferCompilationUnit_field_multiple_different() { | |
| 84 InstanceMemberInferrer inferrer = createInferrer; | |
| 85 String fieldName = 'f'; | |
| 86 CompilationUnitElement unit = resolve(''' | |
| 87 class A { | |
| 88 int $fieldName; | |
| 89 } | |
| 90 class B { | |
| 91 double $fieldName; | |
| 92 } | |
| 93 class C implements A, B { | |
| 94 var $fieldName; | |
| 95 } | |
| 96 '''); | |
| 97 ClassElement classC = unit.getType('C'); | |
| 98 FieldElement fieldC = classC.getField(fieldName); | |
| 99 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 100 expect(fieldC.type.isDynamic, isTrue); | |
| 101 expect(getterC.returnType.isDynamic, isTrue); | |
| 102 (fieldC as FieldElementImpl).hasImplicitType = true; | |
| 103 | |
| 104 inferrer.inferCompilationUnit(unit); | |
| 105 | |
| 106 expect(fieldC.type.isDynamic, isTrue); | |
| 107 expect(getterC.returnType.isDynamic, isTrue); | |
| 108 } | |
| 109 | |
| 110 void test_inferCompilationUnit_field_multiple_dynamic() { | |
| 111 InstanceMemberInferrer inferrer = createInferrer; | |
| 112 String fieldName = 'f'; | |
| 113 CompilationUnitElement unit = resolve(''' | |
| 114 class A { | |
| 115 int $fieldName; | |
| 116 } | |
| 117 class B { | |
| 118 var $fieldName; | |
| 119 } | |
| 120 class C implements A, B { | |
| 121 var $fieldName; | |
| 122 } | |
| 123 '''); | |
| 124 ClassElement classC = unit.getType('C'); | |
| 125 FieldElement fieldC = classC.getField(fieldName); | |
| 126 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 127 expect(fieldC.type.isDynamic, isTrue); | |
| 128 expect(getterC.returnType.isDynamic, isTrue); | |
| 129 (fieldC as FieldElementImpl).hasImplicitType = true; | |
| 130 | |
| 131 inferrer.inferCompilationUnit(unit); | |
| 132 | |
| 133 expect(fieldC.type.isDynamic, isTrue); | |
| 134 expect(getterC.returnType.isDynamic, isTrue); | |
| 135 } | |
| 136 | |
| 137 void test_inferCompilationUnit_field_multiple_same() { | |
| 138 InstanceMemberInferrer inferrer = createInferrer; | |
| 139 String fieldName = 'f'; | |
| 140 CompilationUnitElement unit = resolve(''' | |
| 141 class A { | |
| 142 int $fieldName; | |
| 143 } | |
| 144 class B { | |
| 145 int $fieldName; | |
| 146 } | |
| 147 class C implements A, B { | |
| 148 var $fieldName; | |
| 149 } | |
| 150 '''); | |
| 151 ClassElement classA = unit.getType('A'); | |
| 152 FieldElement fieldA = classA.getField(fieldName); | |
| 153 DartType expectedType = fieldA.type; | |
| 154 ClassElement classC = unit.getType('C'); | |
| 155 FieldElement fieldC = classC.getField(fieldName); | |
| 156 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 157 expect(fieldC.type.isDynamic, isTrue); | |
| 158 expect(getterC.returnType.isDynamic, isTrue); | |
| 159 (fieldC as FieldElementImpl).hasImplicitType = true; | |
|
Leaf
2015/08/22 00:06:55
Why does this need to be set manually?
Brian Wilkerson
2015/08/24 16:52:58
I don't remember why I originally needed to add th
| |
| 160 | |
| 161 inferrer.inferCompilationUnit(unit); | |
| 162 | |
| 163 expect(fieldC.type, expectedType); | |
| 164 expect(getterC.returnType, expectedType); | |
| 165 } | |
| 166 | |
| 167 void test_inferCompilationUnit_field_noOverride() { | |
| 168 InstanceMemberInferrer inferrer = createInferrer; | |
| 169 String fieldName = 'f'; | |
| 170 CompilationUnitElement unit = resolve(''' | |
| 171 class A { | |
| 172 final $fieldName = 0; | |
| 173 } | |
| 174 '''); | |
| 175 ClassElement classA = unit.getType('A'); | |
| 176 FieldElement fieldA = classA.getField(fieldName); | |
| 177 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 178 expect(fieldA.type.isDynamic, isTrue); | |
| 179 expect(getterA.returnType.isDynamic, isTrue); | |
| 180 (fieldA as FieldElementImpl).hasImplicitType = true; | |
| 181 | |
| 182 inferrer.inferCompilationUnit(unit); | |
| 183 | |
| 184 DartType intType = inferrer.typeProvider.intType; | |
| 185 expect(fieldA.type, intType); | |
| 186 expect(getterA.returnType, intType); | |
| 187 } | |
| 188 | |
| 189 void test_inferCompilationUnit_field_single_final() { | |
| 190 InstanceMemberInferrer inferrer = createInferrer; | |
| 191 String fieldName = 'f'; | |
| 192 CompilationUnitElement unit = resolve(''' | |
| 193 class A { | |
| 194 final int $fieldName; | |
| 195 } | |
| 196 class B extends A { | |
| 197 final $fieldName; | |
| 198 } | |
| 199 '''); | |
| 200 ClassElement classA = unit.getType('A'); | |
| 201 FieldElement fieldA = classA.getField(fieldName); | |
| 202 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 203 ClassElement classB = unit.getType('B'); | |
| 204 FieldElement fieldB = classB.getField(fieldName); | |
| 205 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 206 expect(fieldB.type.isDynamic, isTrue); | |
| 207 expect(getterB.returnType.isDynamic, isTrue); | |
| 208 (fieldB as FieldElementImpl).hasImplicitType = true; | |
| 209 | |
| 210 inferrer.inferCompilationUnit(unit); | |
| 211 | |
| 212 expect(fieldB.type, fieldA.type); | |
| 213 expect(getterB.returnType, getterA.returnType); | |
| 214 } | |
| 215 | |
| 216 void test_inferCompilationUnit_field_single_noModifiers() { | |
| 217 InstanceMemberInferrer inferrer = createInferrer; | |
| 218 String fieldName = 'f'; | |
| 219 CompilationUnitElement unit = resolve(''' | |
| 220 class A { | |
| 221 int $fieldName; | |
| 222 } | |
| 223 class B extends A { | |
| 224 var $fieldName; | |
| 225 } | |
| 226 '''); | |
| 227 ClassElement classA = unit.getType('A'); | |
| 228 FieldElement fieldA = classA.getField(fieldName); | |
| 229 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 230 ClassElement classB = unit.getType('B'); | |
| 231 FieldElement fieldB = classB.getField(fieldName); | |
| 232 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 233 expect(fieldB.type.isDynamic, isTrue); | |
| 234 expect(getterB.returnType.isDynamic, isTrue); | |
| 235 (fieldB as FieldElementImpl).hasImplicitType = true; | |
| 236 | |
| 237 inferrer.inferCompilationUnit(unit); | |
| 238 | |
| 239 expect(fieldB.type, fieldA.type); | |
| 240 expect(getterB.returnType, getterA.returnType); | |
| 241 } | |
| 242 | |
| 243 void test_inferCompilationUnit_getter_multiple_different() { | |
| 244 InstanceMemberInferrer inferrer = createInferrer; | |
| 245 String getterName = 'g'; | |
| 246 CompilationUnitElement unit = resolve(''' | |
| 247 class A { | |
| 248 int get $getterName => 0; | |
| 249 } | |
| 250 class B { | |
| 251 double get $getterName => 0.0; | |
| 252 } | |
| 253 class C implements A, B { | |
| 254 get $getterName => 0; | |
| 255 } | |
| 256 '''); | |
| 257 ClassElement classC = unit.getType('C'); | |
| 258 FieldElement fieldC = classC.getField(getterName); | |
| 259 PropertyAccessorElement getterC = classC.getGetter(getterName); | |
| 260 expect(fieldC.type.isDynamic, isTrue); | |
| 261 expect(getterC.returnType.isDynamic, isTrue); | |
| 262 (fieldC as FieldElementImpl).hasImplicitType = true; | |
| 263 | |
| 264 inferrer.inferCompilationUnit(unit); | |
| 265 | |
| 266 expect(fieldC.type.isDynamic, isTrue); | |
| 267 expect(getterC.returnType.isDynamic, isTrue); | |
| 268 } | |
| 269 | |
| 270 void test_inferCompilationUnit_getter_multiple_dynamic() { | |
| 271 InstanceMemberInferrer inferrer = createInferrer; | |
| 272 String getterName = 'g'; | |
| 273 CompilationUnitElement unit = resolve(''' | |
| 274 class A { | |
| 275 int get $getterName => 0; | |
| 276 } | |
| 277 class B { | |
| 278 get $getterName => 0; | |
| 279 } | |
| 280 class C implements A, B { | |
| 281 get $getterName => 0; | |
| 282 } | |
| 283 '''); | |
| 284 ClassElement classC = unit.getType('C'); | |
| 285 FieldElement fieldC = classC.getField(getterName); | |
| 286 PropertyAccessorElement getterC = classC.getGetter(getterName); | |
| 287 expect(fieldC.type.isDynamic, isTrue); | |
| 288 expect(getterC.returnType.isDynamic, isTrue); | |
| 289 (fieldC as FieldElementImpl).hasImplicitType = true; | |
| 290 | |
| 291 inferrer.inferCompilationUnit(unit); | |
| 292 | |
| 293 expect(fieldC.type.isDynamic, isTrue); | |
| 294 expect(getterC.returnType.isDynamic, isTrue); | |
| 295 } | |
| 296 | |
| 297 void test_inferCompilationUnit_getter_multiple_same() { | |
| 298 InstanceMemberInferrer inferrer = createInferrer; | |
| 299 String getterName = 'g'; | |
| 300 CompilationUnitElement unit = resolve(''' | |
| 301 class A { | |
| 302 String get $getterName => ''; | |
| 303 } | |
| 304 class B { | |
| 305 String get $getterName => ''; | |
| 306 } | |
| 307 class C implements A, B { | |
| 308 get $getterName => ''; | |
| 309 } | |
| 310 '''); | |
| 311 ClassElement classA = unit.getType('A'); | |
| 312 PropertyAccessorElement getterA = classA.getGetter(getterName); | |
| 313 DartType expectedType = getterA.returnType; | |
| 314 ClassElement classC = unit.getType('C'); | |
| 315 FieldElement fieldC = classC.getField(getterName); | |
| 316 PropertyAccessorElement getterC = classC.getGetter(getterName); | |
| 317 expect(fieldC.type.isDynamic, isTrue); | |
| 318 expect(getterC.returnType.isDynamic, isTrue); | |
| 319 (fieldC as FieldElementImpl).hasImplicitType = true; | |
| 320 | |
| 321 inferrer.inferCompilationUnit(unit); | |
| 322 | |
| 323 expect(fieldC.type, expectedType); | |
| 324 expect(getterC.returnType, expectedType); | |
| 325 } | |
| 326 | |
| 327 void test_inferCompilationUnit_getter_single() { | |
| 328 InstanceMemberInferrer inferrer = createInferrer; | |
| 329 String getterName = 'g'; | |
| 330 CompilationUnitElement unit = resolve(''' | |
| 331 class A { | |
| 332 int get $getterName => 0; | |
| 333 } | |
| 334 class B extends A { | |
| 335 get $getterName => 0; | |
| 336 } | |
| 337 '''); | |
| 338 ClassElement classA = unit.getType('A'); | |
| 339 FieldElement fieldA = classA.getField(getterName); | |
| 340 PropertyAccessorElement getterA = classA.getGetter(getterName); | |
| 341 ClassElement classB = unit.getType('B'); | |
| 342 FieldElement fieldB = classB.getField(getterName); | |
| 343 PropertyAccessorElement getterB = classB.getGetter(getterName); | |
| 344 expect(fieldB.type.isDynamic, isTrue); | |
| 345 expect(getterB.returnType.isDynamic, isTrue); | |
| 346 (fieldB as FieldElementImpl).hasImplicitType = true; | |
| 347 | |
| 348 inferrer.inferCompilationUnit(unit); | |
| 349 | |
| 350 expect(fieldB.type, fieldA.type); | |
| 351 expect(getterB.returnType, getterA.returnType); | |
| 352 } | |
| 353 | |
| 354 void test_inferCompilationUnit_invalid_inheritanceCycle() { | |
| 355 InstanceMemberInferrer inferrer = createInferrer; | |
| 356 CompilationUnitElement unit = resolve(''' | |
| 357 class A extends C {} | |
| 358 class B extends A {} | |
| 359 class C extends B {} | |
| 360 '''); | |
| 361 inferrer.inferCompilationUnit(unit); | |
| 362 } | |
| 363 | |
| 364 void test_inferCompilationUnit_method_multiple_different() { | |
| 365 InstanceMemberInferrer inferrer = createInferrer; | |
| 366 String methodName = 'm'; | |
| 367 CompilationUnitElement unit = resolve(''' | |
| 368 class A { | |
| 369 int $methodName() => 0; | |
| 370 } | |
| 371 class B { | |
| 372 double $methodName() => 0.0; | |
| 373 } | |
| 374 class C implements A, B { | |
| 375 $methodName() => 0; | |
| 376 } | |
| 377 '''); | |
| 378 ClassElement classC = unit.getType('C'); | |
| 379 MethodElement methodC = classC.getMethod(methodName); | |
| 380 expect(methodC.returnType.isDynamic, isTrue); | |
| 381 (methodC as MethodElementImpl).hasImplicitReturnType = true; | |
| 382 | |
| 383 inferrer.inferCompilationUnit(unit); | |
| 384 | |
| 385 expect(methodC.returnType.isDynamic, isTrue); | |
| 386 } | |
| 387 | |
| 388 void test_inferCompilationUnit_method_multiple_dynamic() { | |
| 389 InstanceMemberInferrer inferrer = createInferrer; | |
| 390 String methodName = 'm'; | |
| 391 CompilationUnitElement unit = resolve(''' | |
| 392 class A { | |
| 393 int $methodName() => 0; | |
| 394 } | |
| 395 class B { | |
| 396 $methodName() => 0; | |
| 397 } | |
| 398 class C implements A, B { | |
| 399 $methodName() => 0; | |
| 400 } | |
| 401 '''); | |
| 402 ClassElement classC = unit.getType('C'); | |
| 403 MethodElement methodC = classC.getMethod(methodName); | |
| 404 expect(methodC.returnType.isDynamic, isTrue); | |
| 405 (methodC as MethodElementImpl).hasImplicitReturnType = true; | |
| 406 | |
| 407 inferrer.inferCompilationUnit(unit); | |
| 408 | |
| 409 expect(methodC.returnType.isDynamic, isTrue); | |
| 410 } | |
| 411 | |
| 412 void test_inferCompilationUnit_method_multiple_same_nonVoid() { | |
| 413 InstanceMemberInferrer inferrer = createInferrer; | |
| 414 String methodName = 'm'; | |
| 415 CompilationUnitElement unit = resolve(''' | |
| 416 class A { | |
| 417 int $methodName() => 0; | |
| 418 } | |
| 419 class B { | |
| 420 int $methodName() => 0.0; | |
| 421 } | |
| 422 class C implements A, B { | |
| 423 $methodName() => 0; | |
| 424 } | |
| 425 '''); | |
|
Leaf
2015/08/22 00:06:55
Might be worth having a test or two that validates
Brian Wilkerson
2015/08/24 16:52:58
That would be good, but these tests are only testi
| |
| 426 ClassElement classA = unit.getType('A'); | |
| 427 MethodElement methodA = classA.getMethod(methodName); | |
| 428 DartType expectedType = methodA.returnType; | |
| 429 ClassElement classC = unit.getType('C'); | |
| 430 MethodElement methodC = classC.getMethod(methodName); | |
| 431 expect(methodC.returnType.isDynamic, isTrue); | |
| 432 (methodC as MethodElementImpl).hasImplicitReturnType = true; | |
| 433 | |
| 434 inferrer.inferCompilationUnit(unit); | |
| 435 | |
| 436 expect(methodC.returnType, expectedType); | |
| 437 } | |
| 438 | |
| 439 void test_inferCompilationUnit_method_multiple_same_void() { | |
| 440 InstanceMemberInferrer inferrer = createInferrer; | |
| 441 String methodName = 'm'; | |
| 442 CompilationUnitElement unit = resolve(''' | |
| 443 class A { | |
| 444 void $methodName() {}; | |
| 445 } | |
| 446 class B { | |
| 447 void $methodName() {}; | |
| 448 } | |
| 449 class C implements A, B { | |
| 450 $methodName() {}; | |
| 451 } | |
| 452 '''); | |
| 453 ClassElement classA = unit.getType('A'); | |
| 454 MethodElement methodA = classA.getMethod(methodName); | |
| 455 DartType expectedType = methodA.returnType; | |
| 456 ClassElement classC = unit.getType('C'); | |
| 457 MethodElement methodC = classC.getMethod(methodName); | |
| 458 expect(methodC.returnType.isDynamic, isTrue); | |
| 459 (methodC as MethodElementImpl).hasImplicitReturnType = true; | |
| 460 | |
| 461 inferrer.inferCompilationUnit(unit); | |
| 462 | |
| 463 expect(methodC.returnType, expectedType); | |
| 464 } | |
| 465 | |
| 466 void test_inferCompilationUnit_method_multiple_void() { | |
| 467 InstanceMemberInferrer inferrer = createInferrer; | |
| 468 String methodName = 'm'; | |
| 469 CompilationUnitElement unit = resolve(''' | |
| 470 class A { | |
| 471 int $methodName() => 0; | |
| 472 } | |
| 473 class B { | |
| 474 void $methodName() => 0; | |
| 475 } | |
| 476 class C implements A, B { | |
| 477 $methodName() => 0; | |
| 478 } | |
| 479 '''); | |
| 480 ClassElement classC = unit.getType('C'); | |
| 481 MethodElement methodC = classC.getMethod(methodName); | |
| 482 expect(methodC.returnType.isDynamic, isTrue); | |
| 483 (methodC as MethodElementImpl).hasImplicitReturnType = true; | |
| 484 | |
| 485 inferrer.inferCompilationUnit(unit); | |
| 486 | |
| 487 expect(methodC.returnType.isDynamic, isTrue); | |
| 488 } | |
| 489 | |
| 490 void test_inferCompilationUnit_method_single() { | |
| 491 InstanceMemberInferrer inferrer = createInferrer; | |
| 492 String methodName = 'm'; | |
| 493 CompilationUnitElement unit = resolve(''' | |
| 494 class A { | |
| 495 int $methodName() => 0; | |
| 496 } | |
| 497 class B extends A { | |
| 498 $methodName() => 0; | |
| 499 } | |
| 500 '''); | |
| 501 ClassElement classA = unit.getType('A'); | |
| 502 MethodElement methodA = classA.getMethod(methodName); | |
| 503 ClassElement classB = unit.getType('B'); | |
| 504 MethodElement methodB = classB.getMethod(methodName); | |
| 505 expect(methodB.returnType.isDynamic, isTrue); | |
| 506 (methodB as MethodElementImpl).hasImplicitReturnType = true; | |
| 507 | |
| 508 inferrer.inferCompilationUnit(unit); | |
| 509 | |
| 510 expect(methodB.returnType, methodA.returnType); | |
| 511 } | |
| 512 } | |
| OLD | NEW |