mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix bug when generic types were lost after reflection access
This commit is contained in:
+1
-1
@@ -106,7 +106,7 @@ public class ConstructorReflectionAccessor extends ReflectionAccessorBase<Constr
|
||||
return null;
|
||||
}
|
||||
|
||||
public ConstructorDescriptor(@NotNull PsiNewExpression expression, @Nullable PsiMethod constructor, PsiClass psiClass) {
|
||||
public ConstructorDescriptor(@NotNull PsiNewExpression expression, @Nullable PsiMethod constructor, @NotNull PsiClass psiClass) {
|
||||
newExpression = expression;
|
||||
this.constructor = constructor;
|
||||
this.psiClass = psiClass;
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ public class FieldReflectionAccessor extends ReferenceReflectionAccessorBase<Fie
|
||||
String methodName = PsiReflectionAccessUtil.getUniqueMethodName(outerClass, "accessToField" + StringUtil.capitalize(fieldName));
|
||||
ReflectionAccessMethodBuilder methodBuilder = new ReflectionAccessMethodBuilder(methodName);
|
||||
if (FieldAccessType.GET.equals(accessType)) {
|
||||
String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(resolveFieldType(descriptor));
|
||||
String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(descriptor.expression, resolveFieldType(descriptor));
|
||||
if (returnType == null) {
|
||||
LOG.warn("Could not resolve field type");
|
||||
return null;
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ public class MethodReflectionAccessor extends ReflectionAccessorBase<MethodRefle
|
||||
@Override
|
||||
protected void grantAccess(@NotNull MethodCallDescriptor descriptor) {
|
||||
PsiClass outerClass = getOuterClass();
|
||||
String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(resolveMethodReturnType(descriptor));
|
||||
String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(descriptor.callExpression, resolveMethodReturnType(descriptor));
|
||||
PsiClass containingClass = descriptor.method.getContainingClass();
|
||||
String containingClassName = containingClass == null ? null : ClassUtil.getJVMClassName(containingClass);
|
||||
String name = descriptor.method.getName();
|
||||
|
||||
+48
-15
@@ -5,8 +5,11 @@ import com.intellij.codeInsight.PsiEquivalenceUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.siyeh.ig.psiutils.ExpectedTypeUtils;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -55,30 +58,37 @@ class PsiReflectionAccessUtil {
|
||||
return psiClass == null || isAccessible(psiClass);
|
||||
}
|
||||
|
||||
@Contract("null -> null")
|
||||
@Nullable
|
||||
public static PsiClass nearestAccessedClass(@Nullable PsiClass psiClass) {
|
||||
while (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
psiClass = psiClass.getSuperClass();
|
||||
}
|
||||
public static String getAccessibleReturnType(@NotNull PsiExpression expression, @Nullable PsiType type) {
|
||||
String expectedType = tryGetExpectedType(expression);
|
||||
if (expectedType != null) return expectedType;
|
||||
|
||||
return psiClass;
|
||||
PsiType nearestAccessibleBaseType = nearestAccessedType(type);
|
||||
if (nearestAccessibleBaseType != null) return nearestAccessibleBaseType.getCanonicalText();
|
||||
|
||||
return nearestAccessibleBaseClass(PsiTypesUtil.getPsiClass(type));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getAccessibleReturnType(@Nullable PsiType type) {
|
||||
PsiClass psiClass = nearestAccessedClass(PsiUtil.resolveClassInType(type));
|
||||
if (psiClass != null) {
|
||||
return psiClass.getQualifiedName();
|
||||
}
|
||||
public static String getAccessibleReturnType(@NotNull PsiExpression expression, @Nullable PsiClass psiClass) {
|
||||
String expectedType = tryGetExpectedType(expression);
|
||||
if (expectedType != null) return expectedType;
|
||||
|
||||
return type != null ? type.getCanonicalText() : null;
|
||||
return nearestAccessibleBaseClass(psiClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getAccessibleReturnType(@Nullable PsiClass psiClass) {
|
||||
psiClass = nearestAccessedClass(psiClass);
|
||||
return psiClass == null ? null : psiClass.getQualifiedName();
|
||||
private static String tryGetExpectedType(@NotNull PsiExpression expression) {
|
||||
PsiType expectedType = ExpectedTypeUtils.findExpectedType(expression, true);
|
||||
if (expectedType != null && isAccessible(expectedType)) {
|
||||
// java allows implicit conversions to java.lang.String. In this case we cannot use java.lang.String as a return type because
|
||||
// it will produce ClassCastException
|
||||
if (!CommonClassNames.JAVA_LANG_STRING.equals(expectedType.getCanonicalText())) {
|
||||
return expectedType.getCanonicalText();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -101,6 +111,29 @@ class PsiReflectionAccessUtil {
|
||||
return name;
|
||||
}
|
||||
|
||||
private static boolean isAccessible(@NotNull PsiType type) {
|
||||
return TypeConversionUtil.isPrimitiveAndNotNull(type) || isAccessible(PsiTypesUtil.getPsiClass(type));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiType nearestAccessedType(@Nullable PsiType type) {
|
||||
while (type != null && !isAccessible(type)) {
|
||||
type = ArrayUtil.getFirstElement(type.getSuperTypes());
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@Contract("null -> null")
|
||||
@Nullable
|
||||
private static String nearestAccessibleBaseClass(@Nullable PsiClass psiClass) {
|
||||
while (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
psiClass = psiClass.getSuperClass();
|
||||
}
|
||||
|
||||
return psiClass == null ? null : psiClass.getQualifiedName();
|
||||
}
|
||||
|
||||
private static boolean isArrayClass(@NotNull PsiClass psiClass) {
|
||||
Project project = psiClass.getProject();
|
||||
PsiClass arrayClass = JavaPsiFacade.getElementFactory(project).getArrayClass(PsiUtil.getLanguageLevel(psiClass));
|
||||
|
||||
Reference in New Issue
Block a user