| 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 analyzer.test.src.task.strong_mode_test; | 5 library analyzer.test.src.task.strong_mode_test; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
| 10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 Future<CompilationUnitElement> resolve(String content) async { | 41 Future<CompilationUnitElement> resolve(String content) async { |
| 42 Source source = addNamedSource('/test.dart', content); | 42 Source source = addNamedSource('/test.dart', content); |
| 43 if (enableNewAnalysisDriver) { | 43 if (enableNewAnalysisDriver) { |
| 44 var analysisResult = await computeAnalysisResult(source); | 44 var analysisResult = await computeAnalysisResult(source); |
| 45 return analysisResult.unit.element; | 45 return analysisResult.unit.element; |
| 46 } else { | 46 } else { |
| 47 return analysisContext.resolveCompilationUnit2(source, source).element; | 47 return analysisContext.resolveCompilationUnit2(source, source).element; |
| 48 } | 48 } |
| 49 } | 49 } |
| 50 | 50 |
| 51 test_inferCompilationUnit_field_multiple_different() async { | |
| 52 String fieldName = 'f'; | |
| 53 CompilationUnitElement unit = await resolve(''' | |
| 54 class A { | |
| 55 int $fieldName; | |
| 56 } | |
| 57 class B { | |
| 58 double $fieldName; | |
| 59 } | |
| 60 class C implements A, B { | |
| 61 var $fieldName; | |
| 62 } | |
| 63 '''); | |
| 64 ClassElement classC = unit.getType('C'); | |
| 65 FieldElement fieldC = classC.getField(fieldName); | |
| 66 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 67 expect(fieldC.type.isDynamic, isTrue); | |
| 68 expect(getterC.returnType.isDynamic, isTrue); | |
| 69 | |
| 70 _runInferrer(unit); | |
| 71 | |
| 72 expect(fieldC.type.isDynamic, isTrue); | |
| 73 expect(getterC.returnType.isDynamic, isTrue); | |
| 74 } | |
| 75 | |
| 76 test_inferCompilationUnit_field_multiple_different_generic() async { | |
| 77 String fieldName = 'f'; | |
| 78 CompilationUnitElement unit = await resolve(''' | |
| 79 class A<E> { | |
| 80 E $fieldName; | |
| 81 } | |
| 82 class B<E> { | |
| 83 E $fieldName; | |
| 84 } | |
| 85 class C implements A<int>, B<double> { | |
| 86 var $fieldName; | |
| 87 } | |
| 88 '''); | |
| 89 ClassElement classC = unit.getType('C'); | |
| 90 FieldElement fieldC = classC.getField(fieldName); | |
| 91 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 92 expect(fieldC.type.isDynamic, isTrue); | |
| 93 expect(getterC.returnType.isDynamic, isTrue); | |
| 94 | |
| 95 _runInferrer(unit); | |
| 96 | |
| 97 expect(fieldC.type.isDynamic, isTrue); | |
| 98 expect(getterC.returnType.isDynamic, isTrue); | |
| 99 } | |
| 100 | |
| 101 test_inferCompilationUnit_field_multiple_dynamic() async { | |
| 102 String fieldName = 'f'; | |
| 103 CompilationUnitElement unit = await resolve(''' | |
| 104 class A { | |
| 105 int $fieldName; | |
| 106 } | |
| 107 class B { | |
| 108 var $fieldName; | |
| 109 } | |
| 110 class C implements A, B { | |
| 111 var $fieldName; | |
| 112 } | |
| 113 '''); | |
| 114 ClassElement classC = unit.getType('C'); | |
| 115 FieldElement fieldC = classC.getField(fieldName); | |
| 116 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 117 expect(fieldC.type.isDynamic, isTrue); | |
| 118 expect(getterC.returnType.isDynamic, isTrue); | |
| 119 | |
| 120 _runInferrer(unit); | |
| 121 | |
| 122 expect(fieldC.type.isDynamic, isTrue); | |
| 123 expect(getterC.returnType.isDynamic, isTrue); | |
| 124 } | |
| 125 | |
| 126 test_inferCompilationUnit_field_multiple_same() async { | |
| 127 String fieldName = 'f'; | |
| 128 CompilationUnitElement unit = await resolve(''' | |
| 129 class A { | |
| 130 int $fieldName; | |
| 131 } | |
| 132 class B { | |
| 133 int $fieldName; | |
| 134 } | |
| 135 class C implements A, B { | |
| 136 var $fieldName; | |
| 137 } | |
| 138 '''); | |
| 139 ClassElement classA = unit.getType('A'); | |
| 140 FieldElement fieldA = classA.getField(fieldName); | |
| 141 DartType expectedType = fieldA.type; | |
| 142 ClassElement classC = unit.getType('C'); | |
| 143 FieldElement fieldC = classC.getField(fieldName); | |
| 144 PropertyAccessorElement getterC = classC.getGetter(fieldName); | |
| 145 expect(fieldC.type.isDynamic, isTrue); | |
| 146 expect(getterC.returnType.isDynamic, isTrue); | |
| 147 | |
| 148 _runInferrer(unit); | |
| 149 | |
| 150 expect(fieldC.type, expectedType); | |
| 151 expect(getterC.returnType, expectedType); | |
| 152 } | |
| 153 | |
| 154 test_inferCompilationUnit_field_noOverride() async { | |
| 155 String fieldName = 'f'; | |
| 156 CompilationUnitElement unit = await resolve(''' | |
| 157 class A { | |
| 158 final $fieldName = 0; | |
| 159 } | |
| 160 '''); | |
| 161 ClassElement classA = unit.getType('A'); | |
| 162 FieldElement fieldA = classA.getField(fieldName); | |
| 163 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 164 expect(fieldA.type.isDynamic, isTrue); | |
| 165 expect(getterA.returnType.isDynamic, isTrue); | |
| 166 | |
| 167 InstanceMemberInferrer inferrer = _runInferrer(unit); | |
| 168 | |
| 169 DartType intType = inferrer.typeProvider.intType; | |
| 170 expect(fieldA.type, intType); | |
| 171 expect(getterA.returnType, intType); | |
| 172 } | |
| 173 | |
| 174 test_inferCompilationUnit_field_noOverride_bottom() async { | |
| 175 String fieldName = 'f'; | |
| 176 CompilationUnitElement unit = await resolve(''' | |
| 177 class A { | |
| 178 var $fieldName = null; | |
| 179 } | |
| 180 '''); | |
| 181 ClassElement classA = unit.getType('A'); | |
| 182 FieldElement fieldA = classA.getField(fieldName); | |
| 183 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 184 expect(fieldA.type.isDynamic, isTrue); | |
| 185 expect(getterA.returnType.isDynamic, isTrue); | |
| 186 | |
| 187 _runInferrer(unit); | |
| 188 | |
| 189 expect(fieldA.type.isDynamic, isTrue); | |
| 190 expect(getterA.returnType.isDynamic, isTrue); | |
| 191 } | |
| 192 | |
| 193 test_inferCompilationUnit_field_single_explicitlyDynamic() async { | |
| 194 String fieldName = 'f'; | |
| 195 CompilationUnitElement unit = await resolve(''' | |
| 196 class A { | |
| 197 dynamic $fieldName; | |
| 198 } | |
| 199 class B extends A { | |
| 200 var $fieldName = 0; | |
| 201 } | |
| 202 '''); | |
| 203 ClassElement classA = unit.getType('A'); | |
| 204 FieldElement fieldA = classA.getField(fieldName); | |
| 205 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 206 ClassElement classB = unit.getType('B'); | |
| 207 FieldElement fieldB = classB.getField(fieldName); | |
| 208 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 209 expect(fieldB.type.isDynamic, isTrue); | |
| 210 expect(getterB.returnType.isDynamic, isTrue); | |
| 211 | |
| 212 _runInferrer(unit); | |
| 213 | |
| 214 expect(fieldB.type, fieldA.type); | |
| 215 expect(getterB.returnType, getterA.returnType); | |
| 216 } | |
| 217 | |
| 218 test_inferCompilationUnit_field_single_final() async { | |
| 219 String fieldName = 'f'; | |
| 220 CompilationUnitElement unit = await resolve(''' | |
| 221 class A { | |
| 222 final int $fieldName; | |
| 223 } | |
| 224 class B extends A { | |
| 225 final $fieldName; | |
| 226 } | |
| 227 '''); | |
| 228 ClassElement classA = unit.getType('A'); | |
| 229 FieldElement fieldA = classA.getField(fieldName); | |
| 230 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 231 ClassElement classB = unit.getType('B'); | |
| 232 FieldElement fieldB = classB.getField(fieldName); | |
| 233 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 234 expect(fieldB.type.isDynamic, isTrue); | |
| 235 expect(getterB.returnType.isDynamic, isTrue); | |
| 236 | |
| 237 _runInferrer(unit); | |
| 238 | |
| 239 expect(fieldB.type, fieldA.type); | |
| 240 expect(getterB.returnType, getterA.returnType); | |
| 241 } | |
| 242 | |
| 243 test_inferCompilationUnit_field_single_final_narrowType() async { | |
| 244 String fieldName = 'f'; | |
| 245 CompilationUnitElement unit = await resolve(''' | |
| 246 class A { | |
| 247 final $fieldName; | |
| 248 } | |
| 249 class B extends A { | |
| 250 final $fieldName = 0; | |
| 251 } | |
| 252 '''); | |
| 253 ClassElement classB = unit.getType('B'); | |
| 254 FieldElement fieldB = classB.getField(fieldName); | |
| 255 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 256 expect(fieldB.type.isDynamic, isTrue); | |
| 257 expect(getterB.returnType.isDynamic, isTrue); | |
| 258 | |
| 259 InstanceMemberInferrer inferrer = _runInferrer(unit); | |
| 260 | |
| 261 expect(fieldB.type, inferrer.typeProvider.intType); | |
| 262 expect(getterB.returnType, fieldB.type); | |
| 263 } | |
| 264 | |
| 265 test_inferCompilationUnit_field_single_generic() async { | |
| 266 String fieldName = 'f'; | |
| 267 CompilationUnitElement unit = await resolve(''' | |
| 268 class A<E> { | |
| 269 E $fieldName; | |
| 270 } | |
| 271 class B<E> extends A<E> { | |
| 272 var $fieldName; | |
| 273 } | |
| 274 '''); | |
| 275 ClassElement classB = unit.getType('B'); | |
| 276 DartType typeBE = classB.typeParameters[0].type; | |
| 277 FieldElement fieldB = classB.getField(fieldName); | |
| 278 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 279 expect(fieldB.type.isDynamic, isTrue); | |
| 280 expect(getterB.returnType.isDynamic, isTrue); | |
| 281 | |
| 282 _runInferrer(unit); | |
| 283 | |
| 284 expect(fieldB.type, typeBE); | |
| 285 expect(getterB.returnType, typeBE); | |
| 286 } | |
| 287 | |
| 288 test_inferCompilationUnit_field_single_inconsistentAccessors() async { | |
| 289 String fieldName = 'f'; | |
| 290 CompilationUnitElement unit = await resolve(''' | |
| 291 class A { | |
| 292 int get $fieldName => 0; | |
| 293 set $fieldName(String value) {} | |
| 294 } | |
| 295 class B extends A { | |
| 296 var $fieldName; | |
| 297 } | |
| 298 '''); | |
| 299 ClassElement classB = unit.getType('B'); | |
| 300 FieldElement fieldB = classB.getField(fieldName); | |
| 301 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 302 expect(fieldB.type.isDynamic, isTrue); | |
| 303 expect(getterB.returnType.isDynamic, isTrue); | |
| 304 | |
| 305 _runInferrer(unit); | |
| 306 | |
| 307 expect(fieldB.type.isDynamic, isTrue); | |
| 308 expect(getterB.returnType.isDynamic, isTrue); | |
| 309 } | |
| 310 | |
| 311 test_inferCompilationUnit_field_single_noModifiers() async { | |
| 312 String fieldName = 'f'; | |
| 313 CompilationUnitElement unit = await resolve(''' | |
| 314 class A { | |
| 315 int $fieldName; | |
| 316 } | |
| 317 class B extends A { | |
| 318 var $fieldName; | |
| 319 } | |
| 320 '''); | |
| 321 ClassElement classA = unit.getType('A'); | |
| 322 FieldElement fieldA = classA.getField(fieldName); | |
| 323 PropertyAccessorElement getterA = classA.getGetter(fieldName); | |
| 324 ClassElement classB = unit.getType('B'); | |
| 325 FieldElement fieldB = classB.getField(fieldName); | |
| 326 PropertyAccessorElement getterB = classB.getGetter(fieldName); | |
| 327 expect(fieldB.type.isDynamic, isTrue); | |
| 328 expect(getterB.returnType.isDynamic, isTrue); | |
| 329 | |
| 330 _runInferrer(unit); | |
| 331 | |
| 332 expect(fieldB.type, fieldA.type); | |
| 333 expect(getterB.returnType, getterA.returnType); | |
| 334 } | |
| 335 | |
| 336 test_inferCompilationUnit_fieldFormal() async { | |
| 337 String fieldName = 'f'; | |
| 338 CompilationUnitElement unit = await resolve(''' | |
| 339 class A { | |
| 340 final $fieldName = 0; | |
| 341 A([this.$fieldName = 'hello']); | |
| 342 } | |
| 343 '''); | |
| 344 ClassElement classA = unit.getType('A'); | |
| 345 FieldElement fieldA = classA.getField(fieldName); | |
| 346 FieldFormalParameterElement paramA = | |
| 347 classA.unnamedConstructor.parameters[0]; | |
| 348 expect(fieldA.type.isDynamic, isTrue); | |
| 349 expect(paramA.type.isDynamic, isTrue); | |
| 350 | |
| 351 InstanceMemberInferrer inferrer = _runInferrer(unit); | |
| 352 | |
| 353 DartType intType = inferrer.typeProvider.intType; | |
| 354 expect(fieldA.type, intType); | |
| 355 expect(paramA.type, intType); | |
| 356 } | |
| 357 | |
| 358 test_inferCompilationUnit_getter_multiple_different() async { | |
| 359 String getterName = 'g'; | |
| 360 CompilationUnitElement unit = await resolve(''' | |
| 361 class A { | |
| 362 int get $getterName => 0; | |
| 363 } | |
| 364 class B { | |
| 365 double get $getterName => 0.0; | |
| 366 } | |
| 367 class C implements A, B { | |
| 368 get $getterName => 0; | |
| 369 } | |
| 370 '''); | |
| 371 ClassElement classC = unit.getType('C'); | |
| 372 FieldElement fieldC = classC.getField(getterName); | |
| 373 PropertyAccessorElement getterC = classC.getGetter(getterName); | |
| 374 expect(fieldC.type.isDynamic, isTrue); | |
| 375 expect(getterC.returnType.isDynamic, isTrue); | |
| 376 | |
| 377 _runInferrer(unit); | |
| 378 | |
| 379 expect(fieldC.type.isDynamic, isTrue); | |
| 380 expect(getterC.returnType.isDynamic, isTrue); | |
| 381 } | |
| 382 | |
| 383 test_inferCompilationUnit_getter_multiple_dynamic() async { | |
| 384 String getterName = 'g'; | |
| 385 CompilationUnitElement unit = await resolve(''' | |
| 386 class A { | |
| 387 int get $getterName => 0; | |
| 388 } | |
| 389 class B { | |
| 390 get $getterName => 0; | |
| 391 } | |
| 392 class C implements A, B { | |
| 393 get $getterName => 0; | |
| 394 } | |
| 395 '''); | |
| 396 ClassElement classC = unit.getType('C'); | |
| 397 FieldElement fieldC = classC.getField(getterName); | |
| 398 PropertyAccessorElement getterC = classC.getGetter(getterName); | |
| 399 expect(fieldC.type.isDynamic, isTrue); | |
| 400 expect(getterC.returnType.isDynamic, isTrue); | |
| 401 | |
| 402 _runInferrer(unit); | |
| 403 | |
| 404 expect(fieldC.type.isDynamic, isTrue); | |
| 405 expect(getterC.returnType.isDynamic, isTrue); | |
| 406 } | |
| 407 | |
| 408 test_inferCompilationUnit_getter_multiple_same() async { | |
| 409 String getterName = 'g'; | |
| 410 CompilationUnitElement unit = await resolve(''' | |
| 411 class A { | |
| 412 String get $getterName => ''; | |
| 413 } | |
| 414 class B { | |
| 415 String get $getterName => ''; | |
| 416 } | |
| 417 class C implements A, B { | |
| 418 get $getterName => ''; | |
| 419 } | |
| 420 '''); | |
| 421 ClassElement classA = unit.getType('A'); | |
| 422 PropertyAccessorElement getterA = classA.getGetter(getterName); | |
| 423 DartType expectedType = getterA.returnType; | |
| 424 ClassElement classC = unit.getType('C'); | |
| 425 FieldElement fieldC = classC.getField(getterName); | |
| 426 PropertyAccessorElement getterC = classC.getGetter(getterName); | |
| 427 expect(fieldC.type.isDynamic, isTrue); | |
| 428 expect(getterC.returnType.isDynamic, isTrue); | |
| 429 | |
| 430 _runInferrer(unit); | |
| 431 | |
| 432 expect(fieldC.type, expectedType); | |
| 433 expect(getterC.returnType, expectedType); | |
| 434 } | |
| 435 | |
| 436 test_inferCompilationUnit_getter_single() async { | |
| 437 String getterName = 'g'; | |
| 438 CompilationUnitElement unit = await resolve(''' | |
| 439 class A { | |
| 440 int get $getterName => 0; | |
| 441 } | |
| 442 class B extends A { | |
| 443 get $getterName => 0; | |
| 444 } | |
| 445 '''); | |
| 446 ClassElement classA = unit.getType('A'); | |
| 447 FieldElement fieldA = classA.getField(getterName); | |
| 448 PropertyAccessorElement getterA = classA.getGetter(getterName); | |
| 449 ClassElement classB = unit.getType('B'); | |
| 450 FieldElement fieldB = classB.getField(getterName); | |
| 451 PropertyAccessorElement getterB = classB.getGetter(getterName); | |
| 452 expect(fieldB.type.isDynamic, isTrue); | |
| 453 expect(getterB.returnType.isDynamic, isTrue); | |
| 454 | |
| 455 _runInferrer(unit); | |
| 456 | |
| 457 expect(fieldB.type, fieldA.type); | |
| 458 expect(getterB.returnType, getterA.returnType); | |
| 459 } | |
| 460 | |
| 461 test_inferCompilationUnit_getter_single_generic() async { | |
| 462 String getterName = 'g'; | |
| 463 CompilationUnitElement unit = await resolve(''' | |
| 464 class A<E> { | |
| 465 E get $getterName => 0; | |
| 466 } | |
| 467 class B<E> extends A<E> { | |
| 468 get $getterName => 0; | |
| 469 } | |
| 470 '''); | |
| 471 ClassElement classB = unit.getType('B'); | |
| 472 DartType typeBE = classB.typeParameters[0].type; | |
| 473 FieldElement fieldB = classB.getField(getterName); | |
| 474 PropertyAccessorElement getterB = classB.getGetter(getterName); | |
| 475 expect(fieldB.type.isDynamic, isTrue); | |
| 476 expect(getterB.returnType.isDynamic, isTrue); | |
| 477 | |
| 478 _runInferrer(unit); | |
| 479 | |
| 480 expect(fieldB.type, typeBE); | |
| 481 expect(getterB.returnType, typeBE); | |
| 482 } | |
| 483 | |
| 484 test_inferCompilationUnit_getter_single_inconsistentAccessors() async { | |
| 485 String getterName = 'g'; | |
| 486 CompilationUnitElement unit = await resolve(''' | |
| 487 class A { | |
| 488 int get $getterName => 0; | |
| 489 set $getterName(String value) {} | |
| 490 } | |
| 491 class B extends A { | |
| 492 var get $getterName => 1; | |
| 493 } | |
| 494 '''); | |
| 495 ClassElement classA = unit.getType('A'); | |
| 496 FieldElement fieldA = classA.getField(getterName); | |
| 497 PropertyAccessorElement getterA = classA.getGetter(getterName); | |
| 498 ClassElement classB = unit.getType('B'); | |
| 499 FieldElement fieldB = classB.getField(getterName); | |
| 500 PropertyAccessorElement getterB = classB.getGetter(getterName); | |
| 501 expect(fieldB.type.isDynamic, isTrue); | |
| 502 expect(getterB.returnType.isDynamic, isTrue); | |
| 503 | |
| 504 _runInferrer(unit); | |
| 505 | |
| 506 // Expected behavior is that the getter is inferred: getters and setters | |
| 507 // are treated as independent methods. | |
| 508 expect(fieldB.type, fieldA.type); | |
| 509 expect(getterB.returnType, getterA.returnType); | |
| 510 } | |
| 511 | |
| 512 test_inferCompilationUnit_invalid_inheritanceCycle() async { | 51 test_inferCompilationUnit_invalid_inheritanceCycle() async { |
| 513 CompilationUnitElement unit = await resolve(''' | 52 CompilationUnitElement unit = await resolve(''' |
| 514 class A extends C {} | 53 class A extends C {} |
| 515 class B extends A {} | 54 class B extends A {} |
| 516 class C extends B {} | 55 class C extends B {} |
| 517 '''); | 56 '''); |
| 518 _runInferrer(unit); | 57 _runInferrer(unit); |
| 519 } | 58 } |
| 520 | 59 |
| 521 test_inferCompilationUnit_method_parameter_multiple_different() async { | 60 test_inferCompilationUnit_method_parameter_multiple_different() async { |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 expect(methodB.returnType.isDynamic, isTrue); | 401 expect(methodB.returnType.isDynamic, isTrue); |
| 863 expect(methodB.type.typeArguments, [typeBE]); | 402 expect(methodB.type.typeArguments, [typeBE]); |
| 864 | 403 |
| 865 _runInferrer(unit); | 404 _runInferrer(unit); |
| 866 | 405 |
| 867 expect(methodB.returnType, classB.typeParameters[0].type); | 406 expect(methodB.returnType, classB.typeParameters[0].type); |
| 868 expect(methodB.type.typeArguments, [typeBE], | 407 expect(methodB.type.typeArguments, [typeBE], |
| 869 reason: 'function type should still have type arguments'); | 408 reason: 'function type should still have type arguments'); |
| 870 } | 409 } |
| 871 | 410 |
| 872 test_inferCompilationUnit_setter_single() async { | |
| 873 String setterName = 'g'; | |
| 874 CompilationUnitElement unit = await resolve(''' | |
| 875 class A { | |
| 876 set $setterName(int x) {} | |
| 877 } | |
| 878 class B extends A { | |
| 879 set $setterName(x) {} | |
| 880 } | |
| 881 '''); | |
| 882 ClassElement classA = unit.getType('A'); | |
| 883 FieldElement fieldA = classA.getField(setterName); | |
| 884 PropertyAccessorElement setterA = classA.getSetter(setterName); | |
| 885 ClassElement classB = unit.getType('B'); | |
| 886 FieldElement fieldB = classB.getField(setterName); | |
| 887 PropertyAccessorElement setterB = classB.getSetter(setterName); | |
| 888 expect(fieldB.type.isDynamic, isTrue); | |
| 889 expect(setterB.parameters[0].type.isDynamic, isTrue); | |
| 890 | |
| 891 _runInferrer(unit); | |
| 892 | |
| 893 expect(fieldB.type, fieldA.type); | |
| 894 expect(setterB.parameters[0].type, setterA.parameters[0].type); | |
| 895 } | |
| 896 | |
| 897 test_inferCompilationUnit_setter_single_generic() async { | |
| 898 String setterName = 'g'; | |
| 899 CompilationUnitElement unit = await resolve(''' | |
| 900 class A<E> { | |
| 901 set $setterName(E x) {} | |
| 902 } | |
| 903 class B<E> extends A<E> { | |
| 904 set $setterName(x) {} | |
| 905 } | |
| 906 '''); | |
| 907 ClassElement classB = unit.getType('B'); | |
| 908 DartType typeBE = classB.typeParameters[0].type; | |
| 909 FieldElement fieldB = classB.getField(setterName); | |
| 910 PropertyAccessorElement setterB = classB.getSetter(setterName); | |
| 911 expect(fieldB.type.isDynamic, isTrue); | |
| 912 expect(setterB.parameters[0].type.isDynamic, isTrue); | |
| 913 | |
| 914 _runInferrer(unit); | |
| 915 | |
| 916 expect(fieldB.type, typeBE); | |
| 917 expect(setterB.parameters[0].type, typeBE); | |
| 918 } | |
| 919 | |
| 920 test_inferCompilationUnit_setter_single_inconsistentAccessors() async { | |
| 921 String getterName = 'g'; | |
| 922 CompilationUnitElement unit = await resolve(''' | |
| 923 class A { | |
| 924 int get $getterName => 0; | |
| 925 set $getterName(String value) {} | |
| 926 } | |
| 927 class B extends A { | |
| 928 set $getterName(x) {} | |
| 929 } | |
| 930 '''); | |
| 931 ClassElement classA = unit.getType('A'); | |
| 932 PropertyAccessorElement setterA = classA.getSetter(getterName); | |
| 933 ClassElement classB = unit.getType('B'); | |
| 934 FieldElement fieldB = classB.getField(getterName); | |
| 935 PropertyAccessorElement setterB = classB.getSetter(getterName); | |
| 936 expect(fieldB.type.isDynamic, isTrue); | |
| 937 expect(setterB.parameters[0].type.isDynamic, isTrue); | |
| 938 | |
| 939 _runInferrer(unit); | |
| 940 | |
| 941 // Expected behavior is that the getter is inferred: getters and setters | |
| 942 // are treated as independent methods. | |
| 943 expect(setterB.parameters[0].type, setterA.parameters[0].type); | |
| 944 | |
| 945 // Note that B's synthetic field type will be String. This matches what | |
| 946 // resolver would do if we explicitly typed the parameter as 'String' | |
| 947 expect(fieldB.type, setterB.parameters[0].type); | |
| 948 } | |
| 949 | |
| 950 InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) { | 411 InstanceMemberInferrer _runInferrer(CompilationUnitElement unit) { |
| 951 InstanceMemberInferrer inferrer = createInferrer(unit.library); | 412 InstanceMemberInferrer inferrer = createInferrer(unit.library); |
| 952 inferrer.inferCompilationUnit(unit); | 413 inferrer.inferCompilationUnit(unit); |
| 953 return inferrer; | 414 return inferrer; |
| 954 } | 415 } |
| 955 } | 416 } |
| 956 | 417 |
| 957 @reflectiveTest | 418 @reflectiveTest |
| 958 class SetFieldTypeTest extends ResolverTestCase { | 419 class SetFieldTypeTest extends ResolverTestCase { |
| 959 test_setter_withoutParameter() async { | 420 test_setter_withoutParameter() async { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 } | 492 } |
| 1032 } | 493 } |
| 1033 } | 494 } |
| 1034 '''); | 495 '''); |
| 1035 var analysisResult = await computeAnalysisResult(source); | 496 var analysisResult = await computeAnalysisResult(source); |
| 1036 VariableGatherer gatherer = new VariableGatherer(filter); | 497 VariableGatherer gatherer = new VariableGatherer(filter); |
| 1037 analysisResult.unit.accept(gatherer); | 498 analysisResult.unit.accept(gatherer); |
| 1038 return gatherer.results; | 499 return gatherer.results; |
| 1039 } | 500 } |
| 1040 } | 501 } |
| OLD | NEW |