blob: 7fad93339ad6c668e81b0092d1d486da983d289e [file] [log] [blame]
package com.jetbrains.python.nameResolver;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* @author Ilya.Kazakevich
*/
public final class NameResolverTools {
private NameResolverTools() {
}
/**
* For each provided element checks if FQ element name is one of provided names
*
* @param elements element to check
* @param namesProviders some enum that has one or more names
* @return true if element's fqn is one of names, provided by provider
*/
public static boolean isElementWithName(@NotNull final Collection<? extends PyElement> elements,
@NotNull final FQNamesProvider... namesProviders) {
for (final PyElement element : elements) {
if (isName(element, namesProviders)) {
return true;
}
}
return false;
}
/**
* Checks if FQ element name is one of provided names
*
* @param element element to check
* @param namesProviders some enum that has one or more names
* @return true if element's fqn is one of names, provided by provider
*/
public static boolean isName(@NotNull final PyElement element, @NotNull final FQNamesProvider... namesProviders) {
PyElement elementToCheck = element;
final PsiReference reference = element.getReference();
if (reference != null) {
final PsiElement resolvedElement = reference.resolve();
if (resolvedElement instanceof PyElement) {
elementToCheck = (PyElement)resolvedElement;
}
}
String qualifiedName = null;
if (elementToCheck instanceof PyQualifiedNameOwner) {
qualifiedName = ((PyQualifiedNameOwner)elementToCheck).getQualifiedName();
}
String className = null;
if (elementToCheck instanceof PyFunction) {
final PyClass aClass = ((PyFunction)elementToCheck).getContainingClass();
if (aClass != null) {
className = aClass.getQualifiedName();
}
}
for (final FQNamesProvider provider : namesProviders) {
final List<String> names = Arrays.asList(provider.getNames());
if (qualifiedName != null && names.contains(qualifiedName)) {
return true;
}
if (className != null && provider.isClass() && names.contains(className)) {
return true;
}
}
return false;
}
/**
* Looks for parent call of certain function
* @param anchor element to look parent for
* @param functionName function to find
* @return parent call or null if not found
*/
@Nullable
public static PyCallExpression findCallExpParent(@NotNull final PsiElement anchor, @NotNull final FQNamesProvider functionName) {
final PsiElement parent = PsiTreeUtil.findFirstParent(anchor, new MyFunctionCondition(functionName));
if (parent instanceof PyCallExpression) {
return (PyCallExpression)parent;
}
return null;
}
/**
* Looks for call of some function
*/
private static class MyFunctionCondition implements Condition<PsiElement> {
@NotNull
private final FQNamesProvider myNameToSearch;
MyFunctionCondition(@NotNull final FQNamesProvider name) {
myNameToSearch = name;
}
@Override
public boolean value(final PsiElement element) {
if (element instanceof PyCallExpression) {
return ((PyCallExpression)element).isCallee(myNameToSearch);
}
return false;
}
}
}