suggest all visible classes everywhere (IDEA-87958)

This commit is contained in:
peter
2012-07-02 18:26:07 +02:00
parent 3407b706a9
commit d75075c0c2
6 changed files with 31 additions and 55 deletions
@@ -31,7 +31,6 @@ import com.intellij.psi.filters.ClassFilter;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.filters.element.ExcludeDeclaredFilter;
import com.intellij.psi.filters.types.AssignableFromFilter;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Consumer;
@@ -74,6 +73,9 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
if (SkipAutopopupInStrings.isInStringLiteral(position)) {
return true;
}
if (PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null) {
return true;
}
return false;
}
@@ -83,22 +85,8 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
@NotNull final Consumer<LookupElement> consumer) {
final PsiElement insertedElement = parameters.getPosition();
final ElementFilter filter;
if (JavaSmartCompletionContributor.AFTER_THROW_NEW.accepts(insertedElement) ||
JavaCompletionContributor.INSIDE_METHOD_THROWS_CLAUSE.accepts(insertedElement) ||
JavaCompletionContributor.IN_CATCH_TYPE.accepts(insertedElement) ||
JavaCompletionContributor.IN_MULTI_CATCH_TYPE.accepts(insertedElement)) {
filter = new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE);
}
else if (JavaCompletionContributor.IN_RESOURCE_TYPE.accepts(insertedElement)) {
filter = new AssignableFromFilter(CommonClassNames.JAVA_LANG_AUTO_CLOSEABLE);
}
else if (IN_TYPE_PARAMETER.accepts(insertedElement)) {
filter = new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class));
}
else {
filter = TrueFilter.INSTANCE;
}
final ElementFilter filter =
IN_TYPE_PARAMETER.accepts(insertedElement) ? new ExcludeDeclaredFilter(new ClassFilter(PsiTypeParameter.class)) : TrueFilter.INSTANCE;
final boolean inJavaContext = parameters.getPosition() instanceof PsiIdentifier;
final boolean afterNew = AFTER_NEW.accepts(insertedElement);
@@ -120,13 +108,10 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
}
}
final boolean lookingForAnnotations = psiElement().afterLeaf("@").accepts(insertedElement);
final boolean pkgContext = JavaCompletionUtil.inSomePackage(insertedElement);
AllClassesGetter.processJavaClasses(parameters, matcher, filterByScope, new Consumer<PsiClass>() {
@Override
public void consume(PsiClass psiClass) {
if (lookingForAnnotations && !psiClass.isAnnotationType()) return;
if (filter.isAcceptable(psiClass, insertedElement)) {
if (!inJavaContext) {
consumer.consume(AllClassesGetter.createLookupItem(psiClass, AllClassesGetter.TRY_SHORTENING));
@@ -65,6 +65,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase {
String path = "/afterNewThrowable";
configureByFile(path + "/before1.java");
myFixture.type('\n');
checkResultByFile(path + "/after1.java");
}
@@ -81,6 +82,7 @@ public class ClassNameCompletionTest extends LightFixtureCompletionTestCase {
String path = "/afterNewThrowable";
configureByFile(path + "/before2.java");
myFixture.type('\n');
checkResultByFile(path + "/after2.java");
}
@@ -34,10 +34,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.SuggestedNameInfo;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.filters.FilterPositionUtil;
import com.intellij.psi.filters.TrueFilter;
import com.intellij.psi.filters.types.AssignableFromFilter;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.InheritanceUtil;
@@ -177,8 +174,8 @@ public class GroovyCompletionContributor extends CompletionContributor {
private static final ElementPattern<PsiElement> AFTER_NUMBER_LITERAL = psiElement().afterLeaf(
psiElement().withElementType(elementType().oneOf(mNUM_DOUBLE, mNUM_INT, mNUM_LONG, mNUM_FLOAT, mNUM_BIG_INT, mNUM_BIG_DECIMAL)));
private static final ElementPattern<PsiElement> AFTER_AT = psiElement().afterLeaf("@");
private static final ElementPattern<PsiElement> IN_CATCH_TYPE = psiElement().afterLeaf(psiElement().withText("(").withParent(GrCatchClause.class));
public static final ElementPattern<PsiElement> AFTER_AT = psiElement().afterLeaf("@");
public static final ElementPattern<PsiElement> IN_CATCH_TYPE = psiElement().afterLeaf(psiElement().withText("(").withParent(GrCatchClause.class));
private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) {
@@ -194,7 +191,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
final Consumer<LookupElement> consumer,
final InheritorsHolder inheritors, final PrefixMatcher matcher) {
final PsiElement position = parameters.getPosition();
final ElementFilter filter = getClassFilter(position);
final boolean afterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position);
AllClassesGetter.processJavaClasses(parameters, matcher, parameters.getInvocationCount() <= 1, new Consumer<PsiClass>() {
@Override
@@ -203,7 +199,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
.createClassLookupItems(psiClass, afterNew, new GroovyClassNameInsertHandler(), new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
return !inheritors.alreadyProcessed(psiClass) && filter.isAcceptable(psiClass, position);
return !inheritors.alreadyProcessed(psiClass);
}
})) {
consumer.consume(element);
@@ -212,16 +208,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
});
}
private static ElementFilter getClassFilter(PsiElement position) {
if (AFTER_AT.accepts(position)) {
return new AssignableFromFilter(CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION);
}
if (IN_CATCH_TYPE.accepts(position)) {
return new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE);
}
return TrueFilter.INSTANCE;
}
public GroovyCompletionContributor() {
//provide 'this' and 'super' completions in ClassName.<caret>
extend(CompletionType.BASIC, AFTER_DOT, new CompletionProvider<CompletionParameters>() {
@@ -378,10 +364,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
public static boolean isClassNamePossible(PsiElement position) {
if (PsiJavaPatterns.psiElement().inside(GrImportStatement.class).accepts(position)) {
return false;
}
if (position instanceof PsiComment) return false;
PsiElement parent = position.getParent();
if (parent instanceof GrReferenceElement) {
return ((GrReferenceElement)parent).getQualifier() == null;
@@ -431,8 +413,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
};
final PsiElement position = parameters.getPosition();
final Map<PsiModifierListOwner, LookupElement> staticMembers = hashMap();
final PsiElement qualifier = reference.getQualifier();
final PsiType qualifierType = qualifier instanceof GrExpression ? ((GrExpression)qualifier).getType() : null;
@@ -455,8 +435,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
unresolvedProps = Collections.emptySet();
}
final ElementFilter classFilter = getClassFilter(position);
final List<LookupElement> zeroPriority = arrayList();
reference.processVariants(matcher, parameters, new Consumer<LookupElement>() {
public void consume(LookupElement lookupElement) {
@@ -489,9 +467,6 @@ public class GroovyCompletionContributor extends CompletionContributor {
staticMembers.put(CompletionUtil.getOriginalOrSelf((PsiModifierListOwner)object), lookupElement);
}
}
if (object instanceof PsiClass && !classFilter.isAcceptable(object, position)) {
return;
}
PrioritizedLookupElement prio = lookupElement.as(PrioritizedLookupElement.CLASS_CONDITION_KEY);
if (prio == null || prio.getPriority() == 0) {
@@ -21,11 +21,13 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.CollectionFactory;
import com.intellij.util.containers.hash.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.extensions.NamedArgumentDescriptor;
import org.jetbrains.plugins.groovy.lang.completion.GroovyCompletionContributor;
import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
@@ -86,6 +88,15 @@ public class GrKindWeigher extends CompletionWeigher {
if (isPriorityKeyword(o)) return NotQualifiedKind.local;
if (isLightElement(o)) return NotQualifiedKind.unknown;
if (o instanceof PsiClass) {
if (((PsiClass)o).isAnnotationType() && GroovyCompletionContributor.AFTER_AT.accepts(position)) {
return NotQualifiedKind.restrictedClass;
}
if (GroovyCompletionContributor.IN_CATCH_TYPE.accepts(position) &&
InheritanceUtil.isInheritor((PsiClass)o, CommonClassNames.JAVA_LANG_THROWABLE)) {
return NotQualifiedKind.restrictedClass;
}
}
if (o instanceof PsiMember) {
final PsiClass containingClass = ((PsiMember)o).getContainingClass();
if (isAccessor((PsiMember)o)) return NotQualifiedKind.accessor;
@@ -145,18 +156,19 @@ public class GrKindWeigher extends CompletionWeigher {
return qualifier.getManager().areElementsEquivalent(member.getContainingClass(), psiClass);
}
private static enum NotQualifiedKind {
private enum NotQualifiedKind {
arrayType,
innerClass,
unknown,
accessor,
member,
currentClassMember,
restrictedClass,
local,
onTop
}
private static enum QualifiedKind {
private enum QualifiedKind {
innerClass,
unknown,
accessor,
@@ -226,14 +226,14 @@ new Fxoo()<caret>\n"""
myFixture.addClass "class AbcdClass {}; @interface AbcdAnno {}"
myFixture.configureByText "a.groovy", "@Abcd<caret>"
complete()
myFixture.checkResult "@AbcdAnno<caret>"
assert myFixture.lookupElementStrings[0] == 'AbcdAnno'
}
public void testOnlyExceptionsInCatch() {
myFixture.addClass "class AbcdClass {}; class AbcdException extends Throwable {}"
myFixture.configureByText "a.groovy", "try {} catch (Abcd<caret>"
complete()
myFixture.checkResult "try {} catch (AbcdException<caret>"
assert myFixture.lookupElementStrings[0] == 'AbcdException'
}
public void testClassNameInMultilineString() {
@@ -712,17 +712,17 @@ format(<caret>)"""
}
public void testOnlyAnnotationsAfterAt() {
myFixture.addClass "class AbcdClass {}; @interface AbcdAnno {}"
myFixture.addClass "class AbcdClass {}; @interface AbcdXAnno {}"
myFixture.configureByText "a.groovy", "@Abcd<caret> class A {}"
myFixture.completeBasic()
myFixture.checkResult "@AbcdAnno<caret> class A {}"
assert myFixture.lookupElementStrings[0] == 'AbcdXAnno'
}
public void testOnlyAnnotationsAfterAtInMethodParameters() {
myFixture.addClass "class AbcdClass {}; @interface AbcdAnno {}"
myFixture.configureByText "a.groovy", "def foo(@Abcd<caret> ) {}"
myFixture.completeBasic()
myFixture.checkResult "def foo(@AbcdAnno<caret> ) {}"
assert myFixture.lookupElementStrings[0] == 'AbcdAnno'
}
public void testNoCompletionInClassBodyComments() {
@@ -767,6 +767,8 @@ try {} catch (AbcdException"""
myFixture.addClass "class AbcdClass {}; class AbcdException extends Throwable {}"
myFixture.configureByText "a.groovy", "try {} catch (Abcd<caret> e) {}"
myFixture.completeBasic()
assert myFixture.lookupElementStrings[0] == 'AbcdException'
myFixture.type('\n')
myFixture.checkResult "try {} catch (AbcdException<caret> e) {}"
}