From c8b9bb9378de4a5293b6fad8bb482ada8ec687c3 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 9 Jan 2015 15:15:23 +0100 Subject: [PATCH] fix "Auto-unboxing" inspection for method reference expressions --- .../siyeh/ig/jdk/AutoUnboxingInspection.java | 57 ++++++++++++++----- .../jdk/auto_unboxing/AutoUnboxing.java | 19 +++++++ 2 files changed, 61 insertions(+), 15 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java index 07772232f063..3ea947880336 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/jdk/AutoUnboxingInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2014 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2015 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -31,6 +31,7 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.PsiReplacementUtil; +import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.ExpectedTypeUtils; import com.siyeh.ig.psiutils.MethodCallUtils; import org.jetbrains.annotations.NonNls; @@ -75,7 +76,7 @@ public class AutoUnboxingInspection extends BaseInspection { @Override @Nullable public InspectionGadgetsFix buildFix(Object... infos) { - if (!isFixApplicable((PsiExpression)infos[0])) { + if (infos.length == 0 || !isFixApplicable((PsiExpression)infos[0])) { return null; } return new AutoUnboxingFix(); @@ -324,7 +325,38 @@ public class AutoUnboxingInspection extends BaseInspection { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - checkExpression(expression); + if (expression instanceof PsiMethodReferenceExpression) { + final PsiMethodReferenceExpression methodReferenceExpression = (PsiMethodReferenceExpression)expression; + if (methodReferenceExpression.isConstructor()) { + return; + } + final PsiElement referenceNameElement = methodReferenceExpression.getReferenceNameElement(); + if (referenceNameElement == null) { + return; + } + final PsiElement target = methodReferenceExpression.resolve(); + if (!(target instanceof PsiMethod)) { + return; + } + final PsiMethod method = (PsiMethod)target; + final PsiType returnType = method.getReturnType(); + if (!TypeConversionUtil.isAssignableFromPrimitiveWrapper(returnType)) { + return; + } + final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(returnType); + if (unboxedType == null) { + return; + } + final PsiType functionalInterfaceReturnType = LambdaUtil.getFunctionalInterfaceReturnType(methodReferenceExpression); + if (functionalInterfaceReturnType == null || !ClassUtils.isPrimitive(functionalInterfaceReturnType) || + !functionalInterfaceReturnType.isAssignableFrom(unboxedType)) { + return; + } + registerError(referenceNameElement); + } + else { + checkExpression(expression); + } } @Override @@ -367,24 +399,19 @@ public class AutoUnboxingInspection extends BaseInspection { return; } final PsiType expressionType = expression.getType(); - if (expressionType == null) { - return; - } - if (expressionType.getArrayDimensions() > 0) { - // a horrible hack to get around what happens when you pass - // an array to a vararg expression - return; - } - if (TypeConversionUtil.isPrimitiveAndNotNull(expressionType)) { - return; - } if (!TypeConversionUtil.isAssignableFromPrimitiveWrapper(expressionType)) { return; } final PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, false, true); - if (expectedType == null || !TypeConversionUtil.isPrimitiveAndNotNull(expectedType)) { + if (!TypeConversionUtil.isPrimitiveAndNotNull(expectedType)) { return; } + if (!(expression.getParent() instanceof PsiTypeCastExpression)) { + final PsiPrimitiveType unboxedType = PsiPrimitiveType.getUnboxedType(expressionType); + if (unboxedType == null || !expectedType.isAssignableFrom(unboxedType)) { + return; + } + } registerError(expression, expression); } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java index 2629059ef985..702c90f1332d 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/auto_unboxing/AutoUnboxing.java @@ -81,4 +81,23 @@ public class AutoUnboxing { int polymorphicSignature(java.lang.invoke.MethodHandle mh) throws Throwable { return (int)mh.invokeExact(); } + + void lambdas() { + R r = () -> Integer.valueOf(1); + R s = () -> { + return Integer.valueOf(2); + }; + R t = AutoUnboxing::bla; + Runnable z = () -> { + System.out.println(); + }; + } + + static Integer bla() { + return Integer.valueOf(1); + } + + interface R { + int unbox(); + } }