mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 05:21:29 +07:00
functional interfaces: allow intersection with 2 independent abstract methods with same signature (IDEA-171622)
This commit is contained in:
@@ -514,13 +514,21 @@ public class LambdaUtil {
|
||||
@Nullable
|
||||
private static PsiType extractFunctionalConjunct(PsiIntersectionType type) {
|
||||
PsiType conjunct = null;
|
||||
for (PsiType conjunctType : type.getConjuncts()) {
|
||||
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(conjunctType);
|
||||
if (interfaceMethod != null) {
|
||||
if (conjunct != null && !conjunct.equals(conjunctType)) return null;
|
||||
conjunct = conjunctType;
|
||||
MethodSignature commonSignature = null;
|
||||
for (PsiType psiType : type.getConjuncts()) {
|
||||
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(psiType);
|
||||
if (aClass instanceof PsiTypeParameter) continue;
|
||||
MethodSignature signature = getFunction(aClass);
|
||||
if (signature == null) continue;
|
||||
if (commonSignature == null) {
|
||||
commonSignature = signature;
|
||||
}
|
||||
else if (!MethodSignatureUtil.areSignaturesEqual(commonSignature, signature)) {
|
||||
return null;
|
||||
}
|
||||
conjunct = psiType;
|
||||
}
|
||||
|
||||
return conjunct;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
interface X {
|
||||
void m(Integer i);
|
||||
}
|
||||
|
||||
interface Y<T> {
|
||||
void m(T t);
|
||||
}
|
||||
|
||||
class Test {
|
||||
{
|
||||
((X & <caret>Y<Integer>) (x) -> {}).m(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
interface X {
|
||||
void m();
|
||||
}
|
||||
|
||||
interface Y {
|
||||
void m();
|
||||
}
|
||||
|
||||
class Test {
|
||||
{
|
||||
((X & <caret>Y) () -> {}).m();
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,15 @@ public class FunctionalInterfaceTest extends LightDaemonAnalyzerTestCase {
|
||||
|
||||
public void testMultipleMethodsInOne() throws Exception {
|
||||
doTestFunctionalInterface(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void testIntersectionOf2FunctionalTypesWithEqualSignatures() throws Exception {
|
||||
doTestIntersection(null);
|
||||
}
|
||||
|
||||
public void testIntersectionOf2FunctionalTypesWithEqualAfterSubstitutionSignatures() throws Exception {
|
||||
doTestIntersection("Multiple non-overriding abstract methods found in X & Y<Integer>");
|
||||
}
|
||||
|
||||
public void testClone() throws Exception {
|
||||
doTestFunctionalInterface("Multiple non-overriding abstract methods found in interface Foo");
|
||||
@@ -92,6 +100,10 @@ public class FunctionalInterfaceTest extends LightDaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
public void testIntersectionTypeWithSameBaseInterfaceInConjuncts() throws Exception {
|
||||
doTestIntersection(null);
|
||||
}
|
||||
|
||||
private void doTestIntersection(final String expectedMessage) {
|
||||
String filePath = BASE_PATH + "/" + getTestName(false) + ".java";
|
||||
configureByFile(filePath);
|
||||
final PsiTypeCastExpression castExpression =
|
||||
@@ -101,6 +113,6 @@ public class FunctionalInterfaceTest extends LightDaemonAnalyzerTestCase {
|
||||
assertNotNull(castTypeElement);
|
||||
final PsiType type = castTypeElement.getType();
|
||||
final String errorMessage = LambdaHighlightingUtil.checkInterfaceFunctional(type);
|
||||
assertEquals(null, errorMessage);
|
||||
assertEquals(expectedMessage, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user