| 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 engine.resolver.element_resolver; | 5 library engine.resolver.element_resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'ast.dart'; |
| 10 import 'element.dart'; | 10 import 'element.dart'; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 137 String methodName = operatorType.lexeme; | 137 String methodName = operatorType.lexeme; |
| 138 DartType staticType = _getStaticType(leftHandSide); | 138 DartType staticType = _getStaticType(leftHandSide); |
| 139 MethodElement staticMethod = | 139 MethodElement staticMethod = |
| 140 _lookUpMethod(leftHandSide, staticType, methodName); | 140 _lookUpMethod(leftHandSide, staticType, methodName); |
| 141 node.staticElement = staticMethod; | 141 node.staticElement = staticMethod; |
| 142 DartType propagatedType = _getPropagatedType(leftHandSide); | 142 DartType propagatedType = _getPropagatedType(leftHandSide); |
| 143 MethodElement propagatedMethod = | 143 MethodElement propagatedMethod = |
| 144 _lookUpMethod(leftHandSide, propagatedType, methodName); | 144 _lookUpMethod(leftHandSide, propagatedType, methodName); |
| 145 node.propagatedElement = propagatedMethod; | 145 node.propagatedElement = propagatedMethod; |
| 146 if (_shouldReportMissingMember(staticType, staticMethod)) { | 146 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 147 _recordUndefinedToken( | 147 _recordUndefinedToken(staticType.element, |
| 148 staticType.element, | 148 StaticTypeWarningCode.UNDEFINED_METHOD, operator, [ |
| 149 StaticTypeWarningCode.UNDEFINED_METHOD, | 149 methodName, |
| 150 operator, | 150 staticType.displayName |
| 151 [methodName, staticType.displayName]); | 151 ]); |
| 152 } else if (_enableHints && | 152 } else if (_enableHints && |
| 153 _shouldReportMissingMember(propagatedType, propagatedMethod) && | 153 _shouldReportMissingMember(propagatedType, propagatedMethod) && |
| 154 !_memberFoundInSubclass(propagatedType.element, methodName, true, fa
lse)) { | 154 !_memberFoundInSubclass( |
| 155 _recordUndefinedToken( | 155 propagatedType.element, methodName, true, false)) { |
| 156 propagatedType.element, | 156 _recordUndefinedToken(propagatedType.element, |
| 157 HintCode.UNDEFINED_METHOD, | 157 HintCode.UNDEFINED_METHOD, operator, [ |
| 158 operator, | 158 methodName, |
| 159 [methodName, propagatedType.displayName]); | 159 propagatedType.displayName |
| 160 ]); |
| 160 } | 161 } |
| 161 } | 162 } |
| 162 } | 163 } |
| 163 return null; | 164 return null; |
| 164 } | 165 } |
| 165 | 166 |
| 166 @override | 167 @override |
| 167 Object visitBinaryExpression(BinaryExpression node) { | 168 Object visitBinaryExpression(BinaryExpression node) { |
| 168 sc.Token operator = node.operator; | 169 sc.Token operator = node.operator; |
| 169 if (operator.isUserDefinableOperator) { | 170 if (operator.isUserDefinableOperator) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 prefix.staticElement = element; | 247 prefix.staticElement = element; |
| 247 // TODO(brianwilkerson) Report this error? | 248 // TODO(brianwilkerson) Report this error? |
| 248 element = _resolver.nameScope.lookup(identifier, _definingLibrary); | 249 element = _resolver.nameScope.lookup(identifier, _definingLibrary); |
| 249 name.staticElement = element; | 250 name.staticElement = element; |
| 250 return null; | 251 return null; |
| 251 } | 252 } |
| 252 LibraryElement library = element.library; | 253 LibraryElement library = element.library; |
| 253 if (library == null) { | 254 if (library == null) { |
| 254 // TODO(brianwilkerson) We need to understand how the library could | 255 // TODO(brianwilkerson) We need to understand how the library could |
| 255 // ever be null. | 256 // ever be null. |
| 256 AnalysisEngine.instance.logger.logError( | 257 AnalysisEngine.instance.logger |
| 257 "Found element with null library: ${element.name}"); | 258 .logError("Found element with null library: ${element.name}"); |
| 258 } else if (library != _definingLibrary) { | 259 } else if (library != _definingLibrary) { |
| 259 // TODO(brianwilkerson) Report this error. | 260 // TODO(brianwilkerson) Report this error. |
| 260 } | 261 } |
| 261 name.staticElement = element; | 262 name.staticElement = element; |
| 262 if (node.newKeyword == null) { | 263 if (node.newKeyword == null) { |
| 263 if (element is ClassElement) { | 264 if (element is ClassElement) { |
| 264 Element memberElement = | 265 Element memberElement = _lookupGetterOrMethod( |
| 265 _lookupGetterOrMethod((element as ClassElement).type, name.name)
; | 266 (element as ClassElement).type, name.name); |
| 266 if (memberElement == null) { | 267 if (memberElement == null) { |
| 267 memberElement = | 268 memberElement = |
| 268 (element as ClassElement).getNamedConstructor(name.name); | 269 (element as ClassElement).getNamedConstructor(name.name); |
| 269 if (memberElement == null) { | 270 if (memberElement == null) { |
| 270 memberElement = | 271 memberElement = _lookUpSetter( |
| 271 _lookUpSetter(prefix, (element as ClassElement).type, name.n
ame); | 272 prefix, (element as ClassElement).type, name.name); |
| 272 } | 273 } |
| 273 } | 274 } |
| 274 if (memberElement == null) { | 275 if (memberElement == null) { |
| 275 // reportGetterOrSetterNotFound(prefixedIdentifier, name, element.g
etDisplayName()); | 276 // reportGetterOrSetterNotFound(prefixedIdentifier, name, element.g
etDisplayName()); |
| 276 } else { | 277 } else { |
| 277 name.staticElement = memberElement; | 278 name.staticElement = memberElement; |
| 278 } | 279 } |
| 279 } else { | 280 } else { |
| 280 // TODO(brianwilkerson) Report this error. | 281 // TODO(brianwilkerson) Report this error. |
| 281 } | 282 } |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 if (isInGetterContext && isInSetterContext) { | 468 if (isInGetterContext && isInSetterContext) { |
| 468 // lookup setter | 469 // lookup setter |
| 469 MethodElement setterStaticMethod = | 470 MethodElement setterStaticMethod = |
| 470 _lookUpMethod(target, staticType, setterMethodName); | 471 _lookUpMethod(target, staticType, setterMethodName); |
| 471 MethodElement setterPropagatedMethod = | 472 MethodElement setterPropagatedMethod = |
| 472 _lookUpMethod(target, propagatedType, setterMethodName); | 473 _lookUpMethod(target, propagatedType, setterMethodName); |
| 473 // set setter element | 474 // set setter element |
| 474 node.staticElement = setterStaticMethod; | 475 node.staticElement = setterStaticMethod; |
| 475 node.propagatedElement = setterPropagatedMethod; | 476 node.propagatedElement = setterPropagatedMethod; |
| 476 // generate undefined method warning | 477 // generate undefined method warning |
| 477 _checkForUndefinedIndexOperator( | 478 _checkForUndefinedIndexOperator(node, target, getterMethodName, |
| 478 node, | 479 setterStaticMethod, setterPropagatedMethod, staticType, |
| 479 target, | |
| 480 getterMethodName, | |
| 481 setterStaticMethod, | |
| 482 setterPropagatedMethod, | |
| 483 staticType, | |
| 484 propagatedType); | 480 propagatedType); |
| 485 // lookup getter method | 481 // lookup getter method |
| 486 MethodElement getterStaticMethod = | 482 MethodElement getterStaticMethod = |
| 487 _lookUpMethod(target, staticType, getterMethodName); | 483 _lookUpMethod(target, staticType, getterMethodName); |
| 488 MethodElement getterPropagatedMethod = | 484 MethodElement getterPropagatedMethod = |
| 489 _lookUpMethod(target, propagatedType, getterMethodName); | 485 _lookUpMethod(target, propagatedType, getterMethodName); |
| 490 // set getter element | 486 // set getter element |
| 491 AuxiliaryElements auxiliaryElements = | 487 AuxiliaryElements auxiliaryElements = |
| 492 new AuxiliaryElements(getterStaticMethod, getterPropagatedMethod); | 488 new AuxiliaryElements(getterStaticMethod, getterPropagatedMethod); |
| 493 node.auxiliaryElements = auxiliaryElements; | 489 node.auxiliaryElements = auxiliaryElements; |
| 494 // generate undefined method warning | 490 // generate undefined method warning |
| 495 _checkForUndefinedIndexOperator( | 491 _checkForUndefinedIndexOperator(node, target, getterMethodName, |
| 496 node, | 492 getterStaticMethod, getterPropagatedMethod, staticType, |
| 497 target, | |
| 498 getterMethodName, | |
| 499 getterStaticMethod, | |
| 500 getterPropagatedMethod, | |
| 501 staticType, | |
| 502 propagatedType); | 493 propagatedType); |
| 503 } else if (isInGetterContext) { | 494 } else if (isInGetterContext) { |
| 504 // lookup getter method | 495 // lookup getter method |
| 505 MethodElement staticMethod = | 496 MethodElement staticMethod = |
| 506 _lookUpMethod(target, staticType, getterMethodName); | 497 _lookUpMethod(target, staticType, getterMethodName); |
| 507 MethodElement propagatedMethod = | 498 MethodElement propagatedMethod = |
| 508 _lookUpMethod(target, propagatedType, getterMethodName); | 499 _lookUpMethod(target, propagatedType, getterMethodName); |
| 509 // set getter element | 500 // set getter element |
| 510 node.staticElement = staticMethod; | 501 node.staticElement = staticMethod; |
| 511 node.propagatedElement = propagatedMethod; | 502 node.propagatedElement = propagatedMethod; |
| 512 // generate undefined method warning | 503 // generate undefined method warning |
| 513 _checkForUndefinedIndexOperator( | 504 _checkForUndefinedIndexOperator(node, target, getterMethodName, |
| 514 node, | 505 staticMethod, propagatedMethod, staticType, propagatedType); |
| 515 target, | |
| 516 getterMethodName, | |
| 517 staticMethod, | |
| 518 propagatedMethod, | |
| 519 staticType, | |
| 520 propagatedType); | |
| 521 } else if (isInSetterContext) { | 506 } else if (isInSetterContext) { |
| 522 // lookup setter method | 507 // lookup setter method |
| 523 MethodElement staticMethod = | 508 MethodElement staticMethod = |
| 524 _lookUpMethod(target, staticType, setterMethodName); | 509 _lookUpMethod(target, staticType, setterMethodName); |
| 525 MethodElement propagatedMethod = | 510 MethodElement propagatedMethod = |
| 526 _lookUpMethod(target, propagatedType, setterMethodName); | 511 _lookUpMethod(target, propagatedType, setterMethodName); |
| 527 // set setter element | 512 // set setter element |
| 528 node.staticElement = staticMethod; | 513 node.staticElement = staticMethod; |
| 529 node.propagatedElement = propagatedMethod; | 514 node.propagatedElement = propagatedMethod; |
| 530 // generate undefined method warning | 515 // generate undefined method warning |
| 531 _checkForUndefinedIndexOperator( | 516 _checkForUndefinedIndexOperator(node, target, setterMethodName, |
| 532 node, | 517 staticMethod, propagatedMethod, staticType, propagatedType); |
| 533 target, | |
| 534 setterMethodName, | |
| 535 staticMethod, | |
| 536 propagatedMethod, | |
| 537 staticType, | |
| 538 propagatedType); | |
| 539 } | 518 } |
| 540 return null; | 519 return null; |
| 541 } | 520 } |
| 542 | 521 |
| 543 @override | 522 @override |
| 544 Object visitInstanceCreationExpression(InstanceCreationExpression node) { | 523 Object visitInstanceCreationExpression(InstanceCreationExpression node) { |
| 545 ConstructorElement invokedConstructor = node.constructorName.staticElement; | 524 ConstructorElement invokedConstructor = node.constructorName.staticElement; |
| 546 node.staticElement = invokedConstructor; | 525 node.staticElement = invokedConstructor; |
| 547 ArgumentList argumentList = node.argumentList; | 526 ArgumentList argumentList = node.argumentList; |
| 548 List<ParameterElement> parameters = | 527 List<ParameterElement> parameters = _resolveArgumentsToFunction( |
| 549 _resolveArgumentsToFunction(node.isConst, argumentList, invokedConstruct
or); | 528 node.isConst, argumentList, invokedConstructor); |
| 550 if (parameters != null) { | 529 if (parameters != null) { |
| 551 argumentList.correspondingStaticParameters = parameters; | 530 argumentList.correspondingStaticParameters = parameters; |
| 552 } | 531 } |
| 553 return null; | 532 return null; |
| 554 } | 533 } |
| 555 | 534 |
| 556 @override | 535 @override |
| 557 Object visitLibraryDirective(LibraryDirective node) { | 536 Object visitLibraryDirective(LibraryDirective node) { |
| 558 _setMetadata(node.element, node); | 537 _setMetadata(node.element, node); |
| 559 return null; | 538 return null; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 // then we don't call resolveInvokedElement(..) which walks up the class | 582 // then we don't call resolveInvokedElement(..) which walks up the class |
| 604 // hierarchy, instead we just look for the member in the type only. | 583 // hierarchy, instead we just look for the member in the type only. |
| 605 // | 584 // |
| 606 ClassElementImpl typeReference = getTypeReference(target); | 585 ClassElementImpl typeReference = getTypeReference(target); |
| 607 if (typeReference != null) { | 586 if (typeReference != null) { |
| 608 staticElement = | 587 staticElement = |
| 609 propagatedElement = _resolveElement(typeReference, methodName); | 588 propagatedElement = _resolveElement(typeReference, methodName); |
| 610 } else { | 589 } else { |
| 611 staticElement = | 590 staticElement = |
| 612 _resolveInvokedElementWithTarget(target, staticType, methodName); | 591 _resolveInvokedElementWithTarget(target, staticType, methodName); |
| 613 propagatedElement = | 592 propagatedElement = _resolveInvokedElementWithTarget( |
| 614 _resolveInvokedElementWithTarget(target, propagatedType, methodName)
; | 593 target, propagatedType, methodName); |
| 615 } | 594 } |
| 616 } | 595 } |
| 617 staticElement = _convertSetterToGetter(staticElement); | 596 staticElement = _convertSetterToGetter(staticElement); |
| 618 propagatedElement = _convertSetterToGetter(propagatedElement); | 597 propagatedElement = _convertSetterToGetter(propagatedElement); |
| 619 // | 598 // |
| 620 // Record the results. | 599 // Record the results. |
| 621 // | 600 // |
| 622 methodName.staticElement = staticElement; | 601 methodName.staticElement = staticElement; |
| 623 methodName.propagatedElement = propagatedElement; | 602 methodName.propagatedElement = propagatedElement; |
| 624 ArgumentList argumentList = node.argumentList; | 603 ArgumentList argumentList = node.argumentList; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 642 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement); | 621 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement); |
| 643 bool generatedWithTypePropagation = false; | 622 bool generatedWithTypePropagation = false; |
| 644 if (_enableHints && errorCode == null && staticElement == null) { | 623 if (_enableHints && errorCode == null && staticElement == null) { |
| 645 // The method lookup may have failed because there were multiple | 624 // The method lookup may have failed because there were multiple |
| 646 // incompatible choices. In this case we don't want to generate a hint. | 625 // incompatible choices. In this case we don't want to generate a hint. |
| 647 if (propagatedElement == null && propagatedType is UnionType) { | 626 if (propagatedElement == null && propagatedType is UnionType) { |
| 648 // TODO(collinsn): an improvement here is to make the propagated type | 627 // TODO(collinsn): an improvement here is to make the propagated type |
| 649 // of the method call the union of the propagated types of all possible | 628 // of the method call the union of the propagated types of all possible |
| 650 // calls. | 629 // calls. |
| 651 if (_lookupMethods( | 630 if (_lookupMethods( |
| 652 target, | 631 target, propagatedType as UnionType, methodName.name).length > |
| 653 propagatedType as UnionType, | |
| 654 methodName.name).length > | |
| 655 1) { | 632 1) { |
| 656 return null; | 633 return null; |
| 657 } | 634 } |
| 658 } | 635 } |
| 659 errorCode = _checkForInvocationError(target, false, propagatedElement); | 636 errorCode = _checkForInvocationError(target, false, propagatedElement); |
| 660 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 637 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 661 ClassElement classElementContext = null; | 638 ClassElement classElementContext = null; |
| 662 if (target == null) { | 639 if (target == null) { |
| 663 classElementContext = _resolver.enclosingClass; | 640 classElementContext = _resolver.enclosingClass; |
| 664 } else { | 641 } else { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 679 } | 656 } |
| 680 } | 657 } |
| 681 } | 658 } |
| 682 } | 659 } |
| 683 generatedWithTypePropagation = true; | 660 generatedWithTypePropagation = true; |
| 684 } | 661 } |
| 685 if (errorCode == null) { | 662 if (errorCode == null) { |
| 686 return null; | 663 return null; |
| 687 } | 664 } |
| 688 if (identical( | 665 if (identical( |
| 689 errorCode, | 666 errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) { |
| 690 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) { | |
| 691 _resolver.reportErrorForNode( | 667 _resolver.reportErrorForNode( |
| 692 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, | 668 StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [ |
| 693 methodName, | 669 methodName.name |
| 694 [methodName.name]); | 670 ]); |
| 695 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { | 671 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { |
| 696 _resolver.reportErrorForNode( | 672 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_FUNCTION, |
| 697 StaticTypeWarningCode.UNDEFINED_FUNCTION, | 673 methodName, [methodName.name]); |
| 698 methodName, | |
| 699 [methodName.name]); | |
| 700 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { | 674 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { |
| 701 String targetTypeName; | 675 String targetTypeName; |
| 702 if (target == null) { | 676 if (target == null) { |
| 703 ClassElement enclosingClass = _resolver.enclosingClass; | 677 ClassElement enclosingClass = _resolver.enclosingClass; |
| 704 targetTypeName = enclosingClass.displayName; | 678 targetTypeName = enclosingClass.displayName; |
| 705 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? | 679 ErrorCode proxyErrorCode = (generatedWithTypePropagation |
| 706 HintCode.UNDEFINED_METHOD : | 680 ? HintCode.UNDEFINED_METHOD |
| 707 StaticTypeWarningCode.UNDEFINED_METHOD); | 681 : StaticTypeWarningCode.UNDEFINED_METHOD); |
| 708 _recordUndefinedNode( | 682 _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode, |
| 709 _resolver.enclosingClass, | 683 methodName, [methodName.name, targetTypeName]); |
| 710 proxyErrorCode, | |
| 711 methodName, | |
| 712 [methodName.name, targetTypeName]); | |
| 713 } else { | 684 } else { |
| 714 // ignore Function "call" | 685 // ignore Function "call" |
| 715 // (if we are about to create a hint using type propagation, | 686 // (if we are about to create a hint using type propagation, |
| 716 // then we can use type propagation here as well) | 687 // then we can use type propagation here as well) |
| 717 DartType targetType = null; | 688 DartType targetType = null; |
| 718 if (!generatedWithTypePropagation) { | 689 if (!generatedWithTypePropagation) { |
| 719 targetType = _getStaticType(target); | 690 targetType = _getStaticType(target); |
| 720 } else { | 691 } else { |
| 721 // choose the best type | 692 // choose the best type |
| 722 targetType = _getPropagatedType(target); | 693 targetType = _getPropagatedType(target); |
| 723 if (targetType == null) { | 694 if (targetType == null) { |
| 724 targetType = _getStaticType(target); | 695 targetType = _getStaticType(target); |
| 725 } | 696 } |
| 726 } | 697 } |
| 727 if (targetType != null && | 698 if (targetType != null && |
| 728 targetType.isDartCoreFunction && | 699 targetType.isDartCoreFunction && |
| 729 methodName.name == FunctionElement.CALL_METHOD_NAME) { | 700 methodName.name == FunctionElement.CALL_METHOD_NAME) { |
| 730 // TODO(brianwilkerson) Can we ever resolve the function being | 701 // TODO(brianwilkerson) Can we ever resolve the function being |
| 731 // invoked? | 702 // invoked? |
| 732 // resolveArgumentsToParameters(node.getArgumentList(), invokedFunction
); | 703 // resolveArgumentsToParameters(node.getArgumentList(), invokedFunction
); |
| 733 return null; | 704 return null; |
| 734 } | 705 } |
| 735 targetTypeName = targetType == null ? null : targetType.displayName; | 706 targetTypeName = targetType == null ? null : targetType.displayName; |
| 736 ErrorCode proxyErrorCode = (generatedWithTypePropagation ? | 707 ErrorCode proxyErrorCode = (generatedWithTypePropagation |
| 737 HintCode.UNDEFINED_METHOD : | 708 ? HintCode.UNDEFINED_METHOD |
| 738 StaticTypeWarningCode.UNDEFINED_METHOD); | 709 : StaticTypeWarningCode.UNDEFINED_METHOD); |
| 739 _recordUndefinedNode( | 710 _recordUndefinedNode(targetType.element, proxyErrorCode, |
| 740 targetType.element, | 711 methodName, [methodName.name, targetTypeName]); |
| 741 proxyErrorCode, | |
| 742 methodName, | |
| 743 [methodName.name, targetTypeName]); | |
| 744 } | 712 } |
| 745 } else if (identical( | 713 } else if (identical( |
| 746 errorCode, | 714 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { |
| 747 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { | |
| 748 // Generate the type name. | 715 // Generate the type name. |
| 749 // The error code will never be generated via type propagation | 716 // The error code will never be generated via type propagation |
| 750 DartType targetType = _getStaticType(target); | 717 DartType targetType = _getStaticType(target); |
| 751 if (targetType is InterfaceType && !targetType.isObject) { | 718 if (targetType is InterfaceType && !targetType.isObject) { |
| 752 targetType = (targetType as InterfaceType).superclass; | 719 targetType = (targetType as InterfaceType).superclass; |
| 753 } | 720 } |
| 754 String targetTypeName = targetType == null ? null : targetType.name; | 721 String targetTypeName = targetType == null ? null : targetType.name; |
| 755 _resolver.reportErrorForNode( | 722 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, |
| 756 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, | 723 methodName, [methodName.name, targetTypeName]); |
| 757 methodName, | |
| 758 [methodName.name, targetTypeName]); | |
| 759 } | 724 } |
| 760 return null; | 725 return null; |
| 761 } | 726 } |
| 762 | 727 |
| 763 @override | 728 @override |
| 764 Object visitPartDirective(PartDirective node) { | 729 Object visitPartDirective(PartDirective node) { |
| 765 _setMetadata(node.element, node); | 730 _setMetadata(node.element, node); |
| 766 return null; | 731 return null; |
| 767 } | 732 } |
| 768 | 733 |
| 769 @override | 734 @override |
| 770 Object visitPartOfDirective(PartOfDirective node) { | 735 Object visitPartOfDirective(PartOfDirective node) { |
| 771 _setMetadata(node.element, node); | 736 _setMetadata(node.element, node); |
| 772 return null; | 737 return null; |
| 773 } | 738 } |
| 774 | 739 |
| 775 @override | 740 @override |
| 776 Object visitPostfixExpression(PostfixExpression node) { | 741 Object visitPostfixExpression(PostfixExpression node) { |
| 777 Expression operand = node.operand; | 742 Expression operand = node.operand; |
| 778 String methodName = _getPostfixOperator(node); | 743 String methodName = _getPostfixOperator(node); |
| 779 DartType staticType = _getStaticType(operand); | 744 DartType staticType = _getStaticType(operand); |
| 780 MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName); | 745 MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName); |
| 781 node.staticElement = staticMethod; | 746 node.staticElement = staticMethod; |
| 782 DartType propagatedType = _getPropagatedType(operand); | 747 DartType propagatedType = _getPropagatedType(operand); |
| 783 MethodElement propagatedMethod = | 748 MethodElement propagatedMethod = |
| 784 _lookUpMethod(operand, propagatedType, methodName); | 749 _lookUpMethod(operand, propagatedType, methodName); |
| 785 node.propagatedElement = propagatedMethod; | 750 node.propagatedElement = propagatedMethod; |
| 786 if (_shouldReportMissingMember(staticType, staticMethod)) { | 751 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 787 if (operand is SuperExpression) { | 752 if (operand is SuperExpression) { |
| 788 _recordUndefinedToken( | 753 _recordUndefinedToken(staticType.element, |
| 789 staticType.element, | 754 StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR, node.operator, [ |
| 790 StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR, | 755 methodName, |
| 791 node.operator, | 756 staticType.displayName |
| 792 [methodName, staticType.displayName]); | 757 ]); |
| 793 } else { | 758 } else { |
| 794 _recordUndefinedToken( | 759 _recordUndefinedToken(staticType.element, |
| 795 staticType.element, | 760 StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [ |
| 796 StaticTypeWarningCode.UNDEFINED_OPERATOR, | 761 methodName, |
| 797 node.operator, | 762 staticType.displayName |
| 798 [methodName, staticType.displayName]); | 763 ]); |
| 799 } | 764 } |
| 800 } else if (_enableHints && | 765 } else if (_enableHints && |
| 801 _shouldReportMissingMember(propagatedType, propagatedMethod) && | 766 _shouldReportMissingMember(propagatedType, propagatedMethod) && |
| 802 !_memberFoundInSubclass(propagatedType.element, methodName, true, false)
) { | 767 !_memberFoundInSubclass( |
| 803 _recordUndefinedToken( | 768 propagatedType.element, methodName, true, false)) { |
| 804 propagatedType.element, | 769 _recordUndefinedToken(propagatedType.element, HintCode.UNDEFINED_OPERATOR, |
| 805 HintCode.UNDEFINED_OPERATOR, | 770 node.operator, [methodName, propagatedType.displayName]); |
| 806 node.operator, | |
| 807 [methodName, propagatedType.displayName]); | |
| 808 } | 771 } |
| 809 return null; | 772 return null; |
| 810 } | 773 } |
| 811 | 774 |
| 812 @override | 775 @override |
| 813 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 776 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 814 SimpleIdentifier prefix = node.prefix; | 777 SimpleIdentifier prefix = node.prefix; |
| 815 SimpleIdentifier identifier = node.identifier; | 778 SimpleIdentifier identifier = node.identifier; |
| 816 // | 779 // |
| 817 // First, check the "lib.loadLibrary" case | 780 // First, check the "lib.loadLibrary" case |
| 818 // | 781 // |
| 819 if (identifier.name == FunctionElement.LOAD_LIBRARY_NAME && | 782 if (identifier.name == FunctionElement.LOAD_LIBRARY_NAME && |
| 820 _isDeferredPrefix(prefix)) { | 783 _isDeferredPrefix(prefix)) { |
| 821 LibraryElement importedLibrary = _getImportedLibrary(prefix); | 784 LibraryElement importedLibrary = _getImportedLibrary(prefix); |
| 822 identifier.staticElement = importedLibrary.loadLibraryFunction; | 785 identifier.staticElement = importedLibrary.loadLibraryFunction; |
| 823 return null; | 786 return null; |
| 824 } | 787 } |
| 825 // | 788 // |
| 826 // Check to see whether the prefix is really a prefix. | 789 // Check to see whether the prefix is really a prefix. |
| 827 // | 790 // |
| 828 Element prefixElement = prefix.staticElement; | 791 Element prefixElement = prefix.staticElement; |
| 829 if (prefixElement is PrefixElement) { | 792 if (prefixElement is PrefixElement) { |
| 830 Element element = _resolver.nameScope.lookup(node, _definingLibrary); | 793 Element element = _resolver.nameScope.lookup(node, _definingLibrary); |
| 831 if (element == null && identifier.inSetterContext()) { | 794 if (element == null && identifier.inSetterContext()) { |
| 832 element = _resolver.nameScope.lookup( | 795 element = _resolver.nameScope.lookup( |
| 833 new SyntheticIdentifier("${node.name}=", node), | 796 new SyntheticIdentifier("${node.name}=", node), _definingLibrary); |
| 834 _definingLibrary); | |
| 835 } | 797 } |
| 836 if (element == null) { | 798 if (element == null) { |
| 837 if (identifier.inSetterContext()) { | 799 if (identifier.inSetterContext()) { |
| 838 _resolver.reportErrorForNode( | 800 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER, |
| 839 StaticWarningCode.UNDEFINED_SETTER, | 801 identifier, [identifier.name, prefixElement.name]); |
| 840 identifier, | |
| 841 [identifier.name, prefixElement.name]); | |
| 842 } else if (node.parent is Annotation) { | 802 } else if (node.parent is Annotation) { |
| 843 Annotation annotation = node.parent as Annotation; | 803 Annotation annotation = node.parent as Annotation; |
| 844 _resolver.reportErrorForNode( | 804 _resolver.reportErrorForNode( |
| 845 CompileTimeErrorCode.INVALID_ANNOTATION, | 805 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); |
| 846 annotation); | |
| 847 return null; | 806 return null; |
| 848 } else { | 807 } else { |
| 849 _resolver.reportErrorForNode( | 808 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER, |
| 850 StaticWarningCode.UNDEFINED_GETTER, | 809 identifier, [identifier.name, prefixElement.name]); |
| 851 identifier, | |
| 852 [identifier.name, prefixElement.name]); | |
| 853 } | 810 } |
| 854 return null; | 811 return null; |
| 855 } | 812 } |
| 856 if (element is PropertyAccessorElement && identifier.inSetterContext()) { | 813 if (element is PropertyAccessorElement && identifier.inSetterContext()) { |
| 857 PropertyInducingElement variable = | 814 PropertyInducingElement variable = |
| 858 (element as PropertyAccessorElement).variable; | 815 (element as PropertyAccessorElement).variable; |
| 859 if (variable != null) { | 816 if (variable != null) { |
| 860 PropertyAccessorElement setter = variable.setter; | 817 PropertyAccessorElement setter = variable.setter; |
| 861 if (setter != null) { | 818 if (setter != null) { |
| 862 element = setter; | 819 element = setter; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 DartType staticType = _getStaticType(operand); | 856 DartType staticType = _getStaticType(operand); |
| 900 MethodElement staticMethod = | 857 MethodElement staticMethod = |
| 901 _lookUpMethod(operand, staticType, methodName); | 858 _lookUpMethod(operand, staticType, methodName); |
| 902 node.staticElement = staticMethod; | 859 node.staticElement = staticMethod; |
| 903 DartType propagatedType = _getPropagatedType(operand); | 860 DartType propagatedType = _getPropagatedType(operand); |
| 904 MethodElement propagatedMethod = | 861 MethodElement propagatedMethod = |
| 905 _lookUpMethod(operand, propagatedType, methodName); | 862 _lookUpMethod(operand, propagatedType, methodName); |
| 906 node.propagatedElement = propagatedMethod; | 863 node.propagatedElement = propagatedMethod; |
| 907 if (_shouldReportMissingMember(staticType, staticMethod)) { | 864 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 908 if (operand is SuperExpression) { | 865 if (operand is SuperExpression) { |
| 909 _recordUndefinedToken( | 866 _recordUndefinedToken(staticType.element, |
| 910 staticType.element, | 867 StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR, operator, [ |
| 911 StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR, | 868 methodName, |
| 912 operator, | 869 staticType.displayName |
| 913 [methodName, staticType.displayName]); | 870 ]); |
| 914 } else { | 871 } else { |
| 915 _recordUndefinedToken( | 872 _recordUndefinedToken(staticType.element, |
| 916 staticType.element, | 873 StaticTypeWarningCode.UNDEFINED_OPERATOR, operator, [ |
| 917 StaticTypeWarningCode.UNDEFINED_OPERATOR, | 874 methodName, |
| 918 operator, | 875 staticType.displayName |
| 919 [methodName, staticType.displayName]); | 876 ]); |
| 920 } | 877 } |
| 921 } else if (_enableHints && | 878 } else if (_enableHints && |
| 922 _shouldReportMissingMember(propagatedType, propagatedMethod) && | 879 _shouldReportMissingMember(propagatedType, propagatedMethod) && |
| 923 !_memberFoundInSubclass(propagatedType.element, methodName, true, fals
e)) { | 880 !_memberFoundInSubclass( |
| 924 _recordUndefinedToken( | 881 propagatedType.element, methodName, true, false)) { |
| 925 propagatedType.element, | 882 _recordUndefinedToken(propagatedType.element, |
| 926 HintCode.UNDEFINED_OPERATOR, | 883 HintCode.UNDEFINED_OPERATOR, operator, [ |
| 927 operator, | 884 methodName, |
| 928 [methodName, propagatedType.displayName]); | 885 propagatedType.displayName |
| 886 ]); |
| 929 } | 887 } |
| 930 } | 888 } |
| 931 return null; | 889 return null; |
| 932 } | 890 } |
| 933 | 891 |
| 934 @override | 892 @override |
| 935 Object visitPropertyAccess(PropertyAccess node) { | 893 Object visitPropertyAccess(PropertyAccess node) { |
| 936 Expression target = node.realTarget; | 894 Expression target = node.realTarget; |
| 937 if (target is SuperExpression && !_isSuperInValidContext(target)) { | 895 if (target is SuperExpression && !_isSuperInValidContext(target)) { |
| 938 return null; | 896 return null; |
| 939 } | 897 } |
| 940 SimpleIdentifier propertyName = node.propertyName; | 898 SimpleIdentifier propertyName = node.propertyName; |
| 941 _resolvePropertyAccess(target, propertyName); | 899 _resolvePropertyAccess(target, propertyName); |
| 942 return null; | 900 return null; |
| 943 } | 901 } |
| 944 | 902 |
| 945 @override | 903 @override |
| 946 Object | 904 Object visitRedirectingConstructorInvocation( |
| 947 visitRedirectingConstructorInvocation(RedirectingConstructorInvocation nod
e) { | 905 RedirectingConstructorInvocation node) { |
| 948 ClassElement enclosingClass = _resolver.enclosingClass; | 906 ClassElement enclosingClass = _resolver.enclosingClass; |
| 949 if (enclosingClass == null) { | 907 if (enclosingClass == null) { |
| 950 // TODO(brianwilkerson) Report this error. | 908 // TODO(brianwilkerson) Report this error. |
| 951 return null; | 909 return null; |
| 952 } | 910 } |
| 953 SimpleIdentifier name = node.constructorName; | 911 SimpleIdentifier name = node.constructorName; |
| 954 ConstructorElement element; | 912 ConstructorElement element; |
| 955 if (name == null) { | 913 if (name == null) { |
| 956 element = enclosingClass.unnamedConstructor; | 914 element = enclosingClass.unnamedConstructor; |
| 957 } else { | 915 } else { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 return null; | 964 return null; |
| 1007 } | 965 } |
| 1008 // | 966 // |
| 1009 // Otherwise, the node should be resolved. | 967 // Otherwise, the node should be resolved. |
| 1010 // | 968 // |
| 1011 Element element = _resolveSimpleIdentifier(node); | 969 Element element = _resolveSimpleIdentifier(node); |
| 1012 ClassElement enclosingClass = _resolver.enclosingClass; | 970 ClassElement enclosingClass = _resolver.enclosingClass; |
| 1013 if (_isFactoryConstructorReturnType(node) && | 971 if (_isFactoryConstructorReturnType(node) && |
| 1014 !identical(element, enclosingClass)) { | 972 !identical(element, enclosingClass)) { |
| 1015 _resolver.reportErrorForNode( | 973 _resolver.reportErrorForNode( |
| 1016 CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, | 974 CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node); |
| 1017 node); | |
| 1018 } else if (_isConstructorReturnType(node) && | 975 } else if (_isConstructorReturnType(node) && |
| 1019 !identical(element, enclosingClass)) { | 976 !identical(element, enclosingClass)) { |
| 1020 _resolver.reportErrorForNode( | 977 _resolver.reportErrorForNode( |
| 1021 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, | 978 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); |
| 1022 node); | |
| 1023 element = null; | 979 element = null; |
| 1024 } else if (element == null || | 980 } else if (element == null || |
| 1025 (element is PrefixElement && !_isValidAsPrefix(node))) { | 981 (element is PrefixElement && !_isValidAsPrefix(node))) { |
| 1026 // TODO(brianwilkerson) Recover from this error. | 982 // TODO(brianwilkerson) Recover from this error. |
| 1027 if (_isConstructorReturnType(node)) { | 983 if (_isConstructorReturnType(node)) { |
| 1028 _resolver.reportErrorForNode( | 984 _resolver.reportErrorForNode( |
| 1029 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, | 985 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); |
| 1030 node); | |
| 1031 } else if (node.parent is Annotation) { | 986 } else if (node.parent is Annotation) { |
| 1032 Annotation annotation = node.parent as Annotation; | 987 Annotation annotation = node.parent as Annotation; |
| 1033 _resolver.reportErrorForNode( | 988 _resolver.reportErrorForNode( |
| 1034 CompileTimeErrorCode.INVALID_ANNOTATION, | 989 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); |
| 1035 annotation); | |
| 1036 } else { | 990 } else { |
| 1037 _recordUndefinedNode( | 991 _recordUndefinedNode(_resolver.enclosingClass, |
| 1038 _resolver.enclosingClass, | 992 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); |
| 1039 StaticWarningCode.UNDEFINED_IDENTIFIER, | |
| 1040 node, | |
| 1041 [node.name]); | |
| 1042 } | 993 } |
| 1043 } | 994 } |
| 1044 node.staticElement = element; | 995 node.staticElement = element; |
| 1045 if (node.inSetterContext() && | 996 if (node.inSetterContext() && |
| 1046 node.inGetterContext() && | 997 node.inGetterContext() && |
| 1047 enclosingClass != null) { | 998 enclosingClass != null) { |
| 1048 InterfaceType enclosingType = enclosingClass.type; | 999 InterfaceType enclosingType = enclosingClass.type; |
| 1049 AuxiliaryElements auxiliaryElements = | 1000 AuxiliaryElements auxiliaryElements = new AuxiliaryElements( |
| 1050 new AuxiliaryElements(_lookUpGetter(null, enclosingType, node.name), n
ull); | 1001 _lookUpGetter(null, enclosingType, node.name), null); |
| 1051 node.auxiliaryElements = auxiliaryElements; | 1002 node.auxiliaryElements = auxiliaryElements; |
| 1052 } | 1003 } |
| 1053 // | 1004 // |
| 1054 // Validate annotation element. | 1005 // Validate annotation element. |
| 1055 // | 1006 // |
| 1056 if (node.parent is Annotation) { | 1007 if (node.parent is Annotation) { |
| 1057 Annotation annotation = node.parent as Annotation; | 1008 Annotation annotation = node.parent as Annotation; |
| 1058 _resolveAnnotationElement(annotation); | 1009 _resolveAnnotationElement(annotation); |
| 1059 } | 1010 } |
| 1060 return null; | 1011 return null; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1074 } | 1025 } |
| 1075 SimpleIdentifier name = node.constructorName; | 1026 SimpleIdentifier name = node.constructorName; |
| 1076 String superName = name != null ? name.name : null; | 1027 String superName = name != null ? name.name : null; |
| 1077 ConstructorElement element = | 1028 ConstructorElement element = |
| 1078 superType.lookUpConstructor(superName, _definingLibrary); | 1029 superType.lookUpConstructor(superName, _definingLibrary); |
| 1079 if (element == null || | 1030 if (element == null || |
| 1080 (!enclosingClass.mixinErrorsReported && | 1031 (!enclosingClass.mixinErrorsReported && |
| 1081 !enclosingClass.isSuperConstructorAccessible(element))) { | 1032 !enclosingClass.isSuperConstructorAccessible(element))) { |
| 1082 if (name != null) { | 1033 if (name != null) { |
| 1083 _resolver.reportErrorForNode( | 1034 _resolver.reportErrorForNode( |
| 1084 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, | 1035 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, node, [ |
| 1085 node, | 1036 superType.displayName, |
| 1086 [superType.displayName, name]); | 1037 name |
| 1038 ]); |
| 1087 } else { | 1039 } else { |
| 1088 _resolver.reportErrorForNode( | 1040 _resolver.reportErrorForNode( |
| 1089 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, | 1041 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, |
| 1090 node, | 1042 node, [superType.displayName]); |
| 1091 [superType.displayName]); | |
| 1092 } | 1043 } |
| 1093 return null; | 1044 return null; |
| 1094 } else { | 1045 } else { |
| 1095 if (element.isFactory) { | 1046 if (element.isFactory) { |
| 1096 _resolver.reportErrorForNode( | 1047 _resolver.reportErrorForNode( |
| 1097 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, | 1048 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]); |
| 1098 node, | |
| 1099 [element]); | |
| 1100 } | 1049 } |
| 1101 } | 1050 } |
| 1102 if (name != null) { | 1051 if (name != null) { |
| 1103 name.staticElement = element; | 1052 name.staticElement = element; |
| 1104 } | 1053 } |
| 1105 node.staticElement = element; | 1054 node.staticElement = element; |
| 1106 ArgumentList argumentList = node.argumentList; | 1055 ArgumentList argumentList = node.argumentList; |
| 1107 List<ParameterElement> parameters = | 1056 List<ParameterElement> parameters = _resolveArgumentsToFunction( |
| 1108 _resolveArgumentsToFunction(isInConstConstructor, argumentList, element)
; | 1057 isInConstConstructor, argumentList, element); |
| 1109 if (parameters != null) { | 1058 if (parameters != null) { |
| 1110 argumentList.correspondingStaticParameters = parameters; | 1059 argumentList.correspondingStaticParameters = parameters; |
| 1111 } | 1060 } |
| 1112 return null; | 1061 return null; |
| 1113 } | 1062 } |
| 1114 | 1063 |
| 1115 @override | 1064 @override |
| 1116 Object visitSuperExpression(SuperExpression node) { | 1065 Object visitSuperExpression(SuperExpression node) { |
| 1117 if (!_isSuperInValidContext(node)) { | 1066 if (!_isSuperInValidContext(node)) { |
| 1118 _resolver.reportErrorForNode( | 1067 _resolver.reportErrorForNode( |
| 1119 CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, | 1068 CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node); |
| 1120 node); | |
| 1121 } | 1069 } |
| 1122 return super.visitSuperExpression(node); | 1070 return super.visitSuperExpression(node); |
| 1123 } | 1071 } |
| 1124 | 1072 |
| 1125 @override | 1073 @override |
| 1126 Object visitTypeParameter(TypeParameter node) { | 1074 Object visitTypeParameter(TypeParameter node) { |
| 1127 _setMetadata(node.element, node); | 1075 _setMetadata(node.element, node); |
| 1128 return null; | 1076 return null; |
| 1129 } | 1077 } |
| 1130 | 1078 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1158 | 1106 |
| 1159 /** | 1107 /** |
| 1160 * Given that we have found code to invoke the given element, return the error
code that should be | 1108 * Given that we have found code to invoke the given element, return the error
code that should be |
| 1161 * reported, or `null` if no error should be reported. | 1109 * reported, or `null` if no error should be reported. |
| 1162 * | 1110 * |
| 1163 * @param target the target of the invocation, or `null` if there was no targe
t | 1111 * @param target the target of the invocation, or `null` if there was no targe
t |
| 1164 * @param useStaticContext | 1112 * @param useStaticContext |
| 1165 * @param element the element to be invoked | 1113 * @param element the element to be invoked |
| 1166 * @return the error code that should be reported | 1114 * @return the error code that should be reported |
| 1167 */ | 1115 */ |
| 1168 ErrorCode _checkForInvocationError(Expression target, bool useStaticContext, | 1116 ErrorCode _checkForInvocationError( |
| 1169 Element element) { | 1117 Expression target, bool useStaticContext, Element element) { |
| 1170 // Prefix is not declared, instead "prefix.id" are declared. | 1118 // Prefix is not declared, instead "prefix.id" are declared. |
| 1171 if (element is PrefixElement) { | 1119 if (element is PrefixElement) { |
| 1172 element = null; | 1120 element = null; |
| 1173 } | 1121 } |
| 1174 if (element is PropertyAccessorElement) { | 1122 if (element is PropertyAccessorElement) { |
| 1175 // | 1123 // |
| 1176 // This is really a function expression invocation. | 1124 // This is really a function expression invocation. |
| 1177 // | 1125 // |
| 1178 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. | 1126 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. |
| 1179 FunctionType getterType = element.type; | 1127 FunctionType getterType = element.type; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 * Check that the for some index expression that the method element was resolv
ed, otherwise a | 1199 * Check that the for some index expression that the method element was resolv
ed, otherwise a |
| 1252 * [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated. | 1200 * [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated. |
| 1253 * | 1201 * |
| 1254 * @param node the index expression to resolve | 1202 * @param node the index expression to resolve |
| 1255 * @param target the target of the expression | 1203 * @param target the target of the expression |
| 1256 * @param methodName the name of the operator associated with the context of u
sing of the given | 1204 * @param methodName the name of the operator associated with the context of u
sing of the given |
| 1257 * index expression | 1205 * index expression |
| 1258 * @return `true` if and only if an error code is generated on the passed node | 1206 * @return `true` if and only if an error code is generated on the passed node |
| 1259 */ | 1207 */ |
| 1260 bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target, | 1208 bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target, |
| 1261 String methodName, MethodElement staticMethod, MethodElement propagatedMet
hod, | 1209 String methodName, MethodElement staticMethod, |
| 1262 DartType staticType, DartType propagatedType) { | 1210 MethodElement propagatedMethod, DartType staticType, |
| 1211 DartType propagatedType) { |
| 1263 bool shouldReportMissingMember_static = | 1212 bool shouldReportMissingMember_static = |
| 1264 _shouldReportMissingMember(staticType, staticMethod); | 1213 _shouldReportMissingMember(staticType, staticMethod); |
| 1265 bool shouldReportMissingMember_propagated = | 1214 bool shouldReportMissingMember_propagated = |
| 1266 !shouldReportMissingMember_static && | 1215 !shouldReportMissingMember_static && |
| 1267 _enableHints && | 1216 _enableHints && |
| 1268 _shouldReportMissingMember(propagatedType, propagatedMethod) && | 1217 _shouldReportMissingMember(propagatedType, propagatedMethod) && |
| 1269 !_memberFoundInSubclass(propagatedType.element, methodName, true, false)
; | 1218 !_memberFoundInSubclass( |
| 1219 propagatedType.element, methodName, true, false); |
| 1270 if (shouldReportMissingMember_static || | 1220 if (shouldReportMissingMember_static || |
| 1271 shouldReportMissingMember_propagated) { | 1221 shouldReportMissingMember_propagated) { |
| 1272 sc.Token leftBracket = node.leftBracket; | 1222 sc.Token leftBracket = node.leftBracket; |
| 1273 sc.Token rightBracket = node.rightBracket; | 1223 sc.Token rightBracket = node.rightBracket; |
| 1274 ErrorCode errorCode; | 1224 ErrorCode errorCode; |
| 1275 if (shouldReportMissingMember_static) { | 1225 if (shouldReportMissingMember_static) { |
| 1276 if (target is SuperExpression) { | 1226 if (target is SuperExpression) { |
| 1277 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR; | 1227 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR; |
| 1278 } else { | 1228 } else { |
| 1279 errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR; | 1229 errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR; |
| 1280 } | 1230 } |
| 1281 } else { | 1231 } else { |
| 1282 errorCode = HintCode.UNDEFINED_OPERATOR; | 1232 errorCode = HintCode.UNDEFINED_OPERATOR; |
| 1283 } | 1233 } |
| 1284 DartType type = | 1234 DartType type = |
| 1285 shouldReportMissingMember_static ? staticType : propagatedType; | 1235 shouldReportMissingMember_static ? staticType : propagatedType; |
| 1286 if (leftBracket == null || rightBracket == null) { | 1236 if (leftBracket == null || rightBracket == null) { |
| 1287 _recordUndefinedNode( | 1237 _recordUndefinedNode( |
| 1288 type.element, | 1238 type.element, errorCode, node, [methodName, type.displayName]); |
| 1289 errorCode, | |
| 1290 node, | |
| 1291 [methodName, type.displayName]); | |
| 1292 } else { | 1239 } else { |
| 1293 int offset = leftBracket.offset; | 1240 int offset = leftBracket.offset; |
| 1294 int length = rightBracket.offset - offset + 1; | 1241 int length = rightBracket.offset - offset + 1; |
| 1295 _recordUndefinedOffset( | 1242 _recordUndefinedOffset(type.element, errorCode, |
| 1296 type.element, | 1243 offset, length, [methodName, type.displayName]); |
| 1297 errorCode, | |
| 1298 offset, | |
| 1299 length, | |
| 1300 [methodName, type.displayName]); | |
| 1301 } | 1244 } |
| 1302 return true; | 1245 return true; |
| 1303 } | 1246 } |
| 1304 return false; | 1247 return false; |
| 1305 } | 1248 } |
| 1306 | 1249 |
| 1307 /** | 1250 /** |
| 1308 * Given a list of arguments and the element that will be invoked using those
argument, compute | 1251 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 1309 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 1252 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 1310 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 1253 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 1311 * | 1254 * |
| 1312 * @param argumentList the list of arguments being passed to the element | 1255 * @param argumentList the list of arguments being passed to the element |
| 1313 * @param executableElement the element that will be invoked with the argument
s | 1256 * @param executableElement the element that will be invoked with the argument
s |
| 1314 * @return the parameters that correspond to the arguments | 1257 * @return the parameters that correspond to the arguments |
| 1315 */ | 1258 */ |
| 1316 List<ParameterElement> | 1259 List<ParameterElement> _computeCorrespondingParameters( |
| 1317 _computeCorrespondingParameters(ArgumentList argumentList, Element element
) { | 1260 ArgumentList argumentList, Element element) { |
| 1318 if (element is PropertyAccessorElement) { | 1261 if (element is PropertyAccessorElement) { |
| 1319 // | 1262 // |
| 1320 // This is an invocation of the call method defined on the value returned | 1263 // This is an invocation of the call method defined on the value returned |
| 1321 // by the getter. | 1264 // by the getter. |
| 1322 // | 1265 // |
| 1323 FunctionType getterType = element.type; | 1266 FunctionType getterType = element.type; |
| 1324 if (getterType != null) { | 1267 if (getterType != null) { |
| 1325 DartType getterReturnType = getterType.returnType; | 1268 DartType getterReturnType = getterType.returnType; |
| 1326 if (getterReturnType is InterfaceType) { | 1269 if (getterReturnType is InterfaceType) { |
| 1327 MethodElement callMethod = getterReturnType.lookUpMethod( | 1270 MethodElement callMethod = getterReturnType.lookUpMethod( |
| 1328 FunctionElement.CALL_METHOD_NAME, | 1271 FunctionElement.CALL_METHOD_NAME, _definingLibrary); |
| 1329 _definingLibrary); | |
| 1330 if (callMethod != null) { | 1272 if (callMethod != null) { |
| 1331 return _resolveArgumentsToFunction(false, argumentList, callMethod); | 1273 return _resolveArgumentsToFunction(false, argumentList, callMethod); |
| 1332 } | 1274 } |
| 1333 } else if (getterReturnType is FunctionType) { | 1275 } else if (getterReturnType is FunctionType) { |
| 1334 List<ParameterElement> parameters = getterReturnType.parameters; | 1276 List<ParameterElement> parameters = getterReturnType.parameters; |
| 1335 return _resolveArgumentsToParameters(false, argumentList, parameters); | 1277 return _resolveArgumentsToParameters(false, argumentList, parameters); |
| 1336 } | 1278 } |
| 1337 } | 1279 } |
| 1338 } else if (element is ExecutableElement) { | 1280 } else if (element is ExecutableElement) { |
| 1339 return _resolveArgumentsToFunction(false, argumentList, element); | 1281 return _resolveArgumentsToFunction(false, argumentList, element); |
| 1340 } else if (element is VariableElement) { | 1282 } else if (element is VariableElement) { |
| 1341 VariableElement variable = element; | 1283 VariableElement variable = element; |
| 1342 DartType type = _promoteManager.getStaticType(variable); | 1284 DartType type = _promoteManager.getStaticType(variable); |
| 1343 if (type is FunctionType) { | 1285 if (type is FunctionType) { |
| 1344 FunctionType functionType = type; | 1286 FunctionType functionType = type; |
| 1345 List<ParameterElement> parameters = functionType.parameters; | 1287 List<ParameterElement> parameters = functionType.parameters; |
| 1346 return _resolveArgumentsToParameters(false, argumentList, parameters); | 1288 return _resolveArgumentsToParameters(false, argumentList, parameters); |
| 1347 } else if (type is InterfaceType) { | 1289 } else if (type is InterfaceType) { |
| 1348 // "call" invocation | 1290 // "call" invocation |
| 1349 MethodElement callMethod = | 1291 MethodElement callMethod = type.lookUpMethod( |
| 1350 type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary
); | 1292 FunctionElement.CALL_METHOD_NAME, _definingLibrary); |
| 1351 if (callMethod != null) { | 1293 if (callMethod != null) { |
| 1352 List<ParameterElement> parameters = callMethod.parameters; | 1294 List<ParameterElement> parameters = callMethod.parameters; |
| 1353 return _resolveArgumentsToParameters(false, argumentList, parameters); | 1295 return _resolveArgumentsToParameters(false, argumentList, parameters); |
| 1354 } | 1296 } |
| 1355 } | 1297 } |
| 1356 } | 1298 } |
| 1357 return null; | 1299 return null; |
| 1358 } | 1300 } |
| 1359 | 1301 |
| 1360 /** | 1302 /** |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1391 * @param identifier the identifier that might have been imported using a pref
ix | 1333 * @param identifier the identifier that might have been imported using a pref
ix |
| 1392 * @return the element that was found | 1334 * @return the element that was found |
| 1393 */ | 1335 */ |
| 1394 Element _findImportWithoutPrefix(SimpleIdentifier identifier) { | 1336 Element _findImportWithoutPrefix(SimpleIdentifier identifier) { |
| 1395 Element element = null; | 1337 Element element = null; |
| 1396 Scope nameScope = _resolver.nameScope; | 1338 Scope nameScope = _resolver.nameScope; |
| 1397 for (ImportElement importElement in _definingLibrary.imports) { | 1339 for (ImportElement importElement in _definingLibrary.imports) { |
| 1398 PrefixElement prefixElement = importElement.prefix; | 1340 PrefixElement prefixElement = importElement.prefix; |
| 1399 if (prefixElement != null) { | 1341 if (prefixElement != null) { |
| 1400 Identifier prefixedIdentifier = new SyntheticIdentifier( | 1342 Identifier prefixedIdentifier = new SyntheticIdentifier( |
| 1401 "${prefixElement.name}.${identifier.name}", | 1343 "${prefixElement.name}.${identifier.name}", identifier); |
| 1402 identifier); | |
| 1403 Element importedElement = | 1344 Element importedElement = |
| 1404 nameScope.lookup(prefixedIdentifier, _definingLibrary); | 1345 nameScope.lookup(prefixedIdentifier, _definingLibrary); |
| 1405 if (importedElement != null) { | 1346 if (importedElement != null) { |
| 1406 if (element == null) { | 1347 if (element == null) { |
| 1407 element = importedElement; | 1348 element = importedElement; |
| 1408 } else { | 1349 } else { |
| 1409 element = MultiplyDefinedElementImpl.fromElements( | 1350 element = MultiplyDefinedElementImpl.fromElements( |
| 1410 _definingLibrary.context, | 1351 _definingLibrary.context, element, importedElement); |
| 1411 element, | |
| 1412 importedElement); | |
| 1413 } | 1352 } |
| 1414 } | 1353 } |
| 1415 } | 1354 } |
| 1416 } | 1355 } |
| 1417 return element; | 1356 return element; |
| 1418 } | 1357 } |
| 1419 | 1358 |
| 1420 /** | 1359 /** |
| 1421 * Assuming that the given expression is a prefix for a deferred import, retur
n the library that | 1360 * Assuming that the given expression is a prefix for a deferred import, retur
n the library that |
| 1422 * is being imported. | 1361 * is being imported. |
| 1423 * | 1362 * |
| 1424 * @param expression the expression representing the deferred import's prefix | 1363 * @param expression the expression representing the deferred import's prefix |
| 1425 * @return the library that is being imported by the import associated with th
e prefix | 1364 * @return the library that is being imported by the import associated with th
e prefix |
| 1426 */ | 1365 */ |
| 1427 LibraryElement _getImportedLibrary(Expression expression) { | 1366 LibraryElement _getImportedLibrary(Expression expression) { |
| 1428 PrefixElement prefixElement = | 1367 PrefixElement prefixElement = |
| 1429 (expression as SimpleIdentifier).staticElement as PrefixElement; | 1368 (expression as SimpleIdentifier).staticElement as PrefixElement; |
| 1430 List<ImportElement> imports = | 1369 List<ImportElement> imports = |
| 1431 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); | 1370 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); |
| 1432 return imports[0].importedLibrary; | 1371 return imports[0].importedLibrary; |
| 1433 } | 1372 } |
| 1434 | 1373 |
| 1435 /** | 1374 /** |
| 1436 * Return the name of the method invoked by the given postfix expression. | 1375 * Return the name of the method invoked by the given postfix expression. |
| 1437 * | 1376 * |
| 1438 * @param node the postfix expression being invoked | 1377 * @param node the postfix expression being invoked |
| 1439 * @return the name of the method invoked by the expression | 1378 * @return the name of the method invoked by the expression |
| 1440 */ | 1379 */ |
| 1441 String _getPostfixOperator(PostfixExpression node) => | 1380 String _getPostfixOperator(PostfixExpression node) => |
| 1442 (node.operator.type == sc.TokenType.PLUS_PLUS) ? | 1381 (node.operator.type == sc.TokenType.PLUS_PLUS) |
| 1443 sc.TokenType.PLUS.lexeme : | 1382 ? sc.TokenType.PLUS.lexeme |
| 1444 sc.TokenType.MINUS.lexeme; | 1383 : sc.TokenType.MINUS.lexeme; |
| 1445 | 1384 |
| 1446 /** | 1385 /** |
| 1447 * Return the name of the method invoked by the given postfix expression. | 1386 * Return the name of the method invoked by the given postfix expression. |
| 1448 * | 1387 * |
| 1449 * @param node the postfix expression being invoked | 1388 * @param node the postfix expression being invoked |
| 1450 * @return the name of the method invoked by the expression | 1389 * @return the name of the method invoked by the expression |
| 1451 */ | 1390 */ |
| 1452 String _getPrefixOperator(PrefixExpression node) { | 1391 String _getPrefixOperator(PrefixExpression node) { |
| 1453 sc.Token operator = node.operator; | 1392 sc.Token operator = node.operator; |
| 1454 sc.TokenType operatorType = operator.type; | 1393 sc.TokenType operatorType = operator.type; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1541 } else if (type is InterfaceType) { | 1480 } else if (type is InterfaceType) { |
| 1542 ClassElement classElement = type.element; | 1481 ClassElement classElement = type.element; |
| 1543 // 16078 from Gilad: If the type is a Functor with the @proxy annotation, | 1482 // 16078 from Gilad: If the type is a Functor with the @proxy annotation, |
| 1544 // treat it as an executable type. | 1483 // treat it as an executable type. |
| 1545 // example code: NonErrorResolverTest. | 1484 // example code: NonErrorResolverTest. |
| 1546 // test_invocationOfNonFunction_proxyOnFunctionClass() | 1485 // test_invocationOfNonFunction_proxyOnFunctionClass() |
| 1547 if (classElement.isProxy && | 1486 if (classElement.isProxy && |
| 1548 type.isSubtypeOf(_resolver.typeProvider.functionType)) { | 1487 type.isSubtypeOf(_resolver.typeProvider.functionType)) { |
| 1549 return true; | 1488 return true; |
| 1550 } | 1489 } |
| 1551 MethodElement methodElement = | 1490 MethodElement methodElement = classElement.lookUpMethod( |
| 1552 classElement.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingL
ibrary); | 1491 FunctionElement.CALL_METHOD_NAME, _definingLibrary); |
| 1553 return methodElement != null; | 1492 return methodElement != null; |
| 1554 } | 1493 } |
| 1555 return false; | 1494 return false; |
| 1556 } | 1495 } |
| 1557 | 1496 |
| 1558 /** | 1497 /** |
| 1559 * Return `true` if the given element is a static element. | 1498 * Return `true` if the given element is a static element. |
| 1560 * | 1499 * |
| 1561 * @param element the element being tested | 1500 * @param element the element being tested |
| 1562 * @return `true` if the given element is a static element | 1501 * @return `true` if the given element is a static element |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1590 return false; | 1529 return false; |
| 1591 } | 1530 } |
| 1592 | 1531 |
| 1593 /** | 1532 /** |
| 1594 * Return the target of a break or continue statement, and update the static | 1533 * Return the target of a break or continue statement, and update the static |
| 1595 * element of its label (if any). [parentNode] is the AST node of the break | 1534 * element of its label (if any). [parentNode] is the AST node of the break |
| 1596 * or continue statement, [labelNode] is the label contained in that | 1535 * or continue statement, [labelNode] is the label contained in that |
| 1597 * statement (if any), and [isContinue] is true if the node being visited is | 1536 * statement (if any), and [isContinue] is true if the node being visited is |
| 1598 * a continue statement. | 1537 * a continue statement. |
| 1599 */ | 1538 */ |
| 1600 AstNode _lookupBreakOrContinueTarget(AstNode parentNode, | 1539 AstNode _lookupBreakOrContinueTarget( |
| 1601 SimpleIdentifier labelNode, bool isContinue) { | 1540 AstNode parentNode, SimpleIdentifier labelNode, bool isContinue) { |
| 1602 if (labelNode == null) { | 1541 if (labelNode == null) { |
| 1603 return _resolver.implicitLabelScope.getTarget(isContinue); | 1542 return _resolver.implicitLabelScope.getTarget(isContinue); |
| 1604 } else { | 1543 } else { |
| 1605 LabelScope labelScope = _resolver.labelScope; | 1544 LabelScope labelScope = _resolver.labelScope; |
| 1606 if (labelScope == null) { | 1545 if (labelScope == null) { |
| 1607 // There are no labels in scope, so by definition the label is | 1546 // There are no labels in scope, so by definition the label is |
| 1608 // undefined. | 1547 // undefined. |
| 1609 _resolver.reportErrorForNode( | 1548 _resolver.reportErrorForNode( |
| 1610 CompileTimeErrorCode.LABEL_UNDEFINED, | 1549 CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]); |
| 1611 labelNode, | |
| 1612 [labelNode.name]); | |
| 1613 return null; | 1550 return null; |
| 1614 } | 1551 } |
| 1615 LabelScope definingScope = labelScope.lookup(labelNode.name); | 1552 LabelScope definingScope = labelScope.lookup(labelNode.name); |
| 1616 if (definingScope == null) { | 1553 if (definingScope == null) { |
| 1617 // No definition of the given label name could be found in any | 1554 // No definition of the given label name could be found in any |
| 1618 // enclosing scope. | 1555 // enclosing scope. |
| 1619 _resolver.reportErrorForNode( | 1556 _resolver.reportErrorForNode( |
| 1620 CompileTimeErrorCode.LABEL_UNDEFINED, | 1557 CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]); |
| 1621 labelNode, | |
| 1622 [labelNode.name]); | |
| 1623 return null; | 1558 return null; |
| 1624 } | 1559 } |
| 1625 // The target has been found. | 1560 // The target has been found. |
| 1626 labelNode.staticElement = definingScope.element; | 1561 labelNode.staticElement = definingScope.element; |
| 1627 ExecutableElement labelContainer = | 1562 ExecutableElement labelContainer = definingScope.element |
| 1628 definingScope.element.getAncestor((element) => element is ExecutableEl
ement); | 1563 .getAncestor((element) => element is ExecutableElement); |
| 1629 if (!identical(labelContainer, _resolver.enclosingFunction)) { | 1564 if (!identical(labelContainer, _resolver.enclosingFunction)) { |
| 1630 _resolver.reportErrorForNode( | 1565 _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, |
| 1631 CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, | 1566 labelNode, [labelNode.name]); |
| 1632 labelNode, | |
| 1633 [labelNode.name]); | |
| 1634 } | 1567 } |
| 1635 return definingScope.node; | 1568 return definingScope.node; |
| 1636 } | 1569 } |
| 1637 } | 1570 } |
| 1638 | 1571 |
| 1639 /** | 1572 /** |
| 1640 * Look up the getter with the given name in the given type. Return the elemen
t representing the | 1573 * Look up the getter with the given name in the given type. Return the elemen
t representing the |
| 1641 * getter that was found, or `null` if there is no getter with the given name. | 1574 * getter that was found, or `null` if there is no getter with the given name. |
| 1642 * | 1575 * |
| 1643 * @param target the target of the invocation, or `null` if there is no target | 1576 * @param target the target of the invocation, or `null` if there is no target |
| 1644 * @param type the type in which the getter is defined | 1577 * @param type the type in which the getter is defined |
| 1645 * @param getterName the name of the getter being looked up | 1578 * @param getterName the name of the getter being looked up |
| 1646 * @return the element representing the getter that was found | 1579 * @return the element representing the getter that was found |
| 1647 */ | 1580 */ |
| 1648 PropertyAccessorElement _lookUpGetter(Expression target, DartType type, | 1581 PropertyAccessorElement _lookUpGetter( |
| 1649 String getterName) { | 1582 Expression target, DartType type, String getterName) { |
| 1650 type = _resolveTypeParameter(type); | 1583 type = _resolveTypeParameter(type); |
| 1651 if (type is InterfaceType) { | 1584 if (type is InterfaceType) { |
| 1652 InterfaceType interfaceType = type; | 1585 InterfaceType interfaceType = type; |
| 1653 PropertyAccessorElement accessor; | 1586 PropertyAccessorElement accessor; |
| 1654 if (target is SuperExpression) { | 1587 if (target is SuperExpression) { |
| 1655 accessor = | 1588 accessor = interfaceType.lookUpGetterInSuperclass( |
| 1656 interfaceType.lookUpGetterInSuperclass(getterName, _definingLibrary)
; | 1589 getterName, _definingLibrary); |
| 1657 } else { | 1590 } else { |
| 1658 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary); | 1591 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary); |
| 1659 } | 1592 } |
| 1660 if (accessor != null) { | 1593 if (accessor != null) { |
| 1661 return accessor; | 1594 return accessor; |
| 1662 } | 1595 } |
| 1663 return _lookUpGetterInInterfaces( | 1596 return _lookUpGetterInInterfaces( |
| 1664 interfaceType, | 1597 interfaceType, false, getterName, new HashSet<ClassElement>()); |
| 1665 false, | |
| 1666 getterName, | |
| 1667 new HashSet<ClassElement>()); | |
| 1668 } | 1598 } |
| 1669 return null; | 1599 return null; |
| 1670 } | 1600 } |
| 1671 | 1601 |
| 1672 /** | 1602 /** |
| 1673 * Look up the getter with the given name in the interfaces implemented by the
given type, either | 1603 * Look up the getter with the given name in the interfaces implemented by the
given type, either |
| 1674 * directly or indirectly. Return the element representing the getter that was
found, or | 1604 * directly or indirectly. Return the element representing the getter that was
found, or |
| 1675 * `null` if there is no getter with the given name. | 1605 * `null` if there is no getter with the given name. |
| 1676 * | 1606 * |
| 1677 * @param targetType the type in which the getter might be defined | 1607 * @param targetType the type in which the getter might be defined |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1693 return null; | 1623 return null; |
| 1694 } | 1624 } |
| 1695 visitedInterfaces.add(targetClass); | 1625 visitedInterfaces.add(targetClass); |
| 1696 if (includeTargetType) { | 1626 if (includeTargetType) { |
| 1697 PropertyAccessorElement getter = targetType.getGetter(getterName); | 1627 PropertyAccessorElement getter = targetType.getGetter(getterName); |
| 1698 if (getter != null && getter.isAccessibleIn(_definingLibrary)) { | 1628 if (getter != null && getter.isAccessibleIn(_definingLibrary)) { |
| 1699 return getter; | 1629 return getter; |
| 1700 } | 1630 } |
| 1701 } | 1631 } |
| 1702 for (InterfaceType interfaceType in targetType.interfaces) { | 1632 for (InterfaceType interfaceType in targetType.interfaces) { |
| 1703 PropertyAccessorElement getter = | 1633 PropertyAccessorElement getter = _lookUpGetterInInterfaces( |
| 1704 _lookUpGetterInInterfaces(interfaceType, true, getterName, visitedInte
rfaces); | 1634 interfaceType, true, getterName, visitedInterfaces); |
| 1705 if (getter != null) { | 1635 if (getter != null) { |
| 1706 return getter; | 1636 return getter; |
| 1707 } | 1637 } |
| 1708 } | 1638 } |
| 1709 for (InterfaceType mixinType in targetType.mixins.reversed) { | 1639 for (InterfaceType mixinType in targetType.mixins.reversed) { |
| 1710 PropertyAccessorElement getter = | 1640 PropertyAccessorElement getter = _lookUpGetterInInterfaces( |
| 1711 _lookUpGetterInInterfaces(mixinType, true, getterName, visitedInterfac
es); | 1641 mixinType, true, getterName, visitedInterfaces); |
| 1712 if (getter != null) { | 1642 if (getter != null) { |
| 1713 return getter; | 1643 return getter; |
| 1714 } | 1644 } |
| 1715 } | 1645 } |
| 1716 InterfaceType superclass = targetType.superclass; | 1646 InterfaceType superclass = targetType.superclass; |
| 1717 if (superclass == null) { | 1647 if (superclass == null) { |
| 1718 return null; | 1648 return null; |
| 1719 } | 1649 } |
| 1720 return _lookUpGetterInInterfaces( | 1650 return _lookUpGetterInInterfaces( |
| 1721 superclass, | 1651 superclass, true, getterName, visitedInterfaces); |
| 1722 true, | |
| 1723 getterName, | |
| 1724 visitedInterfaces); | |
| 1725 } | 1652 } |
| 1726 | 1653 |
| 1727 /** | 1654 /** |
| 1728 * Look up the method or getter with the given name in the given type. Return
the element | 1655 * Look up the method or getter with the given name in the given type. Return
the element |
| 1729 * representing the method or getter that was found, or `null` if there is no
method or | 1656 * representing the method or getter that was found, or `null` if there is no
method or |
| 1730 * getter with the given name. | 1657 * getter with the given name. |
| 1731 * | 1658 * |
| 1732 * @param type the type in which the method or getter is defined | 1659 * @param type the type in which the method or getter is defined |
| 1733 * @param memberName the name of the method or getter being looked up | 1660 * @param memberName the name of the method or getter being looked up |
| 1734 * @return the element representing the method or getter that was found | 1661 * @return the element representing the method or getter that was found |
| 1735 */ | 1662 */ |
| 1736 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) { | 1663 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) { |
| 1737 type = _resolveTypeParameter(type); | 1664 type = _resolveTypeParameter(type); |
| 1738 if (type is InterfaceType) { | 1665 if (type is InterfaceType) { |
| 1739 InterfaceType interfaceType = type; | 1666 InterfaceType interfaceType = type; |
| 1740 ExecutableElement member = | 1667 ExecutableElement member = |
| 1741 interfaceType.lookUpMethod(memberName, _definingLibrary); | 1668 interfaceType.lookUpMethod(memberName, _definingLibrary); |
| 1742 if (member != null) { | 1669 if (member != null) { |
| 1743 return member; | 1670 return member; |
| 1744 } | 1671 } |
| 1745 member = interfaceType.lookUpGetter(memberName, _definingLibrary); | 1672 member = interfaceType.lookUpGetter(memberName, _definingLibrary); |
| 1746 if (member != null) { | 1673 if (member != null) { |
| 1747 return member; | 1674 return member; |
| 1748 } | 1675 } |
| 1749 return _lookUpGetterOrMethodInInterfaces( | 1676 return _lookUpGetterOrMethodInInterfaces( |
| 1750 interfaceType, | 1677 interfaceType, false, memberName, new HashSet<ClassElement>()); |
| 1751 false, | |
| 1752 memberName, | |
| 1753 new HashSet<ClassElement>()); | |
| 1754 } | 1678 } |
| 1755 return null; | 1679 return null; |
| 1756 } | 1680 } |
| 1757 | 1681 |
| 1758 /** | 1682 /** |
| 1759 * Look up the method or getter with the given name in the interfaces implemen
ted by the given | 1683 * Look up the method or getter with the given name in the interfaces implemen
ted by the given |
| 1760 * type, either directly or indirectly. Return the element representing the me
thod or getter that | 1684 * type, either directly or indirectly. Return the element representing the me
thod or getter that |
| 1761 * was found, or `null` if there is no method or getter with the given name. | 1685 * was found, or `null` if there is no method or getter with the given name. |
| 1762 * | 1686 * |
| 1763 * @param targetType the type in which the method or getter might be defined | 1687 * @param targetType the type in which the method or getter might be defined |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1784 if (member != null) { | 1708 if (member != null) { |
| 1785 return member; | 1709 return member; |
| 1786 } | 1710 } |
| 1787 member = targetType.getGetter(memberName); | 1711 member = targetType.getGetter(memberName); |
| 1788 if (member != null) { | 1712 if (member != null) { |
| 1789 return member; | 1713 return member; |
| 1790 } | 1714 } |
| 1791 } | 1715 } |
| 1792 for (InterfaceType interfaceType in targetType.interfaces) { | 1716 for (InterfaceType interfaceType in targetType.interfaces) { |
| 1793 ExecutableElement member = _lookUpGetterOrMethodInInterfaces( | 1717 ExecutableElement member = _lookUpGetterOrMethodInInterfaces( |
| 1794 interfaceType, | 1718 interfaceType, true, memberName, visitedInterfaces); |
| 1795 true, | |
| 1796 memberName, | |
| 1797 visitedInterfaces); | |
| 1798 if (member != null) { | 1719 if (member != null) { |
| 1799 return member; | 1720 return member; |
| 1800 } | 1721 } |
| 1801 } | 1722 } |
| 1802 for (InterfaceType mixinType in targetType.mixins.reversed) { | 1723 for (InterfaceType mixinType in targetType.mixins.reversed) { |
| 1803 ExecutableElement member = _lookUpGetterOrMethodInInterfaces( | 1724 ExecutableElement member = _lookUpGetterOrMethodInInterfaces( |
| 1804 mixinType, | 1725 mixinType, true, memberName, visitedInterfaces); |
| 1805 true, | |
| 1806 memberName, | |
| 1807 visitedInterfaces); | |
| 1808 if (member != null) { | 1726 if (member != null) { |
| 1809 return member; | 1727 return member; |
| 1810 } | 1728 } |
| 1811 } | 1729 } |
| 1812 InterfaceType superclass = targetType.superclass; | 1730 InterfaceType superclass = targetType.superclass; |
| 1813 if (superclass == null) { | 1731 if (superclass == null) { |
| 1814 return null; | 1732 return null; |
| 1815 } | 1733 } |
| 1816 return _lookUpGetterOrMethodInInterfaces( | 1734 return _lookUpGetterOrMethodInInterfaces( |
| 1817 superclass, | 1735 superclass, true, memberName, visitedInterfaces); |
| 1818 true, | |
| 1819 memberName, | |
| 1820 visitedInterfaces); | |
| 1821 } | 1736 } |
| 1822 | 1737 |
| 1823 /** | 1738 /** |
| 1824 * Look up the method with the given name in the given type. Return the elemen
t representing the | 1739 * Look up the method with the given name in the given type. Return the elemen
t representing the |
| 1825 * method that was found, or `null` if there is no method with the given name. | 1740 * method that was found, or `null` if there is no method with the given name. |
| 1826 * | 1741 * |
| 1827 * @param target the target of the invocation, or `null` if there is no target | 1742 * @param target the target of the invocation, or `null` if there is no target |
| 1828 * @param type the type in which the method is defined | 1743 * @param type the type in which the method is defined |
| 1829 * @param methodName the name of the method being looked up | 1744 * @param methodName the name of the method being looked up |
| 1830 * @return the element representing the method that was found | 1745 * @return the element representing the method that was found |
| 1831 */ | 1746 */ |
| 1832 MethodElement _lookUpMethod(Expression target, DartType type, | 1747 MethodElement _lookUpMethod( |
| 1833 String methodName) { | 1748 Expression target, DartType type, String methodName) { |
| 1834 type = _resolveTypeParameter(type); | 1749 type = _resolveTypeParameter(type); |
| 1835 if (type is InterfaceType) { | 1750 if (type is InterfaceType) { |
| 1836 InterfaceType interfaceType = type; | 1751 InterfaceType interfaceType = type; |
| 1837 MethodElement method; | 1752 MethodElement method; |
| 1838 if (target is SuperExpression) { | 1753 if (target is SuperExpression) { |
| 1839 method = | 1754 method = interfaceType.lookUpMethodInSuperclass( |
| 1840 interfaceType.lookUpMethodInSuperclass(methodName, _definingLibrary)
; | 1755 methodName, _definingLibrary); |
| 1841 } else { | 1756 } else { |
| 1842 method = interfaceType.lookUpMethod(methodName, _definingLibrary); | 1757 method = interfaceType.lookUpMethod(methodName, _definingLibrary); |
| 1843 } | 1758 } |
| 1844 if (method != null) { | 1759 if (method != null) { |
| 1845 return method; | 1760 return method; |
| 1846 } | 1761 } |
| 1847 return _lookUpMethodInInterfaces( | 1762 return _lookUpMethodInInterfaces( |
| 1848 interfaceType, | 1763 interfaceType, false, methodName, new HashSet<ClassElement>()); |
| 1849 false, | |
| 1850 methodName, | |
| 1851 new HashSet<ClassElement>()); | |
| 1852 } else if (type is UnionType) { | 1764 } else if (type is UnionType) { |
| 1853 // TODO (collinsn): I want [computeMergedExecutableElement] to be general | 1765 // TODO (collinsn): I want [computeMergedExecutableElement] to be general |
| 1854 // and work with functions, methods, constructors, and property accessors. | 1766 // and work with functions, methods, constructors, and property accessors. |
| 1855 // However, I won't be able to assume it returns [MethodElement] here | 1767 // However, I won't be able to assume it returns [MethodElement] here |
| 1856 // then. | 1768 // then. |
| 1857 return _maybeMergeExecutableElements( | 1769 return _maybeMergeExecutableElements( |
| 1858 _lookupMethods(target, type, methodName)) as MethodElement; | 1770 _lookupMethods(target, type, methodName)) as MethodElement; |
| 1859 } | 1771 } |
| 1860 return null; | 1772 return null; |
| 1861 } | 1773 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1884 return null; | 1796 return null; |
| 1885 } | 1797 } |
| 1886 visitedInterfaces.add(targetClass); | 1798 visitedInterfaces.add(targetClass); |
| 1887 if (includeTargetType) { | 1799 if (includeTargetType) { |
| 1888 MethodElement method = targetType.getMethod(methodName); | 1800 MethodElement method = targetType.getMethod(methodName); |
| 1889 if (method != null && method.isAccessibleIn(_definingLibrary)) { | 1801 if (method != null && method.isAccessibleIn(_definingLibrary)) { |
| 1890 return method; | 1802 return method; |
| 1891 } | 1803 } |
| 1892 } | 1804 } |
| 1893 for (InterfaceType interfaceType in targetType.interfaces) { | 1805 for (InterfaceType interfaceType in targetType.interfaces) { |
| 1894 MethodElement method = | 1806 MethodElement method = _lookUpMethodInInterfaces( |
| 1895 _lookUpMethodInInterfaces(interfaceType, true, methodName, visitedInte
rfaces); | 1807 interfaceType, true, methodName, visitedInterfaces); |
| 1896 if (method != null) { | 1808 if (method != null) { |
| 1897 return method; | 1809 return method; |
| 1898 } | 1810 } |
| 1899 } | 1811 } |
| 1900 for (InterfaceType mixinType in targetType.mixins.reversed) { | 1812 for (InterfaceType mixinType in targetType.mixins.reversed) { |
| 1901 MethodElement method = | 1813 MethodElement method = _lookUpMethodInInterfaces( |
| 1902 _lookUpMethodInInterfaces(mixinType, true, methodName, visitedInterfac
es); | 1814 mixinType, true, methodName, visitedInterfaces); |
| 1903 if (method != null) { | 1815 if (method != null) { |
| 1904 return method; | 1816 return method; |
| 1905 } | 1817 } |
| 1906 } | 1818 } |
| 1907 InterfaceType superclass = targetType.superclass; | 1819 InterfaceType superclass = targetType.superclass; |
| 1908 if (superclass == null) { | 1820 if (superclass == null) { |
| 1909 return null; | 1821 return null; |
| 1910 } | 1822 } |
| 1911 return _lookUpMethodInInterfaces( | 1823 return _lookUpMethodInInterfaces( |
| 1912 superclass, | 1824 superclass, true, methodName, visitedInterfaces); |
| 1913 true, | |
| 1914 methodName, | |
| 1915 visitedInterfaces); | |
| 1916 } | 1825 } |
| 1917 | 1826 |
| 1918 /** | 1827 /** |
| 1919 * Look up all methods of a given name defined on a union type. | 1828 * Look up all methods of a given name defined on a union type. |
| 1920 * | 1829 * |
| 1921 * @param target | 1830 * @param target |
| 1922 * @param type | 1831 * @param type |
| 1923 * @param methodName | 1832 * @param methodName |
| 1924 * @return all methods named `methodName` defined on the union type `type`. | 1833 * @return all methods named `methodName` defined on the union type `type`. |
| 1925 */ | 1834 */ |
| 1926 Set<ExecutableElement> _lookupMethods(Expression target, UnionType type, | 1835 Set<ExecutableElement> _lookupMethods( |
| 1927 String methodName) { | 1836 Expression target, UnionType type, String methodName) { |
| 1928 Set<ExecutableElement> methods = new HashSet<ExecutableElement>(); | 1837 Set<ExecutableElement> methods = new HashSet<ExecutableElement>(); |
| 1929 bool allElementsHaveMethod = true; | 1838 bool allElementsHaveMethod = true; |
| 1930 for (DartType t in type.elements) { | 1839 for (DartType t in type.elements) { |
| 1931 MethodElement m = _lookUpMethod(target, t, methodName); | 1840 MethodElement m = _lookUpMethod(target, t, methodName); |
| 1932 if (m != null) { | 1841 if (m != null) { |
| 1933 methods.add(m); | 1842 methods.add(m); |
| 1934 } else { | 1843 } else { |
| 1935 allElementsHaveMethod = false; | 1844 allElementsHaveMethod = false; |
| 1936 } | 1845 } |
| 1937 } | 1846 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1950 | 1859 |
| 1951 /** | 1860 /** |
| 1952 * Look up the setter with the given name in the given type. Return the elemen
t representing the | 1861 * Look up the setter with the given name in the given type. Return the elemen
t representing the |
| 1953 * setter that was found, or `null` if there is no setter with the given name. | 1862 * setter that was found, or `null` if there is no setter with the given name. |
| 1954 * | 1863 * |
| 1955 * @param target the target of the invocation, or `null` if there is no target | 1864 * @param target the target of the invocation, or `null` if there is no target |
| 1956 * @param type the type in which the setter is defined | 1865 * @param type the type in which the setter is defined |
| 1957 * @param setterName the name of the setter being looked up | 1866 * @param setterName the name of the setter being looked up |
| 1958 * @return the element representing the setter that was found | 1867 * @return the element representing the setter that was found |
| 1959 */ | 1868 */ |
| 1960 PropertyAccessorElement _lookUpSetter(Expression target, DartType type, | 1869 PropertyAccessorElement _lookUpSetter( |
| 1961 String setterName) { | 1870 Expression target, DartType type, String setterName) { |
| 1962 type = _resolveTypeParameter(type); | 1871 type = _resolveTypeParameter(type); |
| 1963 if (type is InterfaceType) { | 1872 if (type is InterfaceType) { |
| 1964 InterfaceType interfaceType = type; | 1873 InterfaceType interfaceType = type; |
| 1965 PropertyAccessorElement accessor; | 1874 PropertyAccessorElement accessor; |
| 1966 if (target is SuperExpression) { | 1875 if (target is SuperExpression) { |
| 1967 accessor = | 1876 accessor = interfaceType.lookUpSetterInSuperclass( |
| 1968 interfaceType.lookUpSetterInSuperclass(setterName, _definingLibrary)
; | 1877 setterName, _definingLibrary); |
| 1969 } else { | 1878 } else { |
| 1970 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary); | 1879 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary); |
| 1971 } | 1880 } |
| 1972 if (accessor != null) { | 1881 if (accessor != null) { |
| 1973 return accessor; | 1882 return accessor; |
| 1974 } | 1883 } |
| 1975 return _lookUpSetterInInterfaces( | 1884 return _lookUpSetterInInterfaces( |
| 1976 interfaceType, | 1885 interfaceType, false, setterName, new HashSet<ClassElement>()); |
| 1977 false, | |
| 1978 setterName, | |
| 1979 new HashSet<ClassElement>()); | |
| 1980 } | 1886 } |
| 1981 return null; | 1887 return null; |
| 1982 } | 1888 } |
| 1983 | 1889 |
| 1984 /** | 1890 /** |
| 1985 * Look up the setter with the given name in the interfaces implemented by the
given type, either | 1891 * Look up the setter with the given name in the interfaces implemented by the
given type, either |
| 1986 * directly or indirectly. Return the element representing the setter that was
found, or | 1892 * directly or indirectly. Return the element representing the setter that was
found, or |
| 1987 * `null` if there is no setter with the given name. | 1893 * `null` if there is no setter with the given name. |
| 1988 * | 1894 * |
| 1989 * @param targetType the type in which the setter might be defined | 1895 * @param targetType the type in which the setter might be defined |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2005 return null; | 1911 return null; |
| 2006 } | 1912 } |
| 2007 visitedInterfaces.add(targetClass); | 1913 visitedInterfaces.add(targetClass); |
| 2008 if (includeTargetType) { | 1914 if (includeTargetType) { |
| 2009 PropertyAccessorElement setter = targetType.getSetter(setterName); | 1915 PropertyAccessorElement setter = targetType.getSetter(setterName); |
| 2010 if (setter != null && setter.isAccessibleIn(_definingLibrary)) { | 1916 if (setter != null && setter.isAccessibleIn(_definingLibrary)) { |
| 2011 return setter; | 1917 return setter; |
| 2012 } | 1918 } |
| 2013 } | 1919 } |
| 2014 for (InterfaceType interfaceType in targetType.interfaces) { | 1920 for (InterfaceType interfaceType in targetType.interfaces) { |
| 2015 PropertyAccessorElement setter = | 1921 PropertyAccessorElement setter = _lookUpSetterInInterfaces( |
| 2016 _lookUpSetterInInterfaces(interfaceType, true, setterName, visitedInte
rfaces); | 1922 interfaceType, true, setterName, visitedInterfaces); |
| 2017 if (setter != null) { | 1923 if (setter != null) { |
| 2018 return setter; | 1924 return setter; |
| 2019 } | 1925 } |
| 2020 } | 1926 } |
| 2021 for (InterfaceType mixinType in targetType.mixins.reversed) { | 1927 for (InterfaceType mixinType in targetType.mixins.reversed) { |
| 2022 PropertyAccessorElement setter = | 1928 PropertyAccessorElement setter = _lookUpSetterInInterfaces( |
| 2023 _lookUpSetterInInterfaces(mixinType, true, setterName, visitedInterfac
es); | 1929 mixinType, true, setterName, visitedInterfaces); |
| 2024 if (setter != null) { | 1930 if (setter != null) { |
| 2025 return setter; | 1931 return setter; |
| 2026 } | 1932 } |
| 2027 } | 1933 } |
| 2028 InterfaceType superclass = targetType.superclass; | 1934 InterfaceType superclass = targetType.superclass; |
| 2029 if (superclass == null) { | 1935 if (superclass == null) { |
| 2030 return null; | 1936 return null; |
| 2031 } | 1937 } |
| 2032 return _lookUpSetterInInterfaces( | 1938 return _lookUpSetterInInterfaces( |
| 2033 superclass, | 1939 superclass, true, setterName, visitedInterfaces); |
| 2034 true, | |
| 2035 setterName, | |
| 2036 visitedInterfaces); | |
| 2037 } | 1940 } |
| 2038 | 1941 |
| 2039 /** | 1942 /** |
| 2040 * Given some class element, this method uses [subtypeManager] to find the set
of all | 1943 * Given some class element, this method uses [subtypeManager] to find the set
of all |
| 2041 * subtypes; the subtypes are then searched for a member (method, getter, or s
etter), that matches | 1944 * subtypes; the subtypes are then searched for a member (method, getter, or s
etter), that matches |
| 2042 * a passed | 1945 * a passed |
| 2043 * | 1946 * |
| 2044 * @param element the class element to search the subtypes of, if a non-ClassE
lement element is | 1947 * @param element the class element to search the subtypes of, if a non-ClassE
lement element is |
| 2045 * passed, then `false` is returned | 1948 * passed, then `false` is returned |
| 2046 * @param memberName the member name to search for | 1949 * @param memberName the member name to search for |
| 2047 * @param asMethod `true` if the methods should be searched for in the subtype
s | 1950 * @param asMethod `true` if the methods should be searched for in the subtype
s |
| 2048 * @param asAccessor `true` if the accessors (getters and setters) should be s
earched for in | 1951 * @param asAccessor `true` if the accessors (getters and setters) should be s
earched for in |
| 2049 * the subtypes | 1952 * the subtypes |
| 2050 * @return `true` if and only if the passed memberName was found in a subtype | 1953 * @return `true` if and only if the passed memberName was found in a subtype |
| 2051 */ | 1954 */ |
| 2052 bool _memberFoundInSubclass(Element element, String memberName, bool asMethod, | 1955 bool _memberFoundInSubclass( |
| 2053 bool asAccessor) { | 1956 Element element, String memberName, bool asMethod, bool asAccessor) { |
| 2054 if (element is ClassElement) { | 1957 if (element is ClassElement) { |
| 2055 _subtypeManager.ensureLibraryVisited(_definingLibrary); | 1958 _subtypeManager.ensureLibraryVisited(_definingLibrary); |
| 2056 HashSet<ClassElement> subtypeElements = | 1959 HashSet<ClassElement> subtypeElements = |
| 2057 _subtypeManager.computeAllSubtypes(element); | 1960 _subtypeManager.computeAllSubtypes(element); |
| 2058 for (ClassElement subtypeElement in subtypeElements) { | 1961 for (ClassElement subtypeElement in subtypeElements) { |
| 2059 if (asMethod && subtypeElement.getMethod(memberName) != null) { | 1962 if (asMethod && subtypeElement.getMethod(memberName) != null) { |
| 2060 return true; | 1963 return true; |
| 2061 } else if (asAccessor && | 1964 } else if (asAccessor && |
| 2062 (subtypeElement.getGetter(memberName) != null || | 1965 (subtypeElement.getGetter(memberName) != null || |
| 2063 subtypeElement.getSetter(memberName) != null)) { | 1966 subtypeElement.getSetter(memberName) != null)) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2151 * @param token the token which is undefined. | 2054 * @param token the token which is undefined. |
| 2152 * @param arguments arguments to the error message. | 2055 * @param arguments arguments to the error message. |
| 2153 */ | 2056 */ |
| 2154 void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode, | 2057 void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode, |
| 2155 sc.Token token, List<Object> arguments) { | 2058 sc.Token token, List<Object> arguments) { |
| 2156 if (_doesntHaveProxy(declaringElement)) { | 2059 if (_doesntHaveProxy(declaringElement)) { |
| 2157 _resolver.reportErrorForToken(errorCode, token, arguments); | 2060 _resolver.reportErrorForToken(errorCode, token, arguments); |
| 2158 } | 2061 } |
| 2159 } | 2062 } |
| 2160 | 2063 |
| 2161 void _resolveAnnotationConstructorInvocationArguments(Annotation annotation, | 2064 void _resolveAnnotationConstructorInvocationArguments( |
| 2162 ConstructorElement constructor) { | 2065 Annotation annotation, ConstructorElement constructor) { |
| 2163 ArgumentList argumentList = annotation.arguments; | 2066 ArgumentList argumentList = annotation.arguments; |
| 2164 // error will be reported in ConstantVerifier | 2067 // error will be reported in ConstantVerifier |
| 2165 if (argumentList == null) { | 2068 if (argumentList == null) { |
| 2166 return; | 2069 return; |
| 2167 } | 2070 } |
| 2168 // resolve arguments to parameters | 2071 // resolve arguments to parameters |
| 2169 List<ParameterElement> parameters = | 2072 List<ParameterElement> parameters = |
| 2170 _resolveArgumentsToFunction(true, argumentList, constructor); | 2073 _resolveArgumentsToFunction(true, argumentList, constructor); |
| 2171 if (parameters != null) { | 2074 if (parameters != null) { |
| 2172 argumentList.correspondingStaticParameters = parameters; | 2075 argumentList.correspondingStaticParameters = parameters; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2200 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { | 2103 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { |
| 2201 Element element1 = nameNode1.staticElement; | 2104 Element element1 = nameNode1.staticElement; |
| 2202 // CONST | 2105 // CONST |
| 2203 if (element1 is PropertyAccessorElement) { | 2106 if (element1 is PropertyAccessorElement) { |
| 2204 _resolveAnnotationElementGetter(annotation, element1); | 2107 _resolveAnnotationElementGetter(annotation, element1); |
| 2205 return; | 2108 return; |
| 2206 } | 2109 } |
| 2207 // Class(args) | 2110 // Class(args) |
| 2208 if (element1 is ClassElement) { | 2111 if (element1 is ClassElement) { |
| 2209 ClassElement classElement = element1; | 2112 ClassElement classElement = element1; |
| 2210 constructor = new InterfaceTypeImpl.con1( | 2113 constructor = new InterfaceTypeImpl.con1(classElement) |
| 2211 classElement).lookUpConstructor(null, _definingLibrary); | 2114 .lookUpConstructor(null, _definingLibrary); |
| 2212 } | 2115 } |
| 2213 } | 2116 } |
| 2214 // | 2117 // |
| 2215 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) | 2118 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) |
| 2216 // | 2119 // |
| 2217 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { | 2120 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { |
| 2218 Element element1 = nameNode1.staticElement; | 2121 Element element1 = nameNode1.staticElement; |
| 2219 Element element2 = nameNode2.staticElement; | 2122 Element element2 = nameNode2.staticElement; |
| 2220 // Class.CONST - not resolved yet | 2123 // Class.CONST - not resolved yet |
| 2221 if (element1 is ClassElement) { | 2124 if (element1 is ClassElement) { |
| 2222 ClassElement classElement = element1; | 2125 ClassElement classElement = element1; |
| 2223 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); | 2126 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary); |
| 2224 } | 2127 } |
| 2225 // prefix.CONST or Class.CONST | 2128 // prefix.CONST or Class.CONST |
| 2226 if (element2 is PropertyAccessorElement) { | 2129 if (element2 is PropertyAccessorElement) { |
| 2227 nameNode2.staticElement = element2; | 2130 nameNode2.staticElement = element2; |
| 2228 annotation.element = element2; | 2131 annotation.element = element2; |
| 2229 _resolveAnnotationElementGetter( | 2132 _resolveAnnotationElementGetter( |
| 2230 annotation, | 2133 annotation, element2 as PropertyAccessorElement); |
| 2231 element2 as PropertyAccessorElement); | |
| 2232 return; | 2134 return; |
| 2233 } | 2135 } |
| 2234 // prefix.Class() | 2136 // prefix.Class() |
| 2235 if (element2 is ClassElement) { | 2137 if (element2 is ClassElement) { |
| 2236 ClassElement classElement = element2 as ClassElement; | 2138 ClassElement classElement = element2 as ClassElement; |
| 2237 constructor = classElement.unnamedConstructor; | 2139 constructor = classElement.unnamedConstructor; |
| 2238 } | 2140 } |
| 2239 // Class.constructor(args) | 2141 // Class.constructor(args) |
| 2240 if (element1 is ClassElement) { | 2142 if (element1 is ClassElement) { |
| 2241 ClassElement classElement = element1; | 2143 ClassElement classElement = element1; |
| 2242 constructor = new InterfaceTypeImpl.con1( | 2144 constructor = new InterfaceTypeImpl.con1(classElement) |
| 2243 classElement).lookUpConstructor(nameNode2.name, _definingLibrary); | 2145 .lookUpConstructor(nameNode2.name, _definingLibrary); |
| 2244 nameNode2.staticElement = constructor; | 2146 nameNode2.staticElement = constructor; |
| 2245 } | 2147 } |
| 2246 } | 2148 } |
| 2247 // | 2149 // |
| 2248 // prefix.Class.CONST or prefix.Class.constructor(args) | 2150 // prefix.Class.CONST or prefix.Class.constructor(args) |
| 2249 // | 2151 // |
| 2250 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { | 2152 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { |
| 2251 Element element2 = nameNode2.staticElement; | 2153 Element element2 = nameNode2.staticElement; |
| 2252 // element2 should be ClassElement | 2154 // element2 should be ClassElement |
| 2253 if (element2 is ClassElement) { | 2155 if (element2 is ClassElement) { |
| 2254 ClassElement classElement = element2; | 2156 ClassElement classElement = element2; |
| 2255 String name3 = nameNode3.name; | 2157 String name3 = nameNode3.name; |
| 2256 // prefix.Class.CONST | 2158 // prefix.Class.CONST |
| 2257 PropertyAccessorElement getter = | 2159 PropertyAccessorElement getter = |
| 2258 classElement.lookUpGetter(name3, _definingLibrary); | 2160 classElement.lookUpGetter(name3, _definingLibrary); |
| 2259 if (getter != null) { | 2161 if (getter != null) { |
| 2260 nameNode3.staticElement = getter; | 2162 nameNode3.staticElement = getter; |
| 2261 annotation.element = element2; | 2163 annotation.element = element2; |
| 2262 _resolveAnnotationElementGetter(annotation, getter); | 2164 _resolveAnnotationElementGetter(annotation, getter); |
| 2263 return; | 2165 return; |
| 2264 } | 2166 } |
| 2265 // prefix.Class.constructor(args) | 2167 // prefix.Class.constructor(args) |
| 2266 constructor = new InterfaceTypeImpl.con1( | 2168 constructor = new InterfaceTypeImpl.con1(classElement) |
| 2267 classElement).lookUpConstructor(name3, _definingLibrary); | 2169 .lookUpConstructor(name3, _definingLibrary); |
| 2268 nameNode3.staticElement = constructor; | 2170 nameNode3.staticElement = constructor; |
| 2269 } | 2171 } |
| 2270 } | 2172 } |
| 2271 // we need constructor | 2173 // we need constructor |
| 2272 if (constructor == null) { | 2174 if (constructor == null) { |
| 2273 _resolver.reportErrorForNode( | 2175 _resolver.reportErrorForNode( |
| 2274 CompileTimeErrorCode.INVALID_ANNOTATION, | 2176 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); |
| 2275 annotation); | |
| 2276 return; | 2177 return; |
| 2277 } | 2178 } |
| 2278 // record element | 2179 // record element |
| 2279 annotation.element = constructor; | 2180 annotation.element = constructor; |
| 2280 // resolve arguments | 2181 // resolve arguments |
| 2281 _resolveAnnotationConstructorInvocationArguments(annotation, constructor); | 2182 _resolveAnnotationConstructorInvocationArguments(annotation, constructor); |
| 2282 } | 2183 } |
| 2283 | 2184 |
| 2284 void _resolveAnnotationElementGetter(Annotation annotation, | 2185 void _resolveAnnotationElementGetter( |
| 2285 PropertyAccessorElement accessorElement) { | 2186 Annotation annotation, PropertyAccessorElement accessorElement) { |
| 2286 // accessor should be synthetic | 2187 // accessor should be synthetic |
| 2287 if (!accessorElement.isSynthetic) { | 2188 if (!accessorElement.isSynthetic) { |
| 2288 _resolver.reportErrorForNode( | 2189 _resolver.reportErrorForNode( |
| 2289 CompileTimeErrorCode.INVALID_ANNOTATION, | 2190 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); |
| 2290 annotation); | |
| 2291 return; | 2191 return; |
| 2292 } | 2192 } |
| 2293 // variable should be constant | 2193 // variable should be constant |
| 2294 VariableElement variableElement = accessorElement.variable; | 2194 VariableElement variableElement = accessorElement.variable; |
| 2295 if (!variableElement.isConst) { | 2195 if (!variableElement.isConst) { |
| 2296 _resolver.reportErrorForNode( | 2196 _resolver.reportErrorForNode( |
| 2297 CompileTimeErrorCode.INVALID_ANNOTATION, | 2197 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); |
| 2298 annotation); | |
| 2299 } | 2198 } |
| 2300 // OK | 2199 // OK |
| 2301 return; | 2200 return; |
| 2302 } | 2201 } |
| 2303 | 2202 |
| 2304 /** | 2203 /** |
| 2305 * Given a list of arguments and the element that will be invoked using those
argument, compute | 2204 * Given a list of arguments and the element that will be invoked using those
argument, compute |
| 2306 * the list of parameters that correspond to the list of arguments. Return the
parameters that | 2205 * the list of parameters that correspond to the list of arguments. Return the
parameters that |
| 2307 * correspond to the arguments, or `null` if no correspondence could be comput
ed. | 2206 * correspond to the arguments, or `null` if no correspondence could be comput
ed. |
| 2308 * | 2207 * |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2360 int positionalArgumentCount = 0; | 2259 int positionalArgumentCount = 0; |
| 2361 HashSet<String> usedNames = new HashSet<String>(); | 2260 HashSet<String> usedNames = new HashSet<String>(); |
| 2362 bool noBlankArguments = true; | 2261 bool noBlankArguments = true; |
| 2363 for (int i = 0; i < argumentCount; i++) { | 2262 for (int i = 0; i < argumentCount; i++) { |
| 2364 Expression argument = arguments[i]; | 2263 Expression argument = arguments[i]; |
| 2365 if (argument is NamedExpression) { | 2264 if (argument is NamedExpression) { |
| 2366 SimpleIdentifier nameNode = argument.name.label; | 2265 SimpleIdentifier nameNode = argument.name.label; |
| 2367 String name = nameNode.name; | 2266 String name = nameNode.name; |
| 2368 ParameterElement element = namedParameters[name]; | 2267 ParameterElement element = namedParameters[name]; |
| 2369 if (element == null) { | 2268 if (element == null) { |
| 2370 ErrorCode errorCode = (reportError ? | 2269 ErrorCode errorCode = (reportError |
| 2371 CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER : | 2270 ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER |
| 2372 StaticWarningCode.UNDEFINED_NAMED_PARAMETER); | 2271 : StaticWarningCode.UNDEFINED_NAMED_PARAMETER); |
| 2373 _resolver.reportErrorForNode(errorCode, nameNode, [name]); | 2272 _resolver.reportErrorForNode(errorCode, nameNode, [name]); |
| 2374 } else { | 2273 } else { |
| 2375 resolvedParameters[i] = element; | 2274 resolvedParameters[i] = element; |
| 2376 nameNode.staticElement = element; | 2275 nameNode.staticElement = element; |
| 2377 } | 2276 } |
| 2378 if (!usedNames.add(name)) { | 2277 if (!usedNames.add(name)) { |
| 2379 _resolver.reportErrorForNode( | 2278 _resolver.reportErrorForNode( |
| 2380 CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, | 2279 CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]); |
| 2381 nameNode, | |
| 2382 [name]); | |
| 2383 } | 2280 } |
| 2384 } else { | 2281 } else { |
| 2385 if (argument is SimpleIdentifier && argument.name.isEmpty) { | 2282 if (argument is SimpleIdentifier && argument.name.isEmpty) { |
| 2386 noBlankArguments = false; | 2283 noBlankArguments = false; |
| 2387 } | 2284 } |
| 2388 positionalArgumentCount++; | 2285 positionalArgumentCount++; |
| 2389 if (unnamedIndex < unnamedParameterCount) { | 2286 if (unnamedIndex < unnamedParameterCount) { |
| 2390 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; | 2287 resolvedParameters[i] = unnamedParameters[unnamedIndex++]; |
| 2391 } | 2288 } |
| 2392 } | 2289 } |
| 2393 } | 2290 } |
| 2394 if (positionalArgumentCount < requiredParameters.length && | 2291 if (positionalArgumentCount < requiredParameters.length && |
| 2395 noBlankArguments) { | 2292 noBlankArguments) { |
| 2396 ErrorCode errorCode = (reportError ? | 2293 ErrorCode errorCode = (reportError |
| 2397 CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS : | 2294 ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS |
| 2398 StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS); | 2295 : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS); |
| 2399 _resolver.reportErrorForNode( | 2296 _resolver.reportErrorForNode(errorCode, argumentList, |
| 2400 errorCode, | |
| 2401 argumentList, | |
| 2402 [requiredParameters.length, positionalArgumentCount]); | 2297 [requiredParameters.length, positionalArgumentCount]); |
| 2403 } else if (positionalArgumentCount > unnamedParameterCount && | 2298 } else if (positionalArgumentCount > unnamedParameterCount && |
| 2404 noBlankArguments) { | 2299 noBlankArguments) { |
| 2405 ErrorCode errorCode = (reportError ? | 2300 ErrorCode errorCode = (reportError |
| 2406 CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS : | 2301 ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS |
| 2407 StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS); | 2302 : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS); |
| 2408 _resolver.reportErrorForNode( | 2303 _resolver.reportErrorForNode(errorCode, argumentList, |
| 2409 errorCode, | |
| 2410 argumentList, | |
| 2411 [unnamedParameterCount, positionalArgumentCount]); | 2304 [unnamedParameterCount, positionalArgumentCount]); |
| 2412 } | 2305 } |
| 2413 return resolvedParameters; | 2306 return resolvedParameters; |
| 2414 } | 2307 } |
| 2415 | 2308 |
| 2416 void _resolveBinaryExpression(BinaryExpression node, String methodName) { | 2309 void _resolveBinaryExpression(BinaryExpression node, String methodName) { |
| 2417 Expression leftOperand = node.leftOperand; | 2310 Expression leftOperand = node.leftOperand; |
| 2418 if (leftOperand != null) { | 2311 if (leftOperand != null) { |
| 2419 DartType staticType = _getStaticType(leftOperand); | 2312 DartType staticType = _getStaticType(leftOperand); |
| 2420 MethodElement staticMethod = | 2313 MethodElement staticMethod = |
| 2421 _lookUpMethod(leftOperand, staticType, methodName); | 2314 _lookUpMethod(leftOperand, staticType, methodName); |
| 2422 node.staticElement = staticMethod; | 2315 node.staticElement = staticMethod; |
| 2423 DartType propagatedType = _getPropagatedType(leftOperand); | 2316 DartType propagatedType = _getPropagatedType(leftOperand); |
| 2424 MethodElement propagatedMethod = | 2317 MethodElement propagatedMethod = |
| 2425 _lookUpMethod(leftOperand, propagatedType, methodName); | 2318 _lookUpMethod(leftOperand, propagatedType, methodName); |
| 2426 node.propagatedElement = propagatedMethod; | 2319 node.propagatedElement = propagatedMethod; |
| 2427 if (_shouldReportMissingMember(staticType, staticMethod)) { | 2320 if (_shouldReportMissingMember(staticType, staticMethod)) { |
| 2428 if (leftOperand is SuperExpression) { | 2321 if (leftOperand is SuperExpression) { |
| 2429 _recordUndefinedToken( | 2322 _recordUndefinedToken(staticType.element, |
| 2430 staticType.element, | 2323 StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR, node.operator, [ |
| 2431 StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR, | 2324 methodName, |
| 2432 node.operator, | 2325 staticType.displayName |
| 2433 [methodName, staticType.displayName]); | 2326 ]); |
| 2434 } else { | 2327 } else { |
| 2435 _recordUndefinedToken( | 2328 _recordUndefinedToken(staticType.element, |
| 2436 staticType.element, | 2329 StaticTypeWarningCode.UNDEFINED_OPERATOR, node.operator, [ |
| 2437 StaticTypeWarningCode.UNDEFINED_OPERATOR, | 2330 methodName, |
| 2438 node.operator, | 2331 staticType.displayName |
| 2439 [methodName, staticType.displayName]); | 2332 ]); |
| 2440 } | 2333 } |
| 2441 } else if (_enableHints && | 2334 } else if (_enableHints && |
| 2442 _shouldReportMissingMember(propagatedType, propagatedMethod) && | 2335 _shouldReportMissingMember(propagatedType, propagatedMethod) && |
| 2443 !_memberFoundInSubclass(propagatedType.element, methodName, true, fals
e)) { | 2336 !_memberFoundInSubclass( |
| 2444 _recordUndefinedToken( | 2337 propagatedType.element, methodName, true, false)) { |
| 2445 propagatedType.element, | 2338 _recordUndefinedToken(propagatedType.element, |
| 2446 HintCode.UNDEFINED_OPERATOR, | 2339 HintCode.UNDEFINED_OPERATOR, node.operator, [ |
| 2447 node.operator, | 2340 methodName, |
| 2448 [methodName, propagatedType.displayName]); | 2341 propagatedType.displayName |
| 2342 ]); |
| 2449 } | 2343 } |
| 2450 } | 2344 } |
| 2451 } | 2345 } |
| 2452 | 2346 |
| 2453 /** | 2347 /** |
| 2454 * Resolve the names in the given combinators in the scope of the given librar
y. | 2348 * Resolve the names in the given combinators in the scope of the given librar
y. |
| 2455 * | 2349 * |
| 2456 * @param library the library that defines the names | 2350 * @param library the library that defines the names |
| 2457 * @param combinators the combinators containing the names to be resolved | 2351 * @param combinators the combinators containing the names to be resolved |
| 2458 */ | 2352 */ |
| 2459 void _resolveCombinators(LibraryElement library, | 2353 void _resolveCombinators( |
| 2460 NodeList<Combinator> combinators) { | 2354 LibraryElement library, NodeList<Combinator> combinators) { |
| 2461 if (library == null) { | 2355 if (library == null) { |
| 2462 // | 2356 // |
| 2463 // The library will be null if the directive containing the combinators | 2357 // The library will be null if the directive containing the combinators |
| 2464 // has a URI that is not valid. | 2358 // has a URI that is not valid. |
| 2465 // | 2359 // |
| 2466 return; | 2360 return; |
| 2467 } | 2361 } |
| 2468 Namespace namespace = | 2362 Namespace namespace = |
| 2469 new NamespaceBuilder().createExportNamespaceForLibrary(library); | 2363 new NamespaceBuilder().createExportNamespaceForLibrary(library); |
| 2470 for (Combinator combinator in combinators) { | 2364 for (Combinator combinator in combinators) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 2489 name.staticElement = element; | 2383 name.staticElement = element; |
| 2490 } | 2384 } |
| 2491 } | 2385 } |
| 2492 } | 2386 } |
| 2493 } | 2387 } |
| 2494 | 2388 |
| 2495 /** | 2389 /** |
| 2496 * Given that we are accessing a property of the given [classElement] with | 2390 * Given that we are accessing a property of the given [classElement] with |
| 2497 * the given [propertyName], return the element that represents the property. | 2391 * the given [propertyName], return the element that represents the property. |
| 2498 */ | 2392 */ |
| 2499 Element _resolveElement(ClassElementImpl classElement, | 2393 Element _resolveElement( |
| 2500 SimpleIdentifier propertyName) { | 2394 ClassElementImpl classElement, SimpleIdentifier propertyName) { |
| 2501 String name = propertyName.name; | 2395 String name = propertyName.name; |
| 2502 Element element = null; | 2396 Element element = null; |
| 2503 if (propertyName.inSetterContext()) { | 2397 if (propertyName.inSetterContext()) { |
| 2504 element = classElement.getSetter(name); | 2398 element = classElement.getSetter(name); |
| 2505 } | 2399 } |
| 2506 if (element == null) { | 2400 if (element == null) { |
| 2507 element = classElement.getGetter(name); | 2401 element = classElement.getGetter(name); |
| 2508 } | 2402 } |
| 2509 if (element == null) { | 2403 if (element == null) { |
| 2510 element = classElement.getMethod(name); | 2404 element = classElement.getMethod(name); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2555 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the el
ement being invoked. | 2449 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the el
ement being invoked. |
| 2556 * If the returned element is a method, then the method will be invoked. If th
e returned element | 2450 * If the returned element is a method, then the method will be invoked. If th
e returned element |
| 2557 * is a getter, the getter will be invoked without arguments and the result of
that invocation | 2451 * is a getter, the getter will be invoked without arguments and the result of
that invocation |
| 2558 * will then be invoked with the arguments. | 2452 * will then be invoked with the arguments. |
| 2559 * | 2453 * |
| 2560 * @param target the target of the invocation ('e') | 2454 * @param target the target of the invocation ('e') |
| 2561 * @param targetType the type of the target | 2455 * @param targetType the type of the target |
| 2562 * @param methodName the name of the method being invoked ('m') | 2456 * @param methodName the name of the method being invoked ('m') |
| 2563 * @return the element being invoked | 2457 * @return the element being invoked |
| 2564 */ | 2458 */ |
| 2565 Element _resolveInvokedElementWithTarget(Expression target, | 2459 Element _resolveInvokedElementWithTarget( |
| 2566 DartType targetType, SimpleIdentifier methodName) { | 2460 Expression target, DartType targetType, SimpleIdentifier methodName) { |
| 2567 if (targetType is InterfaceType || targetType is UnionType) { | 2461 if (targetType is InterfaceType || targetType is UnionType) { |
| 2568 Element element = _lookUpMethod(target, targetType, methodName.name); | 2462 Element element = _lookUpMethod(target, targetType, methodName.name); |
| 2569 if (element == null) { | 2463 if (element == null) { |
| 2570 // | 2464 // |
| 2571 // If there's no method, then it's possible that 'm' is a getter that | 2465 // If there's no method, then it's possible that 'm' is a getter that |
| 2572 // returns a function. | 2466 // returns a function. |
| 2573 // | 2467 // |
| 2574 // TODO (collinsn): need to add union type support here too, in the | 2468 // TODO (collinsn): need to add union type support here too, in the |
| 2575 // style of [lookUpMethod]. | 2469 // style of [lookUpMethod]. |
| 2576 element = _lookUpGetter(target, targetType, methodName.name); | 2470 element = _lookUpGetter(target, targetType, methodName.name); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2602 | 2496 |
| 2603 /** | 2497 /** |
| 2604 * Given that we are accessing a property of the given type with the given nam
e, return the | 2498 * Given that we are accessing a property of the given type with the given nam
e, return the |
| 2605 * element that represents the property. | 2499 * element that represents the property. |
| 2606 * | 2500 * |
| 2607 * @param target the target of the invocation ('e') | 2501 * @param target the target of the invocation ('e') |
| 2608 * @param targetType the type in which the search for the property should begi
n | 2502 * @param targetType the type in which the search for the property should begi
n |
| 2609 * @param propertyName the name of the property being accessed | 2503 * @param propertyName the name of the property being accessed |
| 2610 * @return the element that represents the property | 2504 * @return the element that represents the property |
| 2611 */ | 2505 */ |
| 2612 ExecutableElement _resolveProperty(Expression target, DartType targetType, | 2506 ExecutableElement _resolveProperty( |
| 2613 SimpleIdentifier propertyName) { | 2507 Expression target, DartType targetType, SimpleIdentifier propertyName) { |
| 2614 ExecutableElement memberElement = null; | 2508 ExecutableElement memberElement = null; |
| 2615 if (propertyName.inSetterContext()) { | 2509 if (propertyName.inSetterContext()) { |
| 2616 memberElement = _lookUpSetter(target, targetType, propertyName.name); | 2510 memberElement = _lookUpSetter(target, targetType, propertyName.name); |
| 2617 } | 2511 } |
| 2618 if (memberElement == null) { | 2512 if (memberElement == null) { |
| 2619 memberElement = _lookUpGetter(target, targetType, propertyName.name); | 2513 memberElement = _lookUpGetter(target, targetType, propertyName.name); |
| 2620 } | 2514 } |
| 2621 if (memberElement == null) { | 2515 if (memberElement == null) { |
| 2622 memberElement = _lookUpMethod(target, targetType, propertyName.name); | 2516 memberElement = _lookUpMethod(target, targetType, propertyName.name); |
| 2623 } | 2517 } |
| 2624 return memberElement; | 2518 return memberElement; |
| 2625 } | 2519 } |
| 2626 | 2520 |
| 2627 void _resolvePropertyAccess(Expression target, | 2521 void _resolvePropertyAccess( |
| 2628 SimpleIdentifier propertyName) { | 2522 Expression target, SimpleIdentifier propertyName) { |
| 2629 DartType staticType = _getStaticType(target); | 2523 DartType staticType = _getStaticType(target); |
| 2630 DartType propagatedType = _getPropagatedType(target); | 2524 DartType propagatedType = _getPropagatedType(target); |
| 2631 Element staticElement = null; | 2525 Element staticElement = null; |
| 2632 Element propagatedElement = null; | 2526 Element propagatedElement = null; |
| 2633 // | 2527 // |
| 2634 // If this property access is of the form 'C.m' where 'C' is a class, | 2528 // If this property access is of the form 'C.m' where 'C' is a class, |
| 2635 // then we don't call resolveProperty(..) which walks up the class | 2529 // then we don't call resolveProperty(..) which walks up the class |
| 2636 // hierarchy, instead we just look for the member in the type only. | 2530 // hierarchy, instead we just look for the member in the type only. |
| 2637 // | 2531 // |
| 2638 ClassElementImpl typeReference = getTypeReference(target); | 2532 ClassElementImpl typeReference = getTypeReference(target); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2653 propertyName.staticElement = staticElement; | 2547 propertyName.staticElement = staticElement; |
| 2654 } | 2548 } |
| 2655 return; | 2549 return; |
| 2656 } | 2550 } |
| 2657 propertyName.staticElement = staticElement; | 2551 propertyName.staticElement = staticElement; |
| 2658 propertyName.propagatedElement = propagatedElement; | 2552 propertyName.propagatedElement = propagatedElement; |
| 2659 bool shouldReportMissingMember_static = | 2553 bool shouldReportMissingMember_static = |
| 2660 _shouldReportMissingMember(staticType, staticElement); | 2554 _shouldReportMissingMember(staticType, staticElement); |
| 2661 bool shouldReportMissingMember_propagated = | 2555 bool shouldReportMissingMember_propagated = |
| 2662 !shouldReportMissingMember_static && | 2556 !shouldReportMissingMember_static && |
| 2663 _enableHints && | 2557 _enableHints && |
| 2664 _shouldReportMissingMember(propagatedType, propagatedElement) && | 2558 _shouldReportMissingMember(propagatedType, propagatedElement) && |
| 2665 !_memberFoundInSubclass(propagatedType.element, propertyName.name, false
, true); | 2559 !_memberFoundInSubclass( |
| 2560 propagatedType.element, propertyName.name, false, true); |
| 2666 // TODO(collinsn): add support for errors on union types by extending | 2561 // TODO(collinsn): add support for errors on union types by extending |
| 2667 // [lookupGetter] and [lookupSetter] in analogy with the earlier | 2562 // [lookupGetter] and [lookupSetter] in analogy with the earlier |
| 2668 // [lookupMethod] extensions. | 2563 // [lookupMethod] extensions. |
| 2669 if (propagatedType is UnionType) { | 2564 if (propagatedType is UnionType) { |
| 2670 shouldReportMissingMember_propagated = false; | 2565 shouldReportMissingMember_propagated = false; |
| 2671 } | 2566 } |
| 2672 if (shouldReportMissingMember_static || | 2567 if (shouldReportMissingMember_static || |
| 2673 shouldReportMissingMember_propagated) { | 2568 shouldReportMissingMember_propagated) { |
| 2674 DartType staticOrPropagatedType = | 2569 DartType staticOrPropagatedType = |
| 2675 shouldReportMissingMember_static ? staticType : propagatedType; | 2570 shouldReportMissingMember_static ? staticType : propagatedType; |
| 2676 Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element; | 2571 Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element; |
| 2677 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt); | 2572 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt); |
| 2678 DartType displayType = staticOrPropagatedType != null ? | 2573 DartType displayType = staticOrPropagatedType != null |
| 2679 staticOrPropagatedType : | 2574 ? staticOrPropagatedType |
| 2680 propagatedType != null ? propagatedType : staticType; | 2575 : propagatedType != null ? propagatedType : staticType; |
| 2681 // Special getter cases. | 2576 // Special getter cases. |
| 2682 if (propertyName.inGetterContext()) { | 2577 if (propertyName.inGetterContext()) { |
| 2683 if (!isStaticProperty && | 2578 if (!isStaticProperty && |
| 2684 staticOrPropagatedEnclosingElt is ClassElement) { | 2579 staticOrPropagatedEnclosingElt is ClassElement) { |
| 2685 ClassElement classElement = staticOrPropagatedEnclosingElt; | 2580 ClassElement classElement = staticOrPropagatedEnclosingElt; |
| 2686 InterfaceType targetType = classElement.type; | 2581 InterfaceType targetType = classElement.type; |
| 2687 if (targetType != null && | 2582 if (targetType != null && |
| 2688 targetType.isDartCoreFunction && | 2583 targetType.isDartCoreFunction && |
| 2689 propertyName.name == FunctionElement.CALL_METHOD_NAME) { | 2584 propertyName.name == FunctionElement.CALL_METHOD_NAME) { |
| 2690 // TODO(brianwilkerson) Can we ever resolve the function being | 2585 // TODO(brianwilkerson) Can we ever resolve the function being |
| 2691 // invoked? | 2586 // invoked? |
| 2692 // resolveArgumentsToParameters(node.getArgumentList(), invokedFuncti
on); | 2587 // resolveArgumentsToParameters(node.getArgumentList(), invokedFuncti
on); |
| 2693 return; | 2588 return; |
| 2694 } else if (classElement.isEnum && propertyName.name == "_name") { | 2589 } else if (classElement.isEnum && propertyName.name == "_name") { |
| 2695 _resolver.reportErrorForNode( | 2590 _resolver.reportErrorForNode( |
| 2696 CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, | 2591 CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, propertyName, [ |
| 2697 propertyName, | 2592 propertyName.name |
| 2698 [propertyName.name]); | 2593 ]); |
| 2699 return; | 2594 return; |
| 2700 } | 2595 } |
| 2701 } | 2596 } |
| 2702 } | 2597 } |
| 2703 Element declaringElement = | 2598 Element declaringElement = |
| 2704 staticType.isVoid ? null : staticOrPropagatedEnclosingElt; | 2599 staticType.isVoid ? null : staticOrPropagatedEnclosingElt; |
| 2705 if (propertyName.inSetterContext()) { | 2600 if (propertyName.inSetterContext()) { |
| 2706 ErrorCode errorCode; | 2601 ErrorCode errorCode; |
| 2707 if (shouldReportMissingMember_static) { | 2602 if (shouldReportMissingMember_static) { |
| 2708 if (target is SuperExpression) { | 2603 if (target is SuperExpression) { |
| 2709 if (isStaticProperty && !staticType.isVoid) { | 2604 if (isStaticProperty && !staticType.isVoid) { |
| 2710 errorCode = StaticWarningCode.UNDEFINED_SUPER_SETTER; | 2605 errorCode = StaticWarningCode.UNDEFINED_SUPER_SETTER; |
| 2711 } else { | 2606 } else { |
| 2712 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_SETTER; | 2607 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_SETTER; |
| 2713 } | 2608 } |
| 2714 } else { | 2609 } else { |
| 2715 if (isStaticProperty && !staticType.isVoid) { | 2610 if (isStaticProperty && !staticType.isVoid) { |
| 2716 errorCode = StaticWarningCode.UNDEFINED_SETTER; | 2611 errorCode = StaticWarningCode.UNDEFINED_SETTER; |
| 2717 } else { | 2612 } else { |
| 2718 errorCode = StaticTypeWarningCode.UNDEFINED_SETTER; | 2613 errorCode = StaticTypeWarningCode.UNDEFINED_SETTER; |
| 2719 } | 2614 } |
| 2720 } | 2615 } |
| 2721 } else { | 2616 } else { |
| 2722 errorCode = HintCode.UNDEFINED_SETTER; | 2617 errorCode = HintCode.UNDEFINED_SETTER; |
| 2723 } | 2618 } |
| 2724 _recordUndefinedNode( | 2619 _recordUndefinedNode(declaringElement, errorCode, propertyName, [ |
| 2725 declaringElement, | 2620 propertyName.name, |
| 2726 errorCode, | 2621 displayType.displayName |
| 2727 propertyName, | 2622 ]); |
| 2728 [propertyName.name, displayType.displayName]); | |
| 2729 } else if (propertyName.inGetterContext()) { | 2623 } else if (propertyName.inGetterContext()) { |
| 2730 ErrorCode errorCode; | 2624 ErrorCode errorCode; |
| 2731 if (shouldReportMissingMember_static) { | 2625 if (shouldReportMissingMember_static) { |
| 2732 if (target is SuperExpression) { | 2626 if (target is SuperExpression) { |
| 2733 if (isStaticProperty && !staticType.isVoid) { | 2627 if (isStaticProperty && !staticType.isVoid) { |
| 2734 errorCode = StaticWarningCode.UNDEFINED_SUPER_GETTER; | 2628 errorCode = StaticWarningCode.UNDEFINED_SUPER_GETTER; |
| 2735 } else { | 2629 } else { |
| 2736 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_GETTER; | 2630 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_GETTER; |
| 2737 } | 2631 } |
| 2738 } else { | 2632 } else { |
| 2739 if (isStaticProperty && !staticType.isVoid) { | 2633 if (isStaticProperty && !staticType.isVoid) { |
| 2740 errorCode = StaticWarningCode.UNDEFINED_GETTER; | 2634 errorCode = StaticWarningCode.UNDEFINED_GETTER; |
| 2741 } else { | 2635 } else { |
| 2742 errorCode = StaticTypeWarningCode.UNDEFINED_GETTER; | 2636 errorCode = StaticTypeWarningCode.UNDEFINED_GETTER; |
| 2743 } | 2637 } |
| 2744 } | 2638 } |
| 2745 } else { | 2639 } else { |
| 2746 errorCode = HintCode.UNDEFINED_GETTER; | 2640 errorCode = HintCode.UNDEFINED_GETTER; |
| 2747 } | 2641 } |
| 2748 _recordUndefinedNode( | 2642 _recordUndefinedNode(declaringElement, errorCode, propertyName, [ |
| 2749 declaringElement, | 2643 propertyName.name, |
| 2750 errorCode, | 2644 displayType.displayName |
| 2751 propertyName, | 2645 ]); |
| 2752 [propertyName.name, displayType.displayName]); | |
| 2753 } else { | 2646 } else { |
| 2754 _recordUndefinedNode( | 2647 _recordUndefinedNode(declaringElement, |
| 2755 declaringElement, | 2648 StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [ |
| 2756 StaticWarningCode.UNDEFINED_IDENTIFIER, | 2649 propertyName.name |
| 2757 propertyName, | 2650 ]); |
| 2758 [propertyName.name]); | |
| 2759 } | 2651 } |
| 2760 } | 2652 } |
| 2761 } | 2653 } |
| 2762 | 2654 |
| 2763 /** | 2655 /** |
| 2764 * Resolve the given simple identifier if possible. Return the element to whic
h it could be | 2656 * Resolve the given simple identifier if possible. Return the element to whic
h it could be |
| 2765 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the | 2657 * resolved, or `null` if it could not be resolved. This does not record the r
esults of the |
| 2766 * resolution. | 2658 * resolution. |
| 2767 * | 2659 * |
| 2768 * @param node the identifier to be resolved | 2660 * @param node the identifier to be resolved |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2785 setter = _lookUpSetter(null, enclosingClass.type, node.name); | 2677 setter = _lookUpSetter(null, enclosingClass.type, node.name); |
| 2786 } | 2678 } |
| 2787 } | 2679 } |
| 2788 if (setter != null) { | 2680 if (setter != null) { |
| 2789 element = setter; | 2681 element = setter; |
| 2790 } | 2682 } |
| 2791 } | 2683 } |
| 2792 } else if (element == null && | 2684 } else if (element == null && |
| 2793 (node.inSetterContext() || node.parent is CommentReference)) { | 2685 (node.inSetterContext() || node.parent is CommentReference)) { |
| 2794 element = _resolver.nameScope.lookup( | 2686 element = _resolver.nameScope.lookup( |
| 2795 new SyntheticIdentifier("${node.name}=", node), | 2687 new SyntheticIdentifier("${node.name}=", node), _definingLibrary); |
| 2796 _definingLibrary); | |
| 2797 } | 2688 } |
| 2798 ClassElement enclosingClass = _resolver.enclosingClass; | 2689 ClassElement enclosingClass = _resolver.enclosingClass; |
| 2799 if (element == null && enclosingClass != null) { | 2690 if (element == null && enclosingClass != null) { |
| 2800 InterfaceType enclosingType = enclosingClass.type; | 2691 InterfaceType enclosingType = enclosingClass.type; |
| 2801 if (element == null && | 2692 if (element == null && |
| 2802 (node.inSetterContext() || node.parent is CommentReference)) { | 2693 (node.inSetterContext() || node.parent is CommentReference)) { |
| 2803 element = _lookUpSetter(null, enclosingType, node.name); | 2694 element = _lookUpSetter(null, enclosingType, node.name); |
| 2804 } | 2695 } |
| 2805 if (element == null && node.inGetterContext()) { | 2696 if (element == null && node.inGetterContext()) { |
| 2806 element = _lookUpGetter(null, enclosingType, node.name); | 2697 element = _lookUpGetter(null, enclosingType, node.name); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2914 } | 2805 } |
| 2915 return null; | 2806 return null; |
| 2916 } | 2807 } |
| 2917 | 2808 |
| 2918 /** | 2809 /** |
| 2919 * Helper function for `maybeMergeExecutableElements` that does the actual mer
ging. | 2810 * Helper function for `maybeMergeExecutableElements` that does the actual mer
ging. |
| 2920 * | 2811 * |
| 2921 * @param elementArrayToMerge non-empty array of elements to merge. | 2812 * @param elementArrayToMerge non-empty array of elements to merge. |
| 2922 * @return | 2813 * @return |
| 2923 */ | 2814 */ |
| 2924 static ExecutableElement | 2815 static ExecutableElement _computeMergedExecutableElement( |
| 2925 _computeMergedExecutableElement(List<ExecutableElement> elementArrayToMerg
e) { | 2816 List<ExecutableElement> elementArrayToMerge) { |
| 2926 // Flatten methods structurally. Based on | 2817 // Flatten methods structurally. Based on |
| 2927 // [InheritanceManager.computeMergedExecutableElement] and | 2818 // [InheritanceManager.computeMergedExecutableElement] and |
| 2928 // [InheritanceManager.createSyntheticExecutableElement]. | 2819 // [InheritanceManager.createSyntheticExecutableElement]. |
| 2929 // | 2820 // |
| 2930 // However, the approach we take here is much simpler, but expected to work | 2821 // However, the approach we take here is much simpler, but expected to work |
| 2931 // well in the common case. It degrades gracefully in the uncommon case, | 2822 // well in the common case. It degrades gracefully in the uncommon case, |
| 2932 // by computing the type [dynamic] for the method, preventing any | 2823 // by computing the type [dynamic] for the method, preventing any |
| 2933 // hints from being generated (TODO: not done yet). | 2824 // hints from being generated (TODO: not done yet). |
| 2934 // | 2825 // |
| 2935 // The approach is: we require that each [ExecutableElement] has the | 2826 // The approach is: we require that each [ExecutableElement] has the |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3046 } | 2937 } |
| 3047 | 2938 |
| 3048 /** | 2939 /** |
| 3049 * Return a method representing the merge of the given elements. The type of t
he merged element is | 2940 * Return a method representing the merge of the given elements. The type of t
he merged element is |
| 3050 * the component-wise union of the types of the given elements. If not all inp
ut elements have the | 2941 * the component-wise union of the types of the given elements. If not all inp
ut elements have the |
| 3051 * same shape then [null] is returned. | 2942 * same shape then [null] is returned. |
| 3052 * | 2943 * |
| 3053 * @param elements the `ExecutableElement`s to merge | 2944 * @param elements the `ExecutableElement`s to merge |
| 3054 * @return an `ExecutableElement` representing the merge of `elements` | 2945 * @return an `ExecutableElement` representing the merge of `elements` |
| 3055 */ | 2946 */ |
| 3056 static ExecutableElement | 2947 static ExecutableElement _maybeMergeExecutableElements( |
| 3057 _maybeMergeExecutableElements(Set<ExecutableElement> elements) { | 2948 Set<ExecutableElement> elements) { |
| 3058 List<ExecutableElement> elementArrayToMerge = new List.from(elements); | 2949 List<ExecutableElement> elementArrayToMerge = new List.from(elements); |
| 3059 if (elementArrayToMerge.length == 0) { | 2950 if (elementArrayToMerge.length == 0) { |
| 3060 return null; | 2951 return null; |
| 3061 } else if (elementArrayToMerge.length == 1) { | 2952 } else if (elementArrayToMerge.length == 1) { |
| 3062 // If all methods are equal, don't bother building a new one. | 2953 // If all methods are equal, don't bother building a new one. |
| 3063 return elementArrayToMerge[0]; | 2954 return elementArrayToMerge[0]; |
| 3064 } else { | 2955 } else { |
| 3065 return _computeMergedExecutableElement(elementArrayToMerge); | 2956 return _computeMergedExecutableElement(elementArrayToMerge); |
| 3066 } | 2957 } |
| 3067 } | 2958 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3120 @override | 3011 @override |
| 3121 Element get propagatedElement => null; | 3012 Element get propagatedElement => null; |
| 3122 | 3013 |
| 3123 @override | 3014 @override |
| 3124 Element get staticElement => null; | 3015 Element get staticElement => null; |
| 3125 | 3016 |
| 3126 @override | 3017 @override |
| 3127 accept(AstVisitor visitor) => null; | 3018 accept(AstVisitor visitor) => null; |
| 3128 | 3019 |
| 3129 @override | 3020 @override |
| 3130 void visitChildren(AstVisitor visitor) { | 3021 void visitChildren(AstVisitor visitor) {} |
| 3131 } | |
| 3132 } | 3022 } |
| OLD | NEW |