IDEA-121621 Java 1.8: "Replace with collect" quick fix inserts unresolved method reference

This commit is contained in:
Anna Kozlova
2014-03-04 15:58:43 +01:00
parent fb14201173
commit e31638ac97
9 changed files with 55 additions and 31 deletions

View File

@@ -88,27 +88,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
protected static PsiCallExpression canBeMethodReferenceProblem(@Nullable final PsiElement body,
final PsiParameter[] parameters,
PsiType functionalInterfaceType) {
PsiCallExpression methodCall = null;
if (body instanceof PsiCallExpression) {
methodCall = (PsiCallExpression)body;
}
else if (body instanceof PsiCodeBlock) {
final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
if (statements.length == 1) {
if (statements[0] instanceof PsiReturnStatement) {
final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue();
if (returnValue instanceof PsiCallExpression) {
methodCall = (PsiCallExpression)returnValue;
}
}
else if (statements[0] instanceof PsiExpressionStatement) {
final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression();
if (expr instanceof PsiCallExpression) {
methodCall = (PsiCallExpression)expr;
}
}
}
}
PsiCallExpression methodCall = extractMethodCallFromBlock(body);
if (methodCall != null) {
final PsiExpressionList argumentList = methodCall.getArgumentList();
@@ -218,6 +198,34 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp
return null;
}
public static PsiCallExpression extractMethodCallFromBlock(PsiElement body) {
PsiCallExpression methodCall = null;
if (body instanceof PsiCallExpression) {
methodCall = (PsiCallExpression)body;
}
else if (body instanceof PsiCodeBlock) {
final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
if (statements.length == 1) {
if (statements[0] instanceof PsiReturnStatement) {
final PsiExpression returnValue = ((PsiReturnStatement)statements[0]).getReturnValue();
if (returnValue instanceof PsiCallExpression) {
methodCall = (PsiCallExpression)returnValue;
}
}
else if (statements[0] instanceof PsiExpressionStatement) {
final PsiExpression expr = ((PsiExpressionStatement)statements[0]).getExpression();
if (expr instanceof PsiCallExpression) {
methodCall = (PsiCallExpression)expr;
}
}
}
}
else if (body instanceof PsiBlockStatement) {
return extractMethodCallFromBlock(((PsiBlockStatement)body).getCodeBlock());
}
return methodCall;
}
@Nullable
private static PsiMethod ensureNonAmbiguousMethod(PsiParameter[] parameters, @NotNull PsiMethod psiMethod) {
String methodName = psiMethod.getName();

View File

@@ -23,6 +23,7 @@ import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.controlFlow.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
@@ -213,8 +214,16 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
final PsiParameter[] parameters = {parameter};
final PsiCallExpression expression = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : body, parameters, null);
final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(expression, null, parameters);
String methodReferenceText = null;
final PsiCallExpression callExpression = LambdaCanBeMethodReferenceInspection.extractMethodCallFromBlock(body);
if (callExpression != null) {
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiClass consumerClass = psiFacade.findClass("java.util.function.Consumer", GlobalSearchScope.allScope(project));
final PsiClassType functionalType = consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, callExpression.getType()) : null;
final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(body instanceof PsiBlockStatement ? ((PsiBlockStatement)body).getCodeBlock() : body, parameters, functionalType);
methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalType, parameters);
}
final String lambdaText = parameter.getName() + " -> " + foreEachText;
final String codeBlock8 = methodReferenceText != null ? methodReferenceText : lambdaText;
PsiExpressionStatement callStatement = (PsiExpressionStatement)JavaPsiFacade.getElementFactory(project).createStatementFromText(iterated + ".forEach(" + codeBlock8 + ");", foreachStatement);
@@ -269,7 +278,14 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
final PsiExpression mapperCall = methodCallExpression.getArgumentList().getExpressions()[0];
final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(mapperCall, null, new PsiParameter[]{parameter});
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiClass functionClass = psiFacade.findClass("java.util.function.Function", GlobalSearchScope.allScope(project));
final PsiClassType functionalInterfaceType = functionClass != null ? psiFacade.getElementFactory().createType(functionClass, parameter.getType(), mapperCall.getType()) : null;
final PsiCallExpression toConvertCall = LambdaCanBeMethodReferenceInspection.canBeMethodReferenceProblem(mapperCall,
new PsiParameter[]{
parameter},
functionalInterfaceType);
final String methodReferenceText = LambdaCanBeMethodReferenceInspection.createMethodReferenceText(toConvertCall, functionalInterfaceType, new PsiParameter[]{parameter});
if (methodReferenceText != null) {
iteration += methodReferenceText;
} else {

View File

@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
List<String> names = persons.stream().map(person::getName).collect(Collectors.toList());
List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
}
}

View File

@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
List<String> names = persons.stream().filter(person -> person != null).map(person::getName).collect(Collectors.toList());
List<String> names = persons.stream().filter(person -> person != null).map(Person::getName).collect(Collectors.toList());
}
}

View File

@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
Set<String> names = persons.stream().map(person::getName).collect(Collectors.toSet());
Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toSet());
}
}

View File

@@ -11,6 +11,6 @@ public class Collect {
Set<String> names = new HashSet<>();
void collectNames(List<Person> persons){
names.addAll(persons.stream().map(person::getName).collect(Collectors.toList()));
names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList()));
}
}

View File

@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons){
Set<String> names = persons.stream().map(person::getName).collect(Collectors.toCollection(() -> new LinkedHashSet<>()));
Set<String> names = persons.stream().map(Person::getName).collect(Collectors.toCollection(() -> new LinkedHashSet<>()));
}
}

View File

@@ -10,6 +10,6 @@ public abstract class Collect implements Collection<String>{
}
void collectNames(List<Person> persons){
addAll(persons.stream().map(person::getName).collect(Collectors.toList()));
addAll(persons.stream().map(Person::getName).collect(Collectors.toList()));
}
}

View File

@@ -10,6 +10,6 @@ public class Collect {
}
void collectNames(List<Person> persons, Set<String> names){
names.addAll(persons.stream().map(person::getName).collect(Collectors.toList()));
names.addAll(persons.stream().map(Person::getName).collect(Collectors.toList()));
}
}