@Override public void handleInsert(InsertionContext context) { final Document document = context.getEditor().getDocument(); document.replaceString(context.getStartOffset(), context.getTailOffset(), ";"); final InsertionContext qualifierContext = CompletionUtil.emulateInsertion(context, context.getStartOffset(), myQualifier); OffsetKey oldStart = context.trackOffset(context.getStartOffset(), false); int start = CharArrayUtil.shiftForward( context.getDocument().getCharsSequence(), context.getStartOffset(), " \t\n"); if (shouldParenthesizeQualifier(context.getFile(), start, qualifierContext.getTailOffset())) { final String space = CodeStyleSettingsManager.getSettings(qualifierContext.getProject()) .SPACE_WITHIN_PARENTHESES ? " " : ""; document.insertString(start, "(" + space); document.insertString(qualifierContext.getTailOffset(), space + ")"); } final char atTail = document.getCharsSequence().charAt(context.getTailOffset() - 1); if (atTail != ';') { LOG.error( LogMessageEx.createEvent( "Unexpected character", "atTail=" + atTail + "\n" + "offset=" + context.getTailOffset() + "\n" + "item=" + this + "\n" + "item.class=" + this.getClass() + "\n" + DebugUtil.currentStackTrace(), AttachmentFactory.createAttachment(context.getDocument()))); } document.replaceString(context.getTailOffset() - 1, context.getTailOffset(), "."); CompletionUtil.emulateInsertion(getDelegate(), context.getTailOffset(), context); context.commitDocument(); int formatStart = context.getOffset(oldStart); int formatEnd = context.getTailOffset(); if (formatStart >= 0 && formatEnd >= 0) { CodeStyleManager.getInstance(context.getProject()) .reformatText(context.getFile(), formatStart, formatEnd); } }
public String calcGenerics(@NotNull PsiElement context, InsertionContext insertionContext) { if (insertionContext.getCompletionChar() == '<') { return ""; } assert context.isValid(); if (myDiamond) { return "<>"; } if (getObject() instanceof PsiClass) { PsiClass psiClass = (PsiClass) getObject(); PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(psiClass.getProject()).getResolveHelper(); PsiSubstitutor substitutor = getSubstitutor(); StringBuilder builder = new StringBuilder(); for (PsiTypeParameter parameter : psiClass.getTypeParameters()) { PsiType substitute = substitutor.substitute(parameter); if (substitute == null || (PsiUtil.resolveClassInType(substitute) == parameter && resolveHelper.resolveReferencedClass(parameter.getName(), context) != CompletionUtil.getOriginalOrSelf(parameter))) { return ""; } if (builder.length() > 0) { builder.append(", "); } builder.append(substitute.getCanonicalText()); } if (builder.length() > 0) { return "<" + builder + ">"; } } return ""; }
@Override public void handleInsert(InsertionContext context) { context.getDocument().deleteString(context.getStartOffset(), context.getTailOffset()); for (int i = 0; i < myTypeItems.size(); i++) { PsiTypeLookupItem typeItem = myTypeItems.get(i); CompletionUtil.emulateInsertion(context, context.getTailOffset(), typeItem); if (context.getTailOffset() < 0) { LOG.error("tail offset spoiled by " + typeItem); return; } context.setTailOffset( getTail(i == myTypeItems.size() - 1) .processTail(context.getEditor(), context.getTailOffset())); } context.setAddCompletionChar(false); context.commitDocument(); PsiElement leaf = context.getFile().findElementAt(context.getTailOffset() - 1); if (psiElement() .withParents( PsiReferenceParameterList.class, PsiJavaCodeReferenceElement.class, PsiNewExpression.class) .accepts(leaf)) { ParenthesesInsertHandler.getInstance(myHasParameters).handleInsert(context, this); myGlobalTail.processTail(context.getEditor(), context.getTailOffset()); } }
private static boolean shouldMarkRed(@NotNull Object object, @NotNull PsiElement place) { if (!(object instanceof PsiMember)) return false; if (Java15APIUsageInspectionBase.isForbiddenApiUsage( (PsiMember) object, PsiUtil.getLanguageLevel(place))) return true; if (object instanceof PsiEnumConstant) { return findConstantsUsedInSwitch(place) .contains(CompletionUtil.getOriginalOrSelf((PsiEnumConstant) object)); } return false; }
private static void suggestGeneratedMethods(CompletionResultSet result, PsiElement position) { PsiClass parent = CompletionUtil.getOriginalElement( ObjectUtils.assertNotNull(PsiTreeUtil.getParentOfType(position, PsiClass.class))); if (parent != null) { Set<MethodSignature> addedSignatures = ContainerUtil.newHashSet(); addGetterSetterElements(result, parent, addedSignatures); addSuperSignatureElements(parent, true, result, addedSignatures); addSuperSignatureElements(parent, false, result, addedSignatures); } }
@Override public void consume(CompletionResult plainResult) { myResult.passResult(plainResult); LookupElement element = plainResult.getLookupElement(); if (containsOnlyPackages && !(CompletionUtil.getTargetElement(element) instanceof PsiPackage)) { containsOnlyPackages = false; } betterMatcher = betterMatcher.improve(plainResult); }
private static boolean shouldMarkRed(@NotNull Object object, @NotNull PsiElement place) { if (!(object instanceof PsiMember)) return false; if (Java15APIUsageInspectionBase.isForbiddenApiUsage( (PsiMember) object, PsiUtil.getLanguageLevel(place))) return true; if (object instanceof PsiEnumConstant) { return findConstantsUsedInSwitch(place) .contains(CompletionUtil.getOriginalOrSelf((PsiEnumConstant) object)); } if (object instanceof PsiClass && ReferenceListWeigher.INSTANCE.getApplicability((PsiClass) object, place) == inapplicable) { return true; } return false; }
public static String findPrefixStatic(final PsiElement insertedElement, final int offsetInFile) { if (insertedElement == null) return ""; final String prefix = ApplicationManager.getApplication() .runReadAction( new Computable<String>() { public String compute() { if (!insertedElement.isValid()) { return ""; } return getReferencePrefix(insertedElement, offsetInFile); } }); if (prefix != null) return prefix; if (insertedElement instanceof PsiPlainText || insertedElement instanceof PsiComment) { return CompletionUtil.findJavaIdentifierPrefix(insertedElement, offsetInFile); } return findPrefixDefault(insertedElement, offsetInFile, not(character().javaIdentifierPart())); }
private boolean shouldQualify(PsiField field, InsertionContext context) { if (myHelper != null && !myHelper.willBeImported()) { return true; } if (getAttribute(FORCE_QUALIFY) != null) { return true; } PsiReference reference = context.getFile().findReferenceAt(context.getStartOffset()); if (reference instanceof PsiReferenceExpression && !((PsiReferenceExpression) reference).isQualified()) { final PsiVariable target = JavaPsiFacade.getInstance(context.getProject()) .getResolveHelper() .resolveReferencedVariable(field.getName(), (PsiElement) reference); return !field .getManager() .areElementsEquivalent(target, CompletionUtil.getOriginalOrSelf(field)); } return false; }
@NotNull public static Set<PsiField> findConstantsUsedInSwitch(@Nullable PsiElement position) { if (IN_SWITCH_LABEL.accepts(position)) { Set<PsiField> used = ContainerUtil.newLinkedHashSet(); PsiSwitchStatement sw = PsiTreeUtil.getParentOfType(position, PsiSwitchStatement.class); assert sw != null; final PsiCodeBlock body = sw.getBody(); assert body != null; for (PsiStatement statement : body.getStatements()) { if (statement instanceof PsiSwitchLabelStatement) { final PsiExpression value = ((PsiSwitchLabelStatement) statement).getCaseValue(); if (value instanceof PsiReferenceExpression) { final PsiElement target = ((PsiReferenceExpression) value).resolve(); if (target instanceof PsiField) { used.add(CompletionUtil.getOriginalOrSelf((PsiField) target)); } } } } return used; } return Collections.emptySet(); }
@Override public String advertise(@NotNull final CompletionParameters parameters) { if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null; if (parameters.getCompletionType() == CompletionType.BASIC && parameters.getInvocationCount() > 0) { PsiElement position = parameters.getPosition(); if (psiElement() .withParent( psiReferenceExpression() .withFirstChild(psiReferenceExpression().referencing(psiClass()))) .accepts(position)) { if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.GLOBAL_MEMBER_NAME)) { final String shortcut = getActionShortcut(IdeActions.ACTION_CODE_COMPLETION); if (shortcut != null) { return "Pressing " + shortcut + " twice without a class qualifier would show all accessible static methods"; } } } } if (parameters.getCompletionType() != CompletionType.SMART && shouldSuggestSmartCompletion(parameters.getPosition())) { if (CompletionUtil.shouldShowFeature( parameters, CodeCompletionFeatures.EDITING_COMPLETION_SMARTTYPE_GENERAL)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { return CompletionBundle.message("completion.smart.hint", shortcut); } } } if (parameters.getCompletionType() == CompletionType.SMART && parameters.getInvocationCount() == 1) { final PsiType[] psiTypes = ExpectedTypesGetter.getExpectedTypes(parameters.getPosition(), true); if (psiTypes.length > 0) { if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_TOAR)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { for (final PsiType psiType : psiTypes) { final PsiType type = PsiUtil.extractIterableTypeParameter(psiType, false); if (type != null) { return CompletionBundle.message( "completion.smart.aslist.hint", shortcut, type.getPresentableText()); } } } } if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_ASLIST)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { for (final PsiType psiType : psiTypes) { if (psiType instanceof PsiArrayType) { final PsiType componentType = ((PsiArrayType) psiType).getComponentType(); if (!(componentType instanceof PsiPrimitiveType)) { return CompletionBundle.message( "completion.smart.toar.hint", shortcut, componentType.getPresentableText()); } } } } } if (CompletionUtil.shouldShowFeature( parameters, JavaCompletionFeatures.SECOND_SMART_COMPLETION_CHAIN)) { final String shortcut = getActionShortcut(IdeActions.ACTION_SMART_TYPE_COMPLETION); if (shortcut != null) { return CompletionBundle.message("completion.smart.chain.hint", shortcut); } } } } return null; }
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; }