public static void addAllClasses( CompletionParameters parameters, final CompletionResultSet result, final InheritorsHolder inheritors) { 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(element); } } }); } else { advertiseSecondCompletion(parameters.getPosition().getProject(), result); } }
static boolean isClassNamePossible(CompletionParameters parameters) { boolean isSecondCompletion = parameters.getInvocationCount() >= 2; PsiElement position = parameters.getPosition(); if (JavaCompletionData.isInstanceofPlace(position)) return false; final PsiElement parent = position.getParent(); if (!(parent instanceof PsiJavaCodeReferenceElement)) return isSecondCompletion; if (((PsiJavaCodeReferenceElement) parent).getQualifier() != null) return isSecondCompletion; if (parent instanceof PsiJavaCodeReferenceElementImpl && ((PsiJavaCodeReferenceElementImpl) parent).getKind() == PsiJavaCodeReferenceElementImpl.PACKAGE_NAME_KIND) { return false; } PsiElement grand = parent.getParent(); if (grand instanceof PsiSwitchLabelStatement) { return false; } if (psiElement().inside(PsiImportStatement.class).accepts(parent)) { return isSecondCompletion; } if (grand instanceof PsiAnonymousClass) { grand = grand.getParent(); } if (grand instanceof PsiNewExpression && ((PsiNewExpression) grand).getQualifier() != null) { return false; } if (JavaCompletionData.isAfterPrimitiveOrArrayType(position)) { return false; } return true; }
@Override public String advertise(@NotNull final CompletionParameters parameters) { if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null; if (parameters.getCompletionType() == CompletionType.BASIC && parameters.getInvocationCount() > 0) { PsiElement position = parameters.getPosition(); if (psiElement() .withParent( psiReferenceExpression() .withFirstChild(psiReferenceExpression().referencing(psiClass()))) .accepts(position)) { if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) { final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); if (shortcut != null) { return "Pressing " + shortcut + " twice without a class qualifier would show all accessible static methods"; } } } } if (parameters.getCompletionType() != CompletionType.SMART && shouldSuggestSmartCompletion(parameters.getPosition())) { if (CompletionUtil.shouldShowFeature( parameters, CodeCompletionFeatures.EDITING_COMPLETION_SMARTTYPE_GENERAL)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { return CompletionBundle.message("completion.smart.hint", shortcut); } } } if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 1) { final PsiType[] psiTypes = ExpectedTypesGetter.getExpectedTypes(parameters.getPosition(), true); if (psiTypes.length > 0) { if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_TOAR)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { for (final PsiType psiType : psiTypes) { final PsiType type = PsiUtil.extractIterableTypeParameter(psiType, false); if (type != null) { return CompletionBundle.message( "completion.smart.aslist.hint", shortcut, type.getPresentableText()); } } } } if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_ASLIST)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { for (final PsiType psiType : psiTypes) { if (psiType instanceof PsiArrayType) { final PsiType componentType = ((PsiArrayType) psiType).getComponentType(); if (!(componentType instanceof PsiPrimitiveType)) { return CompletionBundle.message( "completion.smart.toar.hint", shortcut, componentType.getPresentableText()); } } } } } if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_CHAIN)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { return CompletionBundle.message("completion.smart.chain.hint", shortcut); } } } } return null; }
private static Set<String> addReferenceVariants( final CompletionParameters parameters, CompletionResultSet result, final InheritorsHolder inheritors) { final Set<String> usedWords = new HashSet<String>(); final PsiElement position = parameters.getPosition(); final boolean first = parameters.getInvocationCount() <= 1; final boolean isSwitchLabel = SWITCH_LABEL.accepts(position); final boolean isAfterNew = JavaClassNameCompletionContributor.AFTER_NEW.accepts(position); final boolean pkgContext = JavaCompletionUtil.inSomePackage(position); LegacyCompletionContributor.processReferences( parameters, result, new PairConsumer<PsiReference, CompletionResultSet>() { @Override public void consume(final PsiReference reference, final CompletionResultSet result) { if (reference instanceof PsiJavaReference) { final ElementFilter filter = getReferenceFilter(position); if (filter != null) { final PsiFile originalFile = parameters.getOriginalFile(); JavaCompletionProcessor.Options options = JavaCompletionProcessor.Options.DEFAULT_OPTIONS .withCheckAccess(first) .withFilterStaticAfterInstance(first) .withShowInstanceInStaticContext(!first); for (LookupElement element : JavaCompletionUtil.processJavaReference( position, (PsiJavaReference) reference, new ElementExtractorFilter(filter), options, result.getPrefixMatcher(), parameters)) { if (inheritors.alreadyProcessed(element)) { continue; } if (isSwitchLabel) { result.addElement( TailTypeDecorator.withTail(element, TailType.createSimpleTailType(':'))); } else { final LookupItem item = element.as(LookupItem.CLASS_CONDITION_KEY); if (originalFile instanceof PsiJavaCodeReferenceCodeFragment && !((PsiJavaCodeReferenceCodeFragment) originalFile).isClassesAccepted() && item != null) { item.setTailType(TailType.NONE); } result.addElement(element); } } } return; } if (reference instanceof PsiLabelReference) { processLabelReference(result, (PsiLabelReference) reference); return; } final Object[] variants = reference.getVariants(); if (variants == null) { LOG.error("Reference=" + reference); } for (Object completion : variants) { if (completion == null) { LOG.error( "Position=" + position + "\n;Reference=" + reference + "\n;variants=" + Arrays.toString(variants)); } if (completion instanceof LookupElement && !inheritors.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); } })) { usedWords.add(item.getLookupString()); result.addElement(item); } } else { LookupElement element = LookupItemUtil.objectToLookupItem(completion); usedWords.add(element.getLookupString()); result.addElement(element); } } } }); return usedWords; }
public static Set<LookupElement> processJavaReference( PsiElement element, PsiJavaReference javaReference, ElementFilter elementFilter, JavaCompletionProcessor.Options options, final PrefixMatcher matcher, CompletionParameters parameters) { final Set<LookupElement> set = new LinkedHashSet<LookupElement>(); final Condition<String> nameCondition = new Condition<String>() { @Override public boolean value(String s) { return matcher.prefixMatches(s); } }; PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class); boolean checkInitialized = parameters.getInvocationCount() <= 1 && call != null && PsiKeyword.SUPER.equals(call.getMethodExpression().getText()); final JavaCompletionProcessor processor = new JavaCompletionProcessor( element, elementFilter, options.withInitialized(checkInitialized), nameCondition); final PsiType plainQualifier = processor.getQualifierType(); PsiType qualifierType = plainQualifier; PsiType runtimeQualifier = getQualifierCastType(javaReference, parameters); if (runtimeQualifier != null) { PsiType composite = qualifierType == null ? runtimeQualifier : PsiIntersectionType.createIntersection(qualifierType, runtimeQualifier); PsiElement ctx = createContextWithXxxVariable(element, composite); javaReference = (PsiReferenceExpression) JavaPsiFacade.getElementFactory(element.getProject()) .createExpressionFromText("xxx.xxx", ctx); qualifierType = runtimeQualifier; processor.setQualifierType(qualifierType); } javaReference.processVariants(processor); final PsiTypeLookupItem castItem = runtimeQualifier == null ? null : PsiTypeLookupItem.createLookupItem( runtimeQualifier, (PsiReferenceExpression) javaReference); final boolean pkgContext = inSomePackage(element); final Set<PsiMember> mentioned = new THashSet<PsiMember>(); for (CompletionElement completionElement : processor.getResults()) { for (LookupElement item : createLookupElements(completionElement, javaReference)) { item.putUserData(QUALIFIER_TYPE_ATTR, qualifierType); final Object o = item.getObject(); if (o instanceof PsiClass && !isSourceLevelAccessible(element, (PsiClass) o, pkgContext)) { continue; } if (o instanceof PsiMember) { if (isInExcludedPackage((PsiMember) o, true)) { continue; } mentioned.add(CompletionUtil.getOriginalOrSelf((PsiMember) o)); } set.add( highlightIfNeeded( qualifierType, castQualifier(item, castItem, plainQualifier, processor), o, element)); } } if (javaReference instanceof PsiJavaCodeReferenceElement && !((PsiJavaCodeReferenceElement) javaReference).isQualified()) { final StaticMemberProcessor memberProcessor = new JavaStaticMemberProcessor(parameters); memberProcessor.processMembersOfRegisteredClasses( matcher, new PairConsumer<PsiMember, PsiClass>() { @Override public void consume(PsiMember member, PsiClass psiClass) { if (!mentioned.contains(member) && processor.satisfies(member, ResolveState.initial())) { set.add(memberProcessor.createLookupElement(member, psiClass, true)); } } }); } return set; }