mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-inspections] Fix false warnings on signature polymorphic method lookup
PR#2804 Reviewed-by: Tagir Valeev <tagir.valeev@jetbrains.com> GitOrigin-RevId: 28a1abe7b3d83e40737df88c5ce1d39933858755
This commit is contained in:
committed by
intellij-monorepo-bot
parent
6b35e2cece
commit
f49ee04957
+23
@@ -1,6 +1,7 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInspection.reflectiveAccess;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.daemon.JavaErrorBundle;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
|
||||
import com.intellij.codeInsight.lookup.*;
|
||||
@@ -25,6 +26,7 @@ import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -206,6 +208,7 @@ public final class JavaLangInvokeHandleSignatureInspection extends AbstractBaseJ
|
||||
@NotNull PsiReferenceExpression factoryMethodExpression,
|
||||
@NotNull ProblemsHolder holder) {
|
||||
if (!ownerClass.isExact()) return;
|
||||
if (!isStaticExpected && isSignaturePolymorphic(ownerClass, methodName)) return;
|
||||
final PsiMethod[] methods = ownerClass.getPsiClass().findMethodsByName(methodName, true);
|
||||
if (methods.length == 0) {
|
||||
holder.registerProblem(methodNameExpression, JavaErrorBundle.message("cannot.resolve.method", methodName));
|
||||
@@ -225,6 +228,10 @@ public final class JavaLangInvokeHandleSignatureInspection extends AbstractBaseJ
|
||||
return;
|
||||
}
|
||||
}
|
||||
PsiMethod onlyMethod = ContainerUtil.getOnlyItem(filteredMethods);
|
||||
if (onlyMethod != null && AnnotationUtil.isAnnotated(onlyMethod, CommonClassNames.JAVA_LANG_INVOKE_MH_POLYMORPHIC, 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ReflectiveSignature methodSignature = composeMethodSignature(methodTypeExpression);
|
||||
if (methodSignature == null) return;
|
||||
@@ -254,6 +261,22 @@ public final class JavaLangInvokeHandleSignatureInspection extends AbstractBaseJ
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSignaturePolymorphic(@NotNull ReflectiveClass ownerClass,
|
||||
@NotNull String methodName) {
|
||||
if ("java.lang.invoke.MethodHandle".equals(ownerClass.getPsiClass().getQualifiedName())) {
|
||||
return methodName.equals("invoke") || methodName.equals("invokeExact");
|
||||
}
|
||||
if ("java.lang.invoke.VarHandle".equals(ownerClass.getPsiClass().getQualifiedName())) {
|
||||
try {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
VarHandle.AccessMode.valueFromMethodName(methodName);
|
||||
return true;
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static void checkSpecial(@NotNull ReflectiveClass ownerClass,
|
||||
@NotNull PsiExpression callerClassExpression,
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.VarHandle;
|
||||
|
||||
class SignaturePolymorphic {
|
||||
public static void main(String... args) throws Throwable {
|
||||
// signature polymorphic methods allow any lookup, do not warn
|
||||
MethodHandles.lookup().findVirtual(MethodHandle.class, "invoke", MethodType.methodType(int.class, String.class, double.class));
|
||||
MethodHandles.lookup().findVirtual(VarHandle.class, "compareAndSet", MethodType.methodType(int.class, String.class, double.class));
|
||||
// static lookup still warns as the methods are virtual
|
||||
MethodHandles.lookup().<warning descr="Method 'invoke' is not static">findStatic</warning>(MethodHandle.class, "invoke", MethodType.methodType(int.class, String.class, double.class));
|
||||
MethodHandles.lookup().<warning descr="Method 'compareAndSet' is not static">findStatic</warning>(VarHandle.class, "compareAndSet", MethodType.methodType(int.class, String.class, double.class));
|
||||
// unrelated methods in the relevant classes cause warnings
|
||||
MethodHandles.lookup().findVirtual(MethodHandle.class, "toString", <warning descr="Cannot resolve method 'int toString(String, double)'">MethodType.methodType(int.class, String.class, double.class)</warning>);
|
||||
MethodHandles.lookup().findVirtual(VarHandle.class, "toString", <warning descr="Cannot resolve method 'int toString(String, double)'">MethodType.methodType(int.class, String.class, double.class)</warning>);
|
||||
}
|
||||
}
|
||||
+2
@@ -51,6 +51,8 @@ class JavaLangInvokeHandleSignatureTest : LightJavaCodeInsightFixtureTestCase()
|
||||
|
||||
fun testVarArgMethodHandle() = doTest()
|
||||
|
||||
fun testSignaturePolymorphic() = doTest()
|
||||
|
||||
private fun doTest() {
|
||||
myFixture.testHighlighting("${getTestName(false)}.java")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user