From 60e0db2a5cb60904ed3d2f6de0f59fc62824fd57 Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 21 Nov 2016 16:06:00 +0100 Subject: [PATCH] IDEA-163989 IDEA reports Object.getClass() with wrong return type for generic parameters --- .../completion/MemberLookupHelper.java | 19 ++++++++++++++++++- .../completion/normal/GetClassType.java | 5 +++++ .../completion/NormalCompletionTest.groovy | 5 +++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/GetClassType.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/MemberLookupHelper.java b/java/java-impl/src/com/intellij/codeInsight/completion/MemberLookupHelper.java index cd338c747c86..2f362b4898cc 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/MemberLookupHelper.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/MemberLookupHelper.java @@ -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, diff --git a/java/java-tests/testData/codeInsight/completion/normal/GetClassType.java b/java/java-tests/testData/codeInsight/completion/normal/GetClassType.java new file mode 100644 index 000000000000..2b89e81fb824 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/GetClassType.java @@ -0,0 +1,5 @@ +class F { + void foo(R r) { + r.getCla + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index f131f38a8c82..2baf0de8f1bc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -1730,4 +1730,9 @@ class Bar { void testCopyConstructor() { doTest('\n') } + void testGetClassType() { + configure() + assert 'Class' == LookupElementPresentation.renderElement(myFixture.lookupElements[0]).typeText + } + }