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

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

Issue 1506903005: Issue 24648. Report HintCode.UNNECESSARY_NO_SUCH_METHOD. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library engine.resolver; 5 library engine.resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import '../task/strong/info.dart' show InferredType, StaticInfo; 9 import '../task/strong/info.dart' show InferredType, StaticInfo;
10 import '../task/strong/rules.dart' show TypeRules; 10 import '../task/strong/rules.dart' show TypeRules;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 Object visitIsExpression(IsExpression node) { 207 Object visitIsExpression(IsExpression node) {
208 _checkAllTypeChecks(node); 208 _checkAllTypeChecks(node);
209 return super.visitIsExpression(node); 209 return super.visitIsExpression(node);
210 } 210 }
211 211
212 @override 212 @override
213 Object visitMethodDeclaration(MethodDeclaration node) { 213 Object visitMethodDeclaration(MethodDeclaration node) {
214 // This was determined to not be a good hint, see: dartbug.com/16029 214 // This was determined to not be a good hint, see: dartbug.com/16029
215 //checkForOverridingPrivateMember(node); 215 //checkForOverridingPrivateMember(node);
216 _checkForMissingReturn(node.returnType, node.body); 216 _checkForMissingReturn(node.returnType, node.body);
217 _checkForUnnecessaryNoSuchMethod(node);
217 return super.visitMethodDeclaration(node); 218 return super.visitMethodDeclaration(node);
218 } 219 }
219 220
220 @override 221 @override
221 Object visitMethodInvocation(MethodInvocation node) { 222 Object visitMethodInvocation(MethodInvocation node) {
222 _checkForCanBeNullAfterNullAware(node.realTarget, node.operator); 223 _checkForCanBeNullAfterNullAware(node.realTarget, node.operator);
223 return super.visitMethodInvocation(node); 224 return super.visitMethodInvocation(node);
224 } 225 }
225 226
226 @override 227 @override
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 } else if (condition is PropertyAccess) { 747 } else if (condition is PropertyAccess) {
747 Token operator = condition.operator; 748 Token operator = condition.operator;
748 if (operator != null && operator.type == TokenType.QUESTION_PERIOD) { 749 if (operator != null && operator.type == TokenType.QUESTION_PERIOD) {
749 _errorReporter.reportErrorForNode( 750 _errorReporter.reportErrorForNode(
750 HintCode.NULL_AWARE_IN_CONDITION, condition); 751 HintCode.NULL_AWARE_IN_CONDITION, condition);
751 } 752 }
752 } 753 }
753 } 754 }
754 755
755 /** 756 /**
756 * Check for the passed class declaration for the
757 * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
758 *
759 * @param node the class declaration to check
760 * @return `true` if and only if a hint code is generated on the passed node
761 * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
762 */
763 // bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
764 // ClassElement classElement = node.element;
765 // if (classElement == null) {
766 // return false;
767 // }
768 // MethodElement equalsOperatorMethodElement =
769 // classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
770 // if (equalsOperatorMethodElement != null) {
771 // PropertyAccessorElement hashCodeElement =
772 // classElement.getGetter(_HASHCODE_GETTER_NAME);
773 // if (hashCodeElement == null) {
774 // _errorReporter.reportErrorForNode(
775 // HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
776 // node.name,
777 // [classElement.displayName]);
778 // return true;
779 // }
780 // }
781 // return false;
782 // }
783
784 /**
785 * Check for the passed as expression for the [HintCode.UNNECESSARY_CAST] hint code. 757 * Check for the passed as expression for the [HintCode.UNNECESSARY_CAST] hint code.
786 * 758 *
787 * @param node the as expression to check 759 * @param node the as expression to check
788 * @return `true` if and only if a hint code is generated on the passed node 760 * @return `true` if and only if a hint code is generated on the passed node
789 * See [HintCode.UNNECESSARY_CAST]. 761 * See [HintCode.UNNECESSARY_CAST].
790 */ 762 */
791 bool _checkForUnnecessaryCast(AsExpression node) { 763 bool _checkForUnnecessaryCast(AsExpression node) {
792 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to 764 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to
793 // remove the (x is! TypeParameterType) checks. 765 // remove the (x is! TypeParameterType) checks.
794 AstNode parent = node.parent; 766 AstNode parent = node.parent;
(...skipping 29 matching lines...) Expand all
824 !lhsType.isDynamic && 796 !lhsType.isDynamic &&
825 !rhsType.isDynamic && 797 !rhsType.isDynamic &&
826 lhsType.isMoreSpecificThan(rhsType)) { 798 lhsType.isMoreSpecificThan(rhsType)) {
827 _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node); 799 _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node);
828 return true; 800 return true;
829 } 801 }
830 return false; 802 return false;
831 } 803 }
832 804
833 /** 805 /**
806 * Check for the passed class declaration for the
807 * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
808 *
809 * @param node the class declaration to check
810 * @return `true` if and only if a hint code is generated on the passed node
811 * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
812 */
813 // bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
814 // ClassElement classElement = node.element;
815 // if (classElement == null) {
816 // return false;
817 // }
818 // MethodElement equalsOperatorMethodElement =
819 // classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
820 // if (equalsOperatorMethodElement != null) {
821 // PropertyAccessorElement hashCodeElement =
822 // classElement.getGetter(_HASHCODE_GETTER_NAME);
823 // if (hashCodeElement == null) {
824 // _errorReporter.reportErrorForNode(
825 // HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
826 // node.name,
827 // [classElement.displayName]);
828 // return true;
829 // }
830 // }
831 // return false;
832 // }
833
834 /**
835 * Generate a hint for `noSuchMethod` methods that do nothing except of
836 * calling another `noSuchMethod` that is not defined by `Object`.
837 *
838 * @return `true` if and only if a hint code is generated on the passed node
839 * See [HintCode.UNNECESSARY_NO_SUCH_METHOD].
840 */
841 bool _checkForUnnecessaryNoSuchMethod(MethodDeclaration node) {
842 if (node.name.name != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
843 return false;
844 }
845 bool isNonObjectNoSuchMethodInvocation(Expression invocation) {
846 if (invocation is MethodInvocation &&
847 invocation.target is SuperExpression &&
848 invocation.argumentList.arguments.length == 1) {
849 SimpleIdentifier name = invocation.methodName;
850 if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
851 Element methodElement = name.staticElement;
852 Element classElement = methodElement?.enclosingElement;
853 return methodElement is MethodElement &&
854 classElement is ClassElement &&
855 !classElement.type.isObject;
856 }
857 }
858 return false;
859 }
860 FunctionBody body = node.body;
861 if (body is ExpressionFunctionBody) {
862 if (isNonObjectNoSuchMethodInvocation(body.expression)) {
863 _errorReporter.reportErrorForNode(
864 HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
865 return true;
866 }
867 } else if (body is BlockFunctionBody) {
868 List<Statement> statements = body.block.statements;
869 if (statements.length == 1) {
870 Statement returnStatement = statements.first;
871 if (returnStatement is ReturnStatement &&
872 isNonObjectNoSuchMethodInvocation(returnStatement.expression)) {
873 _errorReporter.reportErrorForNode(
874 HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
875 return true;
876 }
877 }
878 }
879 return false;
880 }
881
882 /**
834 * Check for situations where the result of a method or function is used, when it returns 'void'. 883 * Check for situations where the result of a method or function is used, when it returns 'void'.
835 * 884 *
836 * TODO(jwren) Many other situations of use could be covered. We currently cov er the cases var x = 885 * TODO(jwren) Many other situations of use could be covered. We currently cov er the cases var x =
837 * m() and x = m(), but we could also cover cases such as m().x, m()[k], a + m (), f(m()), return 886 * m() and x = m(), but we could also cover cases such as m().x, m()[k], a + m (), f(m()), return
838 * m(). 887 * m().
839 * 888 *
840 * @param node expression on the RHS of some assignment 889 * @param node expression on the RHS of some assignment
841 * @return `true` if and only if a hint code is generated on the passed node 890 * @return `true` if and only if a hint code is generated on the passed node
842 * See [HintCode.USE_OF_VOID_RESULT]. 891 * See [HintCode.USE_OF_VOID_RESULT].
843 */ 892 */
(...skipping 15227 matching lines...) Expand 10 before | Expand all | Expand 10 after
16071 nonFields.add(node); 16120 nonFields.add(node);
16072 return null; 16121 return null;
16073 } 16122 }
16074 16123
16075 @override 16124 @override
16076 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); 16125 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this);
16077 16126
16078 @override 16127 @override
16079 Object visitWithClause(WithClause node) => null; 16128 Object visitWithClause(WithClause node) => null;
16080 } 16129 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/error.dart ('k') | pkg/analyzer/test/generated/resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698