public String toString() { @NonNls StringBuilder buffer = new StringBuilder(); final Set<Map.Entry<PsiTypeParameter, PsiType>> set = mySubstitutionMap.entrySet(); for (Map.Entry<PsiTypeParameter, PsiType> entry : set) { final PsiTypeParameter typeParameter = entry.getKey(); buffer.append(typeParameter.getName()); final PsiElement owner = typeParameter.getOwner(); if (owner instanceof PsiClass) { buffer.append(" of "); buffer.append(((PsiClass) owner).getQualifiedName()); } else if (owner instanceof PsiMethod) { buffer.append(" of "); buffer.append(((PsiMethod) owner).getName()); buffer.append(" in "); buffer.append(((PsiMethod) owner).getContainingClass().getQualifiedName()); } buffer.append(" -> "); if (entry.getValue() != null) { buffer.append(entry.getValue().getCanonicalText()); } else { buffer.append("null"); } buffer.append('\n'); } return buffer.toString(); }
private PsiType rawTypeForTypeParameter(final PsiTypeParameter typeParameter) { final PsiClassType[] extendsTypes = typeParameter.getExtendsListTypes(); if (extendsTypes.length > 0) { // First bound return substitute(extendsTypes[0]); } else { // Object return PsiType.getJavaLangObject(typeParameter.getManager(), typeParameter.getResolveScope()); } }
private static void findTypeParameterExternalUsages( final PsiTypeParameter typeParameter, final Collection<UsageInfo> usages) { PsiTypeParameterListOwner owner = typeParameter.getOwner(); if (owner != null) { final PsiTypeParameterList parameterList = owner.getTypeParameterList(); if (parameterList != null) { final int paramsCount = parameterList.getTypeParameters().length; final int index = parameterList.getTypeParameterIndex(typeParameter); ReferencesSearch.search(owner) .forEach( reference -> { if (reference instanceof PsiJavaCodeReferenceElement) { final PsiReferenceParameterList parameterList1 = ((PsiJavaCodeReferenceElement) reference).getParameterList(); if (parameterList1 != null) { PsiTypeElement[] typeArgs = parameterList1.getTypeParameterElements(); if (typeArgs.length > index) { if (typeArgs.length == 1 && paramsCount > 1 && typeArgs[0].getType() instanceof PsiDiamondType) return true; usages.add( new SafeDeleteReferenceJavaDeleteUsageInfo( typeArgs[index], typeParameter, true)); } } } return true; }); } } }
@Override public PsiType substitute(@NotNull PsiTypeParameter typeParameter) { if (containsInMap(typeParameter)) { return getFromMap(typeParameter); } return JavaPsiFacade.getInstance(typeParameter.getProject()) .getElementFactory() .createType(typeParameter); }
private boolean check(PsiTypeParameter check) { final PsiTypeParameterListOwner owner = check.getOwner(); if (owner == myMethod) { return true; } else if (owner == myClass) { return true; } return false; }
private void buildDelegate() { final PsiManager manager = sourceClass.getManager(); final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); final CodeStyleManager codeStyleManager = CodeStyleManager.getInstance(manager.getProject()); @NonNls final StringBuilder fieldBuffer = new StringBuilder(); final String delegateVisibility = calculateDelegateVisibility(); if (delegateVisibility.length() > 0) fieldBuffer.append(delegateVisibility).append(' '); fieldBuffer.append("final "); final String fullyQualifiedName = getQualifiedName(); fieldBuffer.append(fullyQualifiedName); if (!typeParams.isEmpty()) { fieldBuffer.append('<'); for (PsiTypeParameter typeParameter : typeParams) { fieldBuffer.append(typeParameter.getName()); } fieldBuffer.append('>'); } fieldBuffer.append(' '); fieldBuffer.append(delegateFieldName); fieldBuffer.append(" = new ").append(fullyQualifiedName); if (!typeParams.isEmpty()) { fieldBuffer.append('<'); for (PsiTypeParameter typeParameter : typeParams) { fieldBuffer.append(typeParameter.getName()); } fieldBuffer.append('>'); } fieldBuffer.append('('); if (requiresBackpointer) { fieldBuffer.append("this"); } fieldBuffer.append(");"); try { final String fieldString = fieldBuffer.toString(); final PsiField field = factory.createFieldFromText(fieldString, sourceClass); final PsiElement newField = sourceClass.add(field); codeStyleManager.reformat( JavaCodeStyleManager.getInstance(myProject).shortenClassReferences(newField)); } catch (IncorrectOperationException e) { logger.error(e); } }
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; }
public static PsiSubstitutor substituteByParameterName( final PsiClass psiClass, final PsiSubstitutor parentSubstitutor) { final Map<PsiTypeParameter, PsiType> substitutionMap = parentSubstitutor.getSubstitutionMap(); final List<PsiType> result = new ArrayList<PsiType>(substitutionMap.size()); for (PsiTypeParameter typeParameter : psiClass.getTypeParameters()) { final String name = typeParameter.getName(); final PsiTypeParameter key = ContainerUtil.find( substitutionMap.keySet(), new Condition<PsiTypeParameter>() { @Override public boolean value(final PsiTypeParameter psiTypeParameter) { return name.equals(psiTypeParameter.getName()); } }); if (key != null) { result.add(substitutionMap.get(key)); } } return PsiSubstitutor.EMPTY.putAll( psiClass, result.toArray(PsiType.createArray(result.size()))); }
public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) { if (aClass == another) return true; if (!(another instanceof PsiClass)) return false; String name1 = aClass.getName(); if (name1 == null) return false; if (!another.isValid()) return false; String name2 = ((PsiClass) another).getName(); if (name2 == null) return false; if (name1.hashCode() != name2.hashCode()) return false; if (!name1.equals(name2)) return false; String qName1 = aClass.getQualifiedName(); String qName2 = ((PsiClass) another).getQualifiedName(); if (qName1 == null || qName2 == null) { //noinspection StringEquality if (qName1 != qName2) return false; if (aClass instanceof PsiTypeParameter && another instanceof PsiTypeParameter) { PsiTypeParameter p1 = (PsiTypeParameter) aClass; PsiTypeParameter p2 = (PsiTypeParameter) another; return p1.getIndex() == p2.getIndex() && aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner()); } else { return false; } } if (qName1.hashCode() != qName2.hashCode() || !qName1.equals(qName2)) { return false; } if (originalElement(aClass).equals(originalElement((PsiClass) another))) { return true; } final PsiFile file1 = aClass.getContainingFile().getOriginalFile(); final PsiFile file2 = another.getContainingFile().getOriginalFile(); // see com.intellij.openapi.vcs.changes.PsiChangeTracker // see com.intellij.psi.impl.PsiFileFactoryImpl#createFileFromText(CharSequence,PsiFile) final PsiFile original1 = file1.getUserData(PsiFileFactory.ORIGINAL_FILE); final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE); if (original1 == original2 && original1 != null || original1 == file2 || original2 == file1 || file1 == file2) { return compareClassSeqNumber(aClass, (PsiClass) another); } final FileIndexFacade fileIndex = ServiceManager.getService(file1.getProject(), FileIndexFacade.class); final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile(); final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile(); boolean lib1 = fileIndex.isInLibraryClasses(vfile1); boolean lib2 = fileIndex.isInLibraryClasses(vfile2); return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2); }
@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()]); }
@Override public boolean equals(PsiTypeParameter element1, PsiTypeParameter element2) { return element1.getManager().areElementsEquivalent(element1, element2); }
@Override public int computeHashCode(PsiTypeParameter object) { String name = object.getName(); return name == null ? 0 : name.hashCode(); }