redundant cast: don't warn if functional expression corresponds to another interface method (IDEA-140218)

This commit is contained in:
Anna Kozlova
2015-05-13 14:39:06 +02:00
parent 5b175a09bc
commit ad840dea8a
3 changed files with 39 additions and 3 deletions
@@ -330,7 +330,8 @@ public class RedundantCastUtil {
PsiTypeCastExpression castExpression = (PsiTypeCastExpression) deparenthesizeExpression(newArgs[i]);
PsiExpression castOperand = castExpression.getOperand();
if (castOperand == null) return;
castExpression.replace(castOperand);
final PsiMethod oldFunctionalInterfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(castOperand);
newArgs[i] = (PsiExpression)castExpression.replace(castOperand);
if (newCall instanceof PsiEnumConstant) {
// do this manually, because PsiEnumConstantImpl.resolveMethodGenerics() will assert (no containing class for the copy)
final PsiEnumConstant enumConstant = (PsiEnumConstant)expression;
@@ -344,8 +345,13 @@ public class RedundantCastUtil {
} else {
final JavaResolveResult newResult = newCall.resolveMethodGenerics();
if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult() &&
Comparing.equal(((PsiCallExpression)newCall).getType(), ((PsiCallExpression)expression).getType())) {
addToResults(cast);
Comparing.equal(((PsiCallExpression)newCall).getType(), ((PsiCallExpression)expression).getType())) {
final PsiMethod newFunctionalInterfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(newArgs[i]);
if (oldFunctionalInterfaceMethod == null ||
newFunctionalInterfaceMethod != null && (newFunctionalInterfaceMethod == oldFunctionalInterfaceMethod ||
MethodSignatureUtil.isSuperMethod(newFunctionalInterfaceMethod, oldFunctionalInterfaceMethod))) {
addToResults(cast);
}
}
}
}
@@ -0,0 +1,26 @@
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
interface IoFunction<T> extends Consumer<T> {
@Override
default void accept(T t) {}
void acceptX(T t) throws IOException;
}
interface IFunction<T> extends Consumer<T> {
void accept(T t);
}
interface IIFunction<T> extends Consumer<T> {}
class Test {
public static void main(String[] args) {
List<String> strings = Arrays.asList("a", "b", "c");
strings.forEach((IoFunction<String>) arg -> {throw new IOException();});
strings.forEach((<warning descr="Casting 'arg -> {}' to 'IFunction<String>' is redundant">IFunction<String></warning>) arg -> {});
strings.forEach((<warning descr="Casting 'arg -> {}' to 'IIFunction<String>' is redundant">IIFunction<String></warning>) arg -> {});
}
}
@@ -44,6 +44,10 @@ public class LambdaRedundantCastTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testAnotherInterfaceMethodIsPointed() throws Exception {
doTest();
}
private void doTest() {
doTest(BASE_PATH + "/" + getTestName(false) + ".java", true, false);
}