コード例 #1
0
 @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);
   }
   return 0;
 }
コード例 #2
0
 @NotNull
 @Override
 public Comparable weigh(@NotNull LookupElement element) {
   final PsiTypeLookupItem lookupItem = element.as(PsiTypeLookupItem.CLASS_CONDITION_KEY);
   if (lookupItem != null) {
     return lookupItem.getBracketsCount();
   }
   if (element.as(CastingLookupElementDecorator.CLASS_CONDITION_KEY) != null) {
     return 239;
   }
   return 0;
 }
コード例 #3
0
  private static PsiTypeLookupItem doCreateItem(
      final PsiType type,
      PsiElement context,
      int bracketsCount,
      boolean diamond,
      InsertHandler<PsiTypeLookupItem> importFixer) {
    if (type instanceof PsiClassType) {
      PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType) type).resolveGenerics();
      final PsiClass psiClass = classResolveResult.getElement();

      if (psiClass != null) {
        String name = psiClass.getName();
        if (name != null) {
          final PsiSubstitutor substitutor = classResolveResult.getSubstitutor();

          PsiClass resolved =
              JavaPsiFacade.getInstance(psiClass.getProject())
                  .getResolveHelper()
                  .resolveReferencedClass(name, context);

          Set<String> allStrings = new HashSet<String>();
          allStrings.add(name);
          if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass)
              && !PsiUtil.isInnerClass(psiClass)) {
            // inner class name should be shown qualified if its not accessible by single name
            PsiClass aClass = psiClass.getContainingClass();
            while (aClass != null && !PsiUtil.isInnerClass(aClass) && aClass.getName() != null) {
              name = aClass.getName() + '.' + name;
              allStrings.add(name);
              aClass = aClass.getContainingClass();
            }
          }

          PsiTypeLookupItem item =
              new PsiTypeLookupItem(
                  psiClass, name, diamond, bracketsCount, importFixer, substitutor);
          item.addLookupStrings(ArrayUtil.toStringArray(allStrings));
          return item;
        }
      }
    }
    return new PsiTypeLookupItem(
        type, type.getPresentableText(), false, bracketsCount, importFixer, PsiSubstitutor.EMPTY);
  }
コード例 #4
0
  private static void addPrimitiveTypes(final Consumer<LookupElement> result, PsiElement position) {
    if (AFTER_DOT.accepts(position)) {
      return;
    }

    boolean afterNew =
        psiElement()
            .afterLeaf(
                psiElement()
                    .withText(PsiKeyword.NEW)
                    .andNot(psiElement().afterLeaf(PsiKeyword.THROW, ".")))
            .accepts(position);
    if (afterNew) {
      PsiElementFactory factory = JavaPsiFacade.getElementFactory(position.getProject());
      for (String primitiveType : PRIMITIVE_TYPES) {
        result.consume(
            PsiTypeLookupItem.createLookupItem(
                factory.createTypeFromText(primitiveType + "[]", null), null));
      }
      result.consume(
          PsiTypeLookupItem.createLookupItem(factory.createTypeFromText("void[]", null), null));
      return;
    }

    boolean inCast =
        psiElement()
            .afterLeaf(
                psiElement()
                    .withText("(")
                    .withParent(
                        psiElement(PsiParenthesizedExpression.class, PsiTypeCastExpression.class)))
            .accepts(position);

    boolean typeFragment =
        position.getContainingFile() instanceof PsiTypeCodeFragment
            && PsiTreeUtil.prevVisibleLeaf(position) == null;
    boolean declaration = DECLARATION_START.getValue().accepts(position);
    boolean expressionPosition = isExpressionPosition(position);
    boolean inGenerics =
        PsiTreeUtil.getParentOfType(position, PsiReferenceParameterList.class) != null;
    if (START_FOR.accepts(position)
        || isInsideParameterList(position)
        || inGenerics
        || VARIABLE_AFTER_FINAL.accepts(position)
        || inCast
        || declaration
        || typeFragment
        || expressionPosition
        || isStatementPosition(position)) {
      for (String primitiveType : PRIMITIVE_TYPES) {
        result.consume(createKeyword(position, primitiveType));
      }
    }
    if (declaration) {
      result.consume(
          new OverrideableSpace(
              createKeyword(position, PsiKeyword.VOID), TailType.HUMBLE_SPACE_BEFORE_WORD));
    } else if (typeFragment && ((PsiTypeCodeFragment) position.getContainingFile()).isVoidValid()) {
      result.consume(createKeyword(position, PsiKeyword.VOID));
    }
  }
コード例 #5
0
  @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);
          }
        });
  }
コード例 #6
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;
  }
コード例 #7
0
 @Override
 public void handleInsert(InsertionContext context, PsiTypeLookupItem item) {
   if (item.getObject() instanceof PsiClass) {
     addImportForItem(context, (PsiClass) item.getObject());
   }
 }