Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Issue 2208953002: fix #25944, improve Future.then inference (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: cleanup unused code Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.static_type_analyzer; 5 library analyzer.src.generated.static_type_analyzer;
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/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 computedType = _dynamicType; 498 computedType = _dynamicType;
499 } 499 }
500 500
501 // If we had a better type from the function body, use it. 501 // If we had a better type from the function body, use it.
502 // 502 //
503 // This helps in a few cases: 503 // This helps in a few cases:
504 // * ExpressionFunctionBody, when the surrounding context had a better type. 504 // * ExpressionFunctionBody, when the surrounding context had a better type.
505 // * BlockFunctionBody, if we inferred a type from yield/return. 505 // * BlockFunctionBody, if we inferred a type from yield/return.
506 // * we also normalize bottom to dynamic here. 506 // * we also normalize bottom to dynamic here.
507 if (_strongMode && (computedType.isBottom || computedType.isDynamic)) { 507 if (_strongMode && (computedType.isBottom || computedType.isDynamic)) {
508 computedType = InferenceContext.getType(body) ?? _dynamicType; 508 TypeContext contextType = InferenceContext.getType(body);
509 if (contextType is FutureUnionTypeContext) {
510 // TODO(jmesserly): can we do something better here?
511 computedType = body.isAsynchronous ? contextType.type : _dynamicType;
512 } else {
513 computedType = contextType ?? _dynamicType;
514 }
509 recordInference = !computedType.isDynamic; 515 recordInference = !computedType.isDynamic;
510 } 516 }
511 517
512 computedType = _computeReturnTypeOfFunction(body, computedType); 518 computedType = _computeReturnTypeOfFunction(body, computedType);
513 519
514 functionElement.returnType = computedType; 520 functionElement.returnType = computedType;
515 _recordPropagatedTypeOfFunction(functionElement, node.body); 521 _recordPropagatedTypeOfFunction(functionElement, node.body);
516 _recordStaticType(node, functionElement.type); 522 _recordStaticType(node, functionElement.type);
517 if (recordInference) { 523 if (recordInference) {
518 _resolver.inferenceContext.recordInference(node, functionElement.type); 524 _resolver.inferenceContext.recordInference(node, functionElement.type);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 } 664 }
659 } 665 }
660 _recordStaticType( 666 _recordStaticType(
661 node, _typeProvider.listType.instantiate(<DartType>[staticType])); 667 node, _typeProvider.listType.instantiate(<DartType>[staticType]));
662 return null; 668 return null;
663 } 669 }
664 670
665 // If there are no type arguments and we are in strong mode, try to infer 671 // If there are no type arguments and we are in strong mode, try to infer
666 // some arguments. 672 // some arguments.
667 if (_strongMode) { 673 if (_strongMode) {
668 DartType contextType = InferenceContext.getType(node); 674 DartType contextType = InferenceContext.getNonFutureType(node);
669 675
670 // If we have a type from the context, use it. 676 // If we have a type from the context, use it.
671 if (contextType is InterfaceType && 677 if (contextType is InterfaceType &&
672 contextType.typeArguments.length == 1 && 678 contextType.typeArguments.length == 1 &&
673 contextType.element == _typeProvider.listType.element) { 679 contextType.element == _typeProvider.listType.element) {
674 _resolver.inferenceContext.recordInference(node, contextType); 680 _resolver.inferenceContext.recordInference(node, contextType);
675 _recordStaticType(node, contextType); 681 _recordStaticType(node, contextType);
676 return null; 682 return null;
677 } 683 }
678 684
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
741 _recordStaticType( 747 _recordStaticType(
742 node, 748 node,
743 _typeProvider.mapType 749 _typeProvider.mapType
744 .instantiate(<DartType>[staticKeyType, staticValueType])); 750 .instantiate(<DartType>[staticKeyType, staticValueType]));
745 return null; 751 return null;
746 } 752 }
747 753
748 // If we have no explicit type arguments, and we are in strong mode 754 // If we have no explicit type arguments, and we are in strong mode
749 // then try to infer type arguments. 755 // then try to infer type arguments.
750 if (_strongMode) { 756 if (_strongMode) {
751 DartType contextType = InferenceContext.getType(node); 757 DartType contextType = InferenceContext.getNonFutureType(node);
752 // If we have a context type, use that for inference. 758 // If we have a context type, use that for inference.
753 if (contextType is InterfaceType && 759 if (contextType is InterfaceType &&
754 contextType.typeArguments.length == 2 && 760 contextType.typeArguments.length == 2 &&
755 contextType.element == _typeProvider.mapType.element) { 761 contextType.element == _typeProvider.mapType.element) {
756 _resolver.inferenceContext.recordInference(node, contextType); 762 _resolver.inferenceContext.recordInference(node, contextType);
757 _recordStaticType(node, contextType); 763 _recordStaticType(node, contextType);
758 return null; 764 return null;
759 } 765 }
760 766
761 // Otherwise, try to infer a type from the keys and values. 767 // Otherwise, try to infer a type from the keys and values.
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 _getPropertyPropagatedType(staticElement, propagatedType); 1119 _getPropertyPropagatedType(staticElement, propagatedType);
1114 } else if (staticElement is ExecutableElement) { 1120 } else if (staticElement is ExecutableElement) {
1115 staticType = staticElement.type; 1121 staticType = staticElement.type;
1116 } else if (staticElement is TypeParameterElement) { 1122 } else if (staticElement is TypeParameterElement) {
1117 staticType = staticElement.type; 1123 staticType = staticElement.type;
1118 } else if (staticElement is VariableElement) { 1124 } else if (staticElement is VariableElement) {
1119 staticType = staticElement.type; 1125 staticType = staticElement.type;
1120 } 1126 }
1121 if (_strongMode) { 1127 if (_strongMode) {
1122 staticType = _inferGenericInstantiationFromContext( 1128 staticType = _inferGenericInstantiationFromContext(
1123 InferenceContext.getType(node), staticType); 1129 InferenceContext.getNonFutureType(node), staticType);
1124 } 1130 }
1125 if (!(_strongMode && 1131 if (!(_strongMode &&
1126 _inferObjectAccess(node, staticType, prefixedIdentifier))) { 1132 _inferObjectAccess(node, staticType, prefixedIdentifier))) {
1127 _recordStaticType(prefixedIdentifier, staticType); 1133 _recordStaticType(prefixedIdentifier, staticType);
1128 _recordStaticType(node, staticType); 1134 _recordStaticType(node, staticType);
1129 } 1135 }
1130 Element propagatedElement = prefixedIdentifier.propagatedElement; 1136 Element propagatedElement = prefixedIdentifier.propagatedElement;
1131 // HACK: special case for object getters ([hashCode] and [runtimeType]) on 1137 // HACK: special case for object getters ([hashCode] and [runtimeType]) on
1132 // dynamic expressions. More special cases in [visitMethodInvocation]. 1138 // dynamic expressions. More special cases in [visitMethodInvocation].
1133 if (propagatedElement == null) { 1139 if (propagatedElement == null) {
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 DartType staticType = _dynamicType; 1252 DartType staticType = _dynamicType;
1247 if (staticElement is MethodElement) { 1253 if (staticElement is MethodElement) {
1248 staticType = staticElement.type; 1254 staticType = staticElement.type;
1249 } else if (staticElement is PropertyAccessorElement) { 1255 } else if (staticElement is PropertyAccessorElement) {
1250 staticType = _getTypeOfProperty(staticElement); 1256 staticType = _getTypeOfProperty(staticElement);
1251 } else { 1257 } else {
1252 // TODO(brianwilkerson) Report this internal error. 1258 // TODO(brianwilkerson) Report this internal error.
1253 } 1259 }
1254 if (_strongMode) { 1260 if (_strongMode) {
1255 staticType = _inferGenericInstantiationFromContext( 1261 staticType = _inferGenericInstantiationFromContext(
1256 InferenceContext.getType(node), staticType); 1262 InferenceContext.getNonFutureType(node), staticType);
1257 } 1263 }
1258 if (!(_strongMode && _inferObjectAccess(node, staticType, propertyName))) { 1264 if (!(_strongMode && _inferObjectAccess(node, staticType, propertyName))) {
1259 _recordStaticType(propertyName, staticType); 1265 _recordStaticType(propertyName, staticType);
1260 _recordStaticType(node, staticType); 1266 _recordStaticType(node, staticType);
1261 } 1267 }
1262 Element propagatedElement = propertyName.propagatedElement; 1268 Element propagatedElement = propertyName.propagatedElement;
1263 DartType propagatedType = _overrideManager.getType(propagatedElement); 1269 DartType propagatedType = _overrideManager.getType(propagatedElement);
1264 if (propagatedElement is MethodElement) { 1270 if (propagatedElement is MethodElement) {
1265 propagatedType = propagatedElement.type; 1271 propagatedType = propagatedElement.type;
1266 } else if (propagatedElement is PropertyAccessorElement) { 1272 } else if (propagatedElement is PropertyAccessorElement) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 staticType = _promoteManager.getStaticType(variable); 1356 staticType = _promoteManager.getStaticType(variable);
1351 } else if (element is PrefixElement) { 1357 } else if (element is PrefixElement) {
1352 return null; 1358 return null;
1353 } else if (element is DynamicElementImpl) { 1359 } else if (element is DynamicElementImpl) {
1354 staticType = _typeProvider.typeType; 1360 staticType = _typeProvider.typeType;
1355 } else { 1361 } else {
1356 staticType = _dynamicType; 1362 staticType = _dynamicType;
1357 } 1363 }
1358 if (_strongMode) { 1364 if (_strongMode) {
1359 staticType = _inferGenericInstantiationFromContext( 1365 staticType = _inferGenericInstantiationFromContext(
1360 InferenceContext.getType(node), staticType); 1366 InferenceContext.getNonFutureType(node), staticType);
1361 } 1367 }
1362 _recordStaticType(node, staticType); 1368 _recordStaticType(node, staticType);
1363 // TODO(brianwilkerson) I think we want to repeat the logic above using the 1369 // TODO(brianwilkerson) I think we want to repeat the logic above using the
1364 // propagated element to get another candidate for the propagated type. 1370 // propagated element to get another candidate for the propagated type.
1365 DartType propagatedType = _getPropertyPropagatedType(element, null); 1371 DartType propagatedType = _getPropertyPropagatedType(element, null);
1366 if (propagatedType == null) { 1372 if (propagatedType == null) {
1367 DartType overriddenType = _overrideManager.getType(element); 1373 DartType overriddenType = _overrideManager.getType(element);
1368 if (propagatedType == null || 1374 if (propagatedType == null ||
1369 overriddenType != null && 1375 overriddenType != null &&
1370 overriddenType.isMoreSpecificThan(propagatedType)) { 1376 overriddenType.isMoreSpecificThan(propagatedType)) {
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
1964 List<DartType> paramTypes = <DartType>[]; 1970 List<DartType> paramTypes = <DartType>[];
1965 List<DartType> argTypes = <DartType>[]; 1971 List<DartType> argTypes = <DartType>[];
1966 for (int i = 0, length = rawParameters.length; i < length; i++) { 1972 for (int i = 0, length = rawParameters.length; i < length; i++) {
1967 ParameterElement parameter = rawParameters[i]; 1973 ParameterElement parameter = rawParameters[i];
1968 if (parameter != null) { 1974 if (parameter != null) {
1969 paramTypes.add(parameter.type); 1975 paramTypes.add(parameter.type);
1970 argTypes.add(argumentList.arguments[i].staticType); 1976 argTypes.add(argumentList.arguments[i].staticType);
1971 } 1977 }
1972 } 1978 }
1973 1979
1974 return ts.inferGenericFunctionCall(_typeProvider, fnType, paramTypes, 1980 TypeContext returnContext = InferenceContext.getType(node);
1975 argTypes, InferenceContext.getType(node)); 1981 DartType returnType;
1982 if (returnContext is FutureUnionTypeContext) {
1983 returnType = fnType.returnType.isDartAsyncFuture
1984 ? returnContext.futureOfType
1985 : returnContext.type;
1986 } else {
1987 returnType = returnContext as DartType;
1988 }
1989 return ts.inferGenericFunctionCall(
1990 _typeProvider, fnType, paramTypes, argTypes, returnType);
1976 } 1991 }
1977 return null; 1992 return null;
1978 } 1993 }
1979 1994
1980 /** 1995 /**
1981 * Given an instance creation of a possibly generic type, infer the type 1996 * Given an instance creation of a possibly generic type, infer the type
1982 * arguments using the current context type as well as the argument types. 1997 * arguments using the current context type as well as the argument types.
1983 */ 1998 */
1984 void _inferInstanceCreationExpression(InstanceCreationExpression node) { 1999 void _inferInstanceCreationExpression(InstanceCreationExpression node) {
1985 ConstructorName constructor = node.constructorName; 2000 ConstructorName constructor = node.constructorName;
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
2342 } 2357 }
2343 // merge types 2358 // merge types
2344 if (result == null) { 2359 if (result == null) {
2345 result = type; 2360 result = type;
2346 } else { 2361 } else {
2347 result = _typeSystem.getLeastUpperBound(_typeProvider, result, type); 2362 result = _typeSystem.getLeastUpperBound(_typeProvider, result, type);
2348 } 2363 }
2349 return null; 2364 return null;
2350 } 2365 }
2351 } 2366 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698