public static CompletionResultSet addJavaSorting( final CompletionParameters parameters, CompletionResultSet result) { final PsiElement position = parameters.getPosition(); final ExpectedTypeInfo[] expectedTypes = PsiJavaPatterns.psiElement() .beforeLeaf(PsiJavaPatterns.psiElement().withText(".")) .accepts(position) ? ExpectedTypeInfo.EMPTY_ARRAY : JavaSmartCompletionContributor.getExpectedTypes(parameters); final CompletionType type = parameters.getCompletionType(); final boolean smart = type == CompletionType.SMART; final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position); List<LookupElementWeigher> afterProximity = new ArrayList<LookupElementWeigher>(); afterProximity.add(new PreferContainingSameWords(expectedTypes)); if (smart) { afterProximity.add(new PreferFieldsAndGetters()); } afterProximity.add(new PreferShorter(expectedTypes)); CompletionSorter sorter = CompletionSorter.defaultSorter(parameters, result.getPrefixMatcher()); if (!smart && afterNew) { sorter = sorter.weighBefore("liftShorter", new PreferExpected(true, expectedTypes)); } else if (PsiTreeUtil.getParentOfType(position, PsiReferenceList.class) == null) { sorter = ((CompletionSorterImpl) sorter) .withClassifier("liftShorterClasses", true, new LiftShorterClasses(position)); } if (smart) { sorter = sorter.weighAfter("priority", new PreferDefaultTypeWeigher(expectedTypes, parameters)); } List<LookupElementWeigher> afterPrefix = ContainerUtil.newArrayList(); if (!smart) { ContainerUtil.addIfNotNull(afterPrefix, preferStatics(position, expectedTypes)); } ContainerUtil.addIfNotNull(afterPrefix, recursion(parameters, expectedTypes)); if (!smart && !afterNew) { afterPrefix.add(new PreferExpected(false, expectedTypes)); } Collections.addAll( afterPrefix, new PreferByKindWeigher(type, position), new PreferSimilarlyEnding(expectedTypes), new PreferNonGeneric(), new PreferAccessible(position), new PreferSimple(), new PreferEnumConstants(parameters)); sorter = sorter.weighAfter( "prefix", afterPrefix.toArray(new LookupElementWeigher[afterPrefix.size()])); sorter = sorter.weighAfter( "proximity", afterProximity.toArray(new LookupElementWeigher[afterProximity.size()])); return result.withRelevanceSorter(sorter); }
@Override public void beforeCompletion(@NotNull final CompletionInitializationContext context) { final PsiFile file = context.getFile(); if (file instanceof PsiJavaFile) { JavaCompletionUtil.initOffsets(file, context.getOffsetMap()); autoImport(file, context.getStartOffset() - 1, context.getEditor()); if (context.getCompletionType() == CompletionType.BASIC) { if (semicolonNeeded(context.getEditor(), file, context.getStartOffset())) { context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";"); return; } final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset( file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); if (ref != null && !(ref instanceof PsiReferenceExpression)) { if (ref.getParent() instanceof PsiTypeElement) { context.setDummyIdentifier( CompletionInitializationContext.DUMMY_IDENTIFIER.trim() + ";"); } if (JavaSmartCompletionContributor.AFTER_NEW.accepts(ref)) { final PsiReferenceParameterList paramList = ref.getParameterList(); if (paramList != null && paramList.getTextLength() > 0) { context .getOffsetMap() .addOffset( ConstructorInsertHandler.PARAM_LIST_START, paramList.getTextRange().getStartOffset()); context .getOffsetMap() .addOffset( ConstructorInsertHandler.PARAM_LIST_END, paramList.getTextRange().getEndOffset()); } } return; } final PsiElement element = file.findElementAt(context.getStartOffset()); if (psiElement().inside(PsiAnnotation.class).accepts(element)) { return; } context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED); } } }
@Override public void fillCompletionVariants( @NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) { final JavaCompletionSession session = new JavaCompletionSession(result); ResultTracker tracker = new ResultTracker(result) { @Override public void consume(CompletionResult plainResult) { super.consume(plainResult); LookupElement element = plainResult.getLookupElement(); Object o = element.getObject(); if (o instanceof PsiClass) { session.registerClass((PsiClass) o); } if (element instanceof TypeArgumentCompletionProvider.TypeArgsLookupElement) { ((TypeArgumentCompletionProvider.TypeArgsLookupElement) element) .registerSingleClass(session); } } }; result.runRemainingContributors(parameters, tracker); final boolean empty = tracker.containsOnlyPackages || suggestAllAnnotations(parameters); if (!empty && parameters.getInvocationCount() == 0) { result.restartCompletionWhenNothingMatches(); } if (empty) { 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)), session); } } }
@Override public void fillCompletionVariants( final CompletionParameters parameters, final CompletionResultSet _result) { if (parameters.getCompletionType() != CompletionType.BASIC) { return; } final PsiElement position = parameters.getPosition(); if (!isInJavaContext(position)) { return; } if (AFTER_NUMBER_LITERAL.accepts(position) || UNEXPECTED_REFERENCE_AFTER_DOT.accepts(position)) { _result.stopHere(); return; } final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result); if (ANNOTATION_ATTRIBUTE_NAME.accepts(position) && !JavaCompletionData.isAfterPrimitiveOrArrayType(position)) { JavaCompletionData.addExpectedTypeMembers(parameters, result); completeAnnotationAttributeName(result, position, parameters); result.stopHere(); return; } final InheritorsHolder inheritors = new InheritorsHolder(position, result); if (JavaSmartCompletionContributor.IN_TYPE_ARGS.accepts(position)) { new TypeArgumentCompletionProvider(false, inheritors) .addCompletions(parameters, new ProcessingContext(), result); } PrefixMatcher matcher = result.getPrefixMatcher(); if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { new JavaInheritorsGetter(ConstructorInsertHandler.BASIC_INSTANCE) .generateVariants(parameters, matcher, inheritors); } if (IMPORT_REFERENCE.accepts(position)) { result.addElement(LookupElementBuilder.create("*")); } addKeywords(parameters, result); Set<String> usedWords = addReferenceVariants(parameters, result, inheritors); if (psiElement().inside(PsiLiteralExpression.class).accepts(position)) { PsiReference reference = position.getContainingFile().findReferenceAt(parameters.getOffset()); if (reference == null || reference.isSoft()) { WordCompletionContributor.addWordCompletionVariants(result, parameters, usedWords); } } JavaGenerateMemberCompletionContributor.fillCompletionVariants(parameters, result); addAllClasses(parameters, result, inheritors); final PsiElement parent = position.getParent(); if (parent instanceof PsiReferenceExpression && !((PsiReferenceExpression) parent).isQualified() && parameters.isExtendedCompletion() && StringUtil.isNotEmpty(matcher.getPrefix())) { new JavaStaticMemberProcessor(parameters).processStaticMethodsGlobally(matcher, result); } result.stopHere(); }
@Nullable public static ElementFilter getReferenceFilter(PsiElement position) { // Completion after extends in interface, type parameter and implements in class final PsiClass containingClass = PsiTreeUtil.getParentOfType( position, PsiClass.class, false, PsiCodeBlock.class, PsiMethod.class, PsiExpressionList.class, PsiVariable.class, PsiAnnotation.class); if (containingClass != null && psiElement() .afterLeaf(PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS, ",", "&") .accepts(position)) { return new AndFilter( ElementClassFilter.CLASS, new NotFilter(new AssignableFromContextFilter())); } if (ANNOTATION_NAME.accepts(position)) { return new AnnotationTypeFilter(); } if (JavaCompletionData.DECLARATION_START.accepts(position) || JavaCompletionData.isInsideParameterList(position) || psiElement() .inside(psiElement(PsiJavaCodeReferenceElement.class).withParent(psiAnnotation())) .accepts(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.PACKAGE_FILTER); } if (psiElement().afterLeaf(PsiKeyword.INSTANCEOF).accepts(position)) { return new ElementExtractorFilter(ElementClassFilter.CLASS); } if (JavaCompletionData.VARIABLE_AFTER_FINAL.accepts(position)) { return ElementClassFilter.CLASS; } if (JavaCompletionData.AFTER_TRY_BLOCK.isAcceptable(position, position) || JavaCompletionData.START_SWITCH.accepts(position) || JavaCompletionData.isInstanceofPlace(position) || JavaCompletionData.isAfterPrimitiveOrArrayType(position)) { return null; } if (JavaCompletionData.START_FOR.accepts(position)) { return new OrFilter(ElementClassFilter.CLASS, ElementClassFilter.VARIABLE); } if (JavaSmartCompletionContributor.AFTER_NEW.accepts(position)) { return ElementClassFilter.CLASS; } if (psiElement().inside(PsiReferenceParameterList.class).accepts(position)) { return ElementClassFilter.CLASS; } if (psiElement().inside(PsiAnnotationParameterList.class).accepts(position)) { return createAnnotationFilter(position); } if (psiElement().afterLeaf("=").inside(PsiVariable.class).accepts(position)) { return new OrFilter( new ClassFilter(PsiVariable.class, false), new ExcludeDeclaredFilter(new ClassFilter(PsiVariable.class))); } if (SWITCH_LABEL.accepts(position)) { return new ClassFilter(PsiField.class) { @Override public boolean isAcceptable(Object element, PsiElement context) { return element instanceof PsiEnumConstant; } }; } return TrueFilter.INSTANCE; }
public static CompletionResultSet addJavaSorting( final CompletionParameters parameters, CompletionResultSet result) { String prefix = result.getPrefixMatcher().getPrefix(); final PsiElement position = parameters.getPosition(); final ExpectedTypeInfo[] expectedTypes = PsiJavaPatterns.psiElement() .beforeLeaf(PsiJavaPatterns.psiElement().withText(".")) .accepts(position) ? ExpectedTypeInfo.EMPTY_ARRAY : JavaSmartCompletionContributor.getExpectedTypes(parameters); final CompletionType type = parameters.getCompletionType(); final boolean smart = type == CompletionType.SMART; final boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position); List<LookupElementWeigher> afterNegativeStats = new ArrayList<LookupElementWeigher>(); if (!smart) { ContainerUtil.addIfNotNull(afterNegativeStats, preferStatics(position)); } afterNegativeStats.add(new PreferLocalVariablesLiteralsAndAnnoMethodsWeigher(type, position)); ContainerUtil.addIfNotNull(afterNegativeStats, recursion(parameters, expectedTypes)); if (!smart && !afterNew) { afterNegativeStats.add(new PreferExpected(false, expectedTypes)); } afterNegativeStats.add(new PreferSimilarlyEnding(expectedTypes, prefix)); List<LookupElementWeigher> afterProximity = new ArrayList<LookupElementWeigher>(); afterProximity.add(new PreferContainingSameWords(expectedTypes)); if (smart) { afterProximity.add(new PreferFieldsAndGetters()); } afterProximity.add(new PreferShorter(expectedTypes, prefix)); CompletionSorter sorter = CompletionSorter.defaultSorter(parameters, result.getPrefixMatcher()); if (!smart && afterNew) { sorter = sorter.weighBefore("liftShorter", new PreferExpected(true, expectedTypes)); } else { final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(position.getProject()).getFileIndex(); sorter = ((CompletionSorterImpl) sorter) .withClassifier( "liftShorter", true, new ClassifierFactory<LookupElement>("liftShorterClasses") { @Override public Classifier<LookupElement> createClassifier( Classifier<LookupElement> next) { return new LiftShorterItemsClassifier( next, new LiftShorterItemsClassifier.LiftingCondition() { @Override public boolean shouldLift( LookupElement shorterElement, LookupElement longerElement, ProcessingContext context) { if (super.shouldLift(shorterElement, longerElement, context)) { return true; } Object object = shorterElement.getObject(); if (object instanceof PsiClass) { PsiFile file = ((PsiClass) object).getContainingFile(); if (file != null) { VirtualFile vFile = file.getOriginalFile().getVirtualFile(); if (vFile != null && fileIndex.isInSource(vFile)) { return true; } } } return false; } }); } }); } if (smart) { sorter = sorter.weighBefore( "negativeStats", new PreferDefaultTypeWeigher(expectedTypes, parameters)); } sorter = sorter.weighAfter( "negativeStats", afterNegativeStats.toArray(new LookupElementWeigher[afterNegativeStats.size()])); sorter = sorter.weighAfter( "prefix", new PreferNonGeneric(), new PreferAccessible(position), new PreferSimple(), new PreferEnumConstants(parameters)); sorter = sorter.weighAfter( "proximity", afterProximity.toArray(new LookupElementWeigher[afterProximity.size()])); return result.withRelevanceSorter(sorter); }