guava type migration: support a case when migration chain is an argument of read-only method IDEA-176444

This commit is contained in:
Dmitry Batkovich
2017-07-24 15:37:52 +03:00
parent 3258e44fde
commit c1cf67610f
8 changed files with 51 additions and 18 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -140,7 +140,7 @@ public class FluentIterableConversionUtil {
return new GuavaFilterInstanceOfConversionDescriptor(filterClassName);
}
else if (GuavaLambda.PREDICATE.getClassQName().equals(resolvedClass.getQualifiedName())) {
return new GuavaTypeConversionDescriptor("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)");
return new GuavaTypeConversionDescriptor("$it$.filter($p$)", "$it$." + StreamApiConstants.FILTER + "($p$)", context);
}
return null;
}
@@ -157,8 +157,8 @@ public class FluentIterableConversionUtil {
}
static class TransformAndConcatConversionRule extends GuavaTypeConversionDescriptor {
public TransformAndConcatConversionRule() {
super("$q$.transformAndConcat($params$)", "$q$.flatMap($params$)");
public TransformAndConcatConversionRule(PsiExpression context) {
super("$q$.transformAndConcat($params$)", "$q$.flatMap($params$)", context);
}
@Override
@@ -272,7 +272,7 @@ public class FluentIterableConversionUtil {
final String returnType;
if ("toMap".equals(methodName) || "uniqueIndex".equals(methodName)) {
final GuavaTypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$it$.$methodName$($f$)",
"$it$.collect(java.util.stream.Collectors.toMap(java.util.function.Function.identity(), $f$))");
"$it$.collect(java.util.stream.Collectors.toMap(java.util.function.Function.identity(), $f$))", context);
return descriptor.withConversionType(GuavaConversionUtil.addTypeParameters(CommonClassNames.JAVA_UTIL_MAP, context.getType(), context));
}
else if ("toList".equals(methodName)) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,8 +78,8 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
myFluentIterableReturnType = fluentIterableReturnType;
}
public TypeConversionDescriptor create() {
GuavaTypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor(myStringToReplace, myReplaceByString);
public TypeConversionDescriptor create(PsiExpression context) {
GuavaTypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor(myStringToReplace, myReplaceByString, context);
if (!myWithLambdaParameter) {
descriptor = descriptor.setConvertParameterAsLambda(false);
}
@@ -176,7 +176,7 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
needSpecifyType = false;
}
else if (methodName.equals("transformAndConcat")) {
descriptorBase = new FluentIterableConversionUtil.TransformAndConcatConversionRule();
descriptorBase = new FluentIterableConversionUtil.TransformAndConcatConversionRule(context);
} else if (methodName.equals("toArray")) {
descriptorBase = FluentIterableConversionUtil.getToArrayDescriptor(from, context);
needSpecifyType = false;
@@ -250,7 +250,7 @@ public class GuavaFluentIterableConversionRule extends BaseGuavaTypeConversionRu
else {
final TypeConversionDescriptorFactory base = DESCRIPTORS_MAP.get(methodName);
if (base != null) {
final TypeConversionDescriptor descriptor = base.create();
final TypeConversionDescriptor descriptor = base.create(context);
needSpecifyType = base.isChainedMethod();
if (needSpecifyType && !base.isFluentIterableReturnType()) {
conversionType = GuavaConversionUtil.addTypeParameters(GuavaOptionalConversionRule.JAVA_OPTIONAL, context.getType(), context);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,7 +74,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
return descriptor;
}
return GuavaLambda.SUPPLIER.getClassQName().equals(qName)
? new GuavaTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)")
? new GuavaTypeConversionDescriptor("$val$.or($other$)", "$val$.orElseGet($other$)", context)
: new TypeConversionDescriptor("$val$.or($other$)", "$val$.orElse($other$)");
}
return null;
@@ -86,7 +86,7 @@ public class GuavaOptionalConversionRule extends BaseGuavaTypeConversionRule {
return null;
}
final PsiExpression functionArgument = arguments[0];
final TypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$val$.transform($fun$)", "$val$.map($fun$)");
final TypeConversionDescriptor descriptor = new GuavaTypeConversionDescriptor("$val$.transform($fun$)", "$val$.map($fun$)", context);
final PsiType typeParameter = GuavaConversionUtil.getFunctionReturnType(functionArgument);
if (typeParameter == null) {
return descriptor;
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,11 +32,15 @@ import org.jetbrains.annotations.Nullable;
public class GuavaTypeConversionDescriptor extends TypeConversionDescriptor {
private static final Logger LOG = Logger.getInstance(GuavaTypeConversionDescriptor.class);
private final String myReplaceByStringSource;
private final boolean myIterable;
private boolean myConvertParameterAsLambda = true;
GuavaTypeConversionDescriptor(@NonNls String stringToReplace, @NonNls String replaceByString) {
GuavaTypeConversionDescriptor(@NonNls String stringToReplace,
@NonNls String replaceByString,
@NotNull PsiExpression expression) {
super(stringToReplace, replaceByString);
myReplaceByStringSource = replaceByString;
myIterable = isIterable(expression);
}
public GuavaTypeConversionDescriptor setConvertParameterAsLambda(boolean convertParameterAsLambda) {
@@ -46,7 +50,7 @@ public class GuavaTypeConversionDescriptor extends TypeConversionDescriptor {
@Override
public PsiExpression replace(PsiExpression expression, @NotNull TypeEvaluator evaluator) throws IncorrectOperationException {
setReplaceByString(myReplaceByStringSource + (isIterable(expression) ? ".collect(java.util.stream.Collectors.toList())" : ""));
setReplaceByString(myReplaceByStringSource + (myIterable ? ".collect(java.util.stream.Collectors.toList())" : ""));
if (myConvertParameterAsLambda) {
LOG.assertTrue(expression instanceof PsiMethodCallExpression);
final PsiExpression[] arguments = ((PsiMethodCallExpression)expression).getArgumentList().getExpressions();
@@ -82,6 +86,9 @@ public class GuavaTypeConversionDescriptor extends TypeConversionDescriptor {
}
}
}
else if (parent instanceof PsiMethodCallExpression) {
return isIterable((PsiExpression)parent);
}
return false;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ public class IterableStreamConversionRule extends TypeConversionRule {
to,
CommonClassNames.JAVA_LANG_ITERABLE,
StreamApiConstants.JAVA_UTIL_STREAM_STREAM)) {
return new GuavaTypeConversionDescriptor("$it$", "$it$").setConvertParameterAsLambda(false);
return new GuavaTypeConversionDescriptor("$it$", "$it$", context).setConvertParameterAsLambda(false);
}
return null;
}
@@ -178,6 +178,10 @@ public class GuavaInspectionTest extends JavaCodeInsightFixtureTestCase {
doTest();
}
public void testConvertFluentIterableAsIterableParameter2() {
doTest();
}
public void testConvertFunctionAsParameter() {
doTest();
}
@@ -0,0 +1,11 @@
import com.google.common.collect.FluentIterable;
import com.google.common.collect.Iterables;
import java.util.ArrayList;
public class Main16 {
void m() {
//read-only method with Iterable<A> parameter
Iterables.cycle(FluentIterable.fro<caret>m(new ArrayList<String>()).transform(s -> s));
}
}
@@ -0,0 +1,11 @@
import com.google.common.collect.Iterables;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class Main16 {
void m() {
//read-only method with Iterable<A> parameter
Iterables.cycle(new ArrayList<String>().stream().map(s -> s).collect(Collectors.toList()));
}
}