mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
Java: Filter by 'static' modifier in MethodHandle/VarHandle completion assistance (IDEA-167319, IDEA-CR-19610)
This commit is contained in:
+10
-10
@@ -161,7 +161,7 @@ public class JavaLangInvokeHandleSignatureInspection extends BaseJavaBatchLocalI
|
||||
@NotNull String fieldName,
|
||||
@NotNull PsiExpression fieldNameExpression,
|
||||
@NotNull PsiExpression fieldTypeExpression,
|
||||
boolean isStatic,
|
||||
boolean isStaticExpected,
|
||||
@NotNull PsiReferenceExpression factoryMethodExpression,
|
||||
@NotNull ProblemsHolder holder) {
|
||||
final PsiField field = ownerClass.findFieldByName(fieldName, true);
|
||||
@@ -170,13 +170,13 @@ public class JavaLangInvokeHandleSignatureInspection extends BaseJavaBatchLocalI
|
||||
return;
|
||||
}
|
||||
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC) != isStatic) {
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC) != isStaticExpected) {
|
||||
final String factoryMethodName = factoryMethodExpression.getReferenceName();
|
||||
final PsiElement factoryMethodNameElement = factoryMethodExpression.getReferenceNameElement();
|
||||
if (factoryMethodName != null && factoryMethodNameElement != null) {
|
||||
final LocalQuickFix fix = SwitchStaticnessQuickFix.createFix(factoryMethodName, isStatic);
|
||||
final LocalQuickFix fix = SwitchStaticnessQuickFix.createFix(factoryMethodName, isStaticExpected);
|
||||
final String message = InspectionsBundle.message(
|
||||
isStatic ? "inspection.handle.signature.field.static" : "inspection.handle.signature.field.not.static", fieldName);
|
||||
isStaticExpected ? "inspection.handle.signature.field.not.static" : "inspection.handle.signature.field.static", fieldName);
|
||||
holder.registerProblem(factoryMethodNameElement, message, fix);
|
||||
return;
|
||||
}
|
||||
@@ -196,7 +196,7 @@ public class JavaLangInvokeHandleSignatureInspection extends BaseJavaBatchLocalI
|
||||
@NotNull String methodName,
|
||||
@NotNull PsiExpression methodNameExpression,
|
||||
@NotNull PsiExpression methodTypeExpression,
|
||||
boolean isStatic,
|
||||
boolean isStaticExpected,
|
||||
@NotNull PsiReferenceExpression factoryMethodExpression,
|
||||
@NotNull ProblemsHolder holder) {
|
||||
|
||||
@@ -207,14 +207,14 @@ public class JavaLangInvokeHandleSignatureInspection extends BaseJavaBatchLocalI
|
||||
}
|
||||
|
||||
final List<PsiMethod> filteredMethods =
|
||||
ContainerUtil.filter(methods, method -> method.hasModifierProperty(PsiModifier.STATIC) == isStatic);
|
||||
ContainerUtil.filter(methods, method -> method.hasModifierProperty(PsiModifier.STATIC) == isStaticExpected);
|
||||
if (filteredMethods.isEmpty()) {
|
||||
final String factoryMethodName = factoryMethodExpression.getReferenceName();
|
||||
final PsiElement factoryMethodNameElement = factoryMethodExpression.getReferenceNameElement();
|
||||
if (factoryMethodName != null && factoryMethodNameElement != null) {
|
||||
final LocalQuickFix fix = SwitchStaticnessQuickFix.createFix(factoryMethodName, isStatic);
|
||||
final LocalQuickFix fix = SwitchStaticnessQuickFix.createFix(factoryMethodName, isStaticExpected);
|
||||
final String message = InspectionsBundle.message(
|
||||
isStatic ? "inspection.handle.signature.method.static" : "inspection.handle.signature.method.not.static", methodName);
|
||||
isStaticExpected ? "inspection.handle.signature.method.not.static" : "inspection.handle.signature.method.static", methodName);
|
||||
holder.registerProblem(factoryMethodNameElement, message, fix);
|
||||
return;
|
||||
}
|
||||
@@ -392,8 +392,8 @@ public class JavaLangInvokeHandleSignatureInspection extends BaseJavaBatchLocalI
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static LocalQuickFix createFix(@NotNull String methodName, boolean isStatic) {
|
||||
final String replacementName = isStatic ? STATIC_TO_NON_STATIC.get(methodName) : NON_STATIC_TO_STATIC.get(methodName);
|
||||
public static LocalQuickFix createFix(@NotNull String methodName, boolean wasStatic) {
|
||||
final String replacementName = wasStatic ? STATIC_TO_NON_STATIC.get(methodName) : NON_STATIC_TO_STATIC.get(methodName);
|
||||
return replacementName != null ? new SwitchStaticnessQuickFix(replacementName) : null;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -32,6 +32,7 @@ import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.intellij.codeInsight.completion.JavaCompletionContributor.isInJavaContext;
|
||||
import static com.intellij.patterns.PsiJavaPatterns.*;
|
||||
@@ -105,7 +106,7 @@ public class JavaMethodHandleCompletionContributor extends CompletionContributor
|
||||
case FIND_SPECIAL:
|
||||
final String name = arguments.length > 1 ? computeConstantExpression(arguments[1], String.class) : null;
|
||||
if (!StringUtil.isEmpty(name)) {
|
||||
addMethodSignatures(psiClass, name, result);
|
||||
addMethodSignatures(psiClass, name, FIND_STATIC.equals(methodName), result);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -119,7 +120,7 @@ public class JavaMethodHandleCompletionContributor extends CompletionContributor
|
||||
if (className != null) {
|
||||
final PsiMethod[] constructors = psiClass.getConstructors();
|
||||
if (constructors.length != 0) {
|
||||
lookupMethodTypes(constructors, result);
|
||||
lookupMethodTypes(Arrays.stream(constructors), result);
|
||||
}
|
||||
else {
|
||||
result.addElement(lookupSignature(ReflectiveSignature.NO_ARGUMENT_CONSTRUCTOR_SIGNATURE));
|
||||
@@ -127,15 +128,20 @@ public class JavaMethodHandleCompletionContributor extends CompletionContributor
|
||||
}
|
||||
}
|
||||
|
||||
private static void addMethodSignatures(@NotNull PsiClass psiClass, @NotNull String methodName, @NotNull CompletionResultSet result) {
|
||||
private static void addMethodSignatures(@NotNull PsiClass psiClass,
|
||||
@NotNull String methodName,
|
||||
boolean isStaticExpected,
|
||||
@NotNull CompletionResultSet result) {
|
||||
final PsiMethod[] methods = psiClass.findMethodsByName(methodName, false);
|
||||
if (methods.length != 0) {
|
||||
lookupMethodTypes(methods, result);
|
||||
final Stream<PsiMethod> methodStream = Arrays.stream(methods)
|
||||
.filter(method -> method.hasModifierProperty(PsiModifier.STATIC) == isStaticExpected);
|
||||
lookupMethodTypes(methodStream, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void lookupMethodTypes(@NotNull PsiMethod[] methods, @NotNull CompletionResultSet result) {
|
||||
Arrays.stream(methods)
|
||||
private static void lookupMethodTypes(@NotNull Stream<PsiMethod> methods, @NotNull CompletionResultSet result) {
|
||||
methods
|
||||
.map(JavaReflectionReferenceUtil::getMethodSignature)
|
||||
.filter(Objects::nonNull)
|
||||
.sorted(ReflectiveSignature::compareTo)
|
||||
|
||||
@@ -3,6 +3,6 @@ import java.lang.invoke.*;
|
||||
public class Main {
|
||||
void foo() throws Throwable {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
lookup.findStatic(Types.class, "sObjMethod", <caret>);
|
||||
lookup.findStatic(Types.class, "objMethod", <caret>);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,6 @@ import java.lang.invoke.*;
|
||||
public class Main {
|
||||
void foo() throws Throwable {
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
lookup.findStatic(Types.class, "sObjMethod", MethodType.methodType(Object.class, Object.class));
|
||||
lookup.findStatic(Types.class, "objMethod", MethodType.methodType(Object.class, Object.class));
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,9 @@ class Main {
|
||||
l.findStaticGetter(Test.class, "ourInt", <warning descr="The type of field 'ourInt' is 'int'">void.class</warning>);
|
||||
l.findStaticGetter(Test.class, "ourInts", <warning descr="The type of field 'ourInts' is 'int[]'">int.class</warning>);
|
||||
l.findStaticGetter(Test.class, "ourString", <warning descr="The type of field 'ourString' is 'java.lang.String'">List.class</warning>);
|
||||
|
||||
l.<warning descr="Field 'ourString' is static">findGetter</warning>(Test.class, "ourString", String.class);
|
||||
l.<warning descr="Field 'myString' is not static">findStaticGetter</warning>(Test.class, "myString", String.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ class Main {
|
||||
l.findVirtual(Test.class, "method", <warning descr="Cannot resolve method 'Object[] method(Object[])'">MethodType.methodType(Object[].class, Object[].class)</warning>);
|
||||
l.findVirtual(Test.class, "method", <warning descr="Cannot resolve method 'Object[][] method(Object[][])'">MethodType.methodType(Object[][].class, Object[][].class)</warning>);
|
||||
|
||||
l.<warning descr="Method 'method' is static">findStatic</warning>(Test.class, "method", MethodType.methodType(void.class));
|
||||
l.<warning descr="Method 'method' is not static">findStatic</warning>(Test.class, "method", MethodType.methodType(void.class));
|
||||
l.findVirtual(Test.class, <warning descr="Cannot resolve method 'doesntExist'">"doesntExist"</warning>, MethodType.methodType(void.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ class Main {
|
||||
l.findStaticSetter(Test.class, "ourInt", <warning descr="The type of field 'ourInt' is 'int'">void.class</warning>);
|
||||
l.findStaticSetter(Test.class, "ourInts", <warning descr="The type of field 'ourInts' is 'int[]'">int.class</warning>);
|
||||
l.findStaticSetter(Test.class, "ourString", <warning descr="The type of field 'ourString' is 'java.lang.String'">List.class</warning>);
|
||||
|
||||
l.<warning descr="Field 'myString' is not static">findStaticSetter</warning>(Test.class, "myString", String.class);
|
||||
l.<warning descr="Field 'ourString' is static">findSetter</warning>(Test.class, "ourString", String.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class Main {
|
||||
l.findStatic(Test.class, "method2", <warning descr="Cannot resolve method 'int method2(String)'">MethodType.methodType(int.class, String.class)</warning>);
|
||||
l.findStatic(Test.class, "method3", <warning descr="Cannot resolve method 'String method3()'">MethodType.methodType(String.class)</warning>);
|
||||
|
||||
l.<warning descr="Method 'method1' is not static">findVirtual</warning>(Test.class, "method1", MethodType.methodType(void.class));
|
||||
l.<warning descr="Method 'method1' is static">findVirtual</warning>(Test.class, "method1", MethodType.methodType(void.class));
|
||||
l.findStatic(Test.class, <warning descr="Cannot resolve method 'doesntExist'">"doesntExist"</warning>, MethodType.methodType(String.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,9 @@ class Main {
|
||||
l.findStaticVarHandle(Test.class, "ourInt", <warning descr="The type of field 'ourInt' is 'int'">void.class</warning>);
|
||||
l.findStaticVarHandle(Test.class, "ourInts", <warning descr="The type of field 'ourInts' is 'int[]'">int.class</warning>);
|
||||
l.findStaticVarHandle(Test.class, "ourString", <warning descr="The type of field 'ourString' is 'java.lang.String'">List.class</warning>);
|
||||
|
||||
l.<warning descr="Field 'myString' is not static">findStaticVarHandle</warning>(Test.class, "myString", String.class);
|
||||
l.<warning descr="Field 'ourString' is static">findVarHandle</warning>(Test.class, "ourString", String.class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+12
-8
@@ -45,8 +45,10 @@ class JavaLangInvokeHandleCompletionTest : LightFixtureCompletionTestCase() {
|
||||
fun testStaticVarHandle() = doTest(0, "psf1", "sf1", "sf2")
|
||||
|
||||
|
||||
fun testVirtualType() = doTestTypes(0, "MethodType.methodType(String.class)")
|
||||
fun testStaticType() = doTestTypes(0, "MethodType.methodType(Object.class, Object.class)")
|
||||
fun testVirtualType() = doTestTypes(0, "MethodType.methodType(String.class)", "MethodType.methodType(String.class, int.class, int.class)")
|
||||
fun testStaticType() = doTestTypes(1,
|
||||
"MethodType.methodType(Object.class, int.class, int.class)",
|
||||
"MethodType.methodType(Object.class, Object.class)")
|
||||
|
||||
fun testGetterType() = doTestTypes(0, "int.class")
|
||||
fun testSetterType() = doTestTypes(0, "float.class")
|
||||
@@ -86,7 +88,13 @@ public class Types extends Parent {
|
||||
static Object sObj;
|
||||
|
||||
String strMethod() {return "";}
|
||||
static Object sObjMethod(Object o) {return this;}
|
||||
String strMethod(int n, int m) {return "";}
|
||||
static String strMethod(int n) {return "";}
|
||||
|
||||
static Object objMethod(Object o) {return o;}
|
||||
static Object objMethod(int n, int m) {return n;}
|
||||
Object objMethod(int n) {return n;}
|
||||
|
||||
<T> T genericMethod(T t, String s) {return t;}
|
||||
static <T> T sGenericMethod(List<T> lst, T... ts) {return ts[0];}
|
||||
}""")
|
||||
@@ -105,11 +113,7 @@ public class Constructed<T> {
|
||||
private fun assertLookupTexts(compareFirst: Boolean, vararg expected: String) {
|
||||
val elements = myFixture.lookupElements
|
||||
assertNotNull(elements)
|
||||
val lookupTexts = elements!!.map {
|
||||
val presentation = LookupElementPresentation()
|
||||
it.renderElement(presentation)
|
||||
presentation.itemText
|
||||
}
|
||||
val lookupTexts = elements!!.map { LookupElementPresentation.renderElement(it).itemText }
|
||||
|
||||
val actual = if (compareFirst) lookupTexts.subList(0, Math.min(expected.size, lookupTexts.size)) else lookupTexts
|
||||
assertOrderedEquals(actual, *expected)
|
||||
|
||||
Reference in New Issue
Block a user