private PsiType rawTypeForTypeParameter(final PsiTypeParameter typeParameter) { final PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); if (extendsTypes.length > 0) { // First bound return substitute(extendsTypes[0]); } // Object return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()); }
@NotNull public static PsiClass[] getInterfaces(@NotNull PsiTypeParameter typeParameter) { final PsiClassType[] referencedTypes = typeParameter.getExtendsListTypes(); if (referencedTypes.length == 0) { return PsiClass.EMPTY_ARRAY; } final List<PsiClass> result = new ArrayList<PsiClass>(referencedTypes.length); for (PsiClassType referencedType : referencedTypes) { final PsiClass psiClass = referencedType.resolve(); if (psiClass != null && psiClass.isInterface()) { result.add(psiClass); } } return result.toArray(new PsiClass[result.size()]); }
private PsiType addBounds(PsiType substituted, final PsiTypeParameter typeParameter) { PsiElement captureContext = null; if (substituted instanceof PsiCapturedWildcardType) { final PsiCapturedWildcardType captured = (PsiCapturedWildcardType) substituted; substituted = captured.getWildcard(); captureContext = captured.getContext(); } if (substituted instanceof PsiWildcardType && !((PsiWildcardType) substituted).isSuper()) { PsiType originalBound = ((PsiWildcardType) substituted).getBound(); PsiManager manager = typeParameter.getManager(); final PsiType[] boundTypes = typeParameter.getExtendsListTypes(); for (PsiType boundType : boundTypes) { PsiType substitutedBoundType = boundType.accept(mySimpleSubstitutionVisitor); PsiWildcardType wildcardType = (PsiWildcardType) substituted; if (substitutedBoundType != null && !(substitutedBoundType instanceof PsiWildcardType) && !substitutedBoundType.equalsToText("java.lang.Object")) { if (originalBound == null || (!TypeConversionUtil.erasure(substitutedBoundType) .isAssignableFrom(TypeConversionUtil.erasure(originalBound)) && !TypeConversionUtil.erasure(substitutedBoundType) .isAssignableFrom( originalBound))) { // erasure is essential to avoid infinite recursion if (wildcardType.isExtends()) { final PsiType glb = GenericsUtil.getGreatestLowerBound(wildcardType.getBound(), substitutedBoundType); if (glb != null) { substituted = PsiWildcardType.createExtends(manager, glb); } } else { // unbounded substituted = PsiWildcardType.createExtends(manager, substitutedBoundType); } } } } } if (captureContext != null) { LOG.assertTrue(substituted instanceof PsiWildcardType); substituted = PsiCapturedWildcardType.create((PsiWildcardType) substituted, captureContext); } return substituted; }
public static Pair<PsiTypeParameter, PsiType> findTypeParameterWithBoundError( final PsiTypeParameter[] typeParams, final PsiSubstitutor substitutor, final PsiElement context, final boolean allowUncheckedConversion) { nextTypeParam: for (PsiTypeParameter typeParameter : typeParams) { PsiType substituted = substitutor.substitute(typeParameter); if (substituted == null) return null; substituted = PsiUtil.captureToplevelWildcards(substituted, context); PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); for (PsiClassType type : extendsTypes) { PsiType extendsType = substitutor.substitute(type); if (substituted instanceof PsiWildcardType) { if (((PsiWildcardType) substituted).isSuper()) { continue; } final PsiType extendsBound = ((PsiWildcardType) substituted).getExtendsBound(); if (acceptExtendsBound(extendsType, extendsBound)) { continue nextTypeParam; } } else if (substituted instanceof PsiIntersectionType) { for (PsiType extendsBound : ((PsiIntersectionType) substituted).getConjuncts()) { if (acceptExtendsBound(extendsType, extendsBound)) continue nextTypeParam; } } else if (substituted instanceof PsiCapturedWildcardType) { final PsiType extendsBound = ((PsiCapturedWildcardType) substituted).getUpperBound(); if (acceptExtendsBound(extendsType, extendsBound)) { continue nextTypeParam; } } if (extendsType != null && !TypeConversionUtil.isAssignable( extendsType, substituted, allowUncheckedConversion)) { return Pair.create(typeParameter, extendsType); } } } return null; }
@SuppressWarnings({"HardCodedStringLiteral"}) private static String generateClassInfo(PsiClass aClass) { StringBuilder buffer = new StringBuilder(); GroovyFile file = (GroovyFile) aClass.getContainingFile(); String packageName = file.getPackageName(); if (packageName.length() > 0) { buffer.append(packageName).append("\n"); } final String classString = aClass.isInterface() ? "interface" : aClass instanceof PsiTypeParameter ? "type parameter" : aClass.isEnum() ? "enum" : "class"; buffer.append(classString).append(" ").append(aClass.getName()); if (aClass.hasTypeParameters()) { PsiTypeParameter[] typeParameters = aClass.getTypeParameters(); buffer.append("<"); for (int i = 0; i < typeParameters.length; i++) { if (i > 0) buffer.append(", "); PsiTypeParameter tp = typeParameters[i]; buffer.append(tp.getName()); PsiClassType[] refs = tp.getExtendsListTypes(); if (refs.length > 0) { buffer.append(" extends "); for (int j = 0; j < refs.length; j++) { if (j > 0) buffer.append(" & "); appendTypeString(buffer, refs[j], aClass); } } } buffer.append(">"); } PsiClassType[] refs = aClass.getExtendsListTypes(); if (refs.length > 0 || !aClass.isInterface() && !CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) { buffer.append(" extends "); if (refs.length == 0) { buffer.append("Object"); } else { for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i], aClass); } } } refs = aClass.getImplementsListTypes(); if (refs.length > 0) { buffer.append("\nimplements "); for (int i = 0; i < refs.length; i++) { if (i > 0) buffer.append(", "); appendTypeString(buffer, refs[i], aClass); } } return buffer.toString(); }