@Nullable public static List<? extends PsiElement> getAllPsiElements(final LookupElement item) { List<PsiMethod> allMethods = getAllMethods(item); if (allMethods != null) return allMethods; if (item.getObject() instanceof PsiElement) return Collections.singletonList((PsiElement) item.getObject()); return null; }
@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); } if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) { return 239; } return 0; }
private void addKeyword( Set<LookupElement> set, final TailType tailType, final Object comp, final PrefixMatcher matcher, final PsiFile file, final CompletionVariant variant) { for (final LookupElement item : set) { if (item.getObject().toString().equals(comp.toString())) { return; } } addLookupItem(set, tailType, comp, file, variant); }
@NotNull @Override public String getLookupString() { return maybeAddParentheses(myQualifier.getLookupString()) + "." + getDelegate().getLookupString(); }
@NotNull @Override public Comparable weigh(@NotNull LookupElement item) { return item.getObject() instanceof PsiClass && !myAcceptClasses ? ExpectedTypeMatching.normal : getExpectedTypeMatching(item, myExpectedTypes); }
@Nullable private Object getQualifierObject() { Object qObject = myQualifier.getObject(); if (qObject instanceof ResolveResult) { qObject = ((ResolveResult) qObject).getElement(); } return qObject; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); if (object instanceof PsiField) return -2; if (object instanceof PsiMethod && PropertyUtil.isSimplePropertyGetter((PsiMethod) object)) return -1; return 0; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { if (element.getObject() instanceof PsiEnumConstant) return -2; if (!(myParameters.getOriginalFile() instanceof PsiJavaFile)) return -1; if (PsiKeyword.TRUE.equals(element.getLookupString()) || PsiKeyword.FALSE.equals(element.getLookupString())) { boolean inReturn = PsiTreeUtil.getParentOfType( myParameters.getPosition(), PsiReturnStatement.class, false, PsiMember.class) != null; return inReturn ? -2 : 0; } return -1; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); if (object instanceof PsiMethod) { PsiType type = ((PsiMethod) object).getReturnType(); final JavaMethodCallElement callItem = element.as(JavaMethodCallElement.CLASS_CONDITION_KEY); if (callItem != null) { type = callItem.getSubstitutor().substitute(type); } if (type instanceof PsiClassType && ((PsiClassType) type).resolve() instanceof PsiTypeParameter) return 1; } return 0; }
@Override public void renderElement(LookupElementPresentation presentation) { super.renderElement(presentation); final LookupElementPresentation qualifierPresentation = new LookupElementPresentation(); myQualifier.renderElement(qualifierPresentation); String name = maybeAddParentheses(qualifierPresentation.getItemText()); final String qualifierText = myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null ? "(" + name + ")" : name; presentation.setItemText(qualifierText + "." + presentation.getItemText()); if (myQualifier instanceof LookupItem && getQualifierObject() instanceof PsiClass) { String locationString = JavaPsiClassReferenceElement.getLocationString((LookupItem) myQualifier); presentation.setTailText(StringUtil.notNullize(presentation.getTailText()) + locationString); } }
@NotNull @Override public MyResult weigh(@NotNull LookupElement item) { final Object object = item.getObject(); if (object instanceof PsiClass) { if (object instanceof PsiTypeParameter) return MyResult.typeParameter; if (myTypeParameter != null && object.equals( PsiUtil.resolveClassInType( TypeConversionUtil.typeParameterErasure(myTypeParameter)))) { return MyResult.exactlyExpected; } } if (myExpectedTypes == null) return MyResult.normal; PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType == null || !itemType.isValid()) return MyResult.normal; if (object instanceof PsiClass) { for (final ExpectedTypeInfo info : myExpectedTypes) { if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()) .equals(TypeConversionUtil.erasure(itemType))) { return AbstractExpectedTypeSkipper.skips(item, myLocation) ? MyResult.expectedNoSelect : MyResult.exactlyExpected; } } } for (final ExpectedTypeInfo expectedInfo : myExpectedTypes) { final PsiType defaultType = expectedInfo.getDefaultType(); final PsiType expectedType = expectedInfo.getType(); if (!expectedType.isValid()) { return MyResult.normal; } if (defaultType != expectedType) { if (defaultType.equals(itemType)) { return MyResult.exactlyDefault; } if (defaultType.isAssignableFrom(itemType)) { return MyResult.ofDefaultType; } } if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) { return MyResult.exactlyExpected; } } return MyResult.normal; }
public static boolean insertTail( InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) { TailType toInsert = tailType; LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY); if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) { if (!hasTail && item.getObject() instanceof PsiMethod && ((PsiMethod) item.getObject()).getReturnType() == PsiType.VOID) { PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); if (psiElement() .beforeLeaf(psiElement().withText(".")) .accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) { return false; } boolean insertAdditionalSemicolon = true; final PsiReferenceExpression referenceExpression = PsiTreeUtil.getTopmostParentOfType( context.getFile().findElementAt(context.getStartOffset()), PsiReferenceExpression.class); if (referenceExpression instanceof PsiMethodReferenceExpression && LambdaHighlightingUtil.insertSemicolon(referenceExpression.getParent())) { insertAdditionalSemicolon = false; } else if (referenceExpression != null) { PsiElement parent = referenceExpression.getParent(); if (parent instanceof PsiMethodCallExpression) { parent = parent.getParent(); } if (parent instanceof PsiLambdaExpression && !LambdaHighlightingUtil.insertSemicolonAfter((PsiLambdaExpression) parent)) { insertAdditionalSemicolon = false; } } if (insertAdditionalSemicolon) { toInsert = TailType.SEMICOLON; } } } toInsert.processTail(context.getEditor(), context.getTailOffset()); return true; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); final String name = getLookupObjectName(object); if (name != null && getNameEndMatchingDegree(name, myExpectedTypes) != 0) { return NameUtil.nameToWords(name).length - 1000; } return 0; }
public static void putAllMethods(LookupElement item, List<PsiMethod> methods) { item.putUserData( ALL_METHODS_ATTRIBUTE, ContainerUtil.map( methods, new Function<PsiMethod, SmartPsiElementPointer<PsiMethod>>() { @Override public SmartPsiElementPointer<PsiMethod> fun(PsiMethod method) { return SmartPointerManager.getInstance(method.getProject()) .createSmartPsiElementPointer(method); } })); }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); if (object instanceof PsiDocCommentOwner) { final PsiDocCommentOwner member = (PsiDocCommentOwner) object; if (!JavaPsiFacade.getInstance(member.getProject()) .getResolveHelper() .isAccessible(member, myPosition, null)) return MyEnum.INACCESSIBLE; if (member.isDeprecated()) return MyEnum.DEPRECATED; } return MyEnum.NORMAL; }
public static List<PsiMethod> getAllMethods(LookupElement item) { List<SmartPsiElementPointer<PsiMethod>> pointers = item.getUserData(ALL_METHODS_ATTRIBUTE); if (pointers == null) return null; return ContainerUtil.mapNotNull( pointers, new Function<SmartPsiElementPointer<PsiMethod>, PsiMethod>() { @Override public PsiMethod fun(SmartPsiElementPointer<PsiMethod> pointer) { return pointer.getElement(); } }); }
private static ExpectedTypeMatching getExpectedTypeMatching( LookupElement item, ExpectedTypeInfo[] expectedInfos) { PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType != null) { for (final ExpectedTypeInfo expectedInfo : expectedInfos) { final PsiType defaultType = expectedInfo.getDefaultType(); final PsiType expectedType = expectedInfo.getType(); if (defaultType != expectedType && defaultType.isAssignableFrom(itemType)) { return ExpectedTypeMatching.ofDefaultType; } if (expectedType.isAssignableFrom(itemType)) { return ExpectedTypeMatching.expected; } } } boolean hasNonVoid = false; for (ExpectedTypeInfo info : expectedInfos) { if (!PsiType.VOID.equals(info.getType())) { hasNonVoid = true; } } if (hasNonVoid) { if (item.getObject() instanceof PsiKeyword) { String keyword = ((PsiKeyword) item.getObject()).getText(); if (PsiKeyword.NEW.equals(keyword) || PsiKeyword.NULL.equals(keyword)) { return ExpectedTypeMatching.maybeExpected; } } } else if (expectedInfos.length > 0) { return ExpectedTypeMatching.unexpected; } return ExpectedTypeMatching.normal; }
private static ExpectedTypeMatching getExpectedTypeMatching( LookupElement item, ExpectedTypeInfo[] expectedInfos, @Nullable String expectedMemberName) { PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType != null) { PsiUtil.ensureValidType(itemType); for (final ExpectedTypeInfo expectedInfo : expectedInfos) { final PsiType defaultType = expectedInfo.getDefaultType(); final PsiType expectedType = expectedInfo.getType(); assert expectedType.isValid(); assert defaultType.isValid(); if (defaultType != expectedType && defaultType.isAssignableFrom(itemType)) { return ExpectedTypeMatching.ofDefaultType; } if (expectedType.isAssignableFrom(itemType)) { return ExpectedTypeMatching.expected; } } } if (hasNonVoid(expectedInfos)) { if (item.getObject() instanceof PsiKeyword) { String keyword = ((PsiKeyword) item.getObject()).getText(); if (PsiKeyword.NEW.equals(keyword) || PsiKeyword.NULL.equals(keyword)) { return ExpectedTypeMatching.maybeExpected; } } } else if (expectedInfos.length > 0) { return ExpectedTypeMatching.unexpected; } return preferByMemberName(expectedMemberName, itemType); }
@NotNull @Override public ExpectedTypeMatching weigh(@NotNull LookupElement item) { if (item.getObject() instanceof PsiClass && !myConstructorPossible) { PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType != null) { for (PsiType expectedClass : myExpectedClasses) { if (expectedClass.isAssignableFrom(itemType)) { return ExpectedTypeMatching.expected; } } } return preferByMemberName(myExpectedMemberName, itemType); } return getExpectedTypeMatching(item, myExpectedTypes, myExpectedMemberName); }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final Object object = element.getObject(); final String name = getLookupObjectName(object); if (name != null) { int max = 0; final List<String> wordsNoDigits = NameUtil.nameToWordsLowerCase(truncDigits(name)); for (ExpectedTypeInfo myExpectedInfo : myExpectedTypes) { String expectedName = ((ExpectedTypeInfoImpl) myExpectedInfo).getExpectedName().compute(); if (expectedName != null) { final THashSet<String> set = new THashSet<String>(NameUtil.nameToWordsLowerCase(truncDigits(expectedName))); set.retainAll(wordsNoDigits); max = Math.max(max, set.size()); } } return -max; } return 0; }
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; }
@NotNull @Override public Comparable weigh(@NotNull LookupElement element) { final String name = getLookupObjectName(element.getObject()); return -getNameEndMatchingDegree(name, myExpectedTypes); }
@Nullable public static PsiType getLookupElementType(final LookupElement element) { TypedLookupItem typed = element.as(TypedLookupItem.CLASS_CONDITION_KEY); return typed != null ? typed.getType() : null; }
public static PsiType getQualifierType(LookupElement item) { return item.getUserData(QUALIFIER_TYPE_ATTR); }
public static void insertParentheses( final InsertionContext context, final LookupElement item, boolean overloadsMatter, boolean hasParams, final boolean forceClosingParenthesis) { final Editor editor = context.getEditor(); final char completionChar = context.getCompletionChar(); final PsiFile file = context.getFile(); final TailType tailType = completionChar == '(' ? TailType.NONE : completionChar == ':' ? TailType.COND_EXPR_COLON : LookupItem.handleCompletionChar(context.getEditor(), item, completionChar); final boolean hasTail = tailType != TailType.NONE && tailType != TailType.UNKNOWN; final boolean smart = completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR; if (completionChar == '(' || completionChar == '.' || completionChar == ',' || completionChar == ';' || completionChar == ':' || completionChar == ' ') { context.setAddCompletionChar(false); } if (hasTail) { hasParams = false; } final boolean needRightParenth = forceClosingParenthesis || !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET || !hasParams && completionChar != '('); context.commitDocument(); final CommonCodeStyleSettings styleSettings = context.getCodeStyleSettings(); final PsiElement elementAt = file.findElementAt(context.getStartOffset()); if (elementAt == null || !(elementAt.getParent() instanceof PsiMethodReferenceExpression)) { ParenthesesInsertHandler.getInstance( hasParams, styleSettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES, styleSettings.SPACE_WITHIN_METHOD_CALL_PARENTHESES && hasParams, needRightParenth, styleSettings.METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE) .handleInsert(context, item); } if (hasParams) { // Invoke parameters popup AutoPopupController.getInstance(file.getProject()) .autoPopupParameterInfo(editor, overloadsMatter ? null : (PsiElement) item.getObject()); } if (smart || !needRightParenth || !insertTail(context, item, tailType, hasTail)) { return; } if (completionChar == '.') { AutoPopupController.getInstance(file.getProject()) .autoPopupMemberLookup(context.getEditor(), null); } else if (completionChar == ',') { AutoPopupController.getInstance(file.getProject()) .autoPopupParameterInfo(context.getEditor(), null); } }
@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); } }); }
@NotNull private LookupElement getComparableQualifier() { final CastingLookupElementDecorator casting = myQualifier.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY); return casting == null ? myQualifier : casting.getDelegate(); }