From 1307ac8e7837fd9ff5e83bb592a03399e5ba257a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Thu, 22 Jun 2017 13:00:44 +0300 Subject: [PATCH] abandon isFullyInferred from LambdaUtil --- .../impl/analysis/LambdaHighlightingUtil.java | 29 ----- ...edundantLambdaParameterTypeInspection.java | 43 +------ .../src/com/intellij/psi/LambdaUtil.java | 121 ------------------ ...aCanBeReplacedWithAnonymousInspection.java | 1 - ...ParameterTypeCanBeSpecifiedInspection.java | 3 +- .../ExtractToMethodReferenceIntention.java | 3 +- 6 files changed, 8 insertions(+), 192 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java index 124f6fef5b2a..6cf4c24e7dd2 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LambdaHighlightingUtil.java @@ -112,37 +112,8 @@ public class LambdaHighlightingUtil { if (aClass instanceof PsiTypeParameter) return null; //should be logged as cyclic inference MethodSignature functionalMethod = LambdaUtil.getFunction(aClass); if (functionalMethod != null && functionalMethod.getTypeParameters().length > 0) return "Target method is generic"; - if (checkReturnTypeApplicable(resolveResult, aClass)) { - return "No instance of type " + functionalInterfaceType.getPresentableText() + " exists so that lambda expression can be type-checked"; - } return checkInterfaceFunctional(aClass); } return functionalInterfaceType.getPresentableText() + " is not a functional interface"; } - - private static boolean checkReturnTypeApplicable(PsiClassType.ClassResolveResult resolveResult, final PsiClass aClass) { - final MethodSignature methodSignature = LambdaUtil.getFunction(aClass); - if (methodSignature == null) return false; - - for (PsiTypeParameter parameter : aClass.getTypeParameters()) { - if (parameter.getExtendsListTypes().length == 0) continue; - final PsiType substitution = resolveResult.getSubstitutor().substitute(parameter); - if (substitution instanceof PsiWildcardType && !((PsiWildcardType)substitution).isBounded()) { - boolean depends = false; - for (PsiType paramType : methodSignature.getParameterTypes()) { - if (LambdaUtil.depends(paramType, new LambdaUtil.TypeParamsChecker((PsiMethod)null, aClass) { - @Override - public boolean startedInference() { - return true; - } - }, parameter)) { - depends = true; - break; - } - } - if (!depends) return true; - } - } - return false; - } } diff --git a/java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java b/java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java index efdee9846407..f3b0e6ecf675 100644 --- a/java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/lambda/RedundantLambdaParameterTypeInspection.java @@ -23,9 +23,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.impl.source.resolve.DefaultParameterTypeInferencePolicy; -import com.intellij.psi.infos.MethodCandidateInfo; -import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -55,7 +52,7 @@ public class RedundantLambdaParameterTypeInspection extends BaseJavaBatchLocalIn if (parameter.getTypeElement() == null) return false; } if (parameters.length == 0) return false; - final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(expression, true); + final PsiType functionalInterfaceType = expression.getFunctionalInterfaceType(); if (functionalInterfaceType != null) { final PsiElement lambdaParent = expression.getParent(); if (lambdaParent instanceof PsiExpressionList) { @@ -67,36 +64,15 @@ public class RedundantLambdaParameterTypeInspection extends BaseJavaBatchLocalIn final int idx = LambdaUtil.getLambdaIdx((PsiExpressionList)lambdaParent, expression); if (idx < 0) return false; - final PsiTypeParameter[] typeParameters = method.getTypeParameters(); - final PsiExpression[] arguments = ((PsiExpressionList)lambdaParent).getExpressions(); - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(parameterList.getProject()); - arguments[idx] = javaPsiFacade.getElementFactory().createExpressionFromText( - "(" + StringUtil.join(expression.getParameterList().getParameters(), PsiParameter::getName, ", ") + ") -> {}", expression); - final PsiParameter[] methodParams = method.getParameterList().getParameters(); - final PsiSubstitutor substitutor = javaPsiFacade.getResolveHelper() - .inferTypeArguments(typeParameters, methodParams, arguments, ((MethodCandidateInfo)resolveResult).getSiteSubstitutor(), - gParent, DefaultParameterTypeInferencePolicy.INSTANCE); - - for (PsiTypeParameter parameter : typeParameters) { - final PsiType psiType = substitutor.substitute(parameter); - if (psiType == null || dependsOnTypeParams(psiType, expression, parameter)) return false; + PsiCallExpression copy = (PsiCallExpression)gParent.copy(); + PsiLambdaExpression lambdaToStripTypeParameters = (PsiLambdaExpression)copy.getArgumentList().getExpressions()[idx]; + for (PsiParameter parameter : lambdaToStripTypeParameters.getParameterList().getParameters()) { + parameter.getTypeElement().delete(); } - final PsiType paramType; - if (idx < methodParams.length) { - paramType = methodParams[idx].getType(); - } - else { - final PsiParameter lastParam = methodParams[methodParams.length - 1]; - if (!lastParam.isVarArgs()) return false; - paramType = ((PsiEllipsisType)lastParam.getType()).getComponentType(); - } - return functionalInterfaceType.isAssignableFrom(substitutor.substitute(paramType)); + return functionalInterfaceType.equals(lambdaToStripTypeParameters.getFunctionalInterfaceType()); } } - if (!LambdaUtil.isLambdaFullyInferred(expression, functionalInterfaceType)) { - return false; - } return true; } return false; @@ -118,13 +94,6 @@ public class RedundantLambdaParameterTypeInspection extends BaseJavaBatchLocalIn } } - private static boolean dependsOnTypeParams(PsiType type, - PsiLambdaExpression expr, - PsiTypeParameter param2Check) { - return LambdaUtil.depends(type, new LambdaUtil.TypeParamsChecker(expr, PsiUtil - .resolveGenericsClassInType(LambdaUtil.getFunctionalInterfaceType(expr, false)).getElement()), param2Check); - } - private static class LambdaParametersFix implements LocalQuickFix { @Nls @NotNull diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java index 5aa135fcc2be..a6df241cd27d 100644 --- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java +++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java @@ -154,15 +154,6 @@ public class LambdaUtil { context instanceof PsiArrayInitializerExpression; } - public static boolean isLambdaFullyInferred(PsiLambdaExpression expression, PsiType functionalInterfaceType) { - final boolean hasParams = expression.getParameterList().getParametersCount() > 0; - if (hasParams || !PsiType.VOID.equals(getFunctionalInterfaceReturnType(functionalInterfaceType))) { //todo check that void lambdas without params check - - return !dependsOnTypeParams(functionalInterfaceType, functionalInterfaceType, expression); - } - return true; - } - @Contract("null -> null") @Nullable public static MethodSignature getFunction(final PsiClass psiClass) { @@ -348,23 +339,6 @@ public class LambdaUtil { return -1; } - public static boolean dependsOnTypeParams(PsiType type, - PsiType functionalInterfaceType, - PsiElement lambdaExpression, - PsiTypeParameter... param2Check) { - return depends(type, new TypeParamsChecker(lambdaExpression, - PsiUtil.resolveClassInType(functionalInterfaceType)), param2Check); - } - - public static boolean depends(PsiType type, TypeParamsChecker visitor, PsiTypeParameter... param2Check) { - if (!visitor.startedInference()) return false; - final Boolean accept = type.accept(visitor); - if (param2Check.length > 0) { - return visitor.used(param2Check); - } - return accept != null && accept.booleanValue(); - } - @Nullable public static PsiType getFunctionalInterfaceType(PsiElement expression, final boolean tryToSubstitute) { PsiElement parent = expression.getParent(); @@ -887,99 +861,4 @@ public class LambdaUtil { return expression instanceof PsiReferenceExpression && ((PsiReferenceExpression)expression).isReferenceTo(parameters.getParameters()[0]); } - - public static class TypeParamsChecker extends PsiTypeVisitor { - private PsiMethod myMethod; - private final PsiClass myClass; - public final Set myUsedTypeParams = new HashSet<>(); - - public TypeParamsChecker(PsiElement expression, PsiClass aClass) { - myClass = aClass; - PsiElement parent = expression != null ? expression.getParent() : null; - while (parent instanceof PsiParenthesizedExpression) { - parent = parent.getParent(); - } - if (parent instanceof PsiExpressionList) { - final PsiElement gParent = parent.getParent(); - if (gParent instanceof PsiCall) { - final MethodCandidateInfo.CurrentCandidateProperties pair = MethodCandidateInfo.getCurrentMethod(parent); - myMethod = pair != null ? pair.getMethod() : null; - if (myMethod == null) { - myMethod = ((PsiCall)gParent).resolveMethod(); - } - if (myMethod != null && PsiTreeUtil.isAncestor(myMethod, expression, false)) { - myMethod = null; - } - } - } - } - - public boolean startedInference() { - return myMethod != null; - } - - @Override - public Boolean visitClassType(PsiClassType classType) { - boolean used = false; - for (PsiType paramType : classType.getParameters()) { - final Boolean paramAccepted = paramType.accept(this); - used |= paramAccepted != null && paramAccepted.booleanValue(); - } - final PsiClass resolve = classType.resolve(); - if (resolve instanceof PsiTypeParameter) { - final PsiTypeParameter typeParameter = (PsiTypeParameter)resolve; - if (check(typeParameter)) { - myUsedTypeParams.add(typeParameter); - return true; - } - } - return used; - } - - @Nullable - @Override - public Boolean visitWildcardType(PsiWildcardType wildcardType) { - final PsiType bound = wildcardType.getBound(); - if (bound != null) return bound.accept(this); - return false; - } - - @Nullable - @Override - public Boolean visitCapturedWildcardType(PsiCapturedWildcardType capturedWildcardType) { - return true; - } - - @Nullable - @Override - public Boolean visitLambdaExpressionType(PsiLambdaExpressionType lambdaExpressionType) { - return true; - } - - @Nullable - @Override - public Boolean visitArrayType(PsiArrayType arrayType) { - return arrayType.getComponentType().accept(this); - } - - @Override - public Boolean visitType(PsiType type) { - return false; - } - - private boolean check(PsiTypeParameter check) { - final PsiTypeParameterListOwner owner = check.getOwner(); - if (owner == myMethod || owner == myClass) { - return true; - } - return false; - } - - public boolean used(PsiTypeParameter... parameters) { - for (PsiTypeParameter parameter : parameters) { - if (myUsedTypeParams.contains(parameter)) return true; - } - return false; - } - } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java index 5a6c653ea931..37c2590d583c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaCanBeReplacedWithAnonymousInspection.java @@ -216,7 +216,6 @@ public class LambdaCanBeReplacedWithAnonymousInspection extends BaseInspection { } final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); if (functionalInterfaceType != null && - LambdaUtil.isLambdaFullyInferred(lambdaExpression, functionalInterfaceType) && LambdaUtil.isFunctionalType(functionalInterfaceType)) { final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType); if (interfaceMethod != null) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaParameterTypeCanBeSpecifiedInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaParameterTypeCanBeSpecifiedInspection.java index 4d72d4b73607..34bb84b47719 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaParameterTypeCanBeSpecifiedInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/LambdaParameterTypeCanBeSpecifiedInspection.java @@ -67,8 +67,7 @@ public class LambdaParameterTypeCanBeSpecifiedInspection extends BaseInspection } final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); if (functionalInterfaceType != null && - LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType) != null && - LambdaUtil.isLambdaFullyInferred(lambdaExpression, functionalInterfaceType)) { + LambdaUtil.getFunctionalInterfaceMethod(functionalInterfaceType) != null) { final String inferredTypesText = LambdaRefactoringUtil.createLambdaParameterListWithFormalTypes(functionalInterfaceType, lambdaExpression, true); if (inferredTypesText != null) { diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/functional/ExtractToMethodReferenceIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/functional/ExtractToMethodReferenceIntention.java index 294f6f5074e9..1b7ac54d423d 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/functional/ExtractToMethodReferenceIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/functional/ExtractToMethodReferenceIntention.java @@ -69,8 +69,7 @@ public class ExtractToMethodReferenceIntention extends BaseElementAtCaretIntenti //is a valid lambda PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); if (functionalInterfaceType == null || - LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType) == null || - !LambdaUtil.isLambdaFullyInferred(lambdaExpression, functionalInterfaceType)) { + LambdaUtil.getFunctionalInterfaceReturnType(functionalInterfaceType) == null) { return false; }