@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;
  }
Пример #8
0
  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;
  }