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 |