mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
lambda: intersection type produces conjunction of abstract methods
This commit is contained in:
@@ -97,8 +97,17 @@ public class LambdaHighlightingUtil {
|
||||
@Nullable
|
||||
public static String checkInterfaceFunctional(PsiType functionalInterfaceType) {
|
||||
if (functionalInterfaceType instanceof PsiIntersectionType) {
|
||||
for (PsiType type : ((PsiIntersectionType)functionalInterfaceType).getConjuncts()) {
|
||||
if (checkInterfaceFunctional(type) == null) return null;
|
||||
if (!LambdaUtil.isFunctionalType(functionalInterfaceType)) {
|
||||
int count = 0;
|
||||
for (PsiType type : ((PsiIntersectionType)functionalInterfaceType).getConjuncts()) {
|
||||
if (checkInterfaceFunctional(type) == null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 1) {
|
||||
return "Multiple non-overriding abstract methods found in " + functionalInterfaceType.getPresentableText();
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
|
||||
@@ -103,9 +103,7 @@ public class LambdaUtil {
|
||||
|
||||
public static boolean isFunctionalType(PsiType type) {
|
||||
if (type instanceof PsiIntersectionType) {
|
||||
for (PsiType type1 : ((PsiIntersectionType)type).getConjuncts()) {
|
||||
if (isFunctionalType(type1)) return true;
|
||||
}
|
||||
return extractFunctionalConjunct((PsiIntersectionType)type) != null;
|
||||
}
|
||||
return isFunctionalClass(PsiUtil.resolveGenericsClassInType(type).getElement());
|
||||
}
|
||||
@@ -286,9 +284,8 @@ public class LambdaUtil {
|
||||
} else if (parent instanceof PsiTypeCastExpression) {
|
||||
final PsiType castType = ((PsiTypeCastExpression)parent).getType();
|
||||
if (castType instanceof PsiIntersectionType) {
|
||||
for (PsiType conjunctType : ((PsiIntersectionType)castType).getConjuncts()) {
|
||||
if (getFunctionalInterfaceMethod(conjunctType) != null) return conjunctType;
|
||||
}
|
||||
final PsiType conjunct = extractFunctionalConjunct((PsiIntersectionType)castType);
|
||||
if (conjunct != null) return conjunct;
|
||||
}
|
||||
return castType;
|
||||
}
|
||||
@@ -363,6 +360,19 @@ public class LambdaUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType extractFunctionalConjunct(PsiIntersectionType type) {
|
||||
PsiType conjunct = null;
|
||||
for (PsiType conjunctType : ((PsiIntersectionType)type).getConjuncts()) {
|
||||
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(conjunctType);
|
||||
if (interfaceMethod != null) {
|
||||
if (conjunct != null && !conjunct.equals(conjunctType)) return null;
|
||||
conjunct = conjunctType;
|
||||
}
|
||||
}
|
||||
return conjunct;
|
||||
}
|
||||
|
||||
private static PsiType getFunctionalInterfaceTypeByContainingLambda(@NotNull PsiLambdaExpression parentLambda) {
|
||||
final PsiType parentInterfaceType = parentLambda.getFunctionalInterfaceType();
|
||||
return parentInterfaceType != null ? getFunctionalInterfaceReturnType(parentInterfaceType) : null;
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.io.Serializable;
|
||||
|
||||
class Test {
|
||||
|
||||
interface I {
|
||||
void foo();
|
||||
}
|
||||
|
||||
interface A {
|
||||
void bar(int i);
|
||||
}
|
||||
|
||||
{
|
||||
Object o1 = (Serializable & I) () -> {};
|
||||
Object o2 = (I & Serializable) () -> {};
|
||||
Object o3 = (I & Runnable) <error descr="Multiple non-overriding abstract methods found in Runnable & I">() -> {}</error>;
|
||||
Object o4 = (A & Runnable) <error descr="Multiple non-overriding abstract methods found in Runnable & A">() -> {}</error>;
|
||||
Object o5 = (Runnable & A) <error descr="Multiple non-overriding abstract methods found in Runnable & A">() -> {}</error>;
|
||||
}
|
||||
}
|
||||
@@ -101,6 +101,7 @@ public class LambdaHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testBreakContinueInside() {doTest();}
|
||||
public void testSameLambdaParamNames() {doTest();}
|
||||
public void testIDEA123308() {doTest();}
|
||||
public void testIntersection() {doTest();}
|
||||
|
||||
private void doTest() {
|
||||
doTest(false);
|
||||
|
||||
Reference in New Issue
Block a user