mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 20:39:40 +07:00
don't suggest expected type members twice when they are statically imported (IDEA-79426)
This commit is contained in:
@@ -528,7 +528,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{
|
|||||||
!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position) &&
|
!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position) &&
|
||||||
!(position.getParent() instanceof PsiLiteralExpression)) {
|
!(position.getParent() instanceof PsiLiteralExpression)) {
|
||||||
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) {
|
||||||
new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, parameters.getInvocationCount() > 1, new Consumer<LookupElement>() {
|
new JavaMembersGetter(info.getDefaultType(), position).addMembers(parameters, parameters.getInvocationCount() > 1, new Consumer<LookupElement>() {
|
||||||
@Override
|
@Override
|
||||||
public void consume(LookupElement element) {
|
public void consume(LookupElement element) {
|
||||||
result.addElement(element);
|
result.addElement(element);
|
||||||
|
|||||||
@@ -356,9 +356,9 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
|
|||||||
PsiElement position = params.getPosition();
|
PsiElement position = params.getPosition();
|
||||||
if (!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position)) {
|
if (!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position)) {
|
||||||
for (ExpectedTypeInfo info : mergedInfos) {
|
for (ExpectedTypeInfo info : mergedInfos) {
|
||||||
new JavaMembersGetter(info.getType(), position).addMembers(position, !quick, consumer);
|
new JavaMembersGetter(info.getType(), position).addMembers(params, !quick, consumer);
|
||||||
if (!info.getDefaultType().equals(info.getType())) {
|
if (!info.getDefaultType().equals(info.getType())) {
|
||||||
new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, !quick, consumer);
|
new JavaMembersGetter(info.getDefaultType(), position).addMembers(params, !quick, consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,7 @@
|
|||||||
package com.intellij.psi.filters.getters;
|
package com.intellij.psi.filters.getters;
|
||||||
|
|
||||||
import com.intellij.codeInsight.TailType;
|
import com.intellij.codeInsight.TailType;
|
||||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
import com.intellij.codeInsight.completion.*;
|
||||||
import com.intellij.codeInsight.completion.JavaMethodCallElement;
|
|
||||||
import com.intellij.codeInsight.completion.ReferenceExpressionCompletionContributor;
|
|
||||||
import com.intellij.codeInsight.completion.SmartCompletionDecorator;
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
import com.intellij.codeInsight.lookup.TailTypeDecorator;
|
||||||
import com.intellij.codeInsight.lookup.VariableLookupItem;
|
import com.intellij.codeInsight.lookup.VariableLookupItem;
|
||||||
@@ -47,10 +44,12 @@ public class JavaMembersGetter extends MembersGetter {
|
|||||||
myExpectedType = JavaCompletionUtil.originalize(expectedType);
|
myExpectedType = JavaCompletionUtil.originalize(expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMembers(PsiElement position, boolean searchInheritors, final Consumer<LookupElement> results) {
|
public void addMembers(CompletionParameters parameters, boolean searchInheritors, final Consumer<LookupElement> results) {
|
||||||
|
final StaticMemberProcessor processor = JavaGlobalMemberNameCompletionContributor.completeStaticMembers(parameters);
|
||||||
|
final PsiElement position = parameters.getPosition();
|
||||||
if (myExpectedType instanceof PsiPrimitiveType && PsiType.DOUBLE.isAssignableFrom(myExpectedType)) {
|
if (myExpectedType instanceof PsiPrimitiveType && PsiType.DOUBLE.isAssignableFrom(myExpectedType)) {
|
||||||
addConstantsFromTargetClass(position, results, searchInheritors);
|
addConstantsFromTargetClass(position, results, searchInheritors, processor);
|
||||||
addConstantsFromReferencedClassesInSwitch(position, results);
|
addConstantsFromReferencedClassesInSwitch(position, results, processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (position.getParent().getParent() instanceof PsiSwitchLabelStatement) {
|
if (position.getParent().getParent() instanceof PsiSwitchLabelStatement) {
|
||||||
@@ -58,10 +57,10 @@ public class JavaMembersGetter extends MembersGetter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final PsiClass psiClass = PsiUtil.resolveClassInType(myExpectedType);
|
final PsiClass psiClass = PsiUtil.resolveClassInType(myExpectedType);
|
||||||
processMembers(position, results, psiClass, PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) != null, searchInheritors);
|
processMembers(position, results, psiClass, PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) != null, searchInheritors, processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConstantsFromReferencedClassesInSwitch(PsiElement position, final Consumer<LookupElement> results) {
|
private void addConstantsFromReferencedClassesInSwitch(PsiElement position, final Consumer<LookupElement> results, final StaticMemberProcessor processor) {
|
||||||
final Set<PsiField> fields = ReferenceExpressionCompletionContributor.findConstantsUsedInSwitch(position);
|
final Set<PsiField> fields = ReferenceExpressionCompletionContributor.findConstantsUsedInSwitch(position);
|
||||||
final Set<PsiClass> classes = new HashSet<PsiClass>();
|
final Set<PsiClass> classes = new HashSet<PsiClass>();
|
||||||
for (PsiField field : fields) {
|
for (PsiField field : fields) {
|
||||||
@@ -76,11 +75,13 @@ public class JavaMembersGetter extends MembersGetter {
|
|||||||
results.consume(TailTypeDecorator.withTail(element, TailType.CASE_COLON));
|
results.consume(TailTypeDecorator.withTail(element, TailType.CASE_COLON));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, aClass, false, false);
|
}, aClass, false, false, processor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConstantsFromTargetClass(PsiElement position, Consumer<LookupElement> results, boolean searchInheritors) {
|
private void addConstantsFromTargetClass(PsiElement position,
|
||||||
|
Consumer<LookupElement> results,
|
||||||
|
boolean searchInheritors, final StaticMemberProcessor processor) {
|
||||||
PsiElement parent = position.getParent();
|
PsiElement parent = position.getParent();
|
||||||
if (!(parent instanceof PsiReferenceExpression)) {
|
if (!(parent instanceof PsiReferenceExpression)) {
|
||||||
return;
|
return;
|
||||||
@@ -93,7 +94,8 @@ public class JavaMembersGetter extends MembersGetter {
|
|||||||
final IElementType op = binaryExpression.getOperationTokenType();
|
final IElementType op = binaryExpression.getOperationTokenType();
|
||||||
if (JavaTokenType.EQEQ == op || JavaTokenType.NE == op) {
|
if (JavaTokenType.EQEQ == op || JavaTokenType.NE == op) {
|
||||||
if (prev == binaryExpression.getROperand()) {
|
if (prev == binaryExpression.getROperand()) {
|
||||||
processMembers(position, results, getCalledClass(binaryExpression.getLOperand()), false, searchInheritors);
|
processMembers(position, results, getCalledClass(binaryExpression.getLOperand()), false, searchInheritors,
|
||||||
|
processor);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -101,7 +103,7 @@ public class JavaMembersGetter extends MembersGetter {
|
|||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
if (parent instanceof PsiExpressionList) {
|
if (parent instanceof PsiExpressionList) {
|
||||||
processMembers(position, results, getCalledClass(parent.getParent()), false, searchInheritors);
|
processMembers(position, results, getCalledClass(parent.getParent()), false, searchInheritors, processor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.intellij.psi.filters.getters;
|
|||||||
import com.intellij.codeInsight.CodeInsightUtil;
|
import com.intellij.codeInsight.CodeInsightUtil;
|
||||||
import com.intellij.codeInsight.completion.CompletionUtil;
|
import com.intellij.codeInsight.completion.CompletionUtil;
|
||||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||||
|
import com.intellij.codeInsight.completion.StaticMemberProcessor;
|
||||||
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.openapi.util.Condition;
|
import com.intellij.openapi.util.Condition;
|
||||||
@@ -28,11 +29,14 @@ import com.intellij.psi.util.InheritanceUtil;
|
|||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import com.intellij.psi.util.PsiUtil;
|
import com.intellij.psi.util.PsiUtil;
|
||||||
import com.intellij.util.Consumer;
|
import com.intellij.util.Consumer;
|
||||||
|
import com.intellij.util.PairConsumer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author ik
|
* @author ik
|
||||||
@@ -40,7 +44,9 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public abstract class MembersGetter {
|
public abstract class MembersGetter {
|
||||||
|
|
||||||
public void processMembers(@NotNull final PsiElement context, final Consumer<LookupElement> results, @Nullable final PsiClass where, final boolean acceptMethods, boolean searchInheritors) {
|
public void processMembers(@NotNull final PsiElement context, final Consumer<LookupElement> results, @Nullable final PsiClass where,
|
||||||
|
final boolean acceptMethods, boolean searchInheritors,
|
||||||
|
StaticMemberProcessor processor) {
|
||||||
if (where == null) return;
|
if (where == null) return;
|
||||||
|
|
||||||
final List<PsiClass> placeClasses = new ArrayList<PsiClass>();
|
final List<PsiClass> placeClasses = new ArrayList<PsiClass>();
|
||||||
@@ -51,6 +57,31 @@ public abstract class MembersGetter {
|
|||||||
placeClasses.add(current);
|
placeClasses.add(current);
|
||||||
current = PsiTreeUtil.getContextOfType(current, PsiClass.class);
|
current = PsiTreeUtil.getContextOfType(current, PsiClass.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Set<PsiMember> importedStatically = new HashSet<PsiMember>();
|
||||||
|
processor.processMembersOfRegisteredClasses(null, new PairConsumer<PsiMember, PsiClass>() {
|
||||||
|
@Override
|
||||||
|
public void consume(PsiMember member, PsiClass psiClass) {
|
||||||
|
importedStatically.add(member);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
final Condition<PsiClass> mayProcessMembers = new Condition<PsiClass>() {
|
||||||
|
@Override
|
||||||
|
public boolean value(PsiClass psiClass) {
|
||||||
|
if (psiClass == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
psiClass = CompletionUtil.getOriginalOrSelf(psiClass);
|
||||||
|
for (PsiClass placeClass : placeClasses) {
|
||||||
|
if (InheritanceUtil.isInheritorOrSelf(placeClass, psiClass, true)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper();
|
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(context.getProject()).getResolveHelper();
|
||||||
|
|
||||||
@@ -59,14 +90,14 @@ public abstract class MembersGetter {
|
|||||||
@Override
|
@Override
|
||||||
public void consume(PsiType psiType) {
|
public void consume(PsiType psiType) {
|
||||||
PsiClass psiClass = PsiUtil.resolveClassInType(psiType);
|
PsiClass psiClass = PsiUtil.resolveClassInType(psiType);
|
||||||
if (psiClass != null) {
|
if (mayProcessMembers.value(psiClass)) {
|
||||||
psiClass = CompletionUtil.getOriginalOrSelf(psiClass);
|
psiClass = CompletionUtil.getOriginalOrSelf(psiClass);
|
||||||
for (PsiClass placeClass : placeClasses) {
|
for (PsiClass placeClass : placeClasses) {
|
||||||
if (InheritanceUtil.isInheritorOrSelf(placeClass, where, true)) {
|
if (InheritanceUtil.isInheritorOrSelf(placeClass, psiClass, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
processClassDeclaredMembers(psiClass, context, acceptMethods, results, resolveHelper);
|
processClassDeclaredMembers(psiClass, context, acceptMethods, results, resolveHelper, importedStatically);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -79,14 +110,14 @@ public abstract class MembersGetter {
|
|||||||
private void processClassDeclaredMembers(PsiClass where,
|
private void processClassDeclaredMembers(PsiClass where,
|
||||||
PsiElement context,
|
PsiElement context,
|
||||||
boolean acceptMethods,
|
boolean acceptMethods,
|
||||||
Consumer<LookupElement> results, final PsiResolveHelper resolveHelper) {
|
Consumer<LookupElement> results, final PsiResolveHelper resolveHelper, final Set<PsiMember> importedStatically) {
|
||||||
final FilterScopeProcessor<PsiElement> processor = new FilterScopeProcessor<PsiElement>(TrueFilter.INSTANCE);
|
final FilterScopeProcessor<PsiElement> processor = new FilterScopeProcessor<PsiElement>(TrueFilter.INSTANCE);
|
||||||
where.processDeclarations(processor, ResolveState.initial(), null, context);
|
where.processDeclarations(processor, ResolveState.initial(), null, context);
|
||||||
|
|
||||||
for (final PsiElement result : processor.getResults()) {
|
for (final PsiElement result : processor.getResults()) {
|
||||||
if (result instanceof PsiMember && !(result instanceof PsiClass)) {
|
if (result instanceof PsiMember && !(result instanceof PsiClass)) {
|
||||||
final PsiMember member = (PsiMember)result;
|
final PsiMember member = (PsiMember)result;
|
||||||
if (JavaCompletionUtil.isInExcludedPackage(member)) continue;
|
if (JavaCompletionUtil.isInExcludedPackage(member) || importedStatically.contains(member)) continue;
|
||||||
if (member.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(member, context, null)) {
|
if (member.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(member, context, null)) {
|
||||||
if (result instanceof PsiField && !member.hasModifierProperty(PsiModifier.FINAL)) continue;
|
if (result instanceof PsiField && !member.hasModifierProperty(PsiModifier.FINAL)) continue;
|
||||||
if (result instanceof PsiMethod && acceptMethods) continue;
|
if (result instanceof PsiMethod && acceptMethods) continue;
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import static Super.FOO;
|
||||||
|
|
||||||
|
class Super {
|
||||||
|
public static final Super FOO = null;
|
||||||
|
public static final Super FOX = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
class Intermediate {
|
||||||
|
Super s = FO<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -938,6 +938,11 @@ public class ListUtils {
|
|||||||
public void testSuggestExpectedTypeMembersInCall() throws Throwable { doTest('\n') }
|
public void testSuggestExpectedTypeMembersInCall() throws Throwable { doTest('\n') }
|
||||||
public void testExpectedTypesDotSelectsItem() throws Throwable { doTest('.') }
|
public void testExpectedTypesDotSelectsItem() throws Throwable { doTest('.') }
|
||||||
|
|
||||||
|
public void testExpectedTypeMembersVersusStaticImports() throws Throwable {
|
||||||
|
configure()
|
||||||
|
assertStringItems('FOO', 'FOX')
|
||||||
|
}
|
||||||
|
|
||||||
public void testDoubleExpectedTypeFactoryMethod() throws Throwable {
|
public void testDoubleExpectedTypeFactoryMethod() throws Throwable {
|
||||||
configure()
|
configure()
|
||||||
assertStringItems('Key', 'create', 'create')
|
assertStringItems('Key', 'create', 'create')
|
||||||
|
|||||||
@@ -552,7 +552,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StaticMemberProcessor completeStaticMembers(CompletionParameters parameters) {
|
static StaticMemberProcessor completeStaticMembers(CompletionParameters parameters) {
|
||||||
final PsiElement position = parameters.getPosition();
|
final PsiElement position = parameters.getPosition();
|
||||||
final PsiElement originalPosition = parameters.getOriginalPosition();
|
final PsiElement originalPosition = parameters.getOriginalPosition();
|
||||||
final StaticMemberProcessor processor = new StaticMemberProcessor(position) {
|
final StaticMemberProcessor processor = new StaticMemberProcessor(position) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jetbrains.plugins.groovy.lang.completion;
|
package org.jetbrains.plugins.groovy.lang.completion;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.CompletionParameters;
|
||||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.psi.*;
|
import com.intellij.psi.*;
|
||||||
@@ -31,14 +32,17 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
|
|||||||
class GroovyMembersGetter extends MembersGetter {
|
class GroovyMembersGetter extends MembersGetter {
|
||||||
private final PsiClassType myExpectedType;
|
private final PsiClassType myExpectedType;
|
||||||
private final GroovyPsiElement myContext;
|
private final GroovyPsiElement myContext;
|
||||||
|
private final CompletionParameters myParameters;
|
||||||
|
|
||||||
GroovyMembersGetter(PsiClassType expectedType, PsiElement context) {
|
GroovyMembersGetter(PsiClassType expectedType, PsiElement context, CompletionParameters parameters) {
|
||||||
|
myParameters = parameters;
|
||||||
myExpectedType = JavaCompletionUtil.originalize(expectedType);
|
myExpectedType = JavaCompletionUtil.originalize(expectedType);
|
||||||
myContext = (GroovyPsiElement)context;
|
myContext = (GroovyPsiElement)context;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processMembers(boolean searchInheritors, final Consumer<LookupElement> results) {
|
public void processMembers(boolean searchInheritors, final Consumer<LookupElement> results) {
|
||||||
processMembers(myContext, results, myExpectedType.resolve(), PsiTreeUtil.getParentOfType(myContext, GrAnnotation.class) != null, searchInheritors);
|
processMembers(myContext, results, myExpectedType.resolve(), PsiTreeUtil.getParentOfType(myContext, GrAnnotation.class) != null, searchInheritors,
|
||||||
|
GroovyCompletionContributor.completeStaticMembers(myParameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -220,10 +220,10 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
|
|||||||
PsiType defType = info.getDefaultType();
|
PsiType defType = info.getDefaultType();
|
||||||
boolean searchInheritors = params.getInvocationCount() > 1;
|
boolean searchInheritors = params.getInvocationCount() > 1;
|
||||||
if (type instanceof PsiClassType) {
|
if (type instanceof PsiClassType) {
|
||||||
new GroovyMembersGetter((PsiClassType)type, reference).processMembers(searchInheritors, consumer);
|
new GroovyMembersGetter((PsiClassType)type, reference, params).processMembers(searchInheritors, consumer);
|
||||||
}
|
}
|
||||||
if (!defType.equals(type) && defType instanceof PsiClassType) {
|
if (!defType.equals(type) && defType instanceof PsiClassType) {
|
||||||
new GroovyMembersGetter((PsiClassType)defType, reference).processMembers(searchInheritors, consumer);
|
new GroovyMembersGetter((PsiClassType)defType, reference, params).processMembers(searchInheritors, consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user