mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-05 01:50:56 +07:00
IDEA-122362 'getClass()' should be suggested in smart completion if Class<? extends SomeAncestorOfCurrentClass> is expected
This commit is contained in:
@@ -144,10 +144,8 @@ public class PreferByKindWeigher extends LookupElementWeigher {
|
||||
}
|
||||
}
|
||||
|
||||
if (myCompletionType == CompletionType.SMART) {
|
||||
if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
|
||||
return MyResult.localOrParameter;
|
||||
}
|
||||
if (object instanceof PsiLocalVariable || object instanceof PsiParameter || object instanceof PsiThisExpression) {
|
||||
return MyResult.localOrParameter;
|
||||
}
|
||||
|
||||
if (object instanceof String && item.getUserData(JavaCompletionUtil.SUPER_METHOD_PARAMETERS) == Boolean.TRUE) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.impl.light.LightMethodBuilder;
|
||||
import com.intellij.psi.impl.source.resolve.JavaResolveUtil;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
@@ -100,14 +101,11 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
if (qualifier instanceof PsiSuperExpression) {
|
||||
final PsiJavaCodeReferenceElement qSuper = ((PsiSuperExpression)qualifier).getQualifier();
|
||||
if (qSuper == null) {
|
||||
myQualifierClass = JavaResolveUtil.getContextClass( myElement);
|
||||
myQualifierClass = JavaResolveUtil.getContextClass(myElement);
|
||||
} else {
|
||||
final PsiElement target = qSuper.resolve();
|
||||
myQualifierClass = target instanceof PsiClass ? (PsiClass)target : null;
|
||||
}
|
||||
if (myQualifierClass != null) {
|
||||
myQualifierType = JavaPsiFacade.getInstance(element.getProject()).getElementFactory().createType(myQualifierClass);
|
||||
}
|
||||
}
|
||||
else if (qualifier != null) {
|
||||
setQualifierType(qualifier.getType());
|
||||
@@ -117,8 +115,13 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
myQualifierClass = (PsiClass)target;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
myQualifierClass = JavaResolveUtil.getContextClass(myElement);
|
||||
}
|
||||
}
|
||||
if (myQualifierClass != null && myQualifierType == null) {
|
||||
myQualifierType = JavaPsiFacade.getElementFactory(element.getProject()).createType(myQualifierClass);
|
||||
}
|
||||
|
||||
if (myOptions.checkInitialized) {
|
||||
myNonInitializedFields.addAll(getNonInitializedFields(element));
|
||||
@@ -219,6 +222,19 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
if (PsiTypesUtil.isGetClass(method) && PsiUtil.isLanguageLevel5OrHigher(myElement)) {
|
||||
PsiType patchedType = PsiTypesUtil.createJavaLangClassType(myElement, myQualifierType, false);
|
||||
if (patchedType != null) {
|
||||
element = new LightMethodBuilder(element.getManager(), method.getName()).
|
||||
addModifier(PsiModifier.PUBLIC).
|
||||
setMethodReturnType(patchedType).
|
||||
setContainingClass(method.getContainingClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (satisfies(element, state) && isAccessible(element)) {
|
||||
CompletionElement element1 = new CompletionElement(element, state.get(PsiSubstitutor.KEY));
|
||||
if (myResultNames.add(element1.getUniqueId())) {
|
||||
@@ -288,7 +304,9 @@ public class JavaCompletionProcessor extends BaseScopeProcessor implements Eleme
|
||||
if (!(element instanceof PsiMember)) return true;
|
||||
|
||||
PsiMember member = (PsiMember)element;
|
||||
return JavaPsiFacade.getInstance(element.getProject()).getResolveHelper().isAccessible(member, member.getModifierList(), myElement, myQualifierClass, myDeclarationHolder);
|
||||
PsiClass accessObjectClass = member instanceof PsiClass ? null : myQualifierClass;
|
||||
return JavaPsiFacade.getInstance(element.getProject()).getResolveHelper().isAccessible(member, member.getModifierList(), myElement,
|
||||
accessObjectClass, myDeclarationHolder);
|
||||
}
|
||||
|
||||
public void setCompletionElements(@NotNull Object[] elements) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -151,9 +150,7 @@ public class PsiTypesUtil {
|
||||
@Nullable Condition<IElementType> condition,
|
||||
@NotNull LanguageLevel languageLevel) {
|
||||
//JLS3 15.8.2
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_5) &&
|
||||
GET_CLASS_METHOD.equals(method.getName()) &&
|
||||
CommonClassNames.JAVA_LANG_OBJECT.equals(method.getContainingClass().getQualifiedName())) {
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_5) && isGetClass(method)) {
|
||||
PsiExpression qualifier = methodExpression.getQualifierExpression();
|
||||
PsiType qualifierType = null;
|
||||
final Project project = call.getProject();
|
||||
@@ -169,18 +166,28 @@ public class PsiTypesUtil {
|
||||
qualifierType = JavaPsiFacade.getInstance(project).getElementFactory().createType((PsiClass)parent.getPsi());
|
||||
}
|
||||
}
|
||||
if (qualifierType != null) {
|
||||
PsiClass javaLangClass = JavaPsiFacade.getInstance(project).findClass(CommonClassNames.JAVA_LANG_CLASS, call.getResolveScope());
|
||||
if (javaLangClass != null && javaLangClass.getTypeParameters().length == 1) {
|
||||
Map<PsiTypeParameter, PsiType> map = new HashMap<PsiTypeParameter, PsiType>();
|
||||
map.put(javaLangClass.getTypeParameters()[0], PsiWildcardType.createExtends(call.getManager(), qualifierType));
|
||||
PsiSubstitutor substitutor = JavaPsiFacade.getInstance(project).getElementFactory().createSubstitutor(map);
|
||||
final PsiClassType classType = JavaPsiFacade.getInstance(project).getElementFactory()
|
||||
.createType(javaLangClass, substitutor, languageLevel);
|
||||
final PsiElement parent = call.getParent();
|
||||
return parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression || parent instanceof PsiExpressionList
|
||||
? PsiUtil.captureToplevelWildcards(classType, methodExpression) : classType;
|
||||
}
|
||||
PsiElement parent = call.getParent();
|
||||
boolean captureTopLevelWildcards = parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression ||
|
||||
parent instanceof PsiExpressionList;
|
||||
return createJavaLangClassType(methodExpression, qualifierType, captureTopLevelWildcards);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isGetClass(PsiMethod method) {
|
||||
return GET_CLASS_METHOD.equals(method.getName()) && CommonClassNames.JAVA_LANG_OBJECT.equals(method.getContainingClass().getQualifiedName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType createJavaLangClassType(@NotNull PsiElement context, @Nullable PsiType qualifierType, boolean captureTopLevelWildcards) {
|
||||
if (qualifierType != null) {
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
|
||||
PsiClass javaLangClass = facade.findClass(CommonClassNames.JAVA_LANG_CLASS, context.getResolveScope());
|
||||
if (javaLangClass != null && javaLangClass.getTypeParameters().length == 1) {
|
||||
PsiSubstitutor substitutor = PsiSubstitutor.EMPTY.
|
||||
put(javaLangClass.getTypeParameters()[0], PsiWildcardType.createExtends(context.getManager(), qualifierType));
|
||||
final PsiClassType classType = facade.getElementFactory().createType(javaLangClass, substitutor, PsiUtil.getLanguageLevel(context));
|
||||
return captureTopLevelWildcards ? PsiUtil.captureToplevelWildcards(classType, context) : classType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
}
|
||||
class B extends A {
|
||||
void m() {
|
||||
Class<? extends A> c = getClass();<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class A {
|
||||
}
|
||||
class B extends A {
|
||||
void m() {
|
||||
Class<? extends A> c = g<caret>
|
||||
}
|
||||
}
|
||||
@@ -1022,6 +1022,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
|
||||
public void testDuplicateMembersFromSuperClass() throws Throwable { doTest(); }
|
||||
public void testInnerAfterNew() throws Throwable { doTest(); }
|
||||
public void testEverythingInStringConcatenation() throws Throwable { doTest(); }
|
||||
public void testGetClassWhenClassExpected() { doTest(); }
|
||||
|
||||
public void testMemberImportStatically() {
|
||||
configureByTestName();
|
||||
|
||||
Reference in New Issue
Block a user