StreamToLoop: fixed method references unwrap when functional interface type parameter is captured wildcard with upper bound

This commit is contained in:
Tagir Valeev
2017-01-20 17:52:44 +07:00
parent ef5e6d4d3d
commit 305c101ca6
3 changed files with 71 additions and 1 deletions
@@ -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.
@@ -143,6 +143,7 @@ abstract class FunctionHelper {
PsiType returnType = interfaceMethod.getReturnType();
if (returnType == null) return null;
returnType = ((PsiClassType)type).resolveGenerics().getSubstitutor().substitute(returnType);
type = fixType(type, expression.getProject());
if (expression instanceof PsiLambdaExpression) {
PsiLambdaExpression lambda = (PsiLambdaExpression)expression;
PsiParameterList list = lambda.getParameterList();
@@ -180,6 +181,29 @@ abstract class FunctionHelper {
return new ComplexExpressionFunctionHelper(returnType, type, interfaceMethod.getName(), expression);
}
private static PsiType fixType(PsiType type, Project project) {
if(type instanceof PsiClassType) {
PsiClassType classType = (PsiClassType)type;
PsiClass aClass = classType.resolve();
if (aClass != null && classType.getParameterCount() != 0) {
PsiType[] parameters = classType.getParameters();
Arrays.asList(parameters).replaceAll(t -> fixType(t, project));
return JavaPsiFacade.getElementFactory(project).createType(aClass, parameters);
}
}
else if(type instanceof PsiArrayType) {
PsiType componentType = ((PsiArrayType)type).getComponentType();
PsiType fixedType = fixType(componentType, project);
if(fixedType != componentType) {
return fixedType.createArrayType();
}
}
else if(type instanceof PsiCapturedWildcardType) {
return ((PsiCapturedWildcardType)type).getUpperBound();
}
return type;
}
@Nullable
private static String tryInlineMethodReference(int paramCount, PsiMethodReferenceExpression methodRef) {
PsiElement element = methodRef.resolve();
@@ -0,0 +1,26 @@
// "Replace Stream API chain with loop" "true"
import java.util.List;
import java.util.OptionalInt;
public class Main {
interface Index {
int asInteger();
}
interface IndexSet<S extends Index> {
List<S> asList();
}
public static OptionalInt min(IndexSet<?> set) {
boolean seen = false;
int best = 0;
for (Index index : set.asList()) {
int i = index.asInteger();
if (!seen || i < best) {
seen = true;
best = i;
}
}
return seen ? OptionalInt.of(best) : OptionalInt.empty();
}
}
@@ -0,0 +1,20 @@
// "Replace Stream API chain with loop" "true"
import java.util.List;
import java.util.OptionalInt;
public class Main {
interface Index {
int asInteger();
}
interface IndexSet<S extends Index> {
List<S> asList();
}
public static OptionalInt min(IndexSet<?> set) {
return set.asList()
.<caret>stream()
.mapToInt(Index::asInteger)
.min();
}
}