private static boolean cyclicDependencies( PsiClass aClass, PsiType type, @NotNull Set<PsiClass> checked, @NotNull PsiManager manager) { final PsiClass resolvedClass = PsiUtil.resolveClassInType(type); if (resolvedClass != null && resolvedClass.isAnnotationType()) { if (aClass == resolvedClass) { return true; } if (!checked.add(resolvedClass) || !manager.isInProject(resolvedClass)) return false; final PsiMethod[] methods = resolvedClass.getMethods(); for (PsiMethod method : methods) { if (cyclicDependencies(aClass, method.getReturnType(), checked, manager)) return true; } } return false; }
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!(file instanceof PsiJavaFile)) return false; if (myUnresolvedReference.isQualified()) return false; final String referenceName = myUnresolvedReference.getReferenceName(); if (referenceName == null) return false; PsiManager manager = file.getManager(); if (!myUnresolvedReference.isValid() || !manager.isInProject(myUnresolvedReference)) return false; PsiElement container = PsiTreeUtil.getParentOfType(myUnresolvedReference, PsiCodeBlock.class, PsiClass.class); if (!(container instanceof PsiCodeBlock)) return false; myOutOfScopeVariable = null; while (container.getParent() instanceof PsiStatement || container.getParent() instanceof PsiCatchSection) container = container.getParent(); container.accept( new JavaRecursiveElementWalkingVisitor() { @Override public void visitReferenceExpression(PsiReferenceExpression expression) {} @Override public void visitExpression(PsiExpression expression) { // Don't look inside expressions } @Override public void visitLocalVariable(PsiLocalVariable variable) { if (referenceName.equals(variable.getName())) { if (myOutOfScopeVariable == null) { myOutOfScopeVariable = variable; } else { myOutOfScopeVariable = null; // 2 conflict variables } } } }); return myOutOfScopeVariable != null; }