| 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/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'; |
| 11 import 'package:analyzer/src/dart/element/element.dart'; | 11 import 'package:analyzer/src/dart/element/element.dart'; |
| 12 import 'package:analyzer/src/dart/element/type.dart'; | |
| 13 import 'package:analyzer/src/generated/ast.dart'; | 12 import 'package:analyzer/src/generated/ast.dart'; |
| 14 import 'package:analyzer/src/generated/resolver.dart' | 13 import 'package:analyzer/src/generated/resolver.dart' |
| 15 show TypeProvider, InheritanceManager; | 14 show TypeProvider, InheritanceManager; |
| 16 import 'package:analyzer/src/generated/type_system.dart'; | 15 import 'package:analyzer/src/generated/type_system.dart'; |
| 17 import 'package:analyzer/src/generated/utilities_dart.dart'; | 16 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 18 | 17 |
| 19 /** | 18 /** |
| 20 * Set the type of the sole parameter of the given [element] to the given [type]
. | 19 * Sets the type of the field. This is stored in the field itself, and the |
| 20 * synthetic getter/setter types. |
| 21 */ | 21 */ |
| 22 void setParameterType(PropertyAccessorElement element, DartType type) { | 22 void setFieldType(VariableElement field, DartType newType) { |
| 23 if (element is PropertyAccessorElementImpl) { | 23 (field as VariableElementImpl).type = newType; |
| 24 ParameterElement parameter = _getParameter(element); | 24 if (field.initializer != null) { |
| 25 if (parameter is ParameterElementImpl) { | 25 (field.initializer as ExecutableElementImpl).returnType = newType; |
| 26 // | 26 } |
| 27 // Update the type of the parameter. | 27 if (field is PropertyInducingElementImpl) { |
| 28 // | 28 (field.getter as ExecutableElementImpl).returnType = newType; |
| 29 parameter.type = type; | 29 if (!field.isFinal && !field.isConst) { |
| 30 // | 30 (field.setter.parameters[0] as ParameterElementImpl).type = |
| 31 // Update the type of the setter to reflect the new parameter type. | 31 newType; |
| 32 // | |
| 33 // TODO(jmesserly): why is this necessary? The function type should always | |
| 34 // delegate to the orginal element. | |
| 35 FunctionType functionType = element.type; | |
| 36 if (functionType is FunctionTypeImpl) { | |
| 37 element.type = new FunctionTypeImpl(element); | |
| 38 } else { | |
| 39 assert(false); | |
| 40 } | |
| 41 } else { | |
| 42 assert(false); | |
| 43 } | 32 } |
| 44 } else { | |
| 45 throw new StateError('element is an instance of ${element.runtimeType}'); | |
| 46 assert(false); | |
| 47 } | 33 } |
| 48 } | 34 } |
| 49 | 35 |
| 50 /** | |
| 51 * Set the return type of the given [element] to the given [type]. | |
| 52 */ | |
| 53 void setReturnType(ExecutableElement element, DartType type) { | |
| 54 if (element is ExecutableElementImpl) { | |
| 55 // | |
| 56 // Update the return type of the element, which is stored in two places: | |
| 57 // directly in the element and indirectly in the type of the element. | |
| 58 // | |
| 59 // TODO(jmesserly): why is this necessary? The function type should always | |
| 60 // delegate to the orginal element. | |
| 61 element.returnType = type; | |
| 62 FunctionType functionType = element.type; | |
| 63 if (functionType is FunctionTypeImpl) { | |
| 64 element.type = new FunctionTypeImpl(element); | |
| 65 } else { | |
| 66 assert(false); | |
| 67 } | |
| 68 } else { | |
| 69 assert(false); | |
| 70 } | |
| 71 } | |
| 72 | |
| 73 /** | 36 /** |
| 74 * Return the element for the single parameter of the given [setter], or `null` | 37 * Return the element for the single parameter of the given [setter], or `null` |
| 75 * if the executable element is not a setter or does not have a single | 38 * if the executable element is not a setter or does not have a single |
| 76 * parameter. | 39 * parameter. |
| 77 */ | 40 */ |
| 78 ParameterElement _getParameter(ExecutableElement setter) { | 41 ParameterElement _getParameter(ExecutableElement setter) { |
| 79 if (setter is PropertyAccessorElement && setter.isSetter) { | 42 if (setter is PropertyAccessorElement && setter.isSetter) { |
| 80 List<ParameterElement> parameters = setter.parameters; | 43 List<ParameterElement> parameters = setter.parameters; |
| 81 if (parameters.length == 1) { | 44 if (parameters.length == 1) { |
| 82 return parameters[0]; | 45 return parameters[0]; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 310 // | 273 // |
| 311 // Infer the return type. | 274 // Infer the return type. |
| 312 // | 275 // |
| 313 if (element.hasImplicitReturnType) { | 276 if (element.hasImplicitReturnType) { |
| 314 overriddenMethods = inheritanceManager.lookupOverrides( | 277 overriddenMethods = inheritanceManager.lookupOverrides( |
| 315 element.enclosingElement, element.name); | 278 element.enclosingElement, element.name); |
| 316 if (overriddenMethods.isEmpty || | 279 if (overriddenMethods.isEmpty || |
| 317 !_allSameElementKind(element, overriddenMethods)) { | 280 !_allSameElementKind(element, overriddenMethods)) { |
| 318 return; | 281 return; |
| 319 } | 282 } |
| 320 setReturnType(element, _computeReturnType(overriddenMethods)); | 283 (element as ExecutableElementImpl).returnType = |
| 284 _computeReturnType(overriddenMethods); |
| 321 if (element is PropertyAccessorElement) { | 285 if (element is PropertyAccessorElement) { |
| 322 _updateSyntheticVariableType(element); | 286 _updateSyntheticVariableType(element); |
| 323 } | 287 } |
| 324 } | 288 } |
| 325 // | 289 // |
| 326 // Infer the parameter types. | 290 // Infer the parameter types. |
| 327 // | 291 // |
| 328 List<ParameterElement> parameters = element.parameters; | 292 List<ParameterElement> parameters = element.parameters; |
| 329 int length = parameters.length; | 293 int length = parameters.length; |
| 330 for (int i = 0; i < length; ++i) { | 294 for (int i = 0; i < length; ++i) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 // | 344 // |
| 381 if (newType == null || newType.isDynamic) { | 345 if (newType == null || newType.isDynamic) { |
| 382 if (fieldElement.initializer != null && | 346 if (fieldElement.initializer != null && |
| 383 (fieldElement.isFinal || overriddenGetters.isEmpty)) { | 347 (fieldElement.isFinal || overriddenGetters.isEmpty)) { |
| 384 newType = fieldElement.initializer.returnType; | 348 newType = fieldElement.initializer.returnType; |
| 385 } | 349 } |
| 386 } | 350 } |
| 387 if (newType == null || newType.isBottom) { | 351 if (newType == null || newType.isBottom) { |
| 388 newType = typeProvider.dynamicType; | 352 newType = typeProvider.dynamicType; |
| 389 } | 353 } |
| 390 (fieldElement as FieldElementImpl).type = newType; | 354 setFieldType(fieldElement, newType); |
| 391 setReturnType(fieldElement.getter, newType); | |
| 392 if (!fieldElement.isFinal && !fieldElement.isConst) { | |
| 393 setParameterType(fieldElement.setter, newType); | |
| 394 } | |
| 395 } | 355 } |
| 396 } | 356 } |
| 397 | 357 |
| 398 void _inferFieldFormalParameter(FieldFormalParameterElement element) { | 358 void _inferFieldFormalParameter(FieldFormalParameterElement element) { |
| 399 FieldElement field = element.field; | 359 FieldElement field = element.field; |
| 400 if (field != null && element.hasImplicitType) { | 360 if (field != null && element.hasImplicitType) { |
| 401 (element as FieldFormalParameterElementImpl).type = field.type; | 361 (element as FieldFormalParameterElementImpl).type = field.type; |
| 402 } | 362 } |
| 403 } | 363 } |
| 404 | 364 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 results.add(element); | 463 results.add(element); |
| 504 } | 464 } |
| 505 } | 465 } |
| 506 } | 466 } |
| 507 } | 467 } |
| 508 | 468 |
| 509 /** | 469 /** |
| 510 * A class of exception that is not used anywhere else. | 470 * A class of exception that is not used anywhere else. |
| 511 */ | 471 */ |
| 512 class _CycleException implements Exception {} | 472 class _CycleException implements Exception {} |
| OLD | NEW |