private void buildText(
      @NotNull PsiClass aClass,
      @NotNull PsiSubstitutor substitutor,
      @NotNull StringBuilder buffer,
      @NotNull TextType textType,
      boolean annotated) {
    if (aClass instanceof PsiAnonymousClass) {
      ClassResolveResult baseResolveResult =
          ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics();
      PsiClass baseClass = baseResolveResult.getElement();
      if (baseClass != null) {
        buildText(baseClass, baseResolveResult.getSubstitutor(), buffer, textType, false);
      }
      return;
    }

    boolean qualified = textType != TextType.PRESENTABLE;

    PsiClass enclosingClass = null;
    if (!aClass.hasModifierProperty(PsiModifier.STATIC)) {
      PsiElement parent = aClass.getParent();
      if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) {
        enclosingClass = (PsiClass) parent;
      }
    }
    if (enclosingClass != null) {
      buildText(enclosingClass, substitutor, buffer, textType, false);
      buffer.append('.');
    } else if (qualified) {
      String fqn = aClass.getQualifiedName();
      if (fqn != null) {
        String prefix = StringUtil.getPackageName(fqn);
        if (!StringUtil.isEmpty(prefix)) {
          buffer.append(prefix);
          buffer.append('.');
        }
      }
    }

    if (annotated) {
      PsiNameHelper.appendAnnotations(buffer, getAnnotations(), qualified);
    }

    buffer.append(aClass.getName());

    PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
    if (typeParameters.length > 0) {
      int pos = buffer.length();
      buffer.append('<');

      for (int i = 0; i < typeParameters.length; i++) {
        PsiTypeParameter typeParameter = typeParameters[i];
        PsiUtilCore.ensureValid(typeParameter);

        if (i > 0) {
          buffer.append(',');
          if (textType == TextType.PRESENTABLE) buffer.append(' ');
        }

        PsiType substitutionResult = substitutor.substitute(typeParameter);
        if (substitutionResult == null) {
          buffer.setLength(pos);
          pos = -1;
          break;
        }
        PsiUtil.ensureValidType(substitutionResult);

        if (textType == TextType.PRESENTABLE) {
          buffer.append(substitutionResult.getPresentableText());
        } else if (textType == TextType.CANONICAL) {
          buffer.append(substitutionResult.getCanonicalText(annotated));
        } else {
          buffer.append(substitutionResult.getInternalCanonicalText());
        }
      }

      if (pos >= 0) {
        buffer.append('>');
      }
    }
  }
예제 #2
0
  @Nullable
  public static PsiType getLeastUpperBound(
      @NotNull PsiType type1, @NotNull PsiType type2, PsiManager manager) {
    if (type1 instanceof GrTupleType && type2 instanceof GrTupleType) {
      GrTupleType tuple1 = (GrTupleType) type1;
      GrTupleType tuple2 = (GrTupleType) type2;
      PsiType[] components1 = tuple1.getComponentTypes();
      PsiType[] components2 = tuple2.getComponentTypes();

      if (components1.length == 0) return genNewListBy(type2, manager);
      if (components2.length == 0) return genNewListBy(type1, manager);

      PsiType[] components3 = new PsiType[Math.min(components1.length, components2.length)];
      for (int i = 0; i < components3.length; i++) {
        PsiType c1 = components1[i];
        PsiType c2 = components2[i];
        if (c1 == null || c2 == null) {
          components3[i] = null;
        } else {
          components3[i] = getLeastUpperBound(c1, c2, manager);
        }
      }
      return new GrTupleType(
          components3,
          JavaPsiFacade.getInstance(manager.getProject()),
          tuple1.getScope().intersectWith(tuple2.getResolveScope()));
    } else if (checkEmptyListAndList(type1, type2)) {
      return genNewListBy(type2, manager);
    } else if (checkEmptyListAndList(type2, type1)) {
      return genNewListBy(type1, manager);
    } else if (type1 instanceof GrMapType && type2 instanceof GrMapType) {
      return GrMapType.merge(((GrMapType) type1), ((GrMapType) type2));
    } else if (checkEmptyMapAndMap(type1, type2)) {
      return genNewMapBy(type2, manager);
    } else if (checkEmptyMapAndMap(type2, type1)) {
      return genNewMapBy(type1, manager);
    } else if (type1 instanceof GrClosureType && type2 instanceof GrClosureType) {
      GrClosureType clType1 = (GrClosureType) type1;
      GrClosureType clType2 = (GrClosureType) type2;
      GrSignature signature1 = clType1.getSignature();
      GrSignature signature2 = clType2.getSignature();

      if (signature1 instanceof GrClosureSignature && signature2 instanceof GrClosureSignature) {
        if (((GrClosureSignature) signature1).getParameterCount()
            == ((GrClosureSignature) signature2).getParameterCount()) {
          final GrClosureSignature signature =
              GrClosureSignatureImpl.getLeastUpperBound(
                  ((GrClosureSignature) signature1), ((GrClosureSignature) signature2), manager);
          if (signature != null) {
            GlobalSearchScope scope =
                clType1.getResolveScope().intersectWith(clType2.getResolveScope());
            final LanguageLevel languageLevel =
                ComparatorUtil.max(clType1.getLanguageLevel(), clType2.getLanguageLevel());
            return GrClosureType.create(
                signature,
                scope,
                JavaPsiFacade.getInstance(manager.getProject()),
                languageLevel,
                true);
          }
        }
      }
    } else if (GroovyCommonClassNames.GROOVY_LANG_GSTRING.equals(type1.getCanonicalText())
        && CommonClassNames.JAVA_LANG_STRING.equals(type2.getInternalCanonicalText())) {
      return type2;
    } else if (GroovyCommonClassNames.GROOVY_LANG_GSTRING.equals(type2.getCanonicalText())
        && CommonClassNames.JAVA_LANG_STRING.equals(type1.getInternalCanonicalText())) {
      return type1;
    }
    final PsiType result = getLeastUpperBoundForNumericType(type1, type2);
    if (result != null) return result;
    return GenericsUtil.getLeastUpperBound(type1, type2, manager);
  }
  private void buildText(
      @NotNull PsiClass aClass,
      @NotNull PsiSubstitutor substitutor,
      @NotNull StringBuilder buffer,
      boolean canonical,
      boolean internal) {
    if (aClass instanceof PsiAnonymousClass) {
      ClassResolveResult baseResolveResult =
          ((PsiAnonymousClass) aClass).getBaseClassType().resolveGenerics();
      PsiClass baseClass = baseResolveResult.getElement();
      PsiSubstitutor baseSub = baseResolveResult.getSubstitutor();
      if (baseClass != null) {
        buildText(baseClass, baseSub, buffer, canonical, internal);
      }
      return;
    }

    if (canonical == internal) {
      buffer.append(getAnnotationsTextPrefix(internal, false, true));
    }

    PsiClass enclosingClass = null;
    if (!aClass.hasModifierProperty(PsiModifier.STATIC)) {
      final PsiElement parent = aClass.getParent();
      if (parent instanceof PsiClass && !(parent instanceof PsiAnonymousClass)) {
        enclosingClass = (PsiClass) parent;
      }
    }
    if (enclosingClass != null) {
      buildText(enclosingClass, substitutor, buffer, canonical, false);
      buffer.append('.');
      buffer.append(aClass.getName());
    } else {
      final String name;
      if (!canonical) {
        name = aClass.getName();
      } else {
        final String qualifiedName = aClass.getQualifiedName();
        if (qualifiedName == null) {
          name = aClass.getName();
        } else {
          name = qualifiedName;
        }
      }
      buffer.append(name);
    }

    PsiTypeParameter[] typeParameters = aClass.getTypeParameters();
    if (typeParameters.length > 0) {
      StringBuilder pineBuffer = new StringBuilder();
      pineBuffer.append('<');
      for (int i = 0; i < typeParameters.length; i++) {
        PsiTypeParameter typeParameter = typeParameters[i];
        assert typeParameter.isValid();
        if (i > 0) pineBuffer.append(',');
        final PsiType substitutionResult = substitutor.substitute(typeParameter);
        if (substitutionResult == null) {
          pineBuffer = null;
          break;
        }
        assert substitutionResult.isValid();
        if (canonical) {
          if (internal) {
            pineBuffer.append(substitutionResult.getInternalCanonicalText());
          } else {
            pineBuffer.append(substitutionResult.getCanonicalText());
          }
        } else {
          pineBuffer.append(substitutionResult.getPresentableText());
        }
      }
      if (pineBuffer != null) {
        buffer.append(pineBuffer);
        buffer.append('>');
      }
    }
  }
예제 #4
0
 public static boolean isFromExternalTypeLanguage(@NotNull PsiType type) {
   String internalCanonicalText = type.getInternalCanonicalText();
   return internalCanonicalText != null && internalCanonicalText.equals(type.getCanonicalText());
 }