@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); if (lookupItem != null) { return lookupItem.getBracketsCount() * 10 + (lookupItem.isAddArrayInitializer() ? 1 : 0); } return 0; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY); if (lookupItem != null) { return lookupItem.getBracketsCount(); } if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) { return 239; } return 0; }
private static PsiTypeLookupItem doCreateItem( final PsiType type, PsiElement context, int bracketsCount, boolean diamond, InsertHandler<PsiTypeLookupItem> importFixer) { if (type instanceof PsiClassType) { PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType) type).resolveGenerics(); final PsiClass psiClass = classResolveResult.getElement(); if (psiClass != null) { String name = psiClass.getName(); if (name != null) { final PsiSubstitutor substitutor = classResolveResult.getSubstitutor(); PsiClass resolved = JavaPsiFacade.getInstance(psiClass.getProject()) .getResolveHelper() .resolveReferencedClass(name, context); Set<String> allStrings = new HashSet<String>(); allStrings.add(name); if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass) && !PsiUtil.isInnerClass(psiClass)) { // inner class name should be shown qualified if its not accessible by single name PsiClass aClass = psiClass.getContainingClass(); while (aClass != null && !PsiUtil.isInnerClass(aClass) && aClass.getName() != null) { name = aClass.getName() + '.' + name; allStrings.add(name); aClass = aClass.getContainingClass(); } } PsiTypeLookupItem item = new PsiTypeLookupItem( psiClass, name, diamond, bracketsCount, importFixer, substitutor); item.addLookupStrings(ArrayUtil.toStringArray(allStrings)); return item; } } } return new PsiTypeLookupItem( type, type.getPresentableText(), false, bracketsCount, importFixer, PsiSubstitutor.EMPTY); }
private static void addPrimitiveTypes(final Consumer<LookupElement> result, PsiElement position) { if (AFTER_DOT.accepts(position)) { return; } boolean afterNew = psiElement() .afterLeaf( psiElement() .withText(PsiKeyword.NEW) .andNot(psiElement().afterLeaf(PsiKeyword.THROW, "."))) .accepts(position); if (afterNew) { PsiElementFactory factory = JavaPsiFacade.getElementFactory(position.getProject()); for (String primitiveType : PRIMITIVE_TYPES) { result.consume( PsiTypeLookupItem.createLookupItem( factory.createTypeFromText(primitiveType + "[]", null), null)); } result.consume( PsiTypeLookupItem.createLookupItem(factory.createTypeFromText("void[]", null), null)); return; } boolean inCast = psiElement() .afterLeaf( psiElement() .withText("(") .withParent( psiElement(PsiParenthesizedExpression.class, PsiTypeCastExpression.class))) .accepts(position); boolean typeFragment = position.getContainingFile() instanceof PsiTypeCodeFragment && PsiTreeUtil.prevVisibleLeaf(position) == null; boolean declaration = DECLARATION_START.getValue().accepts(position); boolean expressionPosition = isExpressionPosition(position); boolean inGenerics = PsiTreeUtil.getParentOfType(position, PsiReferenceParameterList.class) != null; if (START_FOR.accepts(position) || isInsideParameterList(position) || inGenerics || VARIABLE_AFTER_FINAL.accepts(position) || inCast || declaration || typeFragment || expressionPosition || isStatementPosition(position)) { for (String primitiveType : PRIMITIVE_TYPES) { result.consume(createKeyword(position, primitiveType)); } } if (declaration) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.VOID), TailType.HUMBLE_SPACE_BEFORE_WORD)); } else if (typeFragment && ((PsiTypeCodeFragment) position.getContainingFile()).isVoidValid()) { result.consume(createKeyword(position, PsiKeyword.VOID)); } }
@NotNull private static LookupElement castQualifier( @NotNull LookupElement item, @Nullable final PsiTypeLookupItem castTypeItem, @Nullable PsiType plainQualifier, JavaCompletionProcessor processor) { if (castTypeItem == null) { return item; } if (plainQualifier != null) { Object o = item.getObject(); if (o instanceof PsiMethod) { PsiType castType = castTypeItem.getType(); if (plainQualifier instanceof PsiClassType && castType instanceof PsiClassType) { PsiMethod method = (PsiMethod) o; PsiClassType.ClassResolveResult plainResult = ((PsiClassType) plainQualifier).resolveGenerics(); PsiClass plainClass = plainResult.getElement(); if (plainClass != null && plainClass.findMethodBySignature(method, true) != null) { PsiClass castClass = ((PsiClassType) castType).resolveGenerics().getElement(); if (castClass == null || !castClass.isInheritor(plainClass, true)) { return item; } PsiSubstitutor plainSub = plainResult.getSubstitutor(); PsiSubstitutor castSub = TypeConversionUtil.getSuperClassSubstitutor(plainClass, (PsiClassType) castType); PsiType returnType = method.getReturnType(); if (method.getSignature(plainSub).equals(method.getSignature(castSub))) { PsiType typeAfterCast = toRaw(castSub.substitute(returnType)); PsiType typeDeclared = toRaw(plainSub.substitute(returnType)); if (typeAfterCast != null && typeDeclared != null && typeAfterCast.isAssignableFrom(typeDeclared) && processor.isAccessible(plainClass.findMethodBySignature(method, true))) { return item; } } } } } else if (containsMember(plainQualifier, o)) { return item; } } return LookupElementDecorator.withInsertHandler( item, new InsertHandlerDecorator<LookupElement>() { @Override public void handleInsert( InsertionContext context, LookupElementDecorator<LookupElement> item) { final Document document = context.getEditor().getDocument(); context.commitDocument(); final PsiFile file = context.getFile(); final PsiJavaCodeReferenceElement ref = PsiTreeUtil.findElementOfClassAtOffset( file, context.getStartOffset(), PsiJavaCodeReferenceElement.class, false); if (ref != null) { final PsiElement qualifier = ref.getQualifier(); if (qualifier != null) { final CommonCodeStyleSettings settings = context.getCodeStyleSettings(); final String parenSpace = settings.SPACE_WITHIN_PARENTHESES ? " " : ""; document.insertString(qualifier.getTextRange().getEndOffset(), parenSpace + ")"); final String spaceWithin = settings.SPACE_WITHIN_CAST_PARENTHESES ? " " : ""; final String prefix = "(" + parenSpace + "(" + spaceWithin; final String spaceAfter = settings.SPACE_AFTER_TYPE_CAST ? " " : ""; final int exprStart = qualifier.getTextRange().getStartOffset(); document.insertString(exprStart, prefix + spaceWithin + ")" + spaceAfter); CompletionUtil.emulateInsertion(context, exprStart + prefix.length(), castTypeItem); PsiDocumentManager.getInstance(file.getProject()) .doPostponedOperationsAndUnblockDocument(document); context.getEditor().getCaretModel().moveToOffset(context.getTailOffset()); } } item.getDelegate().handleInsert(context); } }); }
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; }
@Override public void handleInsert(InsertionContext context, PsiTypeLookupItem item) { if (item.getObject() instanceof PsiClass) { addImportForItem(context, (PsiClass) item.getObject()); } }