rename InheritorsHolder to JavaCompletionSession, since it'll be holding more kinds of stuff soon

This commit is contained in:
peter
2016-04-29 22:56:17 +02:00
parent b57a3485a8
commit 2545fe69d9
8 changed files with 85 additions and 121 deletions
@@ -23,7 +23,6 @@ import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.patterns.ElementPattern;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Consumer;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
@@ -48,27 +47,24 @@ class CatchTypeProvider extends CompletionProvider<CompletionParameters> {
final PsiCodeBlock tryBlock = tryStatement == null ? null : tryStatement.getTryBlock();
if (tryBlock == null) return;
final InheritorsHolder holder = new InheritorsHolder(result);
final JavaCompletionSession session = new JavaCompletionSession(result);
for (final PsiClassType type : ExceptionUtil.getThrownExceptions(tryBlock.getStatements())) {
PsiClass typeClass = type.resolve();
if (typeClass != null) {
result.addElement(createCatchTypeVariant(tryBlock, type));
holder.registerClass(typeClass);
session.registerClass(typeClass);
}
}
final Collection<PsiClassType> expectedClassTypes = Collections.singletonList(JavaPsiFacade.getElementFactory(
tryBlock.getProject()).createTypeByFQClassName(CommonClassNames.JAVA_LANG_THROWABLE));
JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), new Consumer<PsiType>() {
@Override
public void consume(PsiType type) {
final PsiClass psiClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null;
if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
JavaInheritorsGetter.processInheritors(parameters, expectedClassTypes, result.getPrefixMatcher(), type -> {
final PsiClass psiClass = type instanceof PsiClassType ? ((PsiClassType)type).resolve() : null;
if (psiClass == null || psiClass instanceof PsiTypeParameter) return;
if (!holder.alreadyProcessed(psiClass)) {
result.addElement(createCatchTypeVariant(tryBlock, (PsiClassType)type));
}
if (!session.alreadyProcessed(psiClass)) {
result.addElement(createCatchTypeVariant(tryBlock, (PsiClassType)type));
}
});
}
@@ -227,7 +227,7 @@ public class JavaCompletionContributor extends CompletionContributor {
PrefixMatcher matcher = result.getPrefixMatcher();
PsiElement parent = position.getParent();
final InheritorsHolder inheritors = new InheritorsHolder(result);
JavaCompletionSession inheritors = new JavaCompletionSession(result);
if (position instanceof PsiIdentifier) {
addIdentifierVariants(parameters, position, result, matcher, parent, inheritors);
}
@@ -260,34 +260,28 @@ public class JavaCompletionContributor extends CompletionContributor {
private static void addIdentifierVariants(@NotNull CompletionParameters parameters,
PsiElement position,
final CompletionResultSet result,
PrefixMatcher matcher, PsiElement parent, final InheritorsHolder inheritors) {
PrefixMatcher matcher, PsiElement parent, JavaCompletionSession session) {
if (TypeArgumentCompletionProvider.IN_TYPE_ARGS.accepts(position)) {
new TypeArgumentCompletionProvider(false, inheritors).addCompletions(parameters, new ProcessingContext(), result);
new TypeArgumentCompletionProvider(false, session).addCompletions(parameters, new ProcessingContext(), result);
}
result.addAllElements(FunctionalExpressionCompletionProvider.getLambdaVariants(parameters, true));
if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) {
new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE).generateVariants(parameters, matcher, inheritors);
new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE).generateVariants(parameters, matcher, session);
}
if (MethodReturnTypeProvider.IN_METHOD_RETURN_TYPE.accepts(position)) {
MethodReturnTypeProvider.addProbableReturnTypes(parameters, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
registerClassFromTypeElement(element, inheritors);
result.addElement(element);
}
MethodReturnTypeProvider.addProbableReturnTypes(parameters, element -> {
registerClassFromTypeElement(element, session);
result.addElement(element);
});
}
if (SmartCastProvider.shouldSuggestCast(parameters)) {
SmartCastProvider.addCastVariants(parameters, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
registerClassFromTypeElement(element, inheritors);
result.addElement(PrioritizedLookupElement.withPriority(element, 1));
}
SmartCastProvider.addCastVariants(parameters, element -> {
registerClassFromTypeElement(element, session);
result.addElement(PrioritizedLookupElement.withPriority(element, 1));
});
}
@@ -306,7 +300,7 @@ public class JavaCompletionContributor extends CompletionContributor {
addExpressionVariants(parameters, position, result);
}
private static void registerClassFromTypeElement(LookupElement element, InheritorsHolder inheritors) {
private static void registerClassFromTypeElement(LookupElement element, JavaCompletionSession inheritors) {
PsiType type = assertNotNull(element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY)).getType();
PsiClass aClass =
type instanceof PsiClassType && ((PsiClassType)type).getParameterCount() == 0 ? ((PsiClassType)type).resolve() : null;
@@ -331,18 +325,15 @@ public class JavaCompletionContributor extends CompletionContributor {
public static void addAllClasses(final CompletionParameters parameters,
final CompletionResultSet result,
final InheritorsHolder inheritors) {
final JavaCompletionSession session) {
if (!isClassNamePossible(parameters) || !mayStartClassName(result)) {
return;
}
if (parameters.getInvocationCount() >= 2) {
JavaClassNameCompletionContributor.addAllClasses(parameters, parameters.getInvocationCount() <= 2, result.getPrefixMatcher(), new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
if (!inheritors.alreadyProcessed(element)) {
result.addElement(JavaClassNameCompletionContributor.highlightIfNeeded((JavaPsiClassReferenceElement)element, parameters));
}
JavaClassNameCompletionContributor.addAllClasses(parameters, parameters.getInvocationCount() <= 2, result.getPrefixMatcher(), element -> {
if (!session.alreadyProcessed(element)) {
result.addElement(JavaClassNameCompletionContributor.highlightIfNeeded((JavaPsiClassReferenceElement)element, parameters));
}
});
} else {
@@ -356,7 +347,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
}
private static Set<String> addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) {
private static Set<String> addReferenceVariants(final CompletionParameters parameters, CompletionResultSet result, JavaCompletionSession session) {
final Set<String> usedWords = new HashSet<String>();
final PsiElement position = parameters.getPosition();
final boolean first = parameters.getInvocationCount() <= 1;
@@ -385,7 +376,7 @@ public class JavaCompletionContributor extends CompletionContributor {
new ElementExtractorFilter(filter),
options,
result.getPrefixMatcher(), parameters)) {
if (inheritors.alreadyProcessed(element)) {
if (session.alreadyProcessed(element)) {
continue;
}
@@ -403,12 +394,9 @@ public class JavaCompletionContributor extends CompletionContributor {
final PsiMethod method = call.getObject();
if (method.getTypeParameters().length > 0) {
final PsiType returned = TypeConversionUtil.erasure(method.getReturnType());
PsiType matchingExpectation = returned == null ? null : ContainerUtil.find(expectedTypes, new Condition<PsiType>() {
@Override
public boolean value(PsiType type) {
return type.isAssignableFrom(returned);
}
});
PsiType matchingExpectation = returned == null
? null
: ContainerUtil.find(expectedTypes, type -> type.isAssignableFrom(returned));
if (matchingExpectation != null) {
call.setInferenceSubstitutor(SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, matchingExpectation), position);
}
@@ -435,18 +423,17 @@ public class JavaCompletionContributor extends CompletionContributor {
if (completion == null) {
LOG.error("Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants));
}
if (completion instanceof LookupElement && !inheritors.alreadyProcessed((LookupElement)completion)) {
if (completion instanceof LookupElement && !session.alreadyProcessed((LookupElement)completion)) {
usedWords.add(((LookupElement)completion).getLookupString());
result.addElement((LookupElement)completion);
}
else if (completion instanceof PsiClass) {
for (JavaPsiClassReferenceElement item : JavaClassNameCompletionContributor.createClassLookupItems((PsiClass)completion, isAfterNew,
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER, new Condition<PsiClass>() {
@Override
public boolean value(PsiClass psiClass) {
return !inheritors.alreadyProcessed(psiClass) && JavaCompletionUtil.isSourceLevelAccessible(position, psiClass, pkgContext);
}
})) {
Condition<PsiClass> condition = psiClass -> !session.alreadyProcessed(psiClass) &&
JavaCompletionUtil.isSourceLevelAccessible(position, psiClass, pkgContext);
for (JavaPsiClassReferenceElement item : JavaClassNameCompletionContributor.createClassLookupItems((PsiClass)completion,
isAfterNew,
JavaClassNameInsertHandler.JAVA_CLASS_INSERT_HANDLER,
condition)) {
usedWords.add(item.getLookupString());
result.addElement(item);
}
@@ -543,7 +530,7 @@ public class JavaCompletionContributor extends CompletionContributor {
for (final LookupElement element : set) {
result.addElement(element);
}
addAllClasses(parameters, result, new InheritorsHolder(result));
addAllClasses(parameters, result, new JavaCompletionSession(result));
}
if (annoClass != null) {
@@ -29,11 +29,11 @@ import java.util.Set;
/**
* @author peter
*/
public class InheritorsHolder implements Consumer<LookupElement> {
public class JavaCompletionSession implements Consumer<LookupElement> {
private final Set<String> myAddedClasses = new HashSet<String>();
private final CompletionResultSet myResult;
public InheritorsHolder(CompletionResultSet result) {
public JavaCompletionSession(CompletionResultSet result) {
myResult = result;
}
@@ -114,7 +114,7 @@ public class JavaDocCompletionContributor extends CompletionContributor {
result.addElement(item);
}
JavaCompletionContributor.addAllClasses(parameters, result, new InheritorsHolder(result));
JavaCompletionContributor.addAllClasses(parameters, result, new JavaCompletionSession(result));
}
if (tag != null && "author".equals(tag.getName())) {
@@ -42,7 +42,7 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
final InheritorsHolder holder = new InheritorsHolder(result);
final JavaCompletionSession session = new JavaCompletionSession(result);
ResultTracker tracker = new ResultTracker(result) {
@Override
public void consume(CompletionResult plainResult) {
@@ -51,10 +51,10 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
LookupElement element = plainResult.getLookupElement();
Object o = element.getObject();
if (o instanceof PsiClass) {
holder.registerClass((PsiClass)o);
session.registerClass((PsiClass)o);
}
if (element instanceof TypeArgumentCompletionProvider.TypeArgsLookupElement) {
((TypeArgumentCompletionProvider.TypeArgsLookupElement)element).registerSingleClass(holder);
((TypeArgumentCompletionProvider.TypeArgsLookupElement)element).registerSingleClass(session);
}
}
};
@@ -66,14 +66,14 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
}
if (empty) {
delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), holder);
delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result), session);
} else if (Registry.is("ide.completion.show.better.matching.classes")) {
if (parameters.getCompletionType() == CompletionType.BASIC &&
parameters.getInvocationCount() <= 1 &&
JavaCompletionContributor.mayStartClassName(result) &&
JavaCompletionContributor.isClassNamePossible(parameters) &&
!JavaSmartCompletionContributor.AFTER_NEW.accepts(parameters.getPosition())) {
suggestNonImportedClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result.withPrefixMatcher(tracker.betterMatcher)), holder);
suggestNonImportedClasses(parameters, JavaCompletionSorting.addJavaSorting(parameters, result.withPrefixMatcher(tracker.betterMatcher)), session);
}
}
}
@@ -82,7 +82,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
return psiElement().withParents(PsiJavaCodeReferenceElement.class, PsiAnnotation.class).accepts(parameters.getPosition());
}
private static void delegate(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritorsHolder) {
private static void delegate(CompletionParameters parameters, CompletionResultSet result, JavaCompletionSession session) {
if (parameters.getCompletionType() == CompletionType.BASIC) {
PsiElement position = parameters.getPosition();
suggestCollectionUtilities(parameters, result, position);
@@ -90,7 +90,7 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
if (parameters.getInvocationCount() <= 1 &&
(JavaCompletionContributor.mayStartClassName(result) || suggestAllAnnotations(parameters)) &&
JavaCompletionContributor.isClassNamePossible(parameters)) {
suggestNonImportedClasses(parameters, result, inheritorsHolder);
suggestNonImportedClasses(parameters, result, session);
return;
}
@@ -176,22 +176,18 @@ public class JavaNoVariantsDelegator extends CompletionContributor {
return allClasses;
}
private static void suggestNonImportedClasses(final CompletionParameters parameters, final CompletionResultSet result, @Nullable final InheritorsHolder inheritorsHolder) {
JavaClassNameCompletionContributor.addAllClasses(parameters,
true, result.getPrefixMatcher(), new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
if (inheritorsHolder != null && inheritorsHolder.alreadyProcessed(element)) {
return;
}
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
element = JavaClassNameCompletionContributor.highlightIfNeeded(classElement, parameters);
}
result.addElement(element);
private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result, @Nullable JavaCompletionSession session) {
JavaClassNameCompletionContributor.addAllClasses(parameters, true, result.getPrefixMatcher(), element -> {
if (session != null && session.alreadyProcessed(element)) {
return;
}
JavaPsiClassReferenceElement classElement = element.as(JavaPsiClassReferenceElement.CLASS_CONDITION_KEY);
if (classElement != null) {
classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
element = JavaClassNameCompletionContributor.highlightIfNeeded(classElement, parameters);
}
result.addElement(element);
});
}
@@ -52,11 +52,11 @@ class TypeArgumentCompletionProvider extends CompletionProvider<CompletionParame
static final ElementPattern<PsiElement> IN_TYPE_ARGS = psiElement().inside(PsiReferenceParameterList.class);
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.TypeArgumentCompletionProvider");
private final boolean mySmart;
@Nullable private final InheritorsHolder myInheritors;
@Nullable private final JavaCompletionSession mySession;
TypeArgumentCompletionProvider(boolean smart, @Nullable InheritorsHolder inheritors) {
TypeArgumentCompletionProvider(boolean smart, @Nullable JavaCompletionSession session) {
mySmart = smart;
myInheritors = inheritors;
mySession = session;
}
@Override
@@ -114,7 +114,7 @@ class TypeArgumentCompletionProvider extends CompletionProvider<CompletionParame
boolean hasParameters = ConstructorInsertHandler.hasConstructorParameters(actualClass, context);
TypeArgsLookupElement element = new TypeArgsLookupElement(typeItems, globalTail, hasParameters);
element.registerSingleClass(myInheritors);
element.registerSingleClass(mySession);
resultSet.addElement(element);
}
@@ -216,7 +216,7 @@ class TypeArgumentCompletionProvider extends CompletionProvider<CompletionParame
return myTypeItems.get(0).getObject();
}
public void registerSingleClass(@Nullable InheritorsHolder inheritors) {
public void registerSingleClass(@Nullable JavaCompletionSession inheritors) {
if (inheritors != null && myTypeItems.size() == 1) {
PsiType type = myTypeItems.get(0).getType();
PsiClass aClass = PsiUtil.resolveClassInClassTypeOnly(type);
@@ -164,18 +164,13 @@ public class GrMainCompletionProvider extends CompletionProvider<CompletionParam
return couldContainReference(position);
}
private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) {
addAllClasses(parameters, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
result.addElement(element);
}
}, inheritors, result.getPrefixMatcher());
private static void addAllClasses(CompletionParameters parameters, final CompletionResultSet result, final JavaCompletionSession session) {
addAllClasses(parameters, result::addElement, session, result.getPrefixMatcher());
}
public static void addAllClasses(CompletionParameters parameters,
final Consumer<LookupElement> consumer,
final InheritorsHolder inheritors, final PrefixMatcher matcher) {
final JavaCompletionSession inheritors, final PrefixMatcher matcher) {
final PsiElement position = parameters.getPosition();
final boolean afterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position);
AllClassesGetter.processJavaClasses(parameters, matcher, parameters.getInvocationCount() <= 1, new Consumer<PsiClass>() {
@@ -197,7 +192,7 @@ public class GrMainCompletionProvider extends CompletionProvider<CompletionParam
@NotNull
static Runnable completeReference(final CompletionParameters parameters,
final GrReferenceElement reference,
final InheritorsHolder inheritorsHolder,
final JavaCompletionSession inheritorsHolder,
final PrefixMatcher matcher,
final Consumer<LookupElement> _consumer) {
final Consumer<LookupElement> consumer = new Consumer<LookupElement>() {
@@ -473,7 +468,7 @@ public class GrMainCompletionProvider extends CompletionProvider<CompletionParam
if (reference == null) {
if (parameters.getInvocationCount() >= 2) {
result.stopHere();
addAllClasses(parameters, result.withPrefixMatcher(CompletionUtil.findJavaIdentifierPrefix(parameters)), new InheritorsHolder(result));
addAllClasses(parameters, result.withPrefixMatcher(CompletionUtil.findJavaIdentifierPrefix(parameters)), new JavaCompletionSession(result));
}
return;
}
@@ -482,7 +477,7 @@ public class GrMainCompletionProvider extends CompletionProvider<CompletionParam
result.addElement(LookupElementBuilder.create("*"));
}
InheritorsHolder inheritors = new InheritorsHolder(result);
JavaCompletionSession inheritors = new JavaCompletionSession(result);
if (GroovySmartCompletionContributor.AFTER_NEW.accepts(position)) {
GroovySmartCompletionContributor.generateInheritorVariants(parameters, result.getPrefixMatcher(), inheritors);
}
@@ -93,7 +93,7 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
}
result.addElement(element);
}
}, new InheritorsHolder(result), result.getPrefixMatcher());
}, new JavaCompletionSession(result), result.getPrefixMatcher());
}
private static void suggestChainedCalls(CompletionParameters parameters, CompletionResultSet result) {
@@ -114,25 +114,21 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
String fullPrefix = position.getContainingFile().getText().substring(parent.getTextRange().getStartOffset(), parameters.getOffset());
final CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix);
InheritorsHolder inheritors = new InheritorsHolder(result);
for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, inheritors)) {
JavaCompletionSession session = new JavaCompletionSession(result);
for (final LookupElement base : suggestQualifierItems(parameters, (GrReferenceElement)qualifier, session)) {
final PsiType type = getPsiType(base.getObject());
if (type != null && !PsiType.VOID.equals(type)) {
GrReferenceElement ref = createMockReference(position, type, base);
PsiElement refName = ref.getReferenceNameElement();
assert refName != null;
CompletionParameters newParams = parameters.withPosition(refName, refName.getTextRange().getStartOffset());
GrMainCompletionProvider.completeReference(newParams, ref, inheritors, result.getPrefixMatcher(), new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
qualifiedCollector.addElement(new JavaChainLookupElement(base, element) {
@Override
protected boolean shouldParenthesizeQualifier(PsiFile file, int startOffset, int endOffset) {
return false;
}
});
}
});
GrMainCompletionProvider.completeReference(newParams, ref, session, result.getPrefixMatcher(), element ->
qualifiedCollector.addElement(new JavaChainLookupElement(base, element) {
@Override
protected boolean shouldParenthesizeQualifier(PsiFile file, int startOffset, int endOffset) {
return false;
}
}));
}
}
}
@@ -170,7 +166,7 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
private static Set<LookupElement> suggestQualifierItems(CompletionParameters _parameters,
GrReferenceElement qualifier,
InheritorsHolder inheritors) {
JavaCompletionSession session) {
CompletionParameters parameters =
_parameters.withPosition(qualifier.getReferenceNameElement(), qualifier.getTextRange().getEndOffset());
String referenceName = qualifier.getReferenceName();
@@ -180,12 +176,9 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
final PrefixMatcher qMatcher = new CamelHumpMatcher(referenceName);
final Set<LookupElement> variants = new LinkedHashSet<LookupElement>();
GrMainCompletionProvider.completeReference(parameters, qualifier, inheritors, qMatcher, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
if (qMatcher.prefixMatches(element)) {
variants.add(element);
}
GrMainCompletionProvider.completeReference(parameters, qualifier, session, qMatcher, element -> {
if (qMatcher.prefixMatches(element)) {
variants.add(element);
}
});
@@ -195,14 +188,11 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
if (variants.isEmpty()) {
GrMainCompletionProvider.addAllClasses(parameters, new Consumer<LookupElement>() {
@Override
public void consume(LookupElement element) {
if (qMatcher.prefixMatches(element)) {
variants.add(element);
}
GrMainCompletionProvider.addAllClasses(parameters, element -> {
if (qMatcher.prefixMatches(element)) {
variants.add(element);
}
}, inheritors, qMatcher);
}, session, qMatcher);
}
return variants;
}