@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); final PsiModifierListOwner psiElement = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class); if (psiElement != null) { RefJavaElement refElement = (RefJavaElement) (myManager != null ? myManager.getReference(psiElement) : null); try { if (psiElement instanceof PsiVariable) { ((PsiVariable) psiElement).normalizeDeclaration(); } final PsiModifierList modifierList = psiElement.getModifierList(); LOG.assertTrue(modifierList != null); modifierList.setModifierProperty(PsiModifier.FINAL, true); modifierList.setModifierProperty(PsiModifier.VOLATILE, false); } catch (IncorrectOperationException e) { LOG.error(e); } if (refElement != null) { RefJavaUtil.getInstance().setIsFinal(refElement, true); } } }
@Nullable @PsiModifier.ModifierConstant public String getPossibleAccess(@Nullable RefJavaElement refElement) { if (refElement == null) return null; String curAccess = refElement.getAccessModifier(); String weakestAccess = PsiModifier.PRIVATE; if (isTopLevelClass(refElement) || isCalledOnSubClasses(refElement)) { weakestAccess = PsiModifier.PACKAGE_LOCAL; } if (isAbstractMethod(refElement)) { weakestAccess = PsiModifier.PROTECTED; } if (curAccess == weakestAccess) return curAccess; while (true) { String weakerAccess = getWeakerAccess(curAccess, refElement); if (weakerAccess == null || RefJavaUtil.getInstance().compareAccess(weakerAccess, weakestAccess) < 0) break; if (isAccessible(refElement, weakerAccess)) { curAccess = weakerAccess; } else { break; } } return curAccess; }
private boolean isAccessibleFrom(RefElement from, RefJavaElement to, String accessModifier) { if (accessModifier == PsiModifier.PUBLIC) return true; final RefJavaUtil refUtil = RefJavaUtil.getInstance(); if (accessModifier == PsiModifier.PACKAGE_LOCAL) { return RefJavaUtil.getPackage(from) == RefJavaUtil.getPackage(to); } RefClass fromTopLevel = refUtil.getTopLevelClass(from); RefClass toTopLevel = refUtil.getTopLevelClass(to); RefClass fromOwner = refUtil.getOwnerClass(from); RefClass toOwner = refUtil.getOwnerClass(to); if (accessModifier == PsiModifier.PROTECTED) { if (SUGGEST_PRIVATE_FOR_INNERS) { return refUtil.isInheritor(fromTopLevel, toOwner) || fromOwner != null && refUtil.isInheritor(fromOwner, toTopLevel) || toOwner != null && refUtil.getOwnerClass(toOwner) == from; } return refUtil.isInheritor(fromTopLevel, toOwner); } if (accessModifier == PsiModifier.PRIVATE) { if (SUGGEST_PRIVATE_FOR_INNERS) { if (isInExtendsList(to, fromTopLevel.getElement().getExtendsList())) return false; if (isInExtendsList(to, fromTopLevel.getElement().getImplementsList())) return false; if (isInAnnotations(to, fromTopLevel)) return false; return fromTopLevel == toOwner || fromOwner == toTopLevel || toOwner != null && refUtil.getOwnerClass(toOwner) == from; } if (fromOwner != null && fromOwner.isStatic() && !to.isStatic() && refUtil.isInheritor(fromOwner, toOwner)) return false; if (fromTopLevel == toOwner) { if (from instanceof RefClass && to instanceof RefClass) { final PsiClass fromClass = ((RefClass) from).getElement(); LOG.assertTrue(fromClass != null); if (isInExtendsList(to, fromClass.getExtendsList())) return false; if (isInExtendsList(to, fromClass.getImplementsList())) return false; } return true; } } return false; }
private boolean isAccessible( RefJavaElement to, @PsiModifier.ModifierConstant String accessModifier) { for (RefElement refElement : to.getInReferences()) { if (!isAccessibleFrom(refElement, to, accessModifier)) return false; } if (to instanceof RefMethod) { RefMethod refMethod = (RefMethod) to; if (refMethod.isAbstract() && (refMethod.getDerivedMethods().isEmpty() || refMethod.getAccessModifier() == PsiModifier.PRIVATE)) return false; for (RefMethod refOverride : refMethod.getDerivedMethods()) { if (!isAccessibleFrom(refOverride, to, accessModifier)) return false; } for (RefMethod refSuper : refMethod.getSuperMethods()) { if (RefJavaUtil.getInstance().compareAccess(refSuper.getAccessModifier(), accessModifier) > 0) return false; } } if (to instanceof RefClass) { RefClass refClass = (RefClass) to; for (RefClass subClass : refClass.getSubClasses()) { if (!isAccessibleFrom(subClass, to, accessModifier)) return false; } List children = refClass.getChildren(); if (children != null) { for (Object refElement : children) { if (!isAccessible((RefJavaElement) refElement, accessModifier)) return false; } } for (final RefElement refElement : refClass.getInTypeReferences()) { if (!isAccessibleFrom(refElement, refClass, accessModifier)) return false; } List<RefJavaElement> classExporters = ((RefClassImpl) refClass).getClassExporters(); if (classExporters != null) { for (RefJavaElement refExporter : classExporters) { if (getAccessLevel(accessModifier) < getAccessLevel(refExporter.getAccessModifier())) return false; } } } return true; }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { if (!FileModificationService.getInstance() .preparePsiElementForWrite(descriptor.getPsiElement())) return; final PsiModifierListOwner element = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiModifierListOwner.class); if (element != null) { RefElement refElement = null; if (myManager != null) { refElement = myManager.getReference(element); } try { if (element instanceof PsiVariable) { ((PsiVariable) element).normalizeDeclaration(); } PsiModifierList list = element.getModifierList(); LOG.assertTrue(list != null); if (element instanceof PsiMethod) { PsiMethod psiMethod = (PsiMethod) element; PsiClass containingClass = psiMethod.getContainingClass(); if (containingClass != null && containingClass.getParent() instanceof PsiFile && myHint == PsiModifier.PRIVATE && list.hasModifierProperty(PsiModifier.FINAL)) { list.setModifierProperty(PsiModifier.FINAL, false); } } list.setModifierProperty(myHint, true); if (refElement instanceof RefJavaElement) { RefJavaUtil.getInstance().setAccessModifier((RefJavaElement) refElement, myHint); } } catch (IncorrectOperationException e) { LOG.error(e); } } }
private static boolean isTopLevelClass(RefElement refElement) { return refElement instanceof RefClass && RefJavaUtil.getInstance().getTopLevelClass(refElement) == refElement; }