| 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; | 5 library engine.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'java_core.dart'; | 10 import 'java_core.dart'; |
| (...skipping 15536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15547 * Resolved, locally defined elements that are used or potentially can be | 15547 * Resolved, locally defined elements that are used or potentially can be |
| 15548 * used. | 15548 * used. |
| 15549 */ | 15549 */ |
| 15550 final HashSet<Element> elements = new HashSet<Element>(); | 15550 final HashSet<Element> elements = new HashSet<Element>(); |
| 15551 | 15551 |
| 15552 /** | 15552 /** |
| 15553 * Names of resolved or unresolved class members that are referenced in the | 15553 * Names of resolved or unresolved class members that are referenced in the |
| 15554 * library. | 15554 * library. |
| 15555 */ | 15555 */ |
| 15556 final HashSet<String> members = new HashSet<String>(); | 15556 final HashSet<String> members = new HashSet<String>(); |
| 15557 |
| 15558 /** |
| 15559 * Names of resolved or unresolved class members that are read in the |
| 15560 * library. |
| 15561 */ |
| 15562 final HashSet<String> readMembers = new HashSet<String>(); |
| 15557 } | 15563 } |
| 15558 | 15564 |
| 15559 | 15565 |
| 15560 class _GatherUsedElementsVisitor extends RecursiveAstVisitor { | 15566 class _GatherUsedElementsVisitor extends RecursiveAstVisitor { |
| 15561 final _UsedElements usedElements = new _UsedElements(); | 15567 final _UsedElements usedElements = new _UsedElements(); |
| 15562 | 15568 |
| 15563 final LibraryElement _enclosingLibrary; | 15569 final LibraryElement _enclosingLibrary; |
| 15564 ClassElement _enclosingClass; | 15570 ClassElement _enclosingClass; |
| 15565 ExecutableElement _enclosingExec; | 15571 ExecutableElement _enclosingExec; |
| 15566 | 15572 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 15594 _enclosingExec = enclosingExecOld; | 15600 _enclosingExec = enclosingExecOld; |
| 15595 } | 15601 } |
| 15596 } | 15602 } |
| 15597 | 15603 |
| 15598 @override | 15604 @override |
| 15599 visitSimpleIdentifier(SimpleIdentifier node) { | 15605 visitSimpleIdentifier(SimpleIdentifier node) { |
| 15600 if (node.inDeclarationContext()) { | 15606 if (node.inDeclarationContext()) { |
| 15601 return; | 15607 return; |
| 15602 } | 15608 } |
| 15603 Element element = node.staticElement; | 15609 Element element = node.staticElement; |
| 15610 bool isIdentifierRead = _isReadIdentifier(node); |
| 15604 if (element is LocalVariableElement) { | 15611 if (element is LocalVariableElement) { |
| 15605 AstNode parent = node.parent; | 15612 if (isIdentifierRead) { |
| 15606 if (node.inGetterContext()) { | |
| 15607 if (parent.parent is ExpressionStatement && | |
| 15608 (parent is PrefixExpression || | |
| 15609 parent is PostfixExpression || | |
| 15610 parent is AssignmentExpression && parent.leftHandSide == node)) { | |
| 15611 // v++; | |
| 15612 // ++v; | |
| 15613 // v += 2; | |
| 15614 } else { | |
| 15615 _useElement(element); | |
| 15616 } | |
| 15617 } | |
| 15618 if (parent is MethodInvocation && parent.methodName == node) { | |
| 15619 _useElement(element); | 15613 _useElement(element); |
| 15620 } | 15614 } |
| 15615 // } else if (element is PropertyAccessorElement && |
| 15616 // element.isSynthetic && |
| 15617 // element.isPrivate) { |
| 15618 // PropertyInducingElement variable = element.variable; |
| 15619 // if (node.inGetterContext()) { |
| 15620 // AstNode parent = node.parent; |
| 15621 // if (parent.parent is ExpressionStatement && |
| 15622 // (parent is PrefixExpression || |
| 15623 // parent is PostfixExpression || |
| 15624 // parent is AssignmentExpression && parent.leftHandSide == node)) { |
| 15625 // // f++; |
| 15626 // // ++f; |
| 15627 // // f += 2; |
| 15628 // } else { |
| 15629 // _useElement(variable); |
| 15630 // } |
| 15631 // } |
| 15621 } else { | 15632 } else { |
| 15622 _useIdentifierElement(node); | 15633 _useIdentifierElement(node); |
| 15623 if (element == null || | 15634 if (element == null || |
| 15624 element is! LocalElement && !identical(element, _enclosingExec)) { | 15635 element is! LocalElement && !identical(element, _enclosingExec)) { |
| 15625 usedElements.members.add(node.name); | 15636 usedElements.members.add(node.name); |
| 15637 if (isIdentifierRead) { |
| 15638 usedElements.readMembers.add(node.name); |
| 15639 } |
| 15626 } | 15640 } |
| 15627 } | 15641 } |
| 15628 } | 15642 } |
| 15629 | 15643 |
| 15630 @override | 15644 @override |
| 15631 visitTypeName(TypeName node) { | 15645 visitTypeName(TypeName node) { |
| 15632 _useIdentifierElement(node.name); | 15646 _useIdentifierElement(node.name); |
| 15633 } | 15647 } |
| 15634 | 15648 |
| 15635 /** | 15649 /** |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15669 if (element != null) { | 15683 if (element != null) { |
| 15670 usedElements.elements.add(element); | 15684 usedElements.elements.add(element); |
| 15671 } | 15685 } |
| 15672 } | 15686 } |
| 15673 | 15687 |
| 15674 void _useStaticElement(SimpleIdentifier identifier) { | 15688 void _useStaticElement(SimpleIdentifier identifier) { |
| 15675 if (identifier != null) { | 15689 if (identifier != null) { |
| 15676 _useElement(identifier.staticElement); | 15690 _useElement(identifier.staticElement); |
| 15677 } | 15691 } |
| 15678 } | 15692 } |
| 15693 |
| 15694 static bool _isReadIdentifier(SimpleIdentifier node) { |
| 15695 // not reading at all |
| 15696 if (!node.inGetterContext()) { |
| 15697 return false; |
| 15698 } |
| 15699 // check if useless reading |
| 15700 AstNode parent = node.parent; |
| 15701 if (parent.parent is ExpressionStatement && |
| 15702 (parent is PrefixExpression || |
| 15703 parent is PostfixExpression || |
| 15704 parent is AssignmentExpression && parent.leftHandSide == node)) { |
| 15705 // v++; |
| 15706 // ++v; |
| 15707 // v += 2; |
| 15708 return false; |
| 15709 } |
| 15710 // OK |
| 15711 return true; |
| 15712 } |
| 15679 } | 15713 } |
| 15680 | 15714 |
| 15681 | 15715 |
| 15682 /** | 15716 /** |
| 15683 * Instances of the class [_UnusedElementsVerifier] traverse an element | 15717 * Instances of the class [_UnusedElementsVerifier] traverse an element |
| 15684 * structure looking for cases of [HintCode.UNUSED_ELEMENT] and | 15718 * structure looking for cases of [HintCode.UNUSED_ELEMENT] and |
| 15685 * [HintCode.UNUSED_LOCAL_VARIABLE]. | 15719 * [HintCode.UNUSED_LOCAL_VARIABLE]. |
| 15686 */ | 15720 */ |
| 15687 class _UnusedElementsVerifier extends RecursiveElementVisitor { | 15721 class _UnusedElementsVerifier extends RecursiveElementVisitor { |
| 15688 /** | 15722 /** |
| (...skipping 16 matching lines...) Expand all Loading... |
| 15705 if (!_isUsedElement(element)) { | 15739 if (!_isUsedElement(element)) { |
| 15706 _reportErrorForElement( | 15740 _reportErrorForElement( |
| 15707 HintCode.UNUSED_ELEMENT, | 15741 HintCode.UNUSED_ELEMENT, |
| 15708 element, | 15742 element, |
| 15709 [element.kind.displayName, element.displayName]); | 15743 [element.kind.displayName, element.displayName]); |
| 15710 } | 15744 } |
| 15711 super.visitClassElement(element); | 15745 super.visitClassElement(element); |
| 15712 } | 15746 } |
| 15713 | 15747 |
| 15714 @override | 15748 @override |
| 15749 visitFieldElement(FieldElement element) { |
| 15750 if (!element.isSynthetic && !_isReadMember(element)) { |
| 15751 _reportErrorForElement( |
| 15752 HintCode.UNUSED_FIELD, |
| 15753 element, |
| 15754 [element.displayName]); |
| 15755 } |
| 15756 super.visitFieldElement(element); |
| 15757 } |
| 15758 |
| 15759 @override |
| 15715 visitLocalVariableElement(LocalVariableElement element) { | 15760 visitLocalVariableElement(LocalVariableElement element) { |
| 15716 if (!_isUsedElement(element)) { | 15761 if (!_isUsedElement(element)) { |
| 15717 _reportErrorForElement( | 15762 _reportErrorForElement( |
| 15718 HintCode.UNUSED_LOCAL_VARIABLE, | 15763 HintCode.UNUSED_LOCAL_VARIABLE, |
| 15719 element, | 15764 element, |
| 15720 [element.displayName]); | 15765 [element.displayName]); |
| 15721 } | 15766 } |
| 15722 } | 15767 } |
| 15723 | 15768 |
| 15724 @override | 15769 @override |
| (...skipping 20 matching lines...) Expand all Loading... |
| 15745 | 15790 |
| 15746 bool _isUsedElement(Element element) { | 15791 bool _isUsedElement(Element element) { |
| 15747 if (element is! LocalVariableElement) { | 15792 if (element is! LocalVariableElement) { |
| 15748 if (element.isPublic) { | 15793 if (element.isPublic) { |
| 15749 return true; | 15794 return true; |
| 15750 } | 15795 } |
| 15751 } | 15796 } |
| 15752 return _usedElements.elements.contains(element); | 15797 return _usedElements.elements.contains(element); |
| 15753 } | 15798 } |
| 15754 | 15799 |
| 15800 bool _isReadMember(Element element) { |
| 15801 if (element.isPublic) { |
| 15802 return true; |
| 15803 } |
| 15804 return _usedElements.readMembers.contains(element.displayName); |
| 15805 } |
| 15806 |
| 15755 bool _isUsedMember(Element element) { | 15807 bool _isUsedMember(Element element) { |
| 15756 if (element.isPublic) { | 15808 if (element.isPublic) { |
| 15757 return true; | 15809 return true; |
| 15758 } | 15810 } |
| 15759 if (_usedElements.members.contains(element.displayName)) { | 15811 if (_usedElements.members.contains(element.displayName)) { |
| 15760 return true; | 15812 return true; |
| 15761 } | 15813 } |
| 15762 return _usedElements.elements.contains(element); | 15814 return _usedElements.elements.contains(element); |
| 15763 } | 15815 } |
| 15764 | 15816 |
| 15765 void _reportErrorForElement(ErrorCode errorCode, Element element, List<Object>
arguments) { | 15817 void _reportErrorForElement(ErrorCode errorCode, Element element, List<Object>
arguments) { |
| 15766 if (element != null) { | 15818 if (element != null) { |
| 15767 _errorListener.onError( | 15819 _errorListener.onError( |
| 15768 new AnalysisError.con2( | 15820 new AnalysisError.con2( |
| 15769 element.source, | 15821 element.source, |
| 15770 element.nameOffset, | 15822 element.nameOffset, |
| 15771 element.displayName.length, | 15823 element.displayName.length, |
| 15772 errorCode, | 15824 errorCode, |
| 15773 arguments)); | 15825 arguments)); |
| 15774 } | 15826 } |
| 15775 } | 15827 } |
| 15776 } | 15828 } |
| OLD | NEW |