blob: 6cb4504bb960ce045ec046fb71cc29e932c994f5 [file] [log] [blame]
package com.jetbrains.python.refactoring.classes;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
/**
* Searches for element in another element's usages.
* Parametrize it with needle and make stack to accept it.
*
* @author Ilya.Kazakevich
*/
class DependencyVisitor extends PyRecursiveElementVisitor {
@NotNull
private final PyElement myElementToFind;
private boolean myDependencyFound;
/**
* @param elementToFind what to find
*/
DependencyVisitor(@NotNull final PyElement elementToFind) {
myElementToFind = elementToFind;
}
@Override
public void visitPyCallExpression(@NotNull final PyCallExpression node) {
final PyExpression callee = node.getCallee();
if (callee != null) {
final PsiReference calleeReference = callee.getReference();
if ((calleeReference != null) && calleeReference.isReferenceTo(myElementToFind)) {
myDependencyFound = true;
return;
}
final String calleeName = callee.getName();
final String name = myElementToFind.getName();
if ((calleeName != null) && calleeName.equals(name)) { // Check by name also
myDependencyFound = true;
}
// Member could be used as method param
final PyArgumentList list = node.getArgumentList();
if (list != null) {
for (final PyExpression expression : node.getArgumentList().getArgumentExpressions()) {
final PsiReference reference = expression.getReference();
if ((reference != null) && reference.isReferenceTo(myElementToFind)) {
myDependencyFound = true;
}
if ((name != null) && name.equals(expression.getName())) {
myDependencyFound = true;
}
}
}
}
}
@Override
public void visitPyReferenceExpression(final PyReferenceExpression node) {
final PsiPolyVariantReference reference = node.getReference();
if (reference.isReferenceTo(myElementToFind)) {
myDependencyFound = true;
return;
}
// TODO: This step is member-type specific. Move to MemberManagers?
if (myElementToFind instanceof PyAssignmentStatement) {
final PyExpression[] targets = ((PyAssignmentStatement)myElementToFind).getTargets();
if (targets.length != 1) {
return;
}
final PyExpression expression = targets[0];
if (reference.isReferenceTo(expression)) {
myDependencyFound = true;
return;
}
if (node.getText().equals(expression.getText())) { // Check by name also
myDependencyFound = true;
}
return;
}
final PsiElement declaration = reference.resolve();
myDependencyFound = PsiTreeUtil.findFirstParent(declaration, new PsiElementCondition()) != null;
}
public boolean isDependencyFound() {
return myDependencyFound;
}
private class PsiElementCondition implements Condition<PsiElement> {
@Override
public boolean value(final PsiElement psiElement) {
return psiElement.equals(myElementToFind);
}
}
}