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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/lib/src/generated/resolver.dart
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 462339a3d483b39467104bab8b86eb9f0caf6ae0..f853a2dc0e1ed25395f33300fa7a8735ec562358 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -214,6 +214,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
// This was determined to not be a good hint, see: dartbug.com/16029
//checkForOverridingPrivateMember(node);
_checkForMissingReturn(node.returnType, node.body);
+ _checkForUnnecessaryNoSuchMethod(node);
return super.visitMethodDeclaration(node);
}
@@ -753,35 +754,6 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
/**
- * Check for the passed class declaration for the
- * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
- *
- * @param node the class declaration to check
- * @return `true` if and only if a hint code is generated on the passed node
- * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
- */
-// bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
-// ClassElement classElement = node.element;
-// if (classElement == null) {
-// return false;
-// }
-// MethodElement equalsOperatorMethodElement =
-// classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
-// if (equalsOperatorMethodElement != null) {
-// PropertyAccessorElement hashCodeElement =
-// classElement.getGetter(_HASHCODE_GETTER_NAME);
-// if (hashCodeElement == null) {
-// _errorReporter.reportErrorForNode(
-// HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
-// node.name,
-// [classElement.displayName]);
-// return true;
-// }
-// }
-// return false;
-// }
-
- /**
* Check for the passed as expression for the [HintCode.UNNECESSARY_CAST] hint code.
*
* @param node the as expression to check
@@ -831,6 +803,83 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
}
/**
+ * Check for the passed class declaration for the
+ * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+ *
+ * @param node the class declaration to check
+ * @return `true` if and only if a hint code is generated on the passed node
+ * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
+ */
+// bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
+// ClassElement classElement = node.element;
+// if (classElement == null) {
+// return false;
+// }
+// MethodElement equalsOperatorMethodElement =
+// classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
+// if (equalsOperatorMethodElement != null) {
+// PropertyAccessorElement hashCodeElement =
+// classElement.getGetter(_HASHCODE_GETTER_NAME);
+// if (hashCodeElement == null) {
+// _errorReporter.reportErrorForNode(
+// HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+// node.name,
+// [classElement.displayName]);
+// return true;
+// }
+// }
+// return false;
+// }
+
+ /**
+ * Generate a hint for `noSuchMethod` methods that do nothing except of
+ * calling another `noSuchMethod` that is not defined by `Object`.
+ *
+ * @return `true` if and only if a hint code is generated on the passed node
+ * See [HintCode.UNNECESSARY_NO_SUCH_METHOD].
+ */
+ bool _checkForUnnecessaryNoSuchMethod(MethodDeclaration node) {
+ if (node.name.name != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+ return false;
+ }
+ bool isNonObjectNoSuchMethodInvocation(Expression invocation) {
+ if (invocation is MethodInvocation &&
+ invocation.target is SuperExpression &&
+ invocation.argumentList.arguments.length == 1) {
+ SimpleIdentifier name = invocation.methodName;
+ if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+ Element methodElement = name.staticElement;
+ Element classElement = methodElement?.enclosingElement;
+ return methodElement is MethodElement &&
+ classElement is ClassElement &&
+ !classElement.type.isObject;
+ }
+ }
+ return false;
+ }
+ FunctionBody body = node.body;
+ if (body is ExpressionFunctionBody) {
+ if (isNonObjectNoSuchMethodInvocation(body.expression)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+ return true;
+ }
+ } else if (body is BlockFunctionBody) {
+ List<Statement> statements = body.block.statements;
+ if (statements.length == 1) {
+ Statement returnStatement = statements.first;
+ if (returnStatement is ReturnStatement &&
+ isNonObjectNoSuchMethodInvocation(returnStatement.expression)) {
+ _errorReporter.reportErrorForNode(
+ HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Check for situations where the result of a method or function is used, when it returns 'void'.
*
* TODO(jwren) Many other situations of use could be covered. We currently cover the cases var x =
« 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