// TODO: Pull to PyType at next iteration
/**
* Visits all class members. This method is better then bare class since it uses type info and supports not only classes but
- * class-like structures as well. Consider using user-friendly wrapper {@link PyClassLikeTypeUtil#getMembersOfType(PyClassLikeType, Class, TypeEvalContext)}
+ * class-like structures as well. Consider using user-friendly wrapper {@link PyTypeUtil#getMembersOfType(PyClassLikeType, Class, TypeEvalContext)}
*
* @param processor visitor
* @param inherited call on parents too
* @param context context to be used to resolve types
- * @see PyClassLikeTypeUtil#getMembersOfType(PyClassLikeType, Class, TypeEvalContext)
+ * @see PyTypeUtil#getMembersOfType(PyClassLikeType, Class, TypeEvalContext)
*/
void visitMembers(@NotNull Processor<PsiElement> processor, boolean inherited, @NotNull TypeEvalContext context);
import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
final PyUnionType unionType = PyUtil.as(context.getType(callee), PyUnionType.class);
if (unionType != null) {
- fetchCallablesFromUnion(ret, callExpr, unionType);
+ fetchCallablesFromUnion(ret, callExpr, unionType, context);
}
}
}
private static void fetchCallablesFromUnion(@NotNull final List<LookupElement> ret,
@NotNull final PyCallExpression callExpr,
- @NotNull final PyUnionType unionType) {
+ @NotNull final PyUnionType unionType,
+ @NotNull final TypeEvalContext context) {
for (final PyType memberType : unionType.getMembers()) {
if (memberType instanceof PyUnionType) {
- fetchCallablesFromUnion(ret, callExpr, (PyUnionType)memberType);
+ fetchCallablesFromUnion(ret, callExpr, (PyUnionType)memberType, context);
}
if (memberType instanceof PyFunctionType) {
final PyFunctionType type = (PyFunctionType)memberType;
addKeywordArgumentVariants(type.getCallable(), callExpr, ret);
}
}
+ if (memberType instanceof PyCallableType) {
+ final List<PyCallableParameter> callableParameters = ((PyCallableType)memberType).getParameters(context);
+ if (callableParameters != null) {
+ fetchCallablesFromCallableType(ret, callExpr, callableParameters);
+ }
+ }
}
}
+ private static void fetchCallablesFromCallableType(@NotNull final List<LookupElement> ret,
+ @NotNull final PyCallExpression callExpr,
+ @NotNull final Iterable<PyCallableParameter> callableParameters) {
+ final List<String> parameterNames = new ArrayList<String>();
+ for (final PyCallableParameter callableParameter : callableParameters) {
+ final String name = callableParameter.getName();
+ if (name != null) {
+ parameterNames.add(name);
+ }
+ }
+ addKeywordArgumentVariantsForCallable(callExpr, ret, parameterNames);
+ }
+
public static void addKeywordArgumentVariants(PyCallable callable, PyCallExpression callExpr, final List<LookupElement> ret) {
addKeywordArgumentVariants(callable, callExpr, ret, new HashSet<PyCallable>());
}
visited.add(callable);
final TypeEvalContext context = TypeEvalContext.codeCompletion(callable.getProject(), callable.getContainingFile());
+
final List<PyParameter> parameters = PyUtil.getParameters(callable, context);
+ for (final PyParameter parameter : parameters) {
+ parameter.getName();
+ }
+
if (callable instanceof PyFunction) {
addKeywordArgumentVariantsForFunction(callExpr, ret, visited, (PyFunction)callable, parameters, context);
}
else {
- addKeywordArgumentVariantsForCallable(callExpr, ret, parameters);
+ final Collection<String> parameterNames = new ArrayList<String>();
+ for (final PyParameter parameter : parameters) {
+ final String name = parameter.getName();
+ if (name != null) {
+ parameterNames.add(name);
+ }
+ }
+ addKeywordArgumentVariantsForCallable(callExpr, ret, parameterNames);
}
}
private static void addKeywordArgumentVariantsForCallable(@NotNull final PyCallExpression callExpr,
@NotNull final List<LookupElement> ret,
- @NotNull final List<PyParameter> parameters) {
- for (final PyParameter parameter : parameters) {
- final String name = parameter.getName();
- if (name != null && parameter.getAsNamed() != null) {
- ret.add(PyUtil.createNamedParameterLookup(name, callExpr.getProject()));
- }
+ @NotNull final Collection<String> parameterNames) {
+ for (final String parameterName : parameterNames) {
+ ret.add(PyUtil.createNamedParameterLookup(parameterName, callExpr.getProject()));
}
}
import com.intellij.util.QueryExecutor;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyClassLikeType;
-import com.jetbrains.python.psi.types.PyClassLikeTypeUtil;
+import com.jetbrains.python.psi.types.PyTypeUtil;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
// If super method still not found and we have context, we may use it to find method
final PyClassLikeType classLikeType = PyUtil.as(context.getType(superClass), PyClassLikeType.class);
if (classLikeType != null) {
- for (PyFunction function : PyClassLikeTypeUtil.getMembersOfType(classLikeType, PyFunction.class, context)) {
+ for (final PyFunction function : PyTypeUtil.getMembersOfType(classLikeType, PyFunction.class, context)) {
final String elemName = function.getName();
if (elemName != null && elemName.equals(func.getName())) {
consumer.process(function);
*/
package com.jetbrains.python.psi.types;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolder;
import com.intellij.psi.PsiElement;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
- * Tools and wrappers around {@link PyClassLikeType}
+ * Tools and wrappers around {@link PyType} inheritors
*
* @author Ilya.Kazakevich
*/
-public final class PyClassLikeTypeUtil {
- private PyClassLikeTypeUtil() {
+public final class PyTypeUtil {
+ private PyTypeUtil() {
}
/**
}, true, context);
return result;
}
+
+
+ // TODO: DOC
+ @Nullable
+ public static <T> T findData(@NotNull final PyType type, @NotNull final Key<T> key) {
+ if (type instanceof UserDataHolder) {
+ return ((UserDataHolder)type).getUserData(key);
+ }
+ if (type instanceof PyUnionType) {
+ for (final PyType memberType : ((PyUnionType)type).getMembers()) {
+ if (memberType == null) {
+ continue;
+ }
+ final T result = findData(memberType, key);
+ if (result != null) {
+ return result;
+ }
+ }
+ }
+ return null;
+ }
}