TailType (InsertionContext context) { if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) { return TailTypes.noneType(); } if (LookupItem.getDefaultTailType(context.getCompletionChar()) != null) { return null; } LookupElement delegate = getDelegate(); LookupItem<?> item = as(LookupItem.CLASS_CONDITION_KEY); Object object = delegate.getObject(); if (!CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET && (object instanceof PsiMethod || object instanceof PsiClass)) { return TailTypes.noneType(); } PsiExpression enclosing = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiExpression.class, false); if (enclosing != null) { final PsiType type = JavaCompletionUtil.getLookupElementType(delegate); final TailType itemType = item != null ? item.getTailType() : TailTypes.noneType(); if (type != null && type.isValid()) { Set<TailType> voidTyped = new HashSet<>(); Set<TailType> sameTyped = new HashSet<>(); Set<TailType> assignableTyped = new HashSet<>(); for (ExpectedTypeInfo info : myExpectedTypeInfos) { final PsiType infoType = info.getType(); final PsiType originalInfoType = JavaCompletionUtil.originalize(infoType); if (PsiTypes.voidType().equals(infoType)) { voidTyped.add(info.getTailType()); } else if (infoType.equals(type) || originalInfoType.equals(type)) { sameTyped.add(info.getTailType()); } else if ((info.getKind() == ExpectedTypeInfo.TYPE_OR_SUBTYPE && (infoType.isAssignableFrom(type) || originalInfoType.isAssignableFrom(type))) || (info.getKind() == ExpectedTypeInfo.TYPE_OR_SUPERTYPE && (type.isAssignableFrom(infoType) || type.isAssignableFrom(originalInfoType)))) { assignableTyped.add(info.getTailType()); } } if (!sameTyped.isEmpty()) { return sameTyped.size() == 1 ? sameTyped.iterator().next() : itemType; } if (!assignableTyped.isEmpty()) { return assignableTyped.size() == 1 ? assignableTyped.iterator().next() : itemType; } if (!voidTyped.isEmpty()) { return voidTyped.size() == 1 ? voidTyped.iterator().next() : itemType; } } else { if (myExpectedTypeInfos.size() == 1) { return myExpectedTypeInfos.iterator().next().getTailType(); } } return itemType; } return null; }