IDEA-163989 IDEA reports Object.getClass() with wrong return type for generic parameters

This commit is contained in:
peter
2016-11-21 16:41:08 +01:00
parent b798253502
commit 60e0db2a5c
3 changed files with 28 additions and 1 deletions
@@ -20,9 +20,13 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
@@ -89,12 +93,25 @@ public class MemberLookupHelper {
presentation.appendTailText(location, true);
}
final PsiType type = myMember instanceof PsiMethod ? ((PsiMethod)myMember).getReturnType() : ((PsiField) myMember).getType();
PsiType declaredType = myMember instanceof PsiMethod ? ((PsiMethod)myMember).getReturnType() : ((PsiField)myMember).getType();
PsiType type = patchGetClass(substitutor.substitute(declaredType));
if (type != null) {
presentation.setTypeText(substitutor.substitute(type).getPresentableText());
}
}
@Nullable
private PsiType patchGetClass(@Nullable PsiType type) {
if (myMember instanceof PsiMethod && PsiTypesUtil.isGetClass((PsiMethod)myMember) && type instanceof PsiClassType) {
PsiType arg = ContainerUtil.getFirstItem(Arrays.asList(((PsiClassType)type).getParameters()));
PsiType bound = arg instanceof PsiWildcardType ? TypeConversionUtil.erasure(((PsiWildcardType)arg).getExtendsBound()) : null;
if (bound != null) {
return PsiTypesUtil.createJavaLangClassType(myMember, bound, false);
}
}
return type;
}
@NotNull
static String getMethodParameterString(@NotNull PsiMethod method, @NotNull PsiSubstitutor substitutor) {
return PsiFormatUtil.formatMethod(method, substitutor,
@@ -0,0 +1,5 @@
class F {
<R extends Number> void foo(R r) {
r.getCl<caret>a
}
}
@@ -1730,4 +1730,9 @@ class Bar {
void testCopyConstructor() { doTest('\n') }
void testGetClassType() {
configure()
assert 'Class<? extends Number>' == LookupElementPresentation.renderElement(myFixture.lookupElements[0]).typeText
}
}