diff --git a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index 896a6b7fe4d9..ff8b9ab6b4f6 100644 --- a/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -16,6 +16,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.daemon.GroupNames; +import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection.MethodReferenceCandidate; import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -82,12 +83,15 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(aClass, true, reportNotAnnotatedInterfaces, Collections.emptySet())) { final PsiMethod method = aClass.getMethods()[0]; final PsiCodeBlock body = method.getBody(); - PsiExpression lambdaBodyCandidate = LambdaCanBeMethodReferenceInspection.extractMethodReferenceCandidateExpression(body, false); - final PsiExpression methodRefCandidate = + MethodReferenceCandidate methodReferenceCandidate = + LambdaCanBeMethodReferenceInspection.extractMethodReferenceCandidateExpression(body); + if (methodReferenceCandidate == null) return; + final PsiExpression candidate = LambdaCanBeMethodReferenceInspection - .canBeMethodReferenceProblem(method.getParameterList().getParameters(), aClass.getBaseClassType(), aClass.getParent(), lambdaBodyCandidate); - if (methodRefCandidate instanceof PsiCallExpression) { - final PsiCallExpression callExpression = (PsiCallExpression)methodRefCandidate; + .canBeMethodReferenceProblem(method.getParameterList().getParameters(), aClass.getBaseClassType(), aClass.getParent(), + methodReferenceCandidate.myExpression); + if (candidate instanceof PsiCallExpression) { + final PsiCallExpression callExpression = (PsiCallExpression)candidate; final PsiMethod resolveMethod = callExpression.resolveMethod(); if (resolveMethod != method && !AnonymousCanBeLambdaInspection.functionalInterfaceMethodReferenced(resolveMethod, aClass, callExpression)) { @@ -98,8 +102,9 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI final PsiElement lBrace = aClass.getLBrace(); LOG.assertTrue(lBrace != null); final TextRange rangeInElement = new TextRange(0, aClass.getStartOffsetInParent() + lBrace.getStartOffsetInParent()); - ProblemHighlightType type = LambdaCanBeMethodReferenceInspection.checkQualifier(lambdaBodyCandidate) ? ProblemHighlightType.LIKE_UNUSED_SYMBOL - : ProblemHighlightType.INFORMATION; + ProblemHighlightType type = methodReferenceCandidate.mySafeQualifier && methodReferenceCandidate.myConformsCodeStyle + ? ProblemHighlightType.LIKE_UNUSED_SYMBOL + : ProblemHighlightType.INFORMATION; ProblemDescriptorBase descriptor = new ProblemDescriptorBase(parent, parent, "Anonymous #ref #loc can be replaced with method reference", new LocalQuickFix[]{new ReplaceWithMethodRefFix()}, @@ -133,8 +138,11 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI final PsiParameter[] parameters = methods[0].getParameterList().getParameters(); final PsiType functionalInterfaceType = anonymousClass.getBaseClassType(); - PsiExpression methodRefCandidate = LambdaCanBeMethodReferenceInspection.extractMethodReferenceCandidateExpression(methods[0].getBody(), false); - final PsiExpression candidate = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(parameters, functionalInterfaceType, anonymousClass.getParent(), methodRefCandidate); + MethodReferenceCandidate methodRefCandidate = + LambdaCanBeMethodReferenceInspection.extractMethodReferenceCandidateExpression(methods[0].getBody()); + if (methodRefCandidate == null) return; + final PsiExpression candidate = LambdaCanBeMethodReferenceInspection + .canBeMethodReferenceProblem(parameters, functionalInterfaceType, anonymousClass.getParent(), methodRefCandidate.myExpression); final String methodRefText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(candidate, functionalInterfaceType, parameters); diff --git a/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index fe7f1bdc5b57..7f78995afe8c 100644 --- a/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/plugins/InspectionGadgets/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 JetBrains s.r.o. + * Copyright 2000-2017 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. @@ -84,33 +84,30 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp if (PsiUtil.getLanguageLevel(expression).isAtLeast(LanguageLevel.JDK_1_8)) { final PsiElement body = expression.getBody(); final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); - if (functionalInterfaceType != null) { - PsiExpression methodRefCandidate = extractMethodReferenceCandidateExpression(body, false); - final PsiExpression candidate = - canBeMethodReferenceProblem(expression.getParameterList().getParameters(), functionalInterfaceType, null, methodRefCandidate); - if (candidate != null) { - PsiExpression qualifier = - methodRefCandidate instanceof PsiMethodCallExpression ? ((PsiMethodCallExpression)methodRefCandidate).getMethodExpression().getQualifierExpression() - : methodRefCandidate instanceof PsiNewExpression - ? ((PsiNewExpression)methodRefCandidate).getQualifier() - : null; - boolean safeQualifier = checkQualifier(qualifier); - ProblemHighlightType type; - if (safeQualifier) { - type = ProblemHighlightType.GENERIC_ERROR_OR_WARNING; - } - else { - if (!isOnTheFly) return; - type = ProblemHighlightType.INFORMATION; - } - PsiElement element = InspectionProjectProfileManager.isInformationLevel(getShortName(), expression) ? expression : candidate; - holder.registerProblem(holder.getManager().createProblemDescriptor( - element, - "Can be replaced with method reference", - type != ProblemHighlightType.INFORMATION, - type, true, new ReplaceWithMethodRefFix(safeQualifier ? "" : " (may change semantics)"))); - } + if (functionalInterfaceType == null) return; + MethodReferenceCandidate methodRefCandidate = extractMethodReferenceCandidateExpression(body); + if (methodRefCandidate == null) return; + final PsiExpression candidate = + canBeMethodReferenceProblem(expression.getParameterList().getParameters(), functionalInterfaceType, null, + methodRefCandidate.myExpression); + if (candidate == null) return; + ProblemHighlightType type; + if (methodRefCandidate.mySafeQualifier && methodRefCandidate.myConformsCodeStyle) { + type = ProblemHighlightType.GENERIC_ERROR_OR_WARNING; } + else { + if (!isOnTheFly) return; + type = ProblemHighlightType.INFORMATION; + } + PsiElement element = + type == ProblemHighlightType.INFORMATION || InspectionProjectProfileManager.isInformationLevel(getShortName(), expression) + ? expression + : candidate; + holder.registerProblem(holder.getManager().createProblemDescriptor( + element, + "Can be replaced with method reference", + type != ProblemHighlightType.INFORMATION, + type, true, new ReplaceWithMethodRefFix(methodRefCandidate.mySafeQualifier ? "" : " (may change semantics)"))); } } }; @@ -121,8 +118,9 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp final PsiVariable[] parameters, PsiType functionalInterfaceType, @Nullable PsiElement context) { - PsiExpression methodRefCandidate = extractMethodReferenceCandidateExpression(body, true); - return canBeMethodReferenceProblem(parameters, functionalInterfaceType, context, methodRefCandidate); + MethodReferenceCandidate methodRefCandidate = extractMethodReferenceCandidateExpression(body); + if (methodRefCandidate == null || !methodRefCandidate.mySafeQualifier || !methodRefCandidate.myConformsCodeStyle) return null; + return canBeMethodReferenceProblem(parameters, functionalInterfaceType, context, methodRefCandidate.myExpression); } @Nullable @@ -263,32 +261,30 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } @Nullable - public static PsiExpression extractMethodReferenceCandidateExpression(PsiElement body, boolean checkSideEffectPureQualifier) { + static MethodReferenceCandidate extractMethodReferenceCandidateExpression(PsiElement body) { final PsiExpression expression = LambdaUtil.extractSingleExpressionFromBody(body); if (expression == null) { return null; } if (expression instanceof PsiNewExpression) { - if (!checkSideEffectPureQualifier || checkQualifier(((PsiNewExpression)expression).getQualifier())) { - return expression; - } + return new MethodReferenceCandidate(expression, checkQualifier(((PsiNewExpression)expression).getQualifier()), true); } else if (expression instanceof PsiMethodCallExpression) { - if (!checkSideEffectPureQualifier || checkQualifier(((PsiMethodCallExpression)expression).getMethodExpression().getQualifier())) { - return expression; - } + return new MethodReferenceCandidate(expression, + checkQualifier(((PsiMethodCallExpression)expression).getMethodExpression().getQualifier()), true); } - if (expression instanceof PsiInstanceOfExpression && CodeStyleSettingsManager.getSettings(expression.getProject()).REPLACE_INSTANCEOF) { - return expression; + if (expression instanceof PsiInstanceOfExpression) { + return new MethodReferenceCandidate(expression, true, + CodeStyleSettingsManager.getSettings(expression.getProject()).REPLACE_INSTANCEOF); } - else if (expression instanceof PsiBinaryExpression && - CodeStyleSettingsManager.getSettings(expression.getProject()).REPLACE_NULL_CHECK) { + else if (expression instanceof PsiBinaryExpression) { if (ExpressionUtils.getValueComparedWithNull((PsiBinaryExpression)expression) != null) { - return expression; + return new MethodReferenceCandidate(expression, true, + CodeStyleSettingsManager.getSettings(expression.getProject()).REPLACE_NULL_CHECK); } } - else if (expression instanceof PsiTypeCastExpression && CodeStyleSettingsManager.getSettings(expression.getProject()).REPLACE_CAST) { + else if (expression instanceof PsiTypeCastExpression) { PsiTypeElement typeElement = ((PsiTypeCastExpression)expression).getCastType(); if (typeElement != null) { PsiJavaCodeReferenceElement refs = typeElement.getInnermostComponentReferenceElement(); @@ -297,7 +293,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } PsiType type = typeElement.getType(); if (type instanceof PsiPrimitiveType || PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter) return null; - return expression; + return new MethodReferenceCandidate(expression, true, CodeStyleSettingsManager.getSettings(expression.getProject()).REPLACE_CAST); } } return null; @@ -639,4 +635,16 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp } return lambda; } + + static class MethodReferenceCandidate { + final PsiExpression myExpression; + final boolean mySafeQualifier; + final boolean myConformsCodeStyle; + + MethodReferenceCandidate(PsiExpression expression, boolean safeQualifier, boolean conformsCodeStyle) { + myExpression = expression; + mySafeQualifier = safeQualifier; + myConformsCodeStyle = conformsCodeStyle; + } + } }