private static String getName( final PsiClass psiClass, final LookupItem<?> item, boolean diamond) { if (item instanceof JavaPsiClassReferenceElement) { String forced = ((JavaPsiClassReferenceElement) item).getForcedPresentableName(); if (forced != null) { return forced; } } String name = PsiUtilCore.getName(psiClass); if (item.getAttribute(LookupItem.FORCE_QUALIFY) != null) { if (psiClass.getContainingClass() != null) { name = psiClass.getContainingClass().getName() + "." + name; } } if (diamond) { return name + "<>"; } PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR); if (substitutor != null) { final PsiTypeParameter[] params = psiClass.getTypeParameters(); if (params.length > 0) { return name + formatTypeParameters(substitutor, params); } } return StringUtil.notNullize(name); }
private static void addPathCompletions( @NotNull CompletionResultSet result, @NotNull BipartiteString caretBipartiteElementText, @NotNull VirtualFile basePath, boolean directoryExpected) { ParentDirWithLastComponentPrefix parentWithLastComponentPrefix = findParentDirWithLastComponentPrefix(basePath, caretBipartiteElementText.getPrefix()); if (parentWithLastComponentPrefix != null) { PrefixMatcher matcher = new StrictPrefixMatcher(parentWithLastComponentPrefix.getLastComponentPrefix(), false); result = result.withPrefixMatcher(matcher); VirtualFile parentFile = parentWithLastComponentPrefix.getParent(); VirtualFile[] children = parentFile.getChildren(); Character dirSeparatorSuffix = extractDirectoryTrailingFileSeparator(caretBipartiteElementText); if (parentFile.isDirectory()) { result.addElement(LookupItem.fromString("..")); } for (VirtualFile child : children) { if (child.isDirectory() || !directoryExpected) { String name = child.getName(); if (child.isDirectory() && dirSeparatorSuffix != null) { name += dirSeparatorSuffix; } result.addElement(LookupItem.fromString(name)); } } } }
private static void addResult( CompletionResultSet result, Collection<Lookup> collection, PsiElement position, int offset) { result = result.withPrefixMatcher(findPrefixStatic(position, offset)); for (Lookup lookup : collection) { final LookupItem<Lookup> item = new LookupItem<>(lookup, lookup.toString()); item.setInsertHandler(INSERT_HANDLER); if (lookup.isKeyword()) { item.setBold(); } result.addElement(item); } }
@Nullable private static AutoCompletionPolicy getAutocompletionPolicy(LookupElement element) { final AutoCompletionPolicy policy = AutoCompletionPolicy.getPolicy(element); if (policy != null) { return policy; } final LookupItem item = element.as(LookupItem.CLASS_CONDITION_KEY); if (item != null) { return item.getAutoCompletionPolicy(); } return null; }
@Nullable private static Object createSubclassLookupValue( @NotNull final PsiPackage context, @NotNull final PsiClass clazz) { String name = clazz.getQualifiedName(); if (name == null) return null; final String pack = context.getQualifiedName(); if (pack.length() > 0) { if (name.startsWith(pack)) { name = name.substring(pack.length() + 1); } else { return null; } } final LookupItem<PsiClass> lookup = LookupElementFactoryImpl.getInstance().createLookupElement(clazz, name); lookup.addLookupStrings(clazz.getName()); return JavaCompletionUtil.setShowFQN(lookup).setTailType(TailType.NONE); }
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; }
protected void addLookupItem( Set<LookupElement> set, TailType tailType, @NotNull Object completion, final PsiFile file, final CompletionVariant variant) { LookupElement ret = objectToLookupItem(completion); if (ret == null) return; if (!(ret instanceof LookupItem)) { set.add(ret); return; } LookupItem item = (LookupItem) ret; final InsertHandler insertHandler = variant.getInsertHandler(); if (insertHandler != null && item.getInsertHandler() == null) { item.setInsertHandler(insertHandler); item.setTailType(TailType.UNKNOWN); } else if (tailType != TailType.NONE) { item.setTailType(tailType); } final Map<Object, Object> itemProperties = variant.getItemProperties(); for (final Object key : itemProperties.keySet()) { item.setAttribute(key, itemProperties.get(key)); } set.add(ret); }
public static void renderClassItem( LookupElementPresentation presentation, LookupItem item, PsiClass psiClass, boolean diamond) { if (!(psiClass instanceof PsiTypeParameter)) { presentation.setIcon(DefaultLookupItemRenderer.getRawIcon(item, presentation.isReal())); } final boolean bold = item.getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null; boolean strikeout = JavaElementLookupRenderer.isToStrikeout(item); presentation.setItemText(getName(psiClass, item, diamond)); presentation.setStrikeout(strikeout); presentation.setItemTextBold(bold); String tailText = StringUtil.notNullize((String) item.getAttribute(LookupItem.TAIL_TEXT_ATTR)); PsiSubstitutor substitutor = (PsiSubstitutor) item.getAttribute(LookupItem.SUBSTITUTOR); if (item instanceof PsiTypeLookupItem && ((PsiTypeLookupItem) item).isIndicateAnonymous() && (psiClass.isInterface() || psiClass.hasModifierProperty(PsiModifier.ABSTRACT))) { tailText = "{...}" + tailText; } if (substitutor == null && !diamond && psiClass.getTypeParameters().length > 0) { tailText = "<" + StringUtil.join( psiClass.getTypeParameters(), new Function<PsiTypeParameter, String>() { @Override public String fun(PsiTypeParameter psiTypeParameter) { return psiTypeParameter.getName(); } }, "," + (showSpaceAfterComma(psiClass) ? " " : "")) + ">" + tailText; } presentation.setTailText(tailText, true); }
public static LookupElement objectToLookupItem(Object object) { if (object instanceof LookupElement) return (LookupElement) object; String s = null; TailType tailType = TailType.NONE; if (object instanceof PsiElement) { s = PsiUtilBase.getName((PsiElement) object); } else if (object instanceof PsiMetaData) { s = ((PsiMetaData) object).getName(); } else if (object instanceof String) { s = (String) object; } else if (object instanceof Template) { s = ((Template) object).getKey(); } else if (object instanceof PresentableLookupValue) { s = ((PresentableLookupValue) object).getPresentation(); } else { LOG.assertTrue( false, "Null string for object: " + object + " of class " + (object != null ? object.getClass() : null)); } LookupItem item = new LookupItem(object, s); if (object instanceof LookupValueWithUIHint && ((LookupValueWithUIHint) object).isBold()) { item.setBold(); } if (object instanceof LookupValueWithTail) { item.setAttribute( LookupItem.TAIL_TEXT_ATTR, " " + ((LookupValueWithTail) object).getTailText()); } item.setAttribute(CompletionUtil.TAIL_TYPE_ATTR, tailType); return item; }
private static void addTopLevelKeysCompletionIfNeeded( @NotNull CompletionParameters parameters, @NotNull CompletionResultSet result, @NotNull BipartiteString caretBipartiteElementText) { PsiElement element = parameters.getPosition(); YAMLDocument yamlDocument = ObjectUtils.tryCast(element.getParent(), YAMLDocument.class); if (yamlDocument == null) { yamlDocument = JstdConfigFileUtils.getVerifiedHierarchyHead( element.getParent(), new Class[] {YAMLKeyValue.class}, YAMLDocument.class); } if (yamlDocument != null) { String prefix = caretBipartiteElementText.getPrefix(); result = result.withPrefixMatcher(prefix); for (String key : JstdConfigFileUtils.VALID_TOP_LEVEL_KEYS) { if (key.startsWith(prefix)) { result.addElement(LookupItem.fromString(key + ":")); } } } }
public void fillCompletions( CompletionParameters parameters, final Consumer<LookupElement> result) { final PsiElement position = parameters.getPosition(); if (PsiTreeUtil.getParentOfType(position, PsiComment.class, false) != null) { return; } PsiStatement statement = PsiTreeUtil.getParentOfType(position, PsiExpressionStatement.class); if (statement == null) { statement = PsiTreeUtil.getParentOfType(position, PsiDeclarationStatement.class); } PsiElement prevLeaf = PsiTreeUtil.prevVisibleLeaf(position); if (statement != null && statement.getTextRange().getStartOffset() == position.getTextRange().getStartOffset()) { if (!psiElement() .withSuperParent(2, PsiSwitchStatement.class) .afterLeaf("{") .accepts(statement)) { PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(prevLeaf, PsiTryStatement.class); if (tryStatement == null || tryStatement.getCatchSections().length > 0 || tryStatement.getFinallyBlock() != null) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD)); } } } if (isStatementPosition(position)) { if (PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class, false, PsiMember.class) != null) { result.consume( new OverrideableSpace(createKeyword(position, PsiKeyword.CASE), TailType.INSERT_SPACE)); result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.DEFAULT), TailType.CASE_COLON)); if (START_SWITCH.accepts(position)) { return; } } addBreakContinue(result, position); addStatementKeywords(result, position); } if (SUPER_OR_THIS_PATTERN.accepts(position)) { final boolean afterDot = AFTER_DOT.accepts(position); final boolean insideQualifierClass = isInsideQualifierClass(position); final boolean insideInheritorClass = PsiUtil.isLanguageLevel8OrHigher(position) && isInsideInheritorClass(position); if (!afterDot || insideQualifierClass || insideInheritorClass) { if (!afterDot || insideQualifierClass) { result.consume(createKeyword(position, PsiKeyword.THIS)); } final LookupItem superItem = (LookupItem) createKeyword(position, PsiKeyword.SUPER); if (psiElement() .afterLeaf(psiElement().withText("{").withSuperParent(2, psiMethod().constructor(true))) .accepts(position)) { final PsiMethod method = PsiTreeUtil.getParentOfType(position, PsiMethod.class, false, PsiClass.class); assert method != null; final boolean hasParams = superConstructorHasParameters(method); superItem.setInsertHandler( new ParenthesesInsertHandler<LookupElement>() { @Override protected boolean placeCaretInsideParentheses( InsertionContext context, LookupElement item) { return hasParams; } @Override public void handleInsert(InsertionContext context, LookupElement item) { super.handleInsert(context, item); TailType.insertChar(context.getEditor(), context.getTailOffset(), ';'); } }); } result.consume(superItem); } } if (isExpressionPosition(position)) { if (PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) == null) { result.consume( TailTypeDecorator.withTail( createKeyword(position, PsiKeyword.NEW), TailType.INSERT_SPACE)); result.consume(createKeyword(position, PsiKeyword.NULL)); } if (mayExpectBoolean(parameters)) { result.consume(createKeyword(position, PsiKeyword.TRUE)); result.consume(createKeyword(position, PsiKeyword.FALSE)); } } PsiFile file = position.getContainingFile(); if (!(file instanceof PsiExpressionCodeFragment) && !(file instanceof PsiJavaCodeReferenceCodeFragment) && !(file instanceof PsiTypeCodeFragment)) { if (prevLeaf == null) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.PACKAGE), TailType.HUMBLE_SPACE_BEFORE_WORD)); result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.IMPORT), TailType.HUMBLE_SPACE_BEFORE_WORD)); } else if (END_OF_BLOCK.getValue().isAcceptable(position, position) && PsiTreeUtil.getParentOfType(position, PsiMember.class) == null) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.IMPORT), TailType.HUMBLE_SPACE_BEFORE_WORD)); } } if ((isInsideParameterList(position) || isAtResourceVariableStart(position) || isAtCatchVariableStart(position)) && !psiElement().afterLeaf(PsiKeyword.FINAL).accepts(position) && !AFTER_DOT.accepts(position)) { result.consume( TailTypeDecorator.withTail( createKeyword(position, PsiKeyword.FINAL), TailType.HUMBLE_SPACE_BEFORE_WORD)); } if (isInstanceofPlace(position)) { result.consume( LookupElementDecorator.withInsertHandler( createKeyword(position, PsiKeyword.INSTANCEOF), new InsertHandler<LookupElementDecorator<LookupElement>>() { @Override public void handleInsert( InsertionContext context, LookupElementDecorator<LookupElement> item) { TailType tailType = TailType.HUMBLE_SPACE_BEFORE_WORD; if (tailType.isApplicable(context)) { tailType.processTail(context.getEditor(), context.getTailOffset()); } if ('!' == context.getCompletionChar()) { context.setAddCompletionChar(false); context.commitDocument(); PsiInstanceOfExpression expr = PsiTreeUtil.findElementOfClassAtOffset( context.getFile(), context.getStartOffset(), PsiInstanceOfExpression.class, false); if (expr != null) { String space = context.getCodeStyleSettings().SPACE_WITHIN_PARENTHESES ? " " : ""; context .getDocument() .insertString(expr.getTextRange().getStartOffset(), "!(" + space); context.getDocument().insertString(context.getTailOffset(), space + ")"); } } } })); } if (isSuitableForClass(position)) { for (String s : ModifierChooser.getKeywords(position)) { result.consume( new OverrideableSpace(createKeyword(position, s), TailType.HUMBLE_SPACE_BEFORE_WORD)); } result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.CLASS), TailType.HUMBLE_SPACE_BEFORE_WORD)); if (PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, true, PsiMember.class) == null) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.INTERFACE), TailType.HUMBLE_SPACE_BEFORE_WORD)); if (PsiUtil.getLanguageLevel(position).isAtLeast(LanguageLevel.JDK_1_5)) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.ENUM), TailType.INSERT_SPACE)); } } } addPrimitiveTypes(result, position); if (isAfterTypeDot(position)) { result.consume(createKeyword(position, PsiKeyword.CLASS)); } addUnfinishedMethodTypeParameters(position, result); if (JavaMemberNameCompletionContributor.INSIDE_TYPE_PARAMS_PATTERN.accepts(position)) { result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.EXTENDS), TailType.HUMBLE_SPACE_BEFORE_WORD)); result.consume( new OverrideableSpace( createKeyword(position, PsiKeyword.SUPER), TailType.HUMBLE_SPACE_BEFORE_WORD)); } }
public boolean handleUserSelection(LookupItem item, Project project) { if (!myIsStandard) { item.setLookupString(myValue); } return true; }
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); } }
public static LookupItem setShowFQN(final LookupItem ret) { ret.setAttribute( JavaPsiClassReferenceElement.PACKAGE_NAME, PsiFormatUtil.getPackageDisplayName((PsiClass) ret.getObject())); return ret; }
public static LookupItem qualify(final LookupItem ret) { return ret.forceQualify(); }
public static PsiType getQualifierType(LookupItem item) { return item.getUserData(QUALIFIER_TYPE_ATTR); }