예제 #1
0
  private static void addNamesToImport(
      @NotNull Set<String> names,
      @NotNull PsiElement scope,
      @NotNull String thisPackageName,
      @NotNull Set<String> namesToImportStaticly,
      PsiFile context) {
    if (scope instanceof PsiImportList) return;

    final LinkedList<PsiElement> stack = new LinkedList<PsiElement>();
    stack.add(scope);
    while (!stack.isEmpty()) {
      final PsiElement child = stack.removeFirst();
      if (child instanceof PsiImportList) continue;
      stack.addAll(Arrays.asList(child.getChildren()));

      for (final PsiReference reference : child.getReferences()) {
        if (!(reference instanceof PsiJavaReference)) continue;
        final PsiJavaReference javaReference = (PsiJavaReference) reference;
        if (javaReference instanceof JavaClassReference) {
          if (((JavaClassReference) javaReference).getContextReference() != null) continue;
        }
        PsiJavaCodeReferenceElement referenceElement = null;
        if (reference instanceof PsiJavaCodeReferenceElement) {
          referenceElement = (PsiJavaCodeReferenceElement) child;
          if (referenceElement.getQualifier() != null) {
            continue;
          }
          if (reference instanceof PsiJavaCodeReferenceElementImpl
              && ((PsiJavaCodeReferenceElementImpl) reference).getKind()
                  == PsiJavaCodeReferenceElementImpl.CLASS_IN_QUALIFIED_NEW_KIND) {
            continue;
          }
        }

        final JavaResolveResult resolveResult = javaReference.advancedResolve(true);
        PsiElement refElement = resolveResult.getElement();
        if (refElement == null && referenceElement != null) {
          refElement = ResolveClassUtil.resolveClass(referenceElement); // might be uncomplete code
        }

        PsiElement currentFileResolveScope = resolveResult.getCurrentFileResolveScope();
        if (!(currentFileResolveScope instanceof PsiImportStatementBase)) continue;
        if (context != null
            && currentFileResolveScope instanceof JspxImportStatement
            && context != ((JspxImportStatement) currentFileResolveScope).getDeclarationFile()) {
          continue;
        }

        if (refElement != null) {
          // Add names imported statically
          if (referenceElement != null) {
            if (currentFileResolveScope instanceof PsiImportStaticStatement) {
              PsiImportStaticStatement importStaticStatement =
                  (PsiImportStaticStatement) currentFileResolveScope;
              String name = importStaticStatement.getImportReference().getCanonicalText();
              if (importStaticStatement.isOnDemand()) {
                String refName = referenceElement.getReferenceName();
                if (refName != null) name = name + "." + refName;
              }
              names.add(name);
              namesToImportStaticly.add(name);
              continue;
            }
          }

          if (refElement instanceof PsiClass) {
            String qName = ((PsiClass) refElement).getQualifiedName();
            if (hasPackage(qName, thisPackageName)) continue;
            names.add(qName);
          }
        }
      }
    }
  }
  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;
  }