From 0ce4e471d681bec9a54b99debcbd7b3fe78fa802 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 22 Apr 2016 12:48:09 +0200 Subject: [PATCH] IDEA-153192 (Support @CheckReturnValue on classes and packages) --- .../IgnoreResultOfCallInspectionBase.java | 28 ++++++++++++++----- .../IgnoreResultOfCall.html | 3 +- .../IgnoreResultOfCallInspectionTest.groovy | 13 +++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java index 644510df1d04..2881c458dd87 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -148,15 +148,29 @@ public class IgnoreResultOfCallInspectionBase extends BaseInspection { registerMethodCallError(call, aClass); return; } - final PsiAnnotation anno2 = - AnnotationUtil.findAnnotationInHierarchy(method, Collections.singleton("javax.annotation.CheckReturnValue")); - if (anno2 != null) { - registerMethodCallError(call, aClass); - } - if (!myMethodMatcher.matches(method)) { + if (!myMethodMatcher.matches(method) && findAnnotationInTree(method, "javax.annotation.CheckReturnValue") == null) { return; } registerMethodCallError(call, aClass); } + + private PsiAnnotation findAnnotationInTree(PsiMethod method, String fqAnnotationName) { + final PsiAnnotation methodAnnotation = + AnnotationUtil.findAnnotationInHierarchy(method, Collections.singleton(fqAnnotationName)); + if (methodAnnotation != null) { + return methodAnnotation; + } + final PsiClass aClass = method.getContainingClass(); + if (aClass == null) { + return null; + } + final PsiAnnotation classAnnotation = AnnotationUtil.findAnnotation(aClass, fqAnnotationName); + if (classAnnotation != null) { + return classAnnotation; + } + final PsiDirectory directory = aClass.getContainingFile().getContainingDirectory(); + final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(directory); + return AnnotationUtil.findAnnotation(aPackage, fqAnnotationName); + } } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html b/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html index d27bb76bfdc6..f8d1a799a3eb 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/IgnoreResultOfCall.html @@ -2,7 +2,8 @@ Reports any calls to specific methods where the result of that call is ignored. Both methods specified in the inspection's settings and methods annotated with -org.jetbrains.annotations.Contract(pure=true) are checked. +org.jetbrains.annotations.Contract(pure=true) and javax.annotation.CheckReturnValue are checked. +Methods in a class or package annotated with javax.annotation.CheckReturnValue are also checked. For many methods, ignoring the result is perfectly legitimate, but for some methods it is almost certainly an error. Examples of methods where ignoring the result of a call is likely to be an error include java.io.inputStream.read(), diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionTest.groovy b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionTest.groovy index 345ec927aaa6..4bda75f16080 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionTest.groovy +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/IgnoreResultOfCallInspectionTest.groovy @@ -82,6 +82,19 @@ public class IgnoreResultOfCallInspectionTest extends LightInspectionTestCase { "}"); } + public void testJSR305Annotation2() { + doTest("import javax.annotation.CheckReturnValue;" + + "@CheckReturnValue " + + "class A {" + + " static Object a() {" + + " return null;" + + " }" + + " void b() {" + + " /*Result of 'A.a()' is ignored*/a/**/();" + + " }" + + "}"); + } + public void testPureMethod() { doTest """ import org.jetbrains.annotations.Contract;