mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
lambda: do not skip generic method when non-generic method exist in the same class
This commit is contained in:
@@ -36,7 +36,7 @@ public class LambdaHighlightingUtil {
|
||||
@Nullable
|
||||
public static String checkInterfaceFunctional(@NotNull PsiClass psiClass, String interfaceNonFunctionalMessage) {
|
||||
if (psiClass instanceof PsiTypeParameter) return null; //should be logged as cyclic inference
|
||||
final List<MethodSignature> signatures = LambdaUtil.findFunctionCandidates(psiClass);
|
||||
final List<HierarchicalMethodSignature> signatures = LambdaUtil.findFunctionCandidates(psiClass);
|
||||
if (signatures == null) return interfaceNonFunctionalMessage;
|
||||
if (signatures.isEmpty()) return "No target method found";
|
||||
if (signatures.size() == 1) {
|
||||
@@ -113,7 +113,7 @@ public class LambdaHighlightingUtil {
|
||||
final PsiClass aClass = resolveResult.getElement();
|
||||
if (aClass != null) {
|
||||
if (aClass instanceof PsiTypeParameter) return null; //should be logged as cyclic inference
|
||||
final List<MethodSignature> signatures = LambdaUtil.findFunctionCandidates(aClass);
|
||||
final List<HierarchicalMethodSignature> signatures = LambdaUtil.findFunctionCandidates(aClass);
|
||||
if (signatures != null && signatures.size() == 1) {
|
||||
final MethodSignature functionalMethod = signatures.get(0);
|
||||
if (functionalMethod.getTypeParameters().length > 0) return "Target method is generic";
|
||||
|
||||
@@ -112,7 +112,7 @@ public class LambdaUtil {
|
||||
public static boolean isFunctionalClass(PsiClass aClass) {
|
||||
if (aClass != null) {
|
||||
if (aClass instanceof PsiTypeParameter) return false;
|
||||
final List<MethodSignature> signatures = findFunctionCandidates(aClass);
|
||||
final List<HierarchicalMethodSignature> signatures = findFunctionCandidates(aClass);
|
||||
return signatures != null && signatures.size() == 1;
|
||||
}
|
||||
return false;
|
||||
@@ -142,7 +142,7 @@ public class LambdaUtil {
|
||||
@Nullable
|
||||
static MethodSignature getFunction(PsiClass psiClass) {
|
||||
if (psiClass == null) return null;
|
||||
final List<MethodSignature> functions = findFunctionCandidates(psiClass);
|
||||
final List<HierarchicalMethodSignature> functions = findFunctionCandidates(psiClass);
|
||||
if (functions != null && functions.size() == 1) {
|
||||
return functions.get(0);
|
||||
}
|
||||
@@ -176,13 +176,13 @@ public class LambdaUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<MethodSignature> hasSubsignature(List<MethodSignature> signatures) {
|
||||
for (MethodSignature signature : signatures) {
|
||||
private static List<HierarchicalMethodSignature> hasSubsignature(List<HierarchicalMethodSignature> signatures) {
|
||||
for (HierarchicalMethodSignature signature : signatures) {
|
||||
boolean subsignature = true;
|
||||
for (MethodSignature methodSignature : signatures) {
|
||||
for (HierarchicalMethodSignature methodSignature : signatures) {
|
||||
if (!signature.equals(methodSignature)) {
|
||||
if (!MethodSignatureUtil.isSubsignature(signature, methodSignature) &&
|
||||
methodSignature.getTypeParameters().length == 0) {
|
||||
if (!MethodSignatureUtil.isSubsignature(signature, methodSignature) &&
|
||||
!skipMethod(signature, methodSignature)) {
|
||||
subsignature = false;
|
||||
break;
|
||||
}
|
||||
@@ -193,10 +193,20 @@ public class LambdaUtil {
|
||||
return signatures;
|
||||
}
|
||||
|
||||
private static boolean skipMethod(HierarchicalMethodSignature signature,
|
||||
HierarchicalMethodSignature methodSignature) {
|
||||
//not generic
|
||||
if (methodSignature.getTypeParameters().length == 0) {
|
||||
return false;
|
||||
}
|
||||
//foreign class
|
||||
return signature.getMethod().getContainingClass() != methodSignature.getMethod().getContainingClass();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static List<MethodSignature> findFunctionCandidates(PsiClass psiClass) {
|
||||
public static List<HierarchicalMethodSignature> findFunctionCandidates(PsiClass psiClass) {
|
||||
if (psiClass != null && psiClass.isInterface() && !psiClass.isAnnotationType()) {
|
||||
final List<MethodSignature> methods = new ArrayList<MethodSignature>();
|
||||
final List<HierarchicalMethodSignature> methods = new ArrayList<HierarchicalMethodSignature>();
|
||||
final Collection<HierarchicalMethodSignature> visibleSignatures = psiClass.getVisibleSignatures();
|
||||
for (HierarchicalMethodSignature signature : visibleSignatures) {
|
||||
final PsiMethod psiMethod = signature.getMethod();
|
||||
@@ -364,7 +374,7 @@ public class LambdaUtil {
|
||||
@Nullable
|
||||
private static PsiType extractFunctionalConjunct(PsiIntersectionType type) {
|
||||
PsiType conjunct = null;
|
||||
for (PsiType conjunctType : ((PsiIntersectionType)type).getConjuncts()) {
|
||||
for (PsiType conjunctType : type.getConjuncts()) {
|
||||
final PsiMethod interfaceMethod = getFunctionalInterfaceMethod(conjunctType);
|
||||
if (interfaceMethod != null) {
|
||||
if (conjunct != null && !conjunct.equals(conjunctType)) return null;
|
||||
|
||||
+27
@@ -14,3 +14,30 @@ class Test {
|
||||
C c = ()-> {};
|
||||
}
|
||||
}
|
||||
|
||||
class Test1 {
|
||||
|
||||
interface F {
|
||||
<X> void m();
|
||||
}
|
||||
|
||||
{
|
||||
F f = this::g;
|
||||
}
|
||||
|
||||
void g() {}
|
||||
}
|
||||
|
||||
class Test2 {
|
||||
|
||||
interface F {
|
||||
<X> void m();
|
||||
void a();
|
||||
}
|
||||
|
||||
{
|
||||
F f = <error descr="Multiple non-overriding abstract methods found">() -> g()</error>;
|
||||
}
|
||||
|
||||
void g() {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ public class InterfaceMayBeAnnotatedFunctionalInspection extends BaseInspection
|
||||
if (LambdaHighlightingUtil.checkInterfaceFunctional(aClass) != null) {
|
||||
return;
|
||||
}
|
||||
final List<MethodSignature> candidates = LambdaUtil.findFunctionCandidates(aClass);
|
||||
final List<HierarchicalMethodSignature> candidates = LambdaUtil.findFunctionCandidates(aClass);
|
||||
if (candidates == null || candidates.size() != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user