public void removeEntryPoint(RefElement anEntryPoint) { if (anEntryPoint instanceof RefClass) { RefClass refClass = (RefClass) anEntryPoint; if (!refClass.isInterface()) { anEntryPoint = refClass.getDefaultConstructor(); } } if (anEntryPoint == null) return; myTemporaryEntryPoints.remove(anEntryPoint); Set<Map.Entry<String, SmartRefElementPointer>> set = myPersistentEntryPoints.entrySet(); String key = null; for (Map.Entry<String, SmartRefElementPointer> entry : set) { SmartRefElementPointer value = entry.getValue(); if (value.getRefElement() == anEntryPoint) { key = entry.getKey(); break; } } if (key != null) { myPersistentEntryPoints.remove(key); ((RefElementImpl) anEntryPoint).setEntry(false); } if (anEntryPoint.isPermanentEntry() && anEntryPoint.isValid()) { final Project project = anEntryPoint.getElement().getProject(); final EntryPointsManagerImpl entryPointsManager = getInstance(project); if (this != entryPointsManager) { entryPointsManager.removeEntryPoint(anEntryPoint); } } }
@Override public void addEntryPoint(@NotNull RefElement newEntryPoint, boolean isPersistent) { if (!newEntryPoint.isValid()) return; if (isPersistent) { if (newEntryPoint instanceof RefMethod && ((RefMethod) newEntryPoint).isConstructor() || newEntryPoint instanceof RefClass) { final ClassPattern classPattern = new ClassPattern(); classPattern.pattern = new SmartRefElementPointerImpl(newEntryPoint, true).getFQName(); getPatterns().add(classPattern); final EntryPointsManager entryPointsManager = getInstance(newEntryPoint.getElement().getProject()); if (this != entryPointsManager) { entryPointsManager.addEntryPoint(newEntryPoint, true); } return; } } if (newEntryPoint instanceof RefClass) { RefClass refClass = (RefClass) newEntryPoint; if (refClass.isAnonymous()) { // Anonymous class cannot be an entry point. return; } List<RefMethod> refConstructors = refClass.getConstructors(); if (refConstructors.size() == 1) { addEntryPoint(refConstructors.get(0), isPersistent); } else if (refConstructors.size() > 1) { // Many constructors here. Need to ask user which ones are used for (RefMethod refConstructor : refConstructors) { addEntryPoint(refConstructor, isPersistent); } } } if (!isPersistent) { myTemporaryEntryPoints.add(newEntryPoint); ((RefElementImpl) newEntryPoint).setEntry(true); } else { if (myPersistentEntryPoints.get(newEntryPoint.getExternalName()) == null) { final SmartRefElementPointerImpl entry = new SmartRefElementPointerImpl(newEntryPoint, true); myPersistentEntryPoints.put(entry.getFQName(), entry); ((RefElementImpl) newEntryPoint).setEntry(true); ((RefElementImpl) newEntryPoint).setPermanentEntry(true); if (entry.isPersistent()) { // do save entry points final EntryPointsManager entryPointsManager = getInstance(newEntryPoint.getElement().getProject()); if (this != entryPointsManager) { entryPointsManager.addEntryPoint(newEntryPoint, true); } } } } }
public void appendClassExtendsImplements(StringBuffer buf, RefClass refClass) { if (refClass.getBaseClasses().size() > 0) { HTMLComposerImpl.appendHeading( buf, InspectionsBundle.message("inspection.export.results.extends.implements")); myComposer.startList(buf); for (RefClass refBase : refClass.getBaseClasses()) { myComposer.appendListItem(buf, refBase); } myComposer.doneList(buf); } }
public void appendLibraryMethods(StringBuffer buf, RefClass refClass) { if (refClass.getLibraryMethods().size() > 0) { HTMLComposerImpl.appendHeading( buf, InspectionsBundle.message("inspection.export.results.overrides.library.methods")); myComposer.startList(buf); for (RefMethod refMethod : refClass.getLibraryMethods()) { myComposer.appendListItem(buf, refMethod); } myComposer.doneList(buf); } }
public void appendTypeReferences(StringBuffer buf, RefClass refClass) { if (refClass.getInTypeReferences().size() > 0) { HTMLComposer.appendHeading( buf, InspectionsBundle.message("inspection.export.results.type.references")); myComposer.startList(buf); for (final RefElement refElement : refClass.getInTypeReferences()) { myComposer.appendListItem(buf, refElement); } myComposer.doneList(buf); } }
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 @Nullable public CommonProblemDescriptor[] checkElement( @NotNull final RefEntity refEntity, @NotNull final AnalysisScope scope, @NotNull final InspectionManager manager, @NotNull final GlobalInspectionContext globalContext, @NotNull final ProblemDescriptionsProcessor processor) { if (refEntity instanceof RefJavaElement) { final RefJavaElement refElement = (RefJavaElement) refEntity; if (refElement instanceof RefParameter) return null; if (!refElement.isReferenced()) return null; if (refElement.isSyntheticJSP()) return null; if (refElement.isFinal()) return null; if (!((RefElementImpl) refElement).checkFlag(CanBeFinalAnnotator.CAN_BE_FINAL_MASK)) return null; final PsiMember psiMember = (PsiMember) refElement.getElement(); if (psiMember == null || !CanBeFinalHandler.allowToBeFinal(psiMember)) return null; PsiIdentifier psiIdentifier = null; if (refElement instanceof RefClass) { RefClass refClass = (RefClass) refElement; if (refClass.isInterface() || refClass.isAnonymous() || refClass.isAbstract()) return null; if (!isReportClasses()) return null; psiIdentifier = ((PsiClass) psiMember).getNameIdentifier(); } else if (refElement instanceof RefMethod) { RefMethod refMethod = (RefMethod) refElement; if (refMethod.getOwnerClass().isFinal()) return null; if (!isReportMethods()) return null; psiIdentifier = ((PsiMethod) psiMember).getNameIdentifier(); } else if (refElement instanceof RefField) { if (!isReportFields()) return null; psiIdentifier = ((PsiField) psiMember).getNameIdentifier(); } if (psiIdentifier != null) { return new ProblemDescriptor[] { manager.createProblemDescriptor( psiIdentifier, InspectionsBundle.message("inspection.export.results.can.be.final.description"), new AcceptSuggested(globalContext.getRefManager()), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false) }; } } return null; }
public static String getClassOrInterface(RefClass refClass, boolean capitalizeFirstLetter) { if (refClass.isInterface()) { return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.interface") : InspectionsBundle.message("inspection.export.results.interface"); } else if (refClass.isAbstract()) { return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.abstract.class") : InspectionsBundle.message("inspection.export.results.abstract.class"); } else { return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.class") : InspectionsBundle.message("inspection.export.results.class"); } }
@Nullable private CommonProblemDescriptor[] checkElement( RefClass refEntity, InspectionManager manager, final Project project) { final PsiClass psiClass = refEntity.getElement(); if (psiClass == null) return null; return checkElement(psiClass, manager, project); }
public void appendDerivedClasses(StringBuffer buf, RefClass refClass) { if (refClass.getSubClasses().size() > 0) { if (refClass.isInterface()) { HTMLComposerImpl.appendHeading( buf, InspectionsBundle.message("inspection.export.results.extended.implemented")); } else { HTMLComposerImpl.appendHeading( buf, InspectionsBundle.message("inspection.export.results.extended")); } myComposer.startList(buf); for (RefClass refDerived : refClass.getSubClasses()) { myComposer.appendListItem(buf, refDerived); } myComposer.doneList(buf); } }
private static void ignoreElement( @NotNull ProblemDescriptionsProcessor processor, @NotNull RefEntity refElement) { processor.ignoreElement(refElement); if (refElement instanceof RefClass) { RefClass refClass = (RefClass) refElement; RefMethod defaultConstructor = refClass.getDefaultConstructor(); if (defaultConstructor != null) { processor.ignoreElement(defaultConstructor); return; } } RefEntity owner = refElement.getOwner(); if (owner instanceof RefElement) { processor.ignoreElement(owner); } }
public void appendClassOrInterface( StringBuffer buf, RefClass refClass, boolean capitalizeFirstLetter) { if (refClass.isInterface()) { buf.append( capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.interface") : InspectionsBundle.message("inspection.export.results.interface")); } else if (refClass.isAbstract()) { buf.append( capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.abstract.class") : InspectionsBundle.message("inspection.export.results.abstract.class")); } else { buf.append( capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.class") : InspectionsBundle.message("inspection.export.results.class")); } }
@Override public void removeEntryPoint(@NotNull RefElement anEntryPoint) { myTemporaryEntryPoints.remove(anEntryPoint); Set<Map.Entry<String, SmartRefElementPointer>> set = myPersistentEntryPoints.entrySet(); String key = null; for (Map.Entry<String, SmartRefElementPointer> entry : set) { SmartRefElementPointer value = entry.getValue(); if (value.getRefElement() == anEntryPoint) { key = entry.getKey(); break; } } if (key != null) { myPersistentEntryPoints.remove(key); } ((RefElementImpl) anEntryPoint).setEntry(false); if (anEntryPoint.isPermanentEntry() && anEntryPoint.isValid()) { final Project project = anEntryPoint.getElement().getProject(); final EntryPointsManager entryPointsManager = getInstance(project); if (this != entryPointsManager) { entryPointsManager.removeEntryPoint(anEntryPoint); } } if (anEntryPoint instanceof RefMethod && ((RefMethod) anEntryPoint).isConstructor() || anEntryPoint instanceof RefClass) { final RefClass aClass = anEntryPoint instanceof RefClass ? (RefClass) anEntryPoint : ((RefMethod) anEntryPoint).getOwnerClass(); final String qualifiedName = aClass.getQualifiedName(); for (Iterator<ClassPattern> iterator = getPatterns().iterator(); iterator.hasNext(); ) { if (Comparing.equal(iterator.next().pattern, qualifiedName)) { // todo if inheritance or pattern? iterator.remove(); } } } }
@Override public void onInitialize(RefElement refElement) { ((RefElementImpl) refElement).setFlag(true, CAN_BE_FINAL_MASK); if (refElement instanceof RefClass) { final RefClass refClass = (RefClass) refElement; final PsiClass psiClass = refClass.getElement(); if (refClass.isEntry()) { ((RefClassImpl) refClass).setFlag(false, CAN_BE_FINAL_MASK); return; } if (refClass.isAbstract() || refClass.isAnonymous() || refClass.isInterface()) { ((RefClassImpl) refClass).setFlag(false, CAN_BE_FINAL_MASK); return; } if (!refClass.isSelfInheritor(psiClass)) { for (PsiClass psiSuperClass : psiClass.getSupers()) { if (myManager.belongsToScope(psiSuperClass)) { RefClass refSuperClass = (RefClass) myManager.getReference(psiSuperClass); if (refSuperClass != null) { ((RefClassImpl) refSuperClass).setFlag(false, CAN_BE_FINAL_MASK); } } } } } else if (refElement instanceof RefMethod) { final RefMethod refMethod = (RefMethod) refElement; final PsiElement element = refMethod.getElement(); if (element instanceof PsiMethod) { PsiMethod psiMethod = (PsiMethod) element; if (refMethod.isConstructor() || refMethod.isAbstract() || refMethod.isStatic() || PsiModifier.PRIVATE.equals(refMethod.getAccessModifier()) || refMethod.getOwnerClass().isAnonymous() || refMethod.getOwnerClass().isInterface()) { ((RefMethodImpl) refMethod).setFlag(false, CAN_BE_FINAL_MASK); } if (PsiModifier.PRIVATE.equals(refMethod.getAccessModifier()) && refMethod.getOwner() != null && !(refMethod.getOwnerClass().getOwner() instanceof RefElement)) { ((RefMethodImpl) refMethod).setFlag(false, CAN_BE_FINAL_MASK); } for (PsiMethod psiSuperMethod : psiMethod.findSuperMethods()) { if (myManager.belongsToScope(psiSuperMethod)) { RefMethod refSuperMethod = (RefMethod) myManager.getReference(psiSuperMethod); if (refSuperMethod != null) { ((RefMethodImpl) refSuperMethod).setFlag(false, CAN_BE_FINAL_MASK); } } } } } }
private static boolean isInAnnotations(final RefJavaElement to, final RefClass fromTopLevel) { final PsiModifierList modifierList = fromTopLevel.getElement().getModifierList(); if (modifierList == null) return false; final PsiElement toElement = to.getElement(); final boolean[] resolved = new boolean[] {false}; modifierList.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression expression) { if (resolved[0]) return; super.visitReferenceExpression(expression); if (expression.resolve() == toElement) { resolved[0] = true; } } }); return resolved[0]; }
@Override @Nullable public CommonProblemDescriptor[] checkElement( @NotNull final RefEntity refEntity, @NotNull final AnalysisScope scope, @NotNull final InspectionManager manager, @NotNull final GlobalInspectionContext globalContext, @NotNull final ProblemDescriptionsProcessor processor) { if (refEntity instanceof RefJavaElement) { final RefJavaElement refElement = (RefJavaElement) refEntity; if (refElement instanceof RefParameter) return null; if (refElement.isSyntheticJSP()) return null; // ignore entry points. if (refElement.isEntry()) return null; // ignore implicit constructors. User should not be able to see them. if (refElement instanceof RefImplicitConstructor) return null; if (refElement instanceof RefField && ((RefField) refElement).getElement() instanceof PsiEnumConstant) return null; // ignore library override methods. if (refElement instanceof RefMethod) { RefMethod refMethod = (RefMethod) refElement; if (refMethod.isExternalOverride()) return null; if (refMethod.isEntry()) return null; } // ignore anonymous classes. They do not have access modifiers. if (refElement instanceof RefClass) { RefClass refClass = (RefClass) refElement; if (refClass.isAnonymous() || refClass.isEntry() || refClass.isTestCase() || refClass.isServlet() || refClass.isApplet() || refClass.isLocalClass()) return null; if (isTopLevelClass(refClass) && !SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES) return null; } // ignore unreferenced code. They could be a potential entry points. if (refElement.getInReferences().isEmpty()) return null; // ignore interface members. They always have public access modifier. if (refElement.getOwner() instanceof RefClass) { RefClass refClass = (RefClass) refElement.getOwner(); if (refClass.isInterface()) return null; } String access = getPossibleAccess(refElement); if (access != refElement.getAccessModifier() && access != null) { final PsiElement element = refElement.getElement(); final PsiElement nameIdentifier = element != null ? HighlightUsagesHandler.getNameIdentifier(element) : null; if (nameIdentifier != null) { return new ProblemDescriptor[] { manager.createProblemDescriptor( nameIdentifier, access.equals(PsiModifier.PRIVATE) ? CAN_BE_PRIVATE : access.equals(PsiModifier.PACKAGE_LOCAL) ? CAN_BE_PACKAGE_LOCAL : CAN_BE_PROTECTED, new AcceptSuggestedAccess(globalContext.getRefManager(), access), ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false) }; } } } return null; }