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('>'); } } }
@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('>'); } } }
public static boolean isFromExternalTypeLanguage(@NotNull PsiType type) { String internalCanonicalText = type.getInternalCanonicalText(); return internalCanonicalText != null && internalCanonicalText.equals(type.getCanonicalText()); }