public static boolean provablyDistinct(PsiWildcardType type1, PsiWildcardType type2) { if (type1.isSuper() && type2.isSuper()) return false; if (type1.isExtends() && type2.isExtends()) { final PsiType extendsBound1 = type1.getExtendsBound(); final PsiType extendsBound2 = type2.getExtendsBound(); if (extendsBound1 instanceof PsiArrayType && proveArrayTypeDistinct( type1.getManager().getProject(), (PsiArrayType) extendsBound1, extendsBound2) || extendsBound2 instanceof PsiArrayType && proveArrayTypeDistinct( type1.getManager().getProject(), (PsiArrayType) extendsBound2, extendsBound1)) return true; final PsiClass boundClass1 = PsiUtil.resolveClassInType(extendsBound1); final PsiClass boundClass2 = PsiUtil.resolveClassInType(extendsBound2); if (boundClass1 != null && boundClass2 != null) { return proveExtendsBoundsDistinct(type1, type2, boundClass1, boundClass2); } return provablyDistinct(extendsBound1, extendsBound2, 1); } if (type2.isExtends()) return provablyDistinct(type2, type1); if (type1.isExtends() && type2.isSuper()) { final PsiType extendsBound = type1.getExtendsBound(); final PsiType superBound = type2.getSuperBound(); if (extendsBound instanceof PsiArrayType && proveArrayTypeDistinct( type1.getManager().getProject(), (PsiArrayType) extendsBound, superBound) || superBound instanceof PsiArrayType && proveArrayTypeDistinct( type1.getManager().getProject(), (PsiArrayType) superBound, extendsBound)) return true; final PsiClass extendsBoundClass = PsiUtil.resolveClassInType(extendsBound); final PsiClass superBoundClass = PsiUtil.resolveClassInType(superBound); if (extendsBoundClass != null && superBoundClass != null) { if (extendsBoundClass instanceof PsiTypeParameter) { return try2ProveTypeParameterDistinct(type2, extendsBoundClass); } if (superBoundClass instanceof PsiTypeParameter) return false; return !InheritanceUtil.isInheritorOrSelf(superBoundClass, extendsBoundClass, true); } return true; } if (!type1.isBounded() || !type2.isBounded()) { return false; } return !type1.equals(type2); }
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); checkExistingMethods(conflicts, true); checkExistingMethods(conflicts, false); final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll(); for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { final Set<PsiMethod> setters = new HashSet<PsiMethod>(); final Set<PsiMethod> getters = new HashSet<PsiMethod>(); for (PsiClass aClass : classes) { final PsiMethod getterOverrider = myDescriptor.isToEncapsulateGet() ? aClass.findMethodBySignature(fieldDescriptor.getGetterPrototype(), false) : null; if (getterOverrider != null) { getters.add(getterOverrider); } final PsiMethod setterOverrider = myDescriptor.isToEncapsulateSet() ? aClass.findMethodBySignature(fieldDescriptor.getSetterPrototype(), false) : null; if (setterOverrider != null) { setters.add(setterOverrider); } } if (!getters.isEmpty() || !setters.isEmpty()) { final PsiField field = fieldDescriptor.getField(); for (PsiReference reference : ReferencesSearch.search(field)) { final PsiElement place = reference.getElement(); if (place instanceof PsiReferenceExpression) { final PsiExpression qualifierExpression = ((PsiReferenceExpression) place).getQualifierExpression(); final PsiClass ancestor; if (qualifierExpression == null) { ancestor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false); } else { ancestor = PsiUtil.resolveClassInType(qualifierExpression.getType()); } final boolean isGetter = !PsiUtil.isAccessedForWriting((PsiExpression) place); for (PsiMethod overridden : isGetter ? getters : setters) { if (InheritanceUtil.isInheritorOrSelf(myClass, ancestor, true)) { conflicts.putValue( overridden, "There is already a " + RefactoringUIUtil.getDescription(overridden, true) + " which would hide generated " + (isGetter ? "getter" : "setter") + " for " + place.getText()); break; } } } } } } return showConflicts(conflicts, refUsages.get()); }
private static boolean isCollectCall(PsiStatement body, final PsiParameter parameter) { PsiIfStatement ifStatement = extractIfStatement(body); final PsiMethodCallExpression methodCallExpression = extractAddCall(body, ifStatement); if (methodCallExpression != null) { final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); PsiClass qualifierClass = null; if (qualifierExpression instanceof PsiReferenceExpression) { if (ReferencesSearch.search(parameter, new LocalSearchScope(qualifierExpression)) .findFirst() != null) { return false; } final PsiElement resolve = ((PsiReferenceExpression) qualifierExpression).resolve(); if (resolve instanceof PsiVariable) { if (ReferencesSearch.search( resolve, new LocalSearchScope(methodCallExpression.getArgumentList())) .findFirst() != null) { return false; } } qualifierClass = PsiUtil.resolveClassInType(qualifierExpression.getType()); } else if (qualifierExpression == null) { final PsiClass enclosingClass = PsiTreeUtil.getParentOfType(body, PsiClass.class); if (PsiUtil.getEnclosingStaticElement(body, enclosingClass) == null) { qualifierClass = enclosingClass; } } if (qualifierClass != null && InheritanceUtil.isInheritor( qualifierClass, false, CommonClassNames.JAVA_UTIL_COLLECTION)) { while (ifStatement != null && PsiTreeUtil.isAncestor(body, ifStatement, false)) { final PsiExpression condition = ifStatement.getCondition(); if (condition != null && isConditionDependsOnUpdatedCollections(condition, qualifierExpression)) return false; ifStatement = PsiTreeUtil.getParentOfType(ifStatement, PsiIfStatement.class); } final PsiElement resolve = methodExpression.resolve(); if (resolve instanceof PsiMethod && "add".equals(((PsiMethod) resolve).getName()) && ((PsiMethod) resolve).getParameterList().getParametersCount() == 1) { final PsiExpression[] args = methodCallExpression.getArgumentList().getExpressions(); if (args.length == 1) { if (args[0] instanceof PsiCallExpression) { final PsiMethod method = ((PsiCallExpression) args[0]).resolveMethod(); return method != null && !method.hasTypeParameters() && !isThrowsCompatible(method); } return true; } } } } return false; }
public static boolean dependsOnTypeParams( PsiType type, PsiType functionalInterfaceType, PsiElement lambdaExpression, PsiTypeParameter... param2Check) { return depends( type, new TypeParamsChecker( lambdaExpression, PsiUtil.resolveClassInType(functionalInterfaceType)), param2Check); }
public static PsiClass getProviderClass(final PsiElement element, final PsiClass topLevelClass) { final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(element, PsiAnnotation.class); if (annotation != null) { final PsiAnnotationMemberValue value = annotation.findDeclaredAttributeValue("dataProviderClass"); if (value instanceof PsiClassObjectAccessExpression) { final PsiTypeElement operand = ((PsiClassObjectAccessExpression) value).getOperand(); final PsiClass psiClass = PsiUtil.resolveClassInType(operand.getType()); if (psiClass != null) { return psiClass; } } } return topLevelClass; }
public static boolean hasAccessibleConstructor(PsiType type) { if (type instanceof PsiArrayType) return true; final PsiClass psiClass = PsiUtil.resolveClassInType(type); if (psiClass == null || psiClass.isEnum() || psiClass.isAnnotationType()) return false; if (!(psiClass instanceof PsiCompiledElement)) return true; final PsiMethod[] methods = psiClass.getConstructors(); if (methods.length == 0) return true; for (final PsiMethod method : methods) { if (!method.hasModifierProperty(PsiModifier.PRIVATE)) return true; } return false; }
@Nullable static List<MethodSignature> findFunctionCandidates(PsiClass psiClass) { if (psiClass instanceof PsiAnonymousClass) { psiClass = PsiUtil.resolveClassInType(((PsiAnonymousClass) psiClass).getBaseClassType()); } if (psiClass != null && psiClass.isInterface()) { final List<MethodSignature> methods = new ArrayList<MethodSignature>(); final Collection<HierarchicalMethodSignature> visibleSignatures = psiClass.getVisibleSignatures(); for (HierarchicalMethodSignature signature : visibleSignatures) { final PsiMethod psiMethod = signature.getMethod(); if (!psiMethod.hasModifierProperty(PsiModifier.ABSTRACT)) continue; if (psiMethod.hasModifierProperty(PsiModifier.STATIC)) continue; if (!overridesPublicObjectMethod(psiMethod)) { methods.add(signature); } } return hasSubsignature(methods); } return null; }
@SuppressWarnings("HardCodedStringLiteral") public static boolean isSimplePropertySetter(PsiMethod method) { if (method == null) return false; if (method.isConstructor()) return false; String methodName = method.getName(); if (!(methodName.startsWith("set") && methodName.length() > "set".length())) return false; if (Character.isLowerCase(methodName.charAt("set".length()))) return false; if (method.getParameterList().getParametersCount() != 1) { return false; } final PsiType returnType = method.getReturnType(); if (returnType == null || PsiType.VOID.equals(returnType)) { return true; } return Comparing.equal(PsiUtil.resolveClassInType(returnType), method.getContainingClass()); }
@NotNull public static PsiSubstitutor inferFromReturnType( @NotNull PsiTypeParameter[] typeParameters, final PsiType returnType, @Nullable final PsiType interfaceMethodReturnType, @NotNull PsiSubstitutor psiSubstitutor, final LanguageLevel languageLevel, final Project project) { if (interfaceMethodReturnType == null) return psiSubstitutor; final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper(); final PsiSubstitutor substitutor = resolveHelper.inferTypeArguments( typeParameters, new PsiType[] {interfaceMethodReturnType}, new PsiType[] {returnType}, languageLevel); for (PsiTypeParameter typeParameter : typeParameters) { final PsiType inferredType = substitutor.substitute(typeParameter); if (PsiUtil.resolveClassInType(inferredType) != typeParameter) { psiSubstitutor = psiSubstitutor.put(typeParameter, inferredType); } } return psiSubstitutor; }
private void checkExistingMethods(MultiMap<PsiElement, String> conflicts, boolean isGetter) { if (isGetter) { if (!myDescriptor.isToEncapsulateGet()) return; } else { if (!myDescriptor.isToEncapsulateSet()) return; } for (FieldDescriptor descriptor : myFieldDescriptors) { PsiMethod prototype = isGetter ? descriptor.getGetterPrototype() : descriptor.getSetterPrototype(); final PsiType prototypeReturnType = prototype.getReturnType(); PsiMethod existing = myClass.findMethodBySignature(prototype, true); if (existing != null) { final PsiType returnType = existing.getReturnType(); if (!RefactoringUtil.equivalentTypes( prototypeReturnType, returnType, myClass.getManager())) { final String descr = PsiFormatUtil.formatMethod( existing, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS | PsiFormatUtilBase.SHOW_TYPE, PsiFormatUtilBase.SHOW_TYPE); String message = isGetter ? RefactoringBundle.message( "encapsulate.fields.getter.exists", CommonRefactoringUtil.htmlEmphasize(descr), CommonRefactoringUtil.htmlEmphasize(prototype.getName())) : RefactoringBundle.message( "encapsulate.fields.setter.exists", CommonRefactoringUtil.htmlEmphasize(descr), CommonRefactoringUtil.htmlEmphasize(prototype.getName())); conflicts.putValue(existing, message); } } else { PsiClass containingClass = myClass.getContainingClass(); while (containingClass != null && existing == null) { existing = containingClass.findMethodBySignature(prototype, true); if (existing != null) { for (PsiReference reference : ReferencesSearch.search(existing)) { final PsiElement place = reference.getElement(); LOG.assertTrue(place instanceof PsiReferenceExpression); final PsiExpression qualifierExpression = ((PsiReferenceExpression) place).getQualifierExpression(); final PsiClass inheritor; if (qualifierExpression == null) { inheritor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false); } else { inheritor = PsiUtil.resolveClassInType(qualifierExpression.getType()); } if (InheritanceUtil.isInheritorOrSelf(inheritor, myClass, true)) { conflicts.putValue( existing, "There is already a " + RefactoringUIUtil.getDescription(existing, true) + " which would be hidden by generated " + (isGetter ? "getter" : "setter")); break; } } } containingClass = containingClass.getContainingClass(); } } } }
private static boolean provablyDistinct(PsiType type1, PsiType type2, int level) { if (type1 instanceof PsiClassType && ((PsiClassType) type1).resolve() instanceof PsiTypeParameter) return false; if (type2 instanceof PsiClassType && ((PsiClassType) type2).resolve() instanceof PsiTypeParameter) return false; if (type1 instanceof PsiWildcardType) { if (type2 instanceof PsiWildcardType) { return provablyDistinct((PsiWildcardType) type1, (PsiWildcardType) type2); } if (type2 instanceof PsiCapturedWildcardType) { return ((PsiWildcardType) type1).isExtends() && level > 0 || provablyDistinct( (PsiWildcardType) type1, ((PsiCapturedWildcardType) type2).getWildcard()); } if (type2 instanceof PsiClassType) { final PsiClass psiClass2 = PsiUtil.resolveClassInType(type2); if (psiClass2 == null) return false; if (((PsiWildcardType) type1).isExtends()) { final PsiType extendsBound = ((PsiWildcardType) type1).getExtendsBound(); if (extendsBound instanceof PsiArrayType && proveArrayTypeDistinct( ((PsiWildcardType) type1).getManager().getProject(), (PsiArrayType) extendsBound, type2)) return true; final PsiClass boundClass1 = PsiUtil.resolveClassInType(extendsBound); if (boundClass1 == null) return false; return proveExtendsBoundsDistinct(type1, type2, boundClass1, psiClass2); } if (((PsiWildcardType) type1).isSuper()) { final PsiType superBound = ((PsiWildcardType) type1).getSuperBound(); if (superBound instanceof PsiArrayType && proveArrayTypeDistinct( ((PsiWildcardType) type1).getManager().getProject(), (PsiArrayType) superBound, type2)) return true; final PsiClass boundClass1 = PsiUtil.resolveClassInType(superBound); if (boundClass1 == null || boundClass1 instanceof PsiTypeParameter) return false; return !InheritanceUtil.isInheritorOrSelf(boundClass1, psiClass2, true); } final PsiType bound = ((PsiWildcardType) type1).getBound(); return bound != null && !bound.equals(psiClass2); } if (type2 instanceof PsiArrayType) { return proveArrayTypeDistinct( ((PsiWildcardType) type1).getManager().getProject(), (PsiArrayType) type2, type1); } } if (type1 instanceof PsiCapturedWildcardType) return provablyDistinct(((PsiCapturedWildcardType) type1).getWildcard(), type2, level); if (type2 instanceof PsiWildcardType || type2 instanceof PsiCapturedWildcardType) return provablyDistinct(type2, type1, level); final PsiClassType.ClassResolveResult classResolveResult1 = PsiUtil.resolveGenericsClassInType(type1); final PsiClassType.ClassResolveResult classResolveResult2 = PsiUtil.resolveGenericsClassInType(type2); if (Comparing.equal(TypeConversionUtil.erasure(type1), TypeConversionUtil.erasure(type2))) { final PsiSubstitutor substitutor1 = classResolveResult1.getSubstitutor(); final PsiSubstitutor substitutor2 = classResolveResult2.getSubstitutor(); for (PsiTypeParameter parameter : substitutor1.getSubstitutionMap().keySet()) { final PsiType substitutedType1 = substitutor1.substitute(parameter); final PsiType substitutedType2 = substitutor2.substitute(parameter); if (substitutedType1 == null && substitutedType2 == null) return false; if (substitutedType1 == null || substitutedType2 == null) { return true; } else { if (provablyDistinct(substitutedType1, substitutedType2, level + 1)) return true; if (substitutedType1 instanceof PsiWildcardType && !((PsiWildcardType) substitutedType1).isBounded()) return true; } } return false; } final PsiClass boundClass1 = classResolveResult1.getElement(); final PsiClass boundClass2 = classResolveResult2.getElement(); return type2 != null && type1 != null && !type1.equals(type2) && (!InheritanceUtil.isInheritorOrSelf(boundClass1, boundClass2, true) || !InheritanceUtil.isInheritorOrSelf(boundClass2, boundClass1, true)); }