mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
static interface methods: forbid on instance members, inheritors (IDEA-107794)
This commit is contained in:
+3
@@ -326,6 +326,9 @@ public class HighlightMethodUtil {
|
||||
if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
|
||||
TextRange fixRange = getFixRange(methodCall);
|
||||
highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
|
||||
if (highlightInfo == null && !LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression())) {
|
||||
highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create();
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiMethod resolvedMethod = null;
|
||||
|
||||
@@ -789,6 +789,18 @@ public class LambdaUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isValidQualifier4InterfaceStaticMethodCall(@NotNull PsiMethod method, @NotNull PsiReferenceExpression methodReferenceExpression) {
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(methodReferenceExpression)) {
|
||||
final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression();
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return qualifierExpression == null && PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true)||
|
||||
qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == containingClass;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
|
||||
private PsiMethod myMethod;
|
||||
private final PsiClass myClass;
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
|
||||
class Bug {
|
||||
|
||||
interface Function<T, R> {
|
||||
public R apply(T t);
|
||||
|
||||
static <K> Function<K, K> identity() {
|
||||
return k -> k;
|
||||
}
|
||||
}
|
||||
|
||||
interface IFunction extends Function<Integer, Integer> {
|
||||
static void a() {
|
||||
Function<Integer, Integer> identity = <error descr="Static method may be invoked on containing interface class only">identity();</error>
|
||||
}
|
||||
}
|
||||
|
||||
public void foo() {
|
||||
Function<Integer, Integer> f = Function.identity();
|
||||
|
||||
Function<Integer, Integer> g = <error descr="Static method may be invoked on containing interface class only">f.identity();</error>
|
||||
|
||||
Function<Integer, Integer> h = <error descr="Static method may be invoked on containing interface class only">IFunction.identity();</error>
|
||||
}
|
||||
}
|
||||
+1
@@ -30,6 +30,7 @@ public class Interface8MethodsHighlightingTest extends LightDaemonAnalyzerTestCa
|
||||
public void testStaticMethodsInFunctionalInterface() { doTest(false, false); }
|
||||
public void testCyclicSubstitutor() { doTest(false, false); }
|
||||
public void testThisAccessibility() { doTest(false, false); }
|
||||
public void testStaticMethodCalls() { doTest(false, false); }
|
||||
|
||||
private void doTest() {
|
||||
doTest(false, false);
|
||||
|
||||
Reference in New Issue
Block a user