Пример #1
0
 @Nullable
 private static String getTypeName(PsiType type, boolean withIndices) {
   type = type.getDeepComponentType();
   if (type instanceof PsiClassType) {
     final PsiClassType classType = (PsiClassType) type;
     final String className = classType.getClassName();
     if (className != null || !withIndices) return className;
     final PsiClass aClass = classType.resolve();
     return aClass instanceof PsiAnonymousClass
         ? ((PsiAnonymousClass) aClass).getBaseClassType().getClassName()
         : null;
   } else if (type instanceof PsiPrimitiveType) {
     return type.getPresentableText();
   } else if (type instanceof PsiWildcardType) {
     return getTypeName(((PsiWildcardType) type).getExtendsBound(), withIndices);
   } else if (type instanceof PsiIntersectionType) {
     return getTypeName(((PsiIntersectionType) type).getRepresentative(), withIndices);
   } else if (type instanceof PsiCapturedWildcardType) {
     return getTypeName(((PsiCapturedWildcardType) type).getWildcard(), withIndices);
   } else if (type instanceof PsiDisjunctionType) {
     return getTypeName(((PsiDisjunctionType) type).getLeastUpperBound(), withIndices);
   } else {
     return null;
   }
 }
  @Override
  public String handleEmptyLookup(
      @NotNull final CompletionParameters parameters, final Editor editor) {
    if (!(parameters.getOriginalFile() instanceof PsiJavaFile)) return null;

    final String ad = advertise(parameters);
    final String suffix = ad == null ? "" : "; " + StringUtil.decapitalize(ad);
    if (parameters.getCompletionType() == CompletionType.SMART) {
      if (!ApplicationManager.getApplication().isUnitTestMode()) {

        final Project project = parameters.getPosition().getProject();
        final PsiFile file = parameters.getOriginalFile();

        PsiExpression expression =
            PsiTreeUtil.getContextOfType(parameters.getPosition(), PsiExpression.class, true);
        if (expression != null && expression.getParent() instanceof PsiExpressionList) {
          int lbraceOffset = expression.getParent().getTextRange().getStartOffset();
          ShowParameterInfoHandler.invoke(project, editor, file, lbraceOffset, null);
        }

        if (expression instanceof PsiLiteralExpression) {
          return LangBundle.message("completion.no.suggestions") + suffix;
        }

        if (expression instanceof PsiInstanceOfExpression) {
          final PsiInstanceOfExpression instanceOfExpression = (PsiInstanceOfExpression) expression;
          if (PsiTreeUtil.isAncestor(
              instanceOfExpression.getCheckType(), parameters.getPosition(), false)) {
            return LangBundle.message("completion.no.suggestions") + suffix;
          }
        }
      }

      final Set<PsiType> expectedTypes = JavaCompletionUtil.getExpectedTypes(parameters);
      if (expectedTypes != null) {
        PsiType type = expectedTypes.size() == 1 ? expectedTypes.iterator().next() : null;
        if (type != null) {
          final PsiType deepComponentType = type.getDeepComponentType();
          if (deepComponentType instanceof PsiClassType) {
            if (((PsiClassType) deepComponentType).resolve() != null) {
              return CompletionBundle.message(
                      "completion.no.suggestions.of.type", type.getPresentableText())
                  + suffix;
            }
            return CompletionBundle.message("completion.unknown.type", type.getPresentableText())
                + suffix;
          }
          if (!PsiType.NULL.equals(type)) {
            return CompletionBundle.message(
                    "completion.no.suggestions.of.type", type.getPresentableText())
                + suffix;
          }
        }
      }
    }
    return LangBundle.message("completion.no.suggestions") + suffix;
  }
Пример #3
0
  public static void processSubTypes(
      PsiType psiType,
      final PsiElement context,
      boolean getRawSubtypes,
      @NotNull final PrefixMatcher matcher,
      Consumer<PsiType> consumer) {
    int arrayDim = psiType.getArrayDimensions();

    psiType = psiType.getDeepComponentType();
    if (!(psiType instanceof PsiClassType)) return;

    final Condition<String> shortNameCondition =
        new Condition<String>() {
          @Override
          public boolean value(String s) {
            return matcher.prefixMatches(s);
          }
        };

    final PsiClassType baseType = (PsiClassType) psiType;
    final PsiClassType.ClassResolveResult baseResult =
        ApplicationManager.getApplication()
            .runReadAction(
                new Computable<PsiClassType.ClassResolveResult>() {
                  @Override
                  public PsiClassType.ClassResolveResult compute() {
                    return JavaCompletionUtil.originalize(baseType).resolveGenerics();
                  }
                });
    final PsiClass baseClass = baseResult.getElement();
    final PsiSubstitutor baseSubstitutor = baseResult.getSubstitutor();
    if (baseClass == null) return;

    final GlobalSearchScope scope =
        ApplicationManager.getApplication()
            .runReadAction(
                new Computable<GlobalSearchScope>() {
                  @Override
                  public GlobalSearchScope compute() {
                    return context.getResolveScope();
                  }
                });

    final Processor<PsiClass> inheritorsProcessor =
        createInheritorsProcessor(
            context, baseType, arrayDim, getRawSubtypes, consumer, baseClass, baseSubstitutor);
    if (matcher.getPrefix().length() > 2) {
      AllClassesGetter.processJavaClasses(
          matcher,
          context.getProject(),
          scope,
          new Processor<PsiClass>() {
            @Override
            public boolean process(PsiClass psiClass) {
              if (psiClass.isInheritor(baseClass, true)) {
                return inheritorsProcessor.process(psiClass);
              }
              return true;
            }
          });
    } else {
      final Query<PsiClass> baseQuery =
          ClassInheritorsSearch.search(
              new ClassInheritorsSearch.SearchParameters(
                  baseClass, scope, true, false, false, shortNameCondition));
      final Query<PsiClass> query =
          new FilteredQuery<PsiClass>(
              baseQuery,
              new Condition<PsiClass>() {
                @Override
                public boolean value(final PsiClass psiClass) {
                  return !(psiClass instanceof PsiTypeParameter);
                }
              });
      query.forEach(inheritorsProcessor);
    }
  }
Пример #4
0
  @Nullable
  public static PsiType getVariableTypeByExpressionType(
      @Nullable PsiType type, final boolean openCaptured) {
    if (type == null) return null;
    if (type instanceof PsiCapturedWildcardType) {
      type = ((PsiCapturedWildcardType) type).getWildcard();
    }
    PsiType transformed =
        type.accept(
            new PsiTypeVisitor<PsiType>() {
              @Override
              public PsiType visitArrayType(PsiArrayType arrayType) {
                PsiType componentType = arrayType.getComponentType();
                PsiType type = componentType.accept(this);
                if (type == componentType) return arrayType;
                return type.createArrayType();
              }

              @Override
              public PsiType visitType(PsiType type) {
                return type;
              }

              @Override
              public PsiType visitWildcardType(final PsiWildcardType wildcardType) {
                final PsiType bound = wildcardType.getBound();
                PsiManager manager = wildcardType.getManager();
                if (bound != null) {
                  final PsiType acceptedBound = bound.accept(this);
                  if (acceptedBound instanceof PsiWildcardType) {
                    if (((PsiWildcardType) acceptedBound).isExtends() != wildcardType.isExtends())
                      return PsiWildcardType.createUnbounded(manager);
                    return acceptedBound;
                  }
                  if (wildcardType.isExtends()
                      && acceptedBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT))
                    return PsiWildcardType.createUnbounded(manager);
                  if (acceptedBound.equals(bound)) return wildcardType;
                  return wildcardType.isExtends()
                      ? PsiWildcardType.createExtends(manager, acceptedBound)
                      : PsiWildcardType.createSuper(manager, acceptedBound);
                }
                return wildcardType;
              }

              @Override
              public PsiType visitCapturedWildcardType(
                  PsiCapturedWildcardType capturedWildcardType) {
                return openCaptured
                    ? capturedWildcardType.getWildcard().accept(this)
                    : capturedWildcardType;
              }

              @Override
              public PsiType visitClassType(PsiClassType classType) {
                PsiClassType.ClassResolveResult resolveResult = classType.resolveGenerics();
                PsiClass aClass = resolveResult.getElement();
                if (aClass == null) return classType;
                boolean toExtend = false;
                PsiSubstitutor substitutor = PsiSubstitutor.EMPTY;
                for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(aClass)) {
                  PsiType typeArgument = resolveResult.getSubstitutor().substitute(typeParameter);
                  if (typeArgument instanceof PsiCapturedWildcardType) toExtend = true;
                  if (typeArgument instanceof PsiWildcardType
                      && ((PsiWildcardType) typeArgument).getBound()
                          instanceof PsiIntersectionType) {
                    toExtend = true;
                  }
                  PsiType toPut;
                  if (typeArgument == null) {
                    toPut = null;
                  } else {
                    final PsiType accepted = typeArgument.accept(this);
                    if (typeArgument instanceof PsiIntersectionType) {
                      toPut = PsiWildcardType.createExtends(typeParameter.getManager(), accepted);
                    } else {
                      toPut = accepted;
                    }
                  }
                  LOG.assertTrue(toPut == null || toPut.isValid(), toPut);
                  substitutor = substitutor.put(typeParameter, toPut);
                }
                final PsiAnnotation[] applicableAnnotations = classType.getApplicableAnnotations();
                if (substitutor == PsiSubstitutor.EMPTY
                    && !toExtend
                    && applicableAnnotations.length == 0
                    && !(aClass instanceof PsiTypeParameter)) return classType;
                PsiManager manager = aClass.getManager();
                PsiType result =
                    JavaPsiFacade.getInstance(manager.getProject())
                        .getElementFactory()
                        .createType(
                            aClass,
                            substitutor,
                            PsiUtil.getLanguageLevel(aClass),
                            applicableAnnotations);
                if (toExtend) result = PsiWildcardType.createExtends(manager, result);
                return result;
              }
            });

    PsiType componentType = transformed != null ? transformed.getDeepComponentType() : null;
    if (componentType instanceof PsiWildcardType) {
      componentType = ((PsiWildcardType) componentType).getExtendsBound();
      int dims = transformed.getArrayDimensions();
      for (int i = 0; i < dims; i++) componentType = componentType.createArrayType();
      return componentType;
    }

    return transformed;
  }