mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
guava type migration: refactored to merge slightly different places together and reduce count of rules
This commit is contained in:
@@ -11,9 +11,9 @@
|
||||
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaOptionalConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaFluentIterableConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaFunctionConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaLambdaConversionRule$Function"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaLambdaConversionRule$Supplier"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaPredicateConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.GuavaSupplierConversionRule"/>
|
||||
<conversion.rule implementation="com.intellij.refactoring.typeMigration.rules.guava.IterableStreamConversionRule"/>
|
||||
<intentionAction>
|
||||
<className>com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention</className>
|
||||
|
||||
+1
-1
@@ -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<PsiType> types = new ArrayList<PsiType>(substitutionMap.values());
|
||||
types.remove(returnType);
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
+68
-3
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
+83
@@ -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;
|
||||
}
|
||||
}
|
||||
+24
-8
@@ -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<String, TypeConversionDescriptorBase> 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -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$)");
|
||||
}
|
||||
|
||||
+5
-28
@@ -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<String> getAdditionalUtilityClasses() {
|
||||
return Collections.singleton(GUAVA_PREDICATES_UTILITY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillSimpleDescriptors(Map<String, TypeConversionDescriptorBase> 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)) {
|
||||
|
||||
+10
-67
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-58
@@ -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<String, TypeConversionDescriptorBase> 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;
|
||||
}
|
||||
}
|
||||
+1
-56
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user