mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
java class reference: search subtypes only on smart completion, work as usual (and fast) on basic (IDEA-92934)
This commit is contained in:
+20
-7
@@ -15,11 +15,15 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiPackage;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReference;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -31,24 +35,33 @@ public class JavaClassReferenceCompletionContributor extends CompletionContribut
|
||||
public void duringCompletion(@NotNull CompletionInitializationContext context) {
|
||||
JavaClassReference reference = findJavaClassReference(context.getFile(), context.getStartOffset());
|
||||
if (reference != null && reference.getExtendClassNames() != null) {
|
||||
final PsiReference[] references = reference.getJavaClassReferenceSet().getReferences();
|
||||
final PsiReference last = references[references.length - 1];
|
||||
context.setReplacementOffset(last.getRangeInElement().getEndOffset() + last.getElement().getTextRange().getStartOffset());
|
||||
JavaClassReferenceSet set = reference.getJavaClassReferenceSet();
|
||||
context.setReplacementOffset(set.getRangeInElement().getEndOffset() + set.getElement().getTextRange().getStartOffset());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
|
||||
if (parameters.getCompletionType() == CompletionType.SMART) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement position = parameters.getPosition();
|
||||
JavaClassReference reference = findJavaClassReference(position.getContainingFile(), parameters.getOffset());
|
||||
if (reference == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] extendClassNames = reference.getExtendClassNames();
|
||||
PsiElement context = reference.getCompletionContext();
|
||||
if (extendClassNames != null && context instanceof PsiPackage) {
|
||||
if (parameters.getCompletionType() == CompletionType.SMART) {
|
||||
JavaClassReferenceSet set = reference.getJavaClassReferenceSet();
|
||||
int setStart = set.getRangeInElement().getStartOffset() + set.getElement().getTextRange().getStartOffset();
|
||||
String fullPrefix = parameters.getPosition().getContainingFile().getText().substring(setStart, parameters.getOffset());
|
||||
reference.processSubclassVariants((PsiPackage)context, extendClassNames, result.withPrefixMatcher(fullPrefix));
|
||||
return;
|
||||
}
|
||||
result.addLookupAdvertisement("Press " + getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION) + " to see inheritors of " +
|
||||
StringUtil.join(extendClassNames, ", "));
|
||||
}
|
||||
|
||||
if (parameters.getCompletionType() == CompletionType.CLASS_NAME) {
|
||||
JavaClassNameCompletionContributor.addAllClasses(parameters, result);
|
||||
}
|
||||
|
||||
+21
-31
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionResultSet;
|
||||
import com.intellij.codeInsight.completion.JavaLookupElementBuilder;
|
||||
import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
|
||||
import com.intellij.codeInsight.daemon.QuickFixProvider;
|
||||
@@ -23,6 +24,7 @@ import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl;
|
||||
import com.intellij.codeInsight.daemon.quickFix.CreateClassOrPackageFix;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.LocalQuickFixProvider;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
@@ -55,7 +57,10 @@ import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -225,15 +230,8 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
|
||||
@Override
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
PsiElement context = getContext();
|
||||
if (context == null) {
|
||||
context = JavaPsiFacade.getInstance(getElement().getProject()).findPackage("");
|
||||
}
|
||||
PsiElement context = getCompletionContext();
|
||||
if (context instanceof PsiPackage) {
|
||||
final String[] extendClasses = getExtendClassNames();
|
||||
if (extendClasses != null) {
|
||||
return getSubclassVariants((PsiPackage)context, extendClasses);
|
||||
}
|
||||
return processPackage((PsiPackage)context);
|
||||
}
|
||||
if (context instanceof PsiClass) {
|
||||
@@ -257,6 +255,12 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiElement getCompletionContext() {
|
||||
PsiElement context = getContext();
|
||||
return context == null ? JavaPsiFacade.getInstance(getElement().getProject()).findPackage("") : context;
|
||||
}
|
||||
|
||||
public String[] getExtendClassNames() {
|
||||
return JavaClassReferenceProvider.EXTEND_CLASS_NAMES.getValue(getOptions());
|
||||
}
|
||||
@@ -508,8 +512,7 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Object[] getSubclassVariants(@NotNull PsiPackage context, @NotNull String[] extendClasses) {
|
||||
HashSet<Object> lookups = new HashSet<Object>();
|
||||
public void processSubclassVariants(@NotNull PsiPackage context, @NotNull String[] extendClasses, CompletionResultSet result) {
|
||||
GlobalSearchScope packageScope = PackageScope.packageScope(context, true);
|
||||
GlobalSearchScope scope = myJavaClassReferenceSet.getProvider().getScope(getElement().getProject());
|
||||
if (scope != null) {
|
||||
@@ -529,35 +532,22 @@ public class JavaClassReference extends GenericReference implements PsiJavaRefer
|
||||
// add itself
|
||||
if (packageScope.contains(extendClass.getContainingFile().getVirtualFile())) {
|
||||
if (isClassAccepted(extendClass, classKind, instantiatable, concrete, notInterface, notEnum)) {
|
||||
ContainerUtil.addIfNotNull(createSubclassLookupValue(context, extendClass), lookups);
|
||||
result.addElement(createSubclassLookupValue(extendClass, extendClassName));
|
||||
}
|
||||
}
|
||||
for (final PsiClass clazz : ClassInheritorsSearch.search(extendClass, packageScope, true)) {
|
||||
if (isClassAccepted(clazz, classKind, instantiatable, concrete, notInterface, notEnum)) {
|
||||
ContainerUtil.addIfNotNull(createSubclassLookupValue(context, clazz), lookups);
|
||||
String qname = clazz.getQualifiedName();
|
||||
if (qname != null && isClassAccepted(clazz, classKind, instantiatable, concrete, notInterface, notEnum)) {
|
||||
result.addElement(createSubclassLookupValue(clazz, qname));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lookups.toArray();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Object createSubclassLookupValue(@NotNull final PsiPackage context, @NotNull final PsiClass clazz) {
|
||||
final String qname = clazz.getQualifiedName();
|
||||
if (qname == null) return null;
|
||||
|
||||
String name = qname;
|
||||
final String pack = context.getQualifiedName();
|
||||
if (pack.length() > 0) {
|
||||
if (name.startsWith(pack)) {
|
||||
name = name.substring(pack.length() + 1);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return JavaLookupElementBuilder.forClass(clazz, name, true).withLookupString(qname).withLookupString(clazz.getName());
|
||||
@NotNull
|
||||
private static LookupElementBuilder createSubclassLookupValue(@NotNull final PsiClass clazz, @NotNull String qname) {
|
||||
return JavaLookupElementBuilder.forClass(clazz, qname, true).withPresentableText(StringUtil.getShortName(qname));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
@@ -59,6 +59,11 @@ public class JavaClassReferenceSet {
|
||||
return myProvider;
|
||||
}
|
||||
|
||||
public TextRange getRangeInElement() {
|
||||
PsiReference[] references = getReferences();
|
||||
return new TextRange(references[0].getRangeInElement().getStartOffset(), references[references.length - 1].getRangeInElement().getEndOffset());
|
||||
}
|
||||
|
||||
private void reparse(String str, PsiElement element, final boolean isStaticImport, JavaClassReferenceSet context) {
|
||||
myElement = element;
|
||||
myContext = context;
|
||||
|
||||
Reference in New Issue
Block a user