| 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.src.task.strong_mode; | 5 library analyzer.src.task.strong_mode; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart'; | 10 import 'package:analyzer/src/generated/element.dart'; |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 } | 279 } |
| 280 | 280 |
| 281 /** | 281 /** |
| 282 * If the given [accessorElement] represents a non-synthetic instance getter | 282 * If the given [accessorElement] represents a non-synthetic instance getter |
| 283 * for which no return type was provided, infer the return type of the getter. | 283 * for which no return type was provided, infer the return type of the getter. |
| 284 */ | 284 */ |
| 285 void _inferAccessor(PropertyAccessorElement accessorElement) { | 285 void _inferAccessor(PropertyAccessorElement accessorElement) { |
| 286 if (!accessorElement.isSynthetic && | 286 if (!accessorElement.isSynthetic && |
| 287 accessorElement.isGetter && | 287 accessorElement.isGetter && |
| 288 !accessorElement.isStatic && | 288 !accessorElement.isStatic && |
| 289 accessorElement.hasImplicitReturnType && | 289 accessorElement.hasImplicitReturnType) { |
| 290 _getReturnType(accessorElement).isDynamic) { | |
| 291 List<ExecutableElement> overriddenGetters = inheritanceManager | 290 List<ExecutableElement> overriddenGetters = inheritanceManager |
| 292 .lookupOverrides( | 291 .lookupOverrides( |
| 293 accessorElement.enclosingElement, accessorElement.name); | 292 accessorElement.enclosingElement, accessorElement.name); |
| 294 if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) { | 293 if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) { |
| 295 DartType newType = _computeReturnType(overriddenGetters); | 294 DartType newType = _computeReturnType(overriddenGetters); |
| 296 List<ExecutableElement> overriddenSetters = inheritanceManager | 295 List<ExecutableElement> overriddenSetters = inheritanceManager |
| 297 .lookupOverrides( | 296 .lookupOverrides( |
| 298 accessorElement.enclosingElement, accessorElement.name + '='); | 297 accessorElement.enclosingElement, accessorElement.name + '='); |
| 299 PropertyAccessorElement setter = (accessorElement.enclosingElement | 298 PropertyAccessorElement setter = (accessorElement.enclosingElement |
| 300 as ClassElement).getSetter(accessorElement.name); | 299 as ClassElement).getSetter(accessorElement.name); |
| 301 if (setter != null) { | 300 if (setter != null) { |
| 302 overriddenSetters.add(setter); | 301 overriddenSetters.add(setter); |
| 303 } | 302 } |
| 304 if (_isCompatible(newType, overriddenSetters)) { | 303 if (!_isCompatible(newType, overriddenSetters)) { |
| 305 _setReturnType(accessorElement, newType); | 304 newType = typeProvider.dynamicType; |
| 306 (accessorElement.variable as FieldElementImpl).type = newType; | |
| 307 } | 305 } |
| 306 _setReturnType(accessorElement, newType); |
| 307 (accessorElement.variable as FieldElementImpl).type = newType; |
| 308 } | 308 } |
| 309 } | 309 } |
| 310 } | 310 } |
| 311 | 311 |
| 312 /** | 312 /** |
| 313 * Infer type information for all of the instance members in the given | 313 * Infer type information for all of the instance members in the given |
| 314 * [classElement]. | 314 * [classElement]. |
| 315 */ | 315 */ |
| 316 void _inferClass(ClassElement classElement) { | 316 void _inferClass(ClassElement classElement) { |
| 317 if (classElement is ClassElementImpl) { | 317 if (classElement is ClassElementImpl) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 347 } | 347 } |
| 348 } | 348 } |
| 349 | 349 |
| 350 /** | 350 /** |
| 351 * If the given [fieldElement] represents a non-synthetic instance field for | 351 * If the given [fieldElement] represents a non-synthetic instance field for |
| 352 * which no type was provided, infer the type of the field. | 352 * which no type was provided, infer the type of the field. |
| 353 */ | 353 */ |
| 354 void _inferField(FieldElement fieldElement) { | 354 void _inferField(FieldElement fieldElement) { |
| 355 if (!fieldElement.isSynthetic && | 355 if (!fieldElement.isSynthetic && |
| 356 !fieldElement.isStatic && | 356 !fieldElement.isStatic && |
| 357 fieldElement.hasImplicitType && | 357 fieldElement.hasImplicitType) { |
| 358 fieldElement.type.isDynamic) { | |
| 359 // | 358 // |
| 360 // First look for overridden getters with the same name as the field. | 359 // First look for overridden getters with the same name as the field. |
| 361 // | 360 // |
| 362 List<ExecutableElement> overriddenGetters = inheritanceManager | 361 List<ExecutableElement> overriddenGetters = inheritanceManager |
| 363 .lookupOverrides(fieldElement.enclosingElement, fieldElement.name); | 362 .lookupOverrides(fieldElement.enclosingElement, fieldElement.name); |
| 364 DartType newType = null; | 363 DartType newType = null; |
| 365 if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) { | 364 if (overriddenGetters.isNotEmpty && _onlyGetters(overriddenGetters)) { |
| 366 newType = _computeReturnType(overriddenGetters); | 365 newType = _computeReturnType(overriddenGetters); |
| 367 List<ExecutableElement> overriddenSetters = inheritanceManager | 366 List<ExecutableElement> overriddenSetters = inheritanceManager |
| 368 .lookupOverrides( | 367 .lookupOverrides( |
| 369 fieldElement.enclosingElement, fieldElement.name + '='); | 368 fieldElement.enclosingElement, fieldElement.name + '='); |
| 370 if (!_isCompatible(newType, overriddenSetters)) { | 369 if (!_isCompatible(newType, overriddenSetters)) { |
| 371 newType = null; | 370 newType = null; |
| 372 } | 371 } |
| 373 } | 372 } |
| 374 // | 373 // |
| 375 // Then, if none was found, infer the type from the initialization | 374 // Then, if none was found, infer the type from the initialization |
| 376 // expression. | 375 // expression. |
| 377 // | 376 // |
| 378 if (newType == null) { | 377 if (newType == null) { |
| 379 if (fieldElement.initializer != null && | 378 if (fieldElement.initializer != null && |
| 380 (fieldElement.isFinal || overriddenGetters.isEmpty)) { | 379 (fieldElement.isFinal || overriddenGetters.isEmpty)) { |
| 381 newType = fieldElement.initializer.returnType; | 380 newType = fieldElement.initializer.returnType; |
| 382 } | 381 } |
| 383 } | 382 } |
| 384 if (newType != null && !newType.isBottom) { | 383 if (newType == null || newType.isBottom) { |
| 385 (fieldElement as FieldElementImpl).type = newType; | 384 newType = typeProvider.dynamicType; |
| 386 _setReturnType(fieldElement.getter, newType); | |
| 387 _setParameterType(fieldElement.setter, newType); | |
| 388 } | 385 } |
| 386 (fieldElement as FieldElementImpl).type = newType; |
| 387 _setReturnType(fieldElement.getter, newType); |
| 388 _setParameterType(fieldElement.setter, newType); |
| 389 } | 389 } |
| 390 } | 390 } |
| 391 | 391 |
| 392 /** | 392 /** |
| 393 * If the given [methodElement] represents a non-synthetic instance method | 393 * If the given [methodElement] represents a non-synthetic instance method |
| 394 * for which no return type was provided, infer the return type of the method. | 394 * for which no return type was provided, infer the return type of the method. |
| 395 */ | 395 */ |
| 396 void _inferMethod(MethodElement methodElement) { | 396 void _inferMethod(MethodElement methodElement) { |
| 397 if (methodElement.isSynthetic || methodElement.isStatic) { | 397 if (methodElement.isSynthetic || methodElement.isStatic) { |
| 398 return; | 398 return; |
| 399 } | 399 } |
| 400 List<ExecutableElement> overriddenMethods = null; | 400 List<ExecutableElement> overriddenMethods = null; |
| 401 // | 401 // |
| 402 // Infer the return type. | 402 // Infer the return type. |
| 403 // | 403 // |
| 404 if (methodElement.hasImplicitReturnType && | 404 if (methodElement.hasImplicitReturnType) { |
| 405 _getReturnType(methodElement).isDynamic) { | |
| 406 overriddenMethods = inheritanceManager.lookupOverrides( | 405 overriddenMethods = inheritanceManager.lookupOverrides( |
| 407 methodElement.enclosingElement, methodElement.name); | 406 methodElement.enclosingElement, methodElement.name); |
| 408 if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) { | 407 if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) { |
| 409 return; | 408 return; |
| 410 } | 409 } |
| 411 MethodElementImpl element = methodElement as MethodElementImpl; | 410 MethodElementImpl element = methodElement as MethodElementImpl; |
| 412 _setReturnType(element, _computeReturnType(overriddenMethods)); | 411 _setReturnType(element, _computeReturnType(overriddenMethods)); |
| 413 } | 412 } |
| 414 // | 413 // |
| 415 // Infer the parameter types. | 414 // Infer the parameter types. |
| 416 // | 415 // |
| 417 List<ParameterElement> parameters = methodElement.parameters; | 416 List<ParameterElement> parameters = methodElement.parameters; |
| 418 var length = parameters.length; | 417 var length = parameters.length; |
| 419 for (int i = 0; i < length; ++i) { | 418 for (int i = 0; i < length; ++i) { |
| 420 ParameterElement parameter = parameters[i]; | 419 ParameterElement parameter = parameters[i]; |
| 421 if (parameter.hasImplicitType && parameter.type.isDynamic) { | 420 if (parameter is ParameterElementImpl && parameter.hasImplicitType) { |
| 422 overriddenMethods = overriddenMethods ?? | 421 overriddenMethods = overriddenMethods ?? |
| 423 inheritanceManager.lookupOverrides( | 422 inheritanceManager.lookupOverrides( |
| 424 methodElement.enclosingElement, methodElement.name); | 423 methodElement.enclosingElement, methodElement.name); |
| 425 if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) { | 424 if (overriddenMethods.isEmpty || !_onlyMethods(overriddenMethods)) { |
| 426 return; | 425 return; |
| 427 } | 426 } |
| 428 DartType type = _computeParameterType(parameter, i, overriddenMethods); | 427 parameter.type = _computeParameterType(parameter, i, overriddenMethods); |
| 429 if (!type.isDynamic) { | |
| 430 if (parameter is ParameterElementImpl) { | |
| 431 parameter.type = type; | |
| 432 } | |
| 433 } | |
| 434 } | 428 } |
| 435 } | 429 } |
| 436 } | 430 } |
| 437 | 431 |
| 438 /** | 432 /** |
| 439 * Infer type information for all of the instance members in the given | 433 * Infer type information for all of the instance members in the given |
| 440 * interface [type]. | 434 * interface [type]. |
| 441 */ | 435 */ |
| 442 void _inferType(InterfaceType type) { | 436 void _inferType(InterfaceType type) { |
| 443 if (type != null) { | 437 if (type != null) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 new FunctionTypeImpl(element, functionType.prunedTypedefs); | 519 new FunctionTypeImpl(element, functionType.prunedTypedefs); |
| 526 } | 520 } |
| 527 } | 521 } |
| 528 } | 522 } |
| 529 } | 523 } |
| 530 | 524 |
| 531 /** | 525 /** |
| 532 * A class of exception that is not used anywhere else. | 526 * A class of exception that is not used anywhere else. |
| 533 */ | 527 */ |
| 534 class _CycleException implements Exception {} | 528 class _CycleException implements Exception {} |
| OLD | NEW |