diff --git a/python/psi-api/src/com/jetbrains/python/nameResolver/NameResolverTools.java b/python/psi-api/src/com/jetbrains/python/nameResolver/NameResolverTools.java index 336d87d8885f..a8929fd440fa 100644 --- a/python/psi-api/src/com/jetbrains/python/nameResolver/NameResolverTools.java +++ b/python/psi-api/src/com/jetbrains/python/nameResolver/NameResolverTools.java @@ -2,11 +2,15 @@ package com.jetbrains.python.nameResolver; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; -import com.intellij.util.ArrayUtil; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyQualifiedNameOwner; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + /** * @author Ilya.Kazakevich */ @@ -18,11 +22,11 @@ public final class NameResolverTools { /** * Checks if FQ element name is one of provided names * - * @param element element to check - * @param namesProvider some enum that has one or more 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 namesProvider) { + public static boolean isName(@NotNull final PyElement element, @NotNull final FQNamesProvider... namesProviders) { PyElement elementToCheck = element; final PsiReference reference = element.getReference(); if (reference != null) { @@ -33,8 +37,22 @@ public final class NameResolverTools { } if (elementToCheck instanceof PyQualifiedNameOwner) { final String qualifiedName = ((PyQualifiedNameOwner)elementToCheck).getQualifiedName(); - return ArrayUtil.contains(qualifiedName, namesProvider.getNames()); + return getNames(namesProviders).contains(qualifiedName); } return false; } + + /** + * Returns set of names all providers provide + * @param providers providers to check + * @return set of names + */ + @NotNull + private static Collection getNames(@NotNull final FQNamesProvider... providers) { + final Set result = new HashSet(); + for (final FQNamesProvider provider : providers) { + result.addAll(Arrays.asList(provider.getNames())); + } + return result; + } } diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java b/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java index 7867f3c8128d..07dcc0fbfbb5 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java @@ -115,10 +115,10 @@ public interface PyCallExpression extends PyExpression { /** * Checks if the qualified name of the callee matches any of the specified names provided by provider. * @see com.jetbrains.python.nameResolver - * @param name provider that provides one or more names to check + * @param name providers that provides one or more names to check * @return true if matches, false otherwise */ - boolean isCallee(@NotNull FQNamesProvider name); + boolean isCallee(@NotNull FQNamesProvider... name); /** * Couples function with a flag describing the way it is called. diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java index 0560e3f2ac8b..a626310beef4 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java @@ -47,7 +47,8 @@ public class PyCallExpressionHelper { /** * TODO: Copy/Paste with {@link com.jetbrains.python.psi.PyArgumentList#addArgument(com.jetbrains.python.psi.PyExpression)} * Adds an argument to the end of argument list. - * @param us the arg list + * + * @param us the arg list * @param expression what to add */ public static void addArgument(PyCallExpression us, PyExpression expression) { @@ -60,7 +61,7 @@ public class PyCallExpressionHelper { * Tries to interpret a call as a call to built-in {@code classmethod} or {@code staticmethod}. * * @param redefiningCall the possible call, generally a result of chasing a chain of assignments - * @param us any in-project PSI element, used to determine SDK and ultimately builtins module used to check the wrapping functions + * @param us any in-project PSI element, used to determine SDK and ultimately builtins module used to check the wrapping functions * @return a pair of wrapper name and wrapped function; for {@code staticmethod(foo)} it would be ("staticmethod", foo). */ @Nullable @@ -117,8 +118,8 @@ public class PyCallExpressionHelper { return (PyClass)resolved; } else if (resolved instanceof PyFunction) { - final PyFunction pyFunction = (PyFunction) resolved; - return pyFunction.getContainingClass(); + final PyFunction pyFunction = (PyFunction)resolved; + return pyFunction.getContainingClass(); } return null; @@ -148,11 +149,11 @@ public class PyCallExpressionHelper { } } if (resolved instanceof Callable) { - return (Callable) resolved; + return (Callable)resolved; } return null; } - + @Nullable public static PyCallExpression.PyMarkedCallee resolveCallee(PyCallExpression us, PyResolveContext resolveContext) { @@ -211,19 +212,19 @@ public class PyCallExpressionHelper { } if (resolved instanceof Callable) { PyFunction.Modifier modifier = resolved instanceof PyFunction - ? ((PyFunction)resolved).getModifier() - : null; + ? ((PyFunction)resolved).getModifier() + : null; if (modifier == null && wrappedModifier != null) { modifier = wrappedModifier; } boolean isByInstance = isConstructorCall || isQualifiedByInstance((Callable)resolved, qualifiers, context) || resolved instanceof PyBoundFunction; - PyExpression lastQualifier = qualifiers != null && qualifiers.isEmpty() ? null : qualifiers.get(qualifiers.size()-1); + PyExpression lastQualifier = qualifiers != null && qualifiers.isEmpty() ? null : qualifiers.get(qualifiers.size() - 1); boolean isByClass = lastQualifier == null ? false : isQualifiedByClass((Callable)resolved, lastQualifier, context); final Callable callable = (Callable)resolved; implicitOffset += getImplicitArgumentCount(callable, modifier, isConstructorCall, isByInstance, isByClass); - implicitOffset = implicitOffset < 0? 0: implicitOffset; // wrong source can trigger strange behaviour + implicitOffset = implicitOffset < 0 ? 0 : implicitOffset; // wrong source can trigger strange behaviour return new PyCallExpression.PyMarkedCallee(callable, modifier, implicitOffset, resolveResult != null ? resolveResult.isImplicit() : false); } @@ -256,11 +257,11 @@ public class PyCallExpressionHelper { /** * Finds how many arguments are implicit in a given call. * - * @param callable resolved method which is being called; non-methods immediately return 0. - * @param flags set of flags for the call - * @param isByInstance true if the call is known to be by instance (not by class). + * @param callable resolved method which is being called; non-methods immediately return 0. + * @param flags set of flags for the call + * @param isByInstance true if the call is known to be by instance (not by class). * @return a non-negative number of parameters that are implicit to this call. E.g. for a typical method call 1 is returned - * because one parameter ('self') is implicit. + * because one parameter ('self') is implicit. */ private static int getImplicitArgumentCount( Callable callable, @@ -451,7 +452,7 @@ public class PyCallExpressionHelper { } final PyType providedType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(target, context, call); if (providedType instanceof PyCallableType) { - return ((PyCallableType) providedType).getCallType(context, (PyReferenceExpression)callee); + return ((PyCallableType)providedType).getCallType(context, (PyReferenceExpression)callee); } if (target instanceof Callable) { final Callable callable = (Callable)target; @@ -571,13 +572,14 @@ public class PyCallExpressionHelper { /** * Checks if expression callee's name matches one of names, provided by appropriate {@link com.jetbrains.python.nameResolver.FQNamesProvider} - * @see com.jetbrains.python.nameResolver - * @param expression call expression - * @param namesProvider name provider to check name against + * + * @param expression call expression + * @param namesProviders name providers to check name against * @return true if matches + * @see com.jetbrains.python.nameResolver */ - public static boolean isCallee(@NotNull final PyCallExpression expression, @NotNull final FQNamesProvider namesProvider) { + public static boolean isCallee(@NotNull final PyCallExpression expression, @NotNull final FQNamesProvider... namesProviders) { final PyExpression callee = expression.getCallee(); - return (callee != null) && NameResolverTools.isName(callee, namesProvider); + return (callee != null) && NameResolverTools.isName(callee, namesProviders); } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java index e02dbd0f8aad..63e8a71c5741 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java @@ -100,7 +100,7 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress } @Override - public boolean isCallee(@NotNull final FQNamesProvider name) { + public boolean isCallee(@NotNull final FQNamesProvider... name) { return PyCallExpressionHelper.isCallee(this, name); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java index 4553c95dc406..9be3850ed2b3 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java @@ -160,7 +160,7 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase im } @Override - public boolean isCallee(@NotNull final FQNamesProvider name) { + public boolean isCallee(@NotNull final FQNamesProvider... name) { return PyCallExpressionHelper.isCallee(this, name); }