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

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

Issue 1586813002: fix #25425, more inference of generic methods (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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.element_resolver; 5 library analyzer.src.generated.element_resolver;
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';
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 420
421 @override 421 @override
422 Object visitFunctionDeclaration(FunctionDeclaration node) { 422 Object visitFunctionDeclaration(FunctionDeclaration node) {
423 setMetadata(node.element, node); 423 setMetadata(node.element, node);
424 return null; 424 return null;
425 } 425 }
426 426
427 @override 427 @override
428 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 428 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
429 Expression function = node.function; 429 Expression function = node.function;
430 DartType staticInvokeType = 430 DartType staticInvokeType = _instantiateGenericMethod(
431 _resolveGenericMethod(function.staticType, node.typeArguments, node); 431 function.staticType, node.typeArguments, node);
432 DartType propagatedInvokeType = _resolveGenericMethod( 432 DartType propagatedInvokeType = _instantiateGenericMethod(
433 function.propagatedType, node.typeArguments, node); 433 function.propagatedType, node.typeArguments, node);
434 434
435 node.staticInvokeType = staticInvokeType; 435 node.staticInvokeType = staticInvokeType;
436 node.propagatedInvokeType = 436 node.propagatedInvokeType =
437 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType); 437 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
438 438
439 List<ParameterElement> parameters = 439 List<ParameterElement> parameters =
440 _computeCorrespondingParameters(node.argumentList, staticInvokeType); 440 _computeCorrespondingParameters(node.argumentList, staticInvokeType);
441 if (parameters != null) { 441 if (parameters != null) {
442 node.argumentList.correspondingStaticParameters = parameters; 442 node.argumentList.correspondingStaticParameters = parameters;
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 if (propagatedType is InterfaceType) { 645 if (propagatedType is InterfaceType) {
646 propagatedElement = _resolveInvokedElementWithTarget( 646 propagatedElement = _resolveInvokedElementWithTarget(
647 target, propagatedType, methodName, isConditional); 647 target, propagatedType, methodName, isConditional);
648 } 648 }
649 } 649 }
650 } 650 }
651 651
652 staticElement = _convertSetterToGetter(staticElement); 652 staticElement = _convertSetterToGetter(staticElement);
653 propagatedElement = _convertSetterToGetter(propagatedElement); 653 propagatedElement = _convertSetterToGetter(propagatedElement);
654 654
655 DartType staticInvokeType = _computeMethodInvokeType(node, staticElement); 655 //
656 DartType propagatedInvokeType = 656 // Given the elements, determine the type of the function we are invoking
657 _computeMethodInvokeType(node, propagatedElement); 657 //
658 DartType staticInvokeType = _getInvokeType(staticElement);
659 methodName.staticType = staticInvokeType;
Jennifer Messerly 2016/01/13 22:32:46 This stores the element's type in the methodName n
660
661 DartType propagatedInvokeType = _getInvokeType(propagatedElement);
662 methodName.propagatedType =
663 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
664
665 //
666 // Instantiate generic function or method if needed.
667 //
668 staticInvokeType = _instantiateGenericMethod(
669 staticInvokeType, node.typeArguments, node.methodName);
670 propagatedInvokeType = _instantiateGenericMethod(
671 propagatedInvokeType, node.typeArguments, node.methodName);
658 672
659 // 673 //
660 // Record the results. 674 // Record the results.
661 // 675 //
662 methodName.staticElement = staticElement; 676 methodName.staticElement = staticElement;
663 methodName.propagatedElement = propagatedElement; 677 methodName.propagatedElement = propagatedElement;
664 678
665 node.staticInvokeType = staticInvokeType; 679 node.staticInvokeType = staticInvokeType;
666 // 680 //
667 // Store the propagated invoke type if it's more specific than the static 681 // Store the propagated invoke type if it's more specific than the static
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 if (callMethod != null) { 1345 if (callMethod != null) {
1332 return _resolveArgumentsToFunction(false, argumentList, callMethod); 1346 return _resolveArgumentsToFunction(false, argumentList, callMethod);
1333 } 1347 }
1334 } else if (type is FunctionType) { 1348 } else if (type is FunctionType) {
1335 return _resolveArgumentsToParameters( 1349 return _resolveArgumentsToParameters(
1336 false, argumentList, type.parameters); 1350 false, argumentList, type.parameters);
1337 } 1351 }
1338 return null; 1352 return null;
1339 } 1353 }
1340 1354
1341 DartType _computeMethodInvokeType(MethodInvocation node, Element element) { 1355 /**
1342 if (element == null) { 1356 * Given an element, computes the type of the invocation.
1343 // TODO(jmesserly): should we return `dynamic` in this case? 1357 *
1344 // Otherwise we have to guard against `null` every time we use 1358 * For executable elements (like methods, functions) this is just their type.
1345 // `staticInvokeType`. 1359 * For variables it is their type taking into account any type promotion.
1346 // If we do return `dynamic` we need to be careful that this doesn't 1360 * For getters it is the type that they return.
1347 // adversely affect propagatedType code path. But it shouldn't because 1361 */
1348 // we'll discard `dynamic` anyway (see _propagatedInvokeTypeIfBetter). 1362 DartType _getInvokeType(Element element) {
1349 return null;
1350 }
1351
1352 DartType invokeType; 1363 DartType invokeType;
1353 if (element is PropertyAccessorElement) { 1364 if (element is PropertyAccessorElement) {
1354 invokeType = element.returnType; 1365 invokeType = element.returnType;
1355 } else if (element is ExecutableElement) { 1366 } else if (element is ExecutableElement) {
1356 invokeType = element.type; 1367 invokeType = element.type;
1357 } else if (element is VariableElement) { 1368 } else if (element is VariableElement) {
1358 invokeType = _promoteManager.getStaticType(element); 1369 invokeType = _promoteManager.getStaticType(element);
1359 } 1370 }
1360 1371 return invokeType ?? DynamicTypeImpl.instance;
1361 return _resolveGenericMethod(
1362 invokeType, node.typeArguments, node.methodName);
1363 } 1372 }
1364 1373
1365 /** 1374 /**
1366 * If the given [element] is a setter, return the getter associated with it. 1375 * If the given [element] is a setter, return the getter associated with it.
1367 * Otherwise, return the element unchanged. 1376 * Otherwise, return the element unchanged.
1368 */ 1377 */
1369 Element _convertSetterToGetter(Element element) { 1378 Element _convertSetterToGetter(Element element) {
1370 // TODO(brianwilkerson) Determine whether and why the element could ever be 1379 // TODO(brianwilkerson) Determine whether and why the element could ever be
1371 // a setter. 1380 // a setter.
1372 if (element is PropertyAccessorElement) { 1381 if (element is PropertyAccessorElement) {
(...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after
2078 } 2087 }
2079 if (element != null && element.isAccessibleIn(_definingLibrary)) { 2088 if (element != null && element.isAccessibleIn(_definingLibrary)) {
2080 return element; 2089 return element;
2081 } 2090 }
2082 return null; 2091 return null;
2083 } 2092 }
2084 2093
2085 /** 2094 /**
2086 * Check for a generic method & apply type arguments if any were passed. 2095 * Check for a generic method & apply type arguments if any were passed.
2087 */ 2096 */
2088 DartType _resolveGenericMethod( 2097 DartType _instantiateGenericMethod(
2089 DartType invokeType, TypeArgumentList typeArguments, AstNode node) { 2098 DartType invokeType, TypeArgumentList typeArguments, AstNode node) {
2090 // TODO(jmesserly): support generic "call" methods on InterfaceType. 2099 // TODO(jmesserly): support generic "call" methods on InterfaceType.
2091 if (invokeType is FunctionType) { 2100 if (invokeType is FunctionType) {
2092 FunctionType type = invokeType; 2101 FunctionType type = invokeType;
2093 List<TypeParameterElement> parameters = type.typeFormals; 2102 List<TypeParameterElement> parameters = type.typeFormals;
2094 2103
2095 NodeList<TypeName> arguments = typeArguments?.arguments; 2104 NodeList<TypeName> arguments = typeArguments?.arguments;
2096 if (arguments != null && arguments.length != parameters.length) { 2105 if (arguments != null && arguments.length != parameters.length) {
2097 // Wrong number of type arguments. Ignore them 2106 // Wrong number of type arguments. Ignore them
2098 arguments = null; 2107 arguments = null;
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 2618
2610 @override 2619 @override
2611 Element get staticElement => null; 2620 Element get staticElement => null;
2612 2621
2613 @override 2622 @override
2614 accept(AstVisitor visitor) => null; 2623 accept(AstVisitor visitor) => null;
2615 2624
2616 @override 2625 @override
2617 void visitChildren(AstVisitor visitor) {} 2626 void visitChildren(AstVisitor visitor) {}
2618 } 2627 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698