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

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

Issue 718323002: Report HintCode.UNUSED_ELEMENT for unused methods. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library 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 15524 matching lines...) Expand 10 before | Expand all | Expand 10 after
15535 * identifier is not defined). 15535 * identifier is not defined).
15536 * 15536 *
15537 * @return the tag that has the given identifier 15537 * @return the tag that has the given identifier
15538 */ 15538 */
15539 String getTagWithId(String identifier) { 15539 String getTagWithId(String identifier) {
15540 return idToTagMap[identifier]; 15540 return idToTagMap[identifier];
15541 } 15541 }
15542 } 15542 }
15543 15543
15544 15544
15545 class _UsedElements {
15546 /**
15547 * Resolved, locally defined elements that are used or potentially can be
15548 * used.
15549 */
15550 final HashSet<Element> elements = new HashSet<Element>();
15551
15552 /**
15553 * Names of resolved or unresolved class members that are referenced in the
15554 * library.
15555 */
15556 final HashSet<String> members = new HashSet<String>();
15557 }
15558
15559
15545 class _GatherUsedElementsVisitor extends RecursiveAstVisitor { 15560 class _GatherUsedElementsVisitor extends RecursiveAstVisitor {
15546 final Set<Element> usedElements = new HashSet<Element>(); 15561 final _UsedElements usedElements = new _UsedElements();
15547 15562
15548 final LibraryElement _enclosingLibrary; 15563 final LibraryElement _enclosingLibrary;
15549 ClassElement _enclosingClass; 15564 ClassElement _enclosingClass;
15565 ExecutableElement _enclosingExec;
15550 15566
15551 _GatherUsedElementsVisitor(this._enclosingLibrary); 15567 _GatherUsedElementsVisitor(this._enclosingLibrary);
15552 15568
15553 @override 15569 @override
15554 visitCatchClause(CatchClause node) { 15570 visitCatchClause(CatchClause node) {
15555 SimpleIdentifier exceptionParameter = node.exceptionParameter; 15571 SimpleIdentifier exceptionParameter = node.exceptionParameter;
15556 _useStaticElement(exceptionParameter); 15572 _useStaticElement(exceptionParameter);
15557 super.visitCatchClause(node); 15573 super.visitCatchClause(node);
15558 } 15574 }
15559 15575
15560 @override 15576 @override
15561 visitClassDeclaration(ClassDeclaration node) { 15577 visitClassDeclaration(ClassDeclaration node) {
15562 ClassElement enclosingClassOld = _enclosingClass; 15578 ClassElement enclosingClassOld = _enclosingClass;
15563 try { 15579 try {
15564 _enclosingClass = node.element; 15580 _enclosingClass = node.element;
15565 super.visitClassDeclaration(node); 15581 super.visitClassDeclaration(node);
15566 } finally { 15582 } finally {
15567 _enclosingClass = enclosingClassOld; 15583 _enclosingClass = enclosingClassOld;
15568 } 15584 }
15569 } 15585 }
15570 15586
15571 @override 15587 @override
15588 visitMethodDeclaration(MethodDeclaration node) {
15589 ExecutableElement enclosingExecOld = _enclosingExec;
15590 try {
15591 _enclosingExec = node.element;
15592 super.visitMethodDeclaration(node);
15593 } finally {
15594 _enclosingExec = enclosingExecOld;
15595 }
15596 }
15597
15598 @override
15572 visitSimpleIdentifier(SimpleIdentifier node) { 15599 visitSimpleIdentifier(SimpleIdentifier node) {
15573 if (node.inDeclarationContext()) { 15600 if (node.inDeclarationContext()) {
15574 return; 15601 return;
15575 } 15602 }
15576 Element staticElement = node.staticElement; 15603 Element element = node.staticElement;
15577 if (staticElement is LocalVariableElement) { 15604 if (element is LocalVariableElement) {
15578 AstNode parent = node.parent; 15605 AstNode parent = node.parent;
15579 if (node.inGetterContext()) { 15606 if (node.inGetterContext()) {
15580 if (parent.parent is ExpressionStatement && 15607 if (parent.parent is ExpressionStatement &&
15581 (parent is PrefixExpression || 15608 (parent is PrefixExpression ||
15582 parent is PostfixExpression || 15609 parent is PostfixExpression ||
15583 parent is AssignmentExpression && parent.leftHandSide == node)) { 15610 parent is AssignmentExpression && parent.leftHandSide == node)) {
15584 // v++; 15611 // v++;
15585 // ++v; 15612 // ++v;
15586 // v += 2; 15613 // v += 2;
15587 } else { 15614 } else {
15588 _useElement(staticElement); 15615 _useElement(element);
15589 } 15616 }
15590 } 15617 }
15591 if (parent is MethodInvocation && parent.methodName == node) { 15618 if (parent is MethodInvocation && parent.methodName == node) {
15592 _useElement(staticElement); 15619 _useElement(element);
15593 } 15620 }
15594 } else { 15621 } else {
15595 _useIdentifierElement(node); 15622 _useIdentifierElement(node);
15623 if (element == null ||
15624 element is! LocalElement && !identical(element, _enclosingExec)) {
15625 usedElements.members.add(node.name);
15626 }
15596 } 15627 }
15597 } 15628 }
15598 15629
15599 @override 15630 @override
15600 visitTypeName(TypeName node) { 15631 visitTypeName(TypeName node) {
15601 _useIdentifierElement(node.name); 15632 _useIdentifierElement(node.name);
15602 } 15633 }
15603 15634
15604 /** 15635 /**
15605 * Marks an [Element] of [node] as used in the library. 15636 * Marks an [Element] of [node] as used in the library.
15606 */ 15637 */
15607 void _useIdentifierElement(Identifier node) { 15638 void _useIdentifierElement(Identifier node) {
15608 Element element = node.staticElement; 15639 Element element = node.staticElement;
15609 if (element == null) { 15640 if (element == null) {
15610 return; 15641 return;
15611 } 15642 }
15612 // check if a local element 15643 // check if a local element
15613 if (!identical(element.library, _enclosingLibrary)) { 15644 if (!identical(element.library, _enclosingLibrary)) {
15614 return; 15645 return;
15615 } 15646 }
15616 // ignore references to an element from itself 15647 // ignore references to an element from itself
15617 if (identical(element, _enclosingClass)) { 15648 if (identical(element, _enclosingClass)) {
15618 return; 15649 return;
15619 } 15650 }
15651 if (identical(element, _enclosingExec)) {
15652 return;
15653 }
15620 // ignore places where the element is not actually used 15654 // ignore places where the element is not actually used
15621 if (node.parent is TypeName) { 15655 if (node.parent is TypeName) {
15622 AstNode parent2 = node.parent.parent; 15656 AstNode parent2 = node.parent.parent;
15623 if (parent2 is IsExpression) { 15657 if (parent2 is IsExpression) {
15624 return; 15658 return;
15625 } 15659 }
15626 if (parent2 is VariableDeclarationList) { 15660 if (parent2 is VariableDeclarationList) {
15627 return; 15661 return;
15628 } 15662 }
15629 } 15663 }
15630 // OK 15664 // OK
15631 _useElement(element); 15665 _useElement(element);
15632 } 15666 }
15633 15667
15634 _useElement(Element element) { 15668 _useElement(Element element) {
15635 if (element != null) { 15669 if (element != null) {
15636 usedElements.add(element); 15670 usedElements.elements.add(element);
15637 } 15671 }
15638 } 15672 }
15639 15673
15640 void _useStaticElement(SimpleIdentifier identifier) { 15674 void _useStaticElement(SimpleIdentifier identifier) {
15641 if (identifier != null) { 15675 if (identifier != null) {
15642 _useElement(identifier.staticElement); 15676 _useElement(identifier.staticElement);
15643 } 15677 }
15644 } 15678 }
15645 } 15679 }
15646 15680
15647 15681
15648 /** 15682 /**
15649 * Instances of the class [_UnusedElementsVerifier] traverse an element 15683 * Instances of the class [_UnusedElementsVerifier] traverse an element
15650 * structure looking for cases of [HintCode.UNUSED_ELEMENT] and 15684 * structure looking for cases of [HintCode.UNUSED_ELEMENT] and
15651 * [HintCode.UNUSED_LOCAL_VARIABLE]. 15685 * [HintCode.UNUSED_LOCAL_VARIABLE].
15652 */ 15686 */
15653 class _UnusedElementsVerifier extends RecursiveElementVisitor { 15687 class _UnusedElementsVerifier extends RecursiveElementVisitor {
15654 /** 15688 /**
15655 * The error listener to which errors will be reported. 15689 * The error listener to which errors will be reported.
15656 */ 15690 */
15657 final AnalysisErrorListener _errorListener; 15691 final AnalysisErrorListener _errorListener;
15658 15692
15659 /** 15693 /**
15660 * The elements know to be used. 15694 * The elements know to be used.
15661 */ 15695 */
15662 final Set<Element> _usedElements; 15696 final _UsedElements _usedElements;
15663 15697
15664 /** 15698 /**
15665 * Create a new instance of the [_UnusedElementsVerifier]. 15699 * Create a new instance of the [_UnusedElementsVerifier].
15666 */ 15700 */
15667 _UnusedElementsVerifier(this._errorListener, this._usedElements); 15701 _UnusedElementsVerifier(this._errorListener, this._usedElements);
15668 15702
15669 @override 15703 @override
15670 visitClassElement(ClassElement element) { 15704 visitClassElement(ClassElement element) {
15671 if (!_isUsed(element)) { 15705 if (!_isUsedElement(element)) {
15672 _reportErrorForElement( 15706 _reportErrorForElement(
15673 HintCode.UNUSED_ELEMENT, 15707 HintCode.UNUSED_ELEMENT,
15674 element, 15708 element,
15675 [element.kind.displayName, element.displayName]); 15709 [element.kind.displayName, element.displayName]);
15676 } 15710 }
15677 element.visitChildren(this); 15711 super.visitClassElement(element);
15678 } 15712 }
15679 15713
15680 @override 15714 @override
15681 visitLocalVariableElement(LocalVariableElement element) { 15715 visitLocalVariableElement(LocalVariableElement element) {
15682 if (!_isUsed(element)) { 15716 if (!_isUsedElement(element)) {
15683 _reportErrorForElement( 15717 _reportErrorForElement(
15684 HintCode.UNUSED_LOCAL_VARIABLE, 15718 HintCode.UNUSED_LOCAL_VARIABLE,
15685 element, 15719 element,
15686 [element.displayName]); 15720 [element.displayName]);
15687 } 15721 }
15688 } 15722 }
15689 15723
15690 bool _isUsed(Element element) { 15724 @override
15725 visitMethodElement(MethodElement element) {
15726 if (!_isUsedMember(element)) {
15727 _reportErrorForElement(
15728 HintCode.UNUSED_ELEMENT,
15729 element,
15730 [element.kind.displayName, element.displayName]);
15731 }
15732 super.visitMethodElement(element);
15733 }
15734
15735 bool _isUsedElement(Element element) {
15691 if (element is! LocalVariableElement) { 15736 if (element is! LocalVariableElement) {
15692 if (element.isPublic) { 15737 if (element.isPublic) {
15693 return true; 15738 return true;
15694 } 15739 }
15695 } 15740 }
15696 return _usedElements.contains(element); 15741 return _usedElements.elements.contains(element);
15742 }
15743
15744 bool _isUsedMember(Element element) {
15745 if (element.isPublic) {
15746 return true;
15747 }
15748 if (_usedElements.members.contains(element.displayName)) {
15749 return true;
15750 }
15751 return _usedElements.elements.contains(element);
15697 } 15752 }
15698 15753
15699 void _reportErrorForElement(ErrorCode errorCode, Element element, List<Object> arguments) { 15754 void _reportErrorForElement(ErrorCode errorCode, Element element, List<Object> arguments) {
15700 if (element != null) { 15755 if (element != null) {
15701 _errorListener.onError( 15756 _errorListener.onError(
15702 new AnalysisError.con2( 15757 new AnalysisError.con2(
15703 element.source, 15758 element.source,
15704 element.nameOffset, 15759 element.nameOffset,
15705 element.displayName.length, 15760 element.displayName.length,
15706 errorCode, 15761 errorCode,
15707 arguments)); 15762 arguments));
15708 } 15763 }
15709 } 15764 }
15710 } 15765 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698