private void generateVariants(final CompletionParameters parameters, final PrefixMatcher prefixMatcher, final ExpectedTypeInfo[] infos, final Consumer<LookupElement> consumer) { addArrayTypes(parameters.getPosition(), infos, consumer); List<PsiClassType> classTypes = extractClassTypes(infos); boolean arraysWelcome = ContainerUtil.exists(ExpectedTypesGetter.extractTypes(infos, true), t -> t.getDeepComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT)); processInheritors(parameters, classTypes, prefixMatcher, type -> { final LookupElement element = addExpectedType(type, parameters); if(element != null) { Supplier<PsiClassType> itemType = () -> (PsiClassType) ObjectUtils.assertNotNull(element.as(TypedLookupItem.CLASS_CONDITION_KEY)).getType(); JavaConstructorCallElement.wrap(element, (PsiClass) element.getObject(), parameters.getPosition(), itemType).forEach(consumer::consume); } if(arraysWelcome) { consumer.consume(createNewArrayItem(parameters.getPosition(), type.createArrayType())); } }); }
private static void addArrayTypes(PsiElement identifierCopy, ExpectedTypeInfo[] infos, final Consumer<LookupElement> consumer) { for(final PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) { if(type instanceof PsiArrayType) { consumer.consume(createNewArrayItem(identifierCopy, type)); if(shouldAddArrayInitializer(identifierCopy)) { PsiTypeLookupItem item = createNewArrayItem(identifierCopy, type); item.setAddArrayInitializer(); consumer.consume(item); } } } }
private static List<PsiClassType> extractClassTypes(ExpectedTypeInfo[] infos) { final List<PsiClassType> expectedClassTypes = new SmartList<>(); for(PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) { if(type instanceof PsiClassType) { final PsiClassType classType = (PsiClassType) type; if(classType.resolve() != null) { expectedClassTypes.add(classType); } } } return expectedClassTypes; }
private static boolean shouldSuggestSmartCompletion(final PsiElement element) { if(shouldSuggestClassNameCompletion(element)) { return false; } final PsiElement parent = element.getParent(); if(parent instanceof PsiReferenceExpression && ((PsiReferenceExpression) parent).getQualifier() != null) { return false; } if(parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiReferenceExpression) { return true; } return ExpectedTypesGetter.getExpectedTypes(element, false).length > 0; }
@Override public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) { final PsiElement element = parameters.getPosition(); for (final PsiType type : ExpectedTypesGetter.getExpectedTypes(element, false)) { final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass != null && psiClass.isAnnotationType()) { result.addElement(AllClassesGetter.createLookupItem(psiClass, AnnotationInsertHandler.INSTANCE)); } } }
private static void addArrayTypes(PsiElement identifierCopy, ExpectedTypeInfo[] infos, final Consumer<LookupElement> consumer) { for (final PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) { if (type instanceof PsiArrayType) { consumer.consume(createNewArrayItem(identifierCopy, type)); if (shouldAddArrayInitializer(identifierCopy)) { PsiTypeLookupItem item = createNewArrayItem(identifierCopy, type); item.setAddArrayInitializer(); consumer.consume(item); } } } }
private static List<PsiClassType> extractClassTypes(ExpectedTypeInfo[] infos) { final List<PsiClassType> expectedClassTypes = new SmartList<PsiClassType>(); for (PsiType type : ExpectedTypesGetter.extractTypes(infos, true)) { if (type instanceof PsiClassType) { final PsiClassType classType = (PsiClassType)type; if (classType.resolve() != null) { expectedClassTypes.add(classType); } } } return expectedClassTypes; }
@Nullable private static ElementFilter getClassReferenceFilter(PsiElement element) { //throw new foo if (AFTER_THROW_NEW.accepts(element)) { return THROWABLES_FILTER; } //throws list PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class); if (method != null && PsiTreeUtil.isAncestor(method.getThrowsList(), element, true)) { return THROWABLES_FILTER; } //new xxx.yyy if (psiElement().afterLeaf(psiElement().withText(".")).withSuperParent(2, psiElement(PsiNewExpression.class)).accepts(element)) { if (((PsiNewExpression)element.getParent().getParent()).getClassReference() == element.getParent()) { PsiType[] types = ExpectedTypesGetter.getExpectedTypes(element, false); return new OrFilter(ContainerUtil.map2Array(types, ElementFilter.class, new Function<PsiType, ElementFilter>() { @Override public ElementFilter fun(PsiType type) { return new AssignableFromFilter(type); } })); } } return null; }
private static boolean shouldSuggestSmartCompletion(final PsiElement element) { if (shouldSuggestClassNameCompletion(element)) return false; final PsiElement parent = element.getParent(); if (parent instanceof PsiReferenceExpression && ((PsiReferenceExpression)parent).getQualifier() != null) return false; if (parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiReferenceExpression) return true; return ExpectedTypesGetter.getExpectedTypes(element, false).length > 0; }
@RequiredReadAction @Override public void addCompletions(@NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result) { final PsiElement element = parameters.getPosition(); for(final PsiType type : ExpectedTypesGetter.getExpectedTypes(element, false)) { final PsiClass psiClass = PsiUtil.resolveClassInType(type); if(psiClass != null && psiClass.isAnnotationType()) { result.addElement(AllClassesGetter.createLookupItem(psiClass, AnnotationInsertHandler.INSTANCE)); } } }
@Nullable private static ElementFilter getClassReferenceFilter(final PsiElement element, final boolean inRefList) { //throw new foo if(AFTER_THROW_NEW.accepts(element)) { return THROWABLES_FILTER; } //new xxx.yyy if(psiElement().afterLeaf(psiElement().withText(".")).withSuperParent(2, psiElement(PsiNewExpression.class)).accepts(element)) { if(((PsiNewExpression) element.getParent().getParent()).getClassReference() == element.getParent()) { PsiType[] types = ExpectedTypesGetter.getExpectedTypes(element, false); return new OrFilter(ContainerUtil.map2Array(types, ElementFilter.class, (Function<PsiType, ElementFilter>) type -> new AssignableFromFilter(type))); } } // extends/implements/throws if(inRefList) { return new ElementExtractorFilter(new ElementFilter() { @Override public boolean isAcceptable(Object aClass, @Nullable PsiElement context) { return aClass instanceof PsiClass && ReferenceListWeigher.INSTANCE.getApplicability((PsiClass) aClass, element) != ReferenceListWeigher.ReferenceListApplicability.inapplicable; } @Override public boolean isClassAcceptable(Class hintClass) { return true; } }); } return null; }