diff --git a/java/typeMigration/src/META-INF/TypeMigration.xml b/java/typeMigration/src/META-INF/TypeMigration.xml index 569d03caafd4..c27c63eb1afc 100644 --- a/java/typeMigration/src/META-INF/TypeMigration.xml +++ b/java/typeMigration/src/META-INF/TypeMigration.xml @@ -11,9 +11,9 @@ - + + - com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java index f54b089f8614..f1d4635a8c0e 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java @@ -266,7 +266,7 @@ public class GuavaInspection extends BaseJavaLocalInspectionTool { } else { LOG.assertTrue(substitutionMap.size() == 2); - LOG.assertTrue(GuavaFunctionConversionRule.JAVA_UTIL_FUNCTION_FUNCTION.equals(targetClass.getQualifiedName())); + LOG.assertTrue(GuavaLambda.FUNCTION.getJavaAnalogueClassQName().equals(targetClass.getQualifiedName())); final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(currentType); final List types = new ArrayList(substitutionMap.values()); types.remove(returnType); diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/FluentIterableConversionUtil.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/FluentIterableConversionUtil.java index 4e2275a23719..d986896c3b8d 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/FluentIterableConversionUtil.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/FluentIterableConversionUtil.java @@ -127,7 +127,7 @@ public class FluentIterableConversionUtil { if (CommonClassNames.JAVA_LANG_CLASS.equals(resolvedClass.getQualifiedName())) { return new GuavaFilterInstanceOfConversionDescriptor(); } - else if (GuavaPredicateConversionRule.GUAVA_PREDICATE.equals(resolvedClass.getQualifiedName())) { + else if (GuavaLambda.PREDICATE.getClassQName().equals(resolvedClass.getQualifiedName())) { return new GuavaTypeConversionDescriptor("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)"); } return null; diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java index a0da3dbc5d26..44c1b1613520 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaConversionUtil.java @@ -15,9 +15,12 @@ */ package com.intellij.refactoring.typeMigration.rules.guava; +import com.intellij.codeInspection.AnonymousCanBeLambdaInspection; import com.intellij.psi.*; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.refactoring.typeMigration.TypeEvaluator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -25,7 +28,6 @@ import org.jetbrains.annotations.Nullable; * @author Dmitry Batkovich */ public class GuavaConversionUtil { - @Nullable public static PsiType getFunctionReturnType(PsiExpression functionExpression) { if (functionExpression instanceof PsiFunctionalExpression) { @@ -42,7 +44,7 @@ public class GuavaConversionUtil { currentType = null; for (PsiType type : superTypes) { final PsiClass aClass = PsiTypesUtil.getPsiClass(type); - if (aClass != null && InheritanceUtil.isInheritor(aClass, GuavaFunctionConversionRule.GUAVA_FUNCTION)) { + if (aClass != null && InheritanceUtil.isInheritor(aClass, GuavaLambda.FUNCTION.getClassQName())) { currentType = type; break; } @@ -62,7 +64,70 @@ public class GuavaConversionUtil { parameterText = canonicalText.substring(canonicalText.indexOf('<')); } } - return JavaPsiFacade.getElementFactory(context.getProject()).createTypeFromText(baseClassQualifiedName + parameterText, context); } + + public static boolean isJavaLambda(PsiElement element, TypeEvaluator evaluator) { + if (element instanceof PsiLocalVariable) { + return GuavaLambda.findJavaAnalogueFor(evaluator.getType(element)) != null; + } + else if (element instanceof PsiReturnStatement) { + final PsiElement methodOrLambda = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiLambdaExpression.class); + PsiType methodReturnType = null; + if (methodOrLambda instanceof PsiMethod) { + methodReturnType = evaluator.getType(methodOrLambda); + } + return GuavaLambda.findJavaAnalogueFor(methodReturnType) != null; + } + else if (element instanceof PsiExpressionList) { + final PsiElement parent = element.getParent(); + if (parent instanceof PsiMethodCallExpression) { + return evaluator.getType(parent) != null; + } + } + return false; + } + + public static PsiExpression adjust(PsiExpression expression, boolean insertTypeCase, PsiType targetType, TypeEvaluator evaluator) { + if (expression instanceof PsiNewExpression) { + final PsiAnonymousClass anonymousClass = ((PsiNewExpression)expression).getAnonymousClass(); + if (anonymousClass != null) { + if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(anonymousClass, true)) { + return AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(expression, true, true); + } + } + else { + return addApplyReference(expression, evaluator); + } + } + if (expression instanceof PsiMethodReferenceExpression) { + final PsiExpression qualifier = ((PsiMethodReferenceExpression)expression).getQualifierExpression(); + final PsiType evaluatedType = evaluator.evaluateType(qualifier); + final GuavaLambda lambda = GuavaLambda.findJavaAnalogueFor(evaluatedType); + if (lambda != null) { + return adjust((PsiExpression)expression.replace(qualifier), insertTypeCase, targetType, evaluator); + } + } + if (expression instanceof PsiFunctionalExpression) { + if (insertTypeCase) { + return JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText("((" + targetType.getCanonicalText() + ")" + expression.getText() + ")", expression); + } + } + else if (expression instanceof PsiMethodCallExpression || expression instanceof PsiReferenceExpression) { + final GuavaLambda lambda = GuavaLambda.findFor(evaluator.evaluateType(expression)); + if (lambda != null) { + expression = (PsiExpression)expression.replace(JavaPsiFacade.getElementFactory(expression.getProject()) + .createExpressionFromText(expression.getText() + "::" + lambda.getSamName(), expression)); + return adjust(expression, insertTypeCase, targetType, evaluator); + } + } + return expression; + } + + private static PsiExpression addApplyReference(final PsiExpression expression, TypeEvaluator evaluator) { + final GuavaLambda lambda = GuavaLambda.findFor(evaluator.evaluateType(expression)); + return lambda == null ? expression + : (PsiExpression)expression.replace(JavaPsiFacade.getElementFactory(expression.getProject()) + .createExpressionFromText(expression.getText() + "::" + lambda.getSamName(), null)); + } } diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java new file mode 100644 index 000000000000..7e61849e21e3 --- /dev/null +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambda.java @@ -0,0 +1,83 @@ +/* + * Copyright 2000-2015 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.refactoring.typeMigration.rules.guava; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiType; +import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTypesUtil; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dmitry Batkovich + */ +public enum GuavaLambda { + PREDICATE("com.google.common.base.Predicate", "java.util.function.Predicate", "apply", "test"), + FUNCTION("com.google.common.base.Function", "java.util.function.Function", "apply", "apply"), + SUPPLIER("com.google.common.base.Supplier", "java.util.function.Supplier", "get", "get"); + + private final String myClassQName; + private final String myJavaAnalogueClassQName; + private final String mySamName; + private final String myJavaAnalogueSamName; + + GuavaLambda(String classQName, String javaAnalogueClassQName, String samName, String javaAnalogueSamName) { + myClassQName = classQName; + myJavaAnalogueClassQName = javaAnalogueClassQName; + mySamName = samName; + myJavaAnalogueSamName = javaAnalogueSamName; + } + + public String getClassQName() { + return myClassQName; + } + + public String getJavaAnalogueClassQName() { + return myJavaAnalogueClassQName; + } + + public String getSamName() { + return mySamName; + } + + public String getJavaAnalogueSamName() { + return myJavaAnalogueSamName; + } + + @Nullable + static GuavaLambda findFor(@Nullable PsiType type) { + final PsiClass aClass = PsiTypesUtil.getPsiClass(type); + if (aClass == null) return null; + for (GuavaLambda lambda : values()) { + if (InheritanceUtil.isInheritor(aClass, lambda.getClassQName())) { + return lambda; + } + } + return null; + } + + @Nullable + static GuavaLambda findJavaAnalogueFor(@Nullable PsiType type) { + final PsiClass aClass = PsiTypesUtil.getPsiClass(type); + if (aClass == null) return null; + for (GuavaLambda lambda : values()) { + if (InheritanceUtil.isInheritor(aClass, lambda.getJavaAnalogueClassQName())) { + return lambda; + } + } + return null; + } +} diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFunctionConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambdaConversionRule.java similarity index 62% rename from java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFunctionConversionRule.java rename to java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambdaConversionRule.java index 146e19716f87..eaa1d5448c16 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaFunctionConversionRule.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaLambdaConversionRule.java @@ -18,7 +18,6 @@ package com.intellij.refactoring.typeMigration.rules.guava; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiReferenceExpression; import com.intellij.psi.PsiVariable; -import com.intellij.refactoring.typeMigration.TypeConversionDescriptor; import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,31 +27,48 @@ import java.util.Map; /** * @author Dmitry Batkovich */ -public class GuavaFunctionConversionRule extends BaseGuavaTypeConversionRule { - public static final String JAVA_UTIL_FUNCTION_FUNCTION = "java.util.function.Function"; - public static final String GUAVA_FUNCTION = "com.google.common.base.Function"; +public class GuavaLambdaConversionRule extends BaseGuavaTypeConversionRule { + private final GuavaLambda myLambda; + + protected GuavaLambdaConversionRule(GuavaLambda lambda) { + myLambda = lambda; + } @Override protected void fillSimpleDescriptors(Map descriptorsMap) { - descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "apply", JAVA_UTIL_FUNCTION_FUNCTION)); + descriptorsMap.put(myLambda.getSamName(), new FunctionalInterfaceTypeConversionDescriptor(myLambda.getSamName(), myLambda.getJavaAnalogueSamName(), myLambda.getJavaAnalogueClassQName())); } @Nullable @Override protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression, @NotNull PsiVariable psiVariable, PsiExpression context) { - return new FunctionalInterfaceTypeConversionDescriptor("apply", "apply", JAVA_UTIL_FUNCTION_FUNCTION); + return new FunctionalInterfaceTypeConversionDescriptor(myLambda.getSamName(), myLambda.getJavaAnalogueSamName(), myLambda.getJavaAnalogueClassQName()); } @NotNull @Override public String ruleFromClass() { - return GUAVA_FUNCTION; + return myLambda.getClassQName(); } @NotNull @Override public String ruleToClass() { - return JAVA_UTIL_FUNCTION_FUNCTION; + return myLambda.getJavaAnalogueClassQName(); } + + public static class Function extends GuavaLambdaConversionRule { + public Function() { + super(GuavaLambda.FUNCTION); + } + } + + public static class Supplier extends GuavaLambdaConversionRule { + public Supplier() { + super(GuavaLambda.SUPPLIER); + } + } + } + diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java index 99183a4122c8..23cb786295a0 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaOptionalConversionRule.java @@ -73,7 +73,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule { } return descriptor; } - return GuavaSupplierConversionRule.GUAVA_SUPPLIER.equals(qName) + return GuavaLambda.SUPPLIER.getClassQName().equals(qName) ? new GuavaTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)") : new TypeConversionDescriptor("$val$.or($other$)", "$val$.orElse($other$)"); } diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicateConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicateConversionRule.java index d953cc4789cb..b280fecdda60 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicateConversionRule.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicateConversionRule.java @@ -31,30 +31,19 @@ import java.util.Set; /** * @author Dmitry Batkovich */ -public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule { - static final String GUAVA_PREDICATE = "com.google.common.base.Predicate"; - static final String JAVA_PREDICATE = "java.util.function.Predicate"; - +public class GuavaPredicateConversionRule extends GuavaLambdaConversionRule { private static final String GUAVA_PREDICATES_UTILITY = "com.google.common.base.Predicates"; + protected GuavaPredicateConversionRule() { + super(GuavaLambda.PREDICATE); + } + @NotNull @Override protected Set getAdditionalUtilityClasses() { return Collections.singleton(GUAVA_PREDICATES_UTILITY); } - @Override - protected void fillSimpleDescriptors(Map descriptorsMap) { - descriptorsMap.put("apply", new FunctionalInterfaceTypeConversionDescriptor("apply", "test", JAVA_PREDICATE)); - } - - @Nullable - @Override - protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression, - @NotNull PsiVariable psiVariable, PsiExpression context) { - return new FunctionalInterfaceTypeConversionDescriptor("apply", "test", JAVA_PREDICATE); - } - @Nullable @Override protected TypeConversionDescriptorBase findConversionForMethod(PsiType from, @@ -81,18 +70,6 @@ public class GuavaPredicateConversionRule extends BaseGuavaTypeConversionRule { }; } - @NotNull - @Override - public String ruleFromClass() { - return GUAVA_PREDICATE; - } - - @NotNull - @Override - public String ruleToClass() { - return JAVA_PREDICATE; - } - public static boolean isPredicates(PsiMethodCallExpression expression) { final String methodName = expression.getMethodExpression().getReferenceName(); if (GuavaPredicatesUtil.PREDICATES_METHOD_NAMES.contains(methodName)) { diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicatesUtil.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicatesUtil.java index 16a3d04fc0a1..c3dd18f0bbd5 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicatesUtil.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaPredicatesUtil.java @@ -18,6 +18,7 @@ package com.intellij.refactoring.typeMigration.rules.guava; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.RedundantCastUtil; @@ -57,10 +58,10 @@ public class GuavaPredicatesUtil { } if (!isConvertablePredicatesMethod(method)) return null; if (PREDICATES_AND_OR.contains(name) && canMigrateAndOrOr((PsiMethodCallExpression)context)) { - return new AndOrOrConversionDescriptor(GuavaConversionUtil.addTypeParameters(GuavaPredicateConversionRule.JAVA_PREDICATE, context.getType(), context)); + return new AndOrOrConversionDescriptor(GuavaConversionUtil.addTypeParameters(GuavaLambda.PREDICATE.getJavaAnalogueClassQName(), context.getType(), context)); } else if (PREDICATES_NOT.equals(name)) { - return new NotConversionDescriptor(GuavaConversionUtil.addTypeParameters(GuavaPredicateConversionRule.JAVA_PREDICATE, context.getType(), context)); + return new NotConversionDescriptor(GuavaConversionUtil.addTypeParameters(GuavaLambda.PREDICATE.getJavaAnalogueClassQName(), context.getType(), context)); } return null; } @@ -129,13 +130,13 @@ public class GuavaPredicatesUtil { @Override public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException { String newExpressionString = - adjust(((PsiMethodCallExpression)expression).getArgumentList().getExpressions()[0], true, myTargetType, evaluator) + ".negate()"; + GuavaConversionUtil.adjust(((PsiMethodCallExpression)expression).getArgumentList().getExpressions()[0], true, myTargetType, evaluator).getText() + ".negate()"; final PsiElement parent = expression.getParent(); if (parent instanceof PsiMethodReferenceExpression) { expression = replaceTypeCast(expression, parent); } - else if (!isJavaPredicate(parent, evaluator)) { + else if (!GuavaConversionUtil.isJavaLambda(parent, evaluator)) { newExpressionString += "::test"; } final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); @@ -167,20 +168,20 @@ public class GuavaPredicatesUtil { final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions(); final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(expression.getProject()); if (arguments.length == 1) { - return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(adjust(arguments[0], true, myTargetType, evaluator), expression)); + return (PsiExpression)expression.replace(GuavaConversionUtil.adjust(arguments[0], true, myTargetType, evaluator)); } LOG.assertTrue(arguments.length != 0); StringBuilder replaceBy = new StringBuilder(); for (int i = 1; i < arguments.length; i++) { PsiExpression argument = arguments[i]; - replaceBy.append(".").append(methodName).append("(").append(adjust(argument, false, myTargetType, evaluator)).append(")"); + replaceBy.append(".").append(methodName).append("(").append(GuavaConversionUtil.adjust(argument, false, myTargetType, evaluator).getText()).append(")"); } - replaceBy.insert(0, adjust(arguments[0], true, myTargetType, evaluator)); + replaceBy.insert(0, GuavaConversionUtil.adjust(arguments[0], true, myTargetType, evaluator).getText()); final PsiElement parent = expression.getParent(); if (parent instanceof PsiMethodReferenceExpression) { expression = replaceTypeCast(expression, parent); } - else if (!isJavaPredicate(parent, evaluator)) { + else if (!GuavaConversionUtil.isJavaLambda(parent, evaluator)) { replaceBy.append("::test"); } return (PsiExpression)expression.replace(elementFactory.createExpressionFromText(replaceBy.toString(), expression)); @@ -194,69 +195,11 @@ public class GuavaPredicatesUtil { if (typeElement != null) { final PsiType type = typeElement.getType(); final PsiClass aClass = PsiTypesUtil.getPsiClass(type); - if (aClass != null && GuavaPredicateConversionRule.JAVA_PREDICATE.equals(aClass.getQualifiedName())) { + if (aClass != null && GuavaLambda.PREDICATE.equals(aClass.getQualifiedName())) { expression = (PsiExpression)parParent.replace(expression); } } } return expression; } - - public static boolean isJavaPredicate(PsiElement element, TypeEvaluator evaluator) { - if (element instanceof PsiLocalVariable) { - return isJavaPredicate(evaluator.getType(element)); - } - else if (element instanceof PsiReturnStatement) { - final PsiElement methodOrLambda = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiLambdaExpression.class); - PsiType methodReturnType = null; - if (methodOrLambda instanceof PsiMethod) { - methodReturnType = evaluator.getType(methodOrLambda); - } - return isJavaPredicate(methodReturnType); - } - else if (element instanceof PsiExpressionList) { - final PsiElement parent = element.getParent(); - if (parent instanceof PsiMethodCallExpression) { - return evaluator.getType(parent) != null; - } - } - return false; - } - - private static boolean isJavaPredicate(@Nullable PsiType type) { - PsiClass aClass; - return (aClass = PsiTypesUtil.getPsiClass(type)) != null && GuavaPredicateConversionRule.JAVA_PREDICATE.equals(aClass.getQualifiedName()); - } - - private static boolean isUnconverted(PsiType type) { - final PsiClass predicateClass = PsiTypesUtil.getPsiClass(type); - return predicateClass != null && !GuavaPredicateConversionRule.JAVA_PREDICATE.equals(predicateClass.getQualifiedName()); - } - - private static String adjust(PsiExpression expression, boolean insertTypeCase, PsiType targetType, TypeEvaluator evaluator) { - if (expression instanceof PsiMethodReferenceExpression) { - final PsiExpression qualifier = ((PsiMethodReferenceExpression)expression).getQualifierExpression(); - final PsiType evaluatedType = evaluator.evaluateType(qualifier); - final PsiClass evaluateClass; - if (evaluatedType != null && - (evaluateClass = PsiTypesUtil.getPsiClass(evaluatedType)) != null && - GuavaPredicateConversionRule.JAVA_PREDICATE.equals(evaluateClass.getQualifiedName())) { - return adjust((PsiExpression)expression.replace(qualifier), insertTypeCase, targetType, evaluator); - } - } - if (expression instanceof PsiFunctionalExpression) { - if (insertTypeCase) { - return "((" + targetType.getCanonicalText() + ")" + expression.getText() + ")"; - } - } - else if (expression instanceof PsiMethodCallExpression || expression instanceof PsiReferenceExpression) { - if (isUnconverted(evaluator.evaluateType(expression))) { - expression = (PsiExpression)expression.replace(JavaPsiFacade.getElementFactory(expression.getProject()) - .createExpressionFromText(expression.getText() + "::apply", expression)); - return adjust(expression, insertTypeCase, targetType, evaluator); - } - } - return expression.getText(); - } - } diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaSupplierConversionRule.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaSupplierConversionRule.java deleted file mode 100644 index edf064563321..000000000000 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaSupplierConversionRule.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2000-2015 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.refactoring.typeMigration.rules.guava; - -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiReferenceExpression; -import com.intellij.psi.PsiVariable; -import com.intellij.refactoring.typeMigration.TypeConversionDescriptor; -import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Map; - -/** - * @author Dmitry Batkovich - */ -public class GuavaSupplierConversionRule extends BaseGuavaTypeConversionRule { - public final static String GUAVA_SUPPLIER = "com.google.common.base.Supplier"; - public static final String JAVA_SUPPLIER = "java.util.function.Supplier"; - - @Override - protected void fillSimpleDescriptors(Map descriptorsMap) { - descriptorsMap.put("get", new FunctionalInterfaceTypeConversionDescriptor("get", "get", JAVA_SUPPLIER)); - } - - @Nullable - @Override - protected TypeConversionDescriptorBase findConversionForVariableReference(@NotNull PsiReferenceExpression referenceExpression, - @NotNull PsiVariable psiVariable, PsiExpression context) { - return new FunctionalInterfaceTypeConversionDescriptor("get", "get", JAVA_SUPPLIER); - } - - @NotNull - @Override - public String ruleFromClass() { - return GUAVA_SUPPLIER; - } - - @NotNull - @Override - public String ruleToClass() { - return JAVA_SUPPLIER; - } -} diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaTypeConversionDescriptor.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaTypeConversionDescriptor.java index 2ffa70ce1802..72ad916f9dfd 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaTypeConversionDescriptor.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/rules/guava/GuavaTypeConversionDescriptor.java @@ -55,67 +55,12 @@ public class GuavaTypeConversionDescriptor extends TypeConversionDescriptor { if (myConvertParameterAsLambda) { final PsiExpression[] arguments = methodCall.getArgumentList().getExpressions(); if (arguments.length == 1) { - final PsiExpression functionArg = arguments[0]; - convertParameter(functionArg, evaluator); + GuavaConversionUtil.adjust(arguments[0], false, null, evaluator); } } return super.replace(expression, evaluator); } - private static PsiExpression addApplyReference(final PsiExpression expression, TypeEvaluator evaluator) { - String samMethodName = null; - PsiType type = evaluator.evaluateType(expression); - if (type instanceof PsiClassType) { - PsiClass resolvedClass = ((PsiClassType)type).resolve(); - if (resolvedClass != null) { - final JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(expression.getProject()); - final GlobalSearchScope scope = resolvedClass.getResolveScope(); - if (InheritanceUtil.isInheritorOrSelf(resolvedClass, javaPsiFacade.findClass(GuavaSupplierConversionRule.GUAVA_SUPPLIER, scope), true)) { - samMethodName = "get"; - } - else if (InheritanceUtil.isInheritorOrSelf(resolvedClass, javaPsiFacade.findClass(GuavaFunctionConversionRule.GUAVA_FUNCTION, scope), true) || - InheritanceUtil.isInheritorOrSelf(resolvedClass, javaPsiFacade.findClass(GuavaPredicateConversionRule.GUAVA_PREDICATE, scope), true)) { - samMethodName = "apply"; - } - } - } - if (samMethodName == null) { - return expression; - } - return (PsiExpression)expression.replace( - JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(expression.getText() + "::" + samMethodName, null)); - } - - public static PsiExpression convertParameter(PsiExpression expression, TypeEvaluator evaluator) { - if (expression instanceof PsiNewExpression) { - final PsiAnonymousClass anonymousClass = ((PsiNewExpression)expression).getAnonymousClass(); - if (anonymousClass != null) { - if (AnonymousCanBeLambdaInspection.canBeConvertedToLambda(anonymousClass, true)) { - AnonymousCanBeLambdaInspection.replacePsiElementWithLambda(expression, true, true); - } - } - else { - return addApplyReference(expression, evaluator); - } - } - else if (!(expression instanceof PsiFunctionalExpression)) { - return addApplyReference(expression, evaluator); - } - else if (expression instanceof PsiMethodReferenceExpression) { - final PsiElement qualifier = ((PsiMethodReferenceExpression)expression).getQualifier(); - PsiType qualifierType; - if (qualifier instanceof PsiExpression && (qualifierType = evaluator.evaluateType((PsiExpression)qualifier)) != null) { - final PsiClass qualifierClass = PsiTypesUtil.getPsiClass(qualifierType); - if (qualifierClass != null && (Comparing.equal(qualifierClass.getQualifiedName(), GuavaFunctionConversionRule.JAVA_UTIL_FUNCTION_FUNCTION) || - Comparing.equal(qualifierClass.getQualifiedName(), GuavaOptionalConversionRule.JAVA_OPTIONAL) || - Comparing.equal(qualifierClass.getQualifiedName(), GuavaSupplierConversionRule.JAVA_SUPPLIER) || - Comparing.equal(qualifierClass.getQualifiedName(), GuavaPredicateConversionRule.JAVA_PREDICATE))) - return (PsiExpression)expression.replace(qualifier); - } - } - return expression; - } - public static boolean isIterable(PsiMethodCallExpression expression) { final PsiElement parent = expression.getParent(); if (parent instanceof PsiLocalVariable) {