diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/BoundedWildcardInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/BoundedWildcardInspection.java index bd15eac2641e..573e3d3c19c3 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/BoundedWildcardInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/BoundedWildcardInspection.java @@ -337,11 +337,11 @@ public class BoundedWildcardInspection extends AbstractBaseJavaLocalInspectionTo if (PsiTreeUtil.isAncestor(ignoreUsagesIn, ref.getElement(), false)) return true; PsiMethod calledMethod = getMethodCallOnReference(ref); if (calledMethod == null) { - if (isInPolyadicExpression(ref)) return true; // ignore "x == y" + if (isInPolyadicOrInstanceOf(ref)) return true; // ignore "x == y" PsiField field = isAssignedToField(ref); if (field != null) { // check if e.g. "Processor field" is used in "field.process(xxx)" only - PsiElement ignoreUsagesInAssignment = PsiUtil.skipParenthesizedExprUp(ref.getElement().getParent()); + PsiElement ignoreUsagesInAssignment = skipParensAndCastsUp(ref.getElement()); PsiFile fieldFile = field.getContainingFile(); Variance fv = fieldFile == null ? Variance.INVARIANT : getVariance(field, new LocalSearchScope(fieldFile), ignoreUsagesInAssignment, containingMethod, typeParameter, extendsT, superT); @@ -385,7 +385,7 @@ public class BoundedWildcardInspection extends AbstractBaseJavaLocalInspectionTo @NotNull PsiClassReferenceType suggestedMethodParameterType, @NotNull PsiMethod myself) { PsiElement refElement = ref.getElement(); - PsiElement parent = PsiUtil.skipParenthesizedExprUp(refElement.getParent()); + PsiElement parent = skipParensAndCastsUp(refElement); if (!(parent instanceof PsiExpressionList)) return false; List exprs = Arrays.asList(((PsiExpressionList)parent).getExpressions()); int index = ContainerUtil.indexOf(exprs, (Condition)(PsiExpression e) -> PsiTreeUtil.isAncestor(e, refElement, false)); @@ -421,12 +421,37 @@ public class BoundedWildcardInspection extends AbstractBaseJavaLocalInspectionTo return TypeConversionUtil.isAssignable(paramType, capturedSuggested); } + private static PsiElement skipParensAndCastsUp(@NotNull PsiElement element) { + PsiElement prev = element; + PsiElement parent = element.getParent(); + while (parent instanceof PsiParenthesizedExpression || + parent instanceof PsiTypeCastExpression && ((PsiTypeCastExpression)parent).getOperand() == prev) { + prev = parent; + parent = parent.getParent(); + } + return parent; + + } + + private static PsiExpression skipParensAndCastsDown(@Nullable PsiExpression element) { + while (element instanceof PsiParenthesizedExpression || element instanceof PsiTypeCastExpression) { + if (element instanceof PsiParenthesizedExpression) { + element = ((PsiParenthesizedExpression)element).getExpression(); + } + if (element instanceof PsiTypeCastExpression) { + element = ((PsiTypeCastExpression)element).getOperand(); + } + } + return element; + + } + private static PsiMethod getMethodCallOnReference(@NotNull PsiReference ref) { PsiElement refElement = ref.getElement(); - PsiElement parent = PsiUtil.skipParenthesizedExprUp(refElement.getParent()); + PsiElement parent = skipParensAndCastsUp(refElement); if (!(parent instanceof PsiReferenceExpression)) return null; PsiReferenceExpression refExpression = (PsiReferenceExpression)parent; - if (!refElement.equals(PsiUtil.skipParenthesizedExprDown(refExpression.getQualifierExpression()))) { + if (!refElement.equals(skipParensAndCastsDown(refExpression.getQualifierExpression()))) { return null; } // "foo(parameter::consume)" variance is equivalent to "parameter.consume(xxx)" @@ -447,9 +472,9 @@ public class BoundedWildcardInspection extends AbstractBaseJavaLocalInspectionTo private static boolean isIteratedValueInForeachExpression(@NotNull PsiReference ref) { PsiElement refElement = ref.getElement(); - PsiElement parent = PsiUtil.skipParenthesizedExprUp(refElement.getParent()); + PsiElement parent = skipParensAndCastsUp(refElement); if (!(parent instanceof PsiForeachStatement)) return false; - PsiExpression iteratedValue = PsiUtil.skipParenthesizedExprDown(((PsiForeachStatement)parent).getIteratedValue()); + PsiExpression iteratedValue = skipParensAndCastsDown(((PsiForeachStatement)parent).getIteratedValue()); if (iteratedValue != ref) return false; PsiType type = iteratedValue.getType(); @@ -459,22 +484,22 @@ public class BoundedWildcardInspection extends AbstractBaseJavaLocalInspectionTo return aClass != null; } - private static boolean isInPolyadicExpression(@NotNull PsiReference ref) { + private static boolean isInPolyadicOrInstanceOf(@NotNull PsiReference ref) { PsiElement refElement = ref.getElement(); - PsiElement parent = PsiUtil.skipParenthesizedExprUp(refElement.getParent()); - return parent instanceof PsiPolyadicExpression; + PsiElement parent = skipParensAndCastsUp(refElement); + return parent instanceof PsiPolyadicExpression || parent instanceof PsiInstanceOfExpression; } private static PsiField isAssignedToField(@NotNull PsiReference ref) { PsiElement refElement = ref.getElement(); - PsiElement parent = PsiUtil.skipParenthesizedExprUp(refElement.getParent()); + PsiElement parent = skipParensAndCastsUp(refElement); if (!(parent instanceof PsiAssignmentExpression) || ((PsiAssignmentExpression)parent).getOperationTokenType() != JavaTokenType.EQ) return null; PsiExpression r = ((PsiAssignmentExpression)parent).getRExpression(); if (!PsiTreeUtil.isAncestor(r, refElement, false)) return null; - PsiExpression l = PsiUtil.skipParenthesizedExprDown(((PsiAssignmentExpression)parent).getLExpression()); + PsiExpression l = skipParensAndCastsDown(((PsiAssignmentExpression)parent).getLExpression()); if (!(l instanceof PsiReferenceExpression)) return null; PsiReferenceExpression lExpression = (PsiReferenceExpression)l; - PsiExpression lQualifier = PsiUtil.skipParenthesizedExprDown(lExpression.getQualifierExpression()); + PsiExpression lQualifier = skipParensAndCastsDown(lExpression.getQualifierExpression()); if (lQualifier != null && !(lQualifier instanceof PsiThisExpression)) return null; PsiElement field = lExpression.resolve(); // too expensive to search for usages of public field otherwise diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/bounded_wildcard/Simple.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/bounded_wildcard/Simple.java index 903a6c9ac1ad..0e00935672c7 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/style/bounded_wildcard/Simple.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/style/bounded_wildcard/Simple.java @@ -194,4 +194,12 @@ public class Simple { return myProcessor; } } + + ///////// instanceof and cast + boolean castandinstanceof(Processor<Number> p) { + if (p instanceof Number) return ((Number)p).intValue()==0; + if ((p) instanceof Number) return ((Number)(p)).intValue()==0; + return p.process(null); + } + } \ No newline at end of file