guava type migration: refactored to merge slightly different places together and reduce count of rules

This commit is contained in:
Dmitry Batkovich
2015-12-30 17:10:27 +03:00
parent b77ef2c4b2
commit 1eddae8d58
11 changed files with 196 additions and 225 deletions
@@ -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>
@@ -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);
@@ -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;
@@ -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));
}
}
@@ -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;
}
}
@@ -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);
}
}
}
@@ -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$)");
}
@@ -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)) {
@@ -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();
}
}
@@ -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;
}
}
@@ -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) {