OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.generated.resolver; | 5 library analyzer.src.generated.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
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'; |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 } | 902 } |
903 // For async, give no hint if the return type does not matter, i.e. | 903 // For async, give no hint if the return type does not matter, i.e. |
904 // dynamic, Future<Null> or Future<dynamic>. | 904 // dynamic, Future<Null> or Future<dynamic>. |
905 if (body.isAsynchronous) { | 905 if (body.isAsynchronous) { |
906 if (returnTypeType.isDynamic) { | 906 if (returnTypeType.isDynamic) { |
907 return; | 907 return; |
908 } | 908 } |
909 if (returnTypeType is InterfaceType && | 909 if (returnTypeType is InterfaceType && |
910 returnTypeType.isDartAsyncFuture) { | 910 returnTypeType.isDartAsyncFuture) { |
911 DartType futureArgument = returnTypeType.typeArguments[0]; | 911 DartType futureArgument = returnTypeType.typeArguments[0]; |
912 if (futureArgument.isDynamic || futureArgument.isDartCoreNull) { | 912 if (futureArgument.isDynamic || |
| 913 futureArgument.isDartCoreNull || |
| 914 futureArgument.isObject) { |
913 return; | 915 return; |
914 } | 916 } |
915 } | 917 } |
916 } | 918 } |
917 // Check the block for a return statement, if not, create the hint | 919 // Check the block for a return statement, if not, create the hint |
918 if (!ExitDetector.exits(body)) { | 920 if (!ExitDetector.exits(body)) { |
919 _errorReporter.reportErrorForNode( | 921 _errorReporter.reportErrorForNode( |
920 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); | 922 HintCode.MISSING_RETURN, returnType, [returnTypeType.displayName]); |
921 } | 923 } |
922 } | 924 } |
(...skipping 3257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4180 * Pop a return type off of the return stack. | 4182 * Pop a return type off of the return stack. |
4181 * | 4183 * |
4182 * Also record any inferred return type using [setType], unless this node | 4184 * Also record any inferred return type using [setType], unless this node |
4183 * already has a context type. This recorded type will be the least upper | 4185 * already has a context type. This recorded type will be the least upper |
4184 * bound of all types added with [addReturnOrYieldType]. | 4186 * bound of all types added with [addReturnOrYieldType]. |
4185 */ | 4187 */ |
4186 void popReturnContext(BlockFunctionBody node) { | 4188 void popReturnContext(BlockFunctionBody node) { |
4187 if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) { | 4189 if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) { |
4188 DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance; | 4190 DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance; |
4189 DartType inferred = _inferredReturn.removeLast(); | 4191 DartType inferred = _inferredReturn.removeLast(); |
4190 if (inferred.isBottom) { | 4192 if (inferred.isBottom || inferred.isDartCoreNull) { |
4191 return; | 4193 return; |
4192 } | 4194 } |
4193 | 4195 |
4194 if (context is FutureUnionType) { | 4196 if (context is FutureUnionType) { |
4195 // Try and match the Future type first. | 4197 // Try and match the Future type first. |
4196 if (_typeSystem.isSubtypeOf(inferred, context.futureOfType) || | 4198 if (_typeSystem.isSubtypeOf(inferred, context.futureOfType) || |
4197 _typeSystem.isSubtypeOf(inferred, context.type)) { | 4199 _typeSystem.isSubtypeOf(inferred, context.type)) { |
4198 setType(node, inferred); | 4200 setType(node, inferred); |
4199 } | 4201 } |
4200 } else if (_typeSystem.isSubtypeOf(inferred, context)) { | 4202 } else if (_typeSystem.isSubtypeOf(inferred, context)) { |
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5323 DartType overrideVariable(VariableElement element, DartType potentialType, | 5325 DartType overrideVariable(VariableElement element, DartType potentialType, |
5324 bool allowPrecisionLoss) { | 5326 bool allowPrecisionLoss) { |
5325 // TODO(scheglov) type propagation for instance/top-level fields | 5327 // TODO(scheglov) type propagation for instance/top-level fields |
5326 // was disabled because it depends on the order or visiting. | 5328 // was disabled because it depends on the order or visiting. |
5327 // If both field and its client are in the same unit, and we visit | 5329 // If both field and its client are in the same unit, and we visit |
5328 // the client before the field, then propagated type is not set yet. | 5330 // the client before the field, then propagated type is not set yet. |
5329 if (element is PropertyInducingElement) { | 5331 if (element is PropertyInducingElement) { |
5330 return null; | 5332 return null; |
5331 } | 5333 } |
5332 | 5334 |
5333 if (potentialType == null || potentialType.isBottom) { | 5335 if (potentialType == null || |
| 5336 potentialType.isBottom || |
| 5337 potentialType.isDartCoreNull) { |
5334 return null; | 5338 return null; |
5335 } | 5339 } |
5336 DartType currentType = _overrideManager.getBestType(element); | 5340 DartType currentType = _overrideManager.getBestType(element); |
5337 | 5341 |
5338 if (potentialType == currentType) { | 5342 if (potentialType == currentType) { |
5339 return null; | 5343 return null; |
5340 } | 5344 } |
5341 | 5345 |
5342 // If we aren't allowing precision loss then the third and fourth conditions | 5346 // If we aren't allowing precision loss then the third and fourth conditions |
5343 // check that we aren't losing precision. | 5347 // check that we aren't losing precision. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5381 * If the given [type] is valid, strongly more specific than the | 5385 * If the given [type] is valid, strongly more specific than the |
5382 * existing static type of the given [expression], record it as a propagated | 5386 * existing static type of the given [expression], record it as a propagated |
5383 * type of the given [expression]. Otherwise, reset it to `null`. | 5387 * type of the given [expression]. Otherwise, reset it to `null`. |
5384 * | 5388 * |
5385 * If [hasOldPropagatedType] is `true` then the existing propagated type | 5389 * If [hasOldPropagatedType] is `true` then the existing propagated type |
5386 * should also is checked. | 5390 * should also is checked. |
5387 */ | 5391 */ |
5388 void recordPropagatedTypeIfBetter(Expression expression, DartType type, | 5392 void recordPropagatedTypeIfBetter(Expression expression, DartType type, |
5389 [bool hasOldPropagatedType = false]) { | 5393 [bool hasOldPropagatedType = false]) { |
5390 // Ensure that propagated type invalid. | 5394 // Ensure that propagated type invalid. |
5391 if (strongMode || type == null || type.isDynamic || type.isBottom) { | 5395 if (strongMode || |
| 5396 type == null || |
| 5397 type.isBottom || |
| 5398 type.isDynamic || |
| 5399 type.isDartCoreNull) { |
5392 if (!hasOldPropagatedType) { | 5400 if (!hasOldPropagatedType) { |
5393 expression.propagatedType = null; | 5401 expression.propagatedType = null; |
5394 } | 5402 } |
5395 return; | 5403 return; |
5396 } | 5404 } |
5397 // Ensure that propagated type is more specific than the static type. | 5405 // Ensure that propagated type is more specific than the static type. |
5398 DartType staticType = expression.staticType; | 5406 DartType staticType = expression.staticType; |
5399 if (type == staticType || !type.isMoreSpecificThan(staticType)) { | 5407 if (type == staticType || !type.isMoreSpecificThan(staticType)) { |
5400 expression.propagatedType = null; | 5408 expression.propagatedType = null; |
5401 return; | 5409 return; |
(...skipping 5420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10822 return null; | 10830 return null; |
10823 } | 10831 } |
10824 if (identical(node.staticElement, variable)) { | 10832 if (identical(node.staticElement, variable)) { |
10825 if (node.inSetterContext()) { | 10833 if (node.inSetterContext()) { |
10826 result = true; | 10834 result = true; |
10827 } | 10835 } |
10828 } | 10836 } |
10829 return null; | 10837 return null; |
10830 } | 10838 } |
10831 } | 10839 } |
OLD | NEW |