@Nullable public static Runnable fillCompletionVariants( final JavaSmartCompletionParameters parameters, final Consumer<LookupElement> result) { final PsiElement element = parameters.getPosition(); if (JavaSmartCompletionContributor.INSIDE_TYPECAST_EXPRESSION.accepts(element)) return null; if (JavaKeywordCompletion.isAfterPrimitiveOrArrayType(element)) return null; final int offset = parameters.getParameters().getOffset(); final PsiJavaCodeReferenceElement reference = PsiTreeUtil.findElementOfClassAtOffset( element.getContainingFile(), offset, PsiJavaCodeReferenceElement.class, false); if (reference != null) { final ElementFilter filter = getReferenceFilter(element, false); for (final LookupElement item : completeFinalReference(element, reference, filter, parameters)) { result.consume(item); } final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2; final Set<LookupElement> base = JavaSmartCompletionContributor.completeReference( element, reference, filter, false, true, parameters.getParameters(), PrefixMatcher.ALWAYS_TRUE); for (final LookupElement item : new LinkedHashSet<LookupElement>(base)) { ExpressionLookupItem access = ArrayMemberAccess.getSingleArrayElementAccess(element, item); if (access != null) { base.add(access); PsiType type = access.getType(); if (type != null && parameters.getExpectedType().isAssignableFrom(type)) { result.consume(access); } } } if (secondTime) { return new SlowerTypeConversions(base, element, reference, parameters, result); } } return null; }
static Set<LookupElement> completeFinalReference( final PsiElement element, PsiJavaCodeReferenceElement reference, ElementFilter filter, final JavaSmartCompletionParameters parameters) { final Set<PsiField> used = parameters.getParameters().getInvocationCount() < 2 ? findConstantsUsedInSwitch(element) : Collections.<PsiField>emptySet(); final Set<LookupElement> elements = JavaSmartCompletionContributor.completeReference( element, reference, new AndFilter( filter, new ElementFilter() { @Override public boolean isAcceptable(Object o, PsiElement context) { if (o instanceof CandidateInfo) { final CandidateInfo info = (CandidateInfo) o; final PsiElement member = info.getElement(); final PsiType expectedType = parameters.getExpectedType(); if (expectedType.equals(PsiType.VOID)) { return member instanceof PsiMethod; } //noinspection SuspiciousMethodCalls if (member instanceof PsiEnumConstant && used.contains(CompletionUtil.getOriginalOrSelf(member))) { return false; } return AssignableFromFilter.isAcceptable( member, element, expectedType, info.getSubstitutor()); } return false; } @Override public boolean isClassAcceptable(Class hintClass) { return true; } }), false, true, parameters.getParameters(), PrefixMatcher.ALWAYS_TRUE); for (LookupElement lookupElement : elements) { if (lookupElement.getObject() instanceof PsiMethod) { final JavaMethodCallElement item = lookupElement.as(JavaMethodCallElement.CLASS_CONDITION_KEY); if (item != null) { final PsiMethod method = (PsiMethod) lookupElement.getObject(); if (SmartCompletionDecorator.hasUnboundTypeParams(method, parameters.getExpectedType())) { item.setInferenceSubstitutor( SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor( method, parameters.getExpectedType()), element); } } } } return elements; }