mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
static methods of interfaces: accept calls on type parameters with exact one interface bound (IDEA-145269)
This commit is contained in:
@@ -468,11 +468,29 @@ public class LambdaUtil {
|
||||
return "Static interface method invocations are not supported at this language level";
|
||||
}
|
||||
|
||||
if (qualifierExpression == null &&
|
||||
(scope instanceof PsiImportStaticStatement || PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true)) ||
|
||||
qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == containingClass) {
|
||||
if (qualifierExpression == null && (scope instanceof PsiImportStaticStatement || PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true))) {
|
||||
return null;
|
||||
}
|
||||
if (qualifierExpression instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve();
|
||||
if (resolve == containingClass) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (resolve instanceof PsiTypeParameter) {
|
||||
final Set<PsiClass> classes = new HashSet<PsiClass>();
|
||||
for (PsiClassType type : ((PsiTypeParameter)resolve).getExtendsListTypes()) {
|
||||
final PsiClass aClass = type.resolve();
|
||||
if (aClass != null) {
|
||||
classes.add(aClass);
|
||||
}
|
||||
}
|
||||
|
||||
if (classes.size() == 1 && classes.contains(containingClass)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "Static method may be invoked on containing interface class only";
|
||||
}
|
||||
return null;
|
||||
|
||||
+4
-1
@@ -58,7 +58,10 @@ public class MethodCandidatesProcessor extends MethodsProcessor{
|
||||
if (isAccepted(method) && !(isInterfaceStaticMethodAccessibleThroughInheritance(method) && ImportsUtil.hasStaticImportOn(myPlace, method, true))) {
|
||||
if (!staticProblem && myAccessClass != null && method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface() && !containingClass.equals(myAccessClass)) {
|
||||
if (containingClass != null &&
|
||||
containingClass.isInterface() &&
|
||||
!(myAccessClass instanceof PsiTypeParameter) &&
|
||||
!containingClass.equals(myAccessClass)) {
|
||||
staticProblem = true;
|
||||
}
|
||||
}
|
||||
|
||||
+29
@@ -22,4 +22,33 @@ class Bug {
|
||||
|
||||
Function<Integer, Integer> h = IFunction.<error descr="Static method may be invoked on containing interface class only">identity</error>();
|
||||
}
|
||||
}
|
||||
|
||||
class StaticMethodInterfaceExample {
|
||||
|
||||
interface X {}
|
||||
interface MyInterface {
|
||||
static void staticMethod() {}
|
||||
}
|
||||
|
||||
static class MyImplementation implements MyInterface { }
|
||||
|
||||
public static class Usage {
|
||||
|
||||
public <T extends MyInterface> void doStuff() {
|
||||
T.staticMethod();
|
||||
}
|
||||
|
||||
public <T extends MyImplementation> void doStuff1() {
|
||||
<error descr="Static method may be invoked on containing interface class only">T.staticMethod();</error>
|
||||
}
|
||||
|
||||
public <T extends MyInterface & X> void doStuff2() {
|
||||
<error descr="Static method may be invoked on containing interface class only">T.staticMethod();</error>
|
||||
}
|
||||
|
||||
public <T extends MyImplementation & MyInterface> void doStuff3() {
|
||||
<error descr="Static method may be invoked on containing interface class only">T.staticMethod();</error>
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user