mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
support members completion for classes inherited with six.with_metaclass
* Instead of low-level expression parsing, we use type-based api.
This commit is contained in:
@@ -28,7 +28,6 @@ import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiInvalidElementAccessException;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
@@ -594,33 +593,25 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
|
||||
ProcessingContext context,
|
||||
List<Object> ret,
|
||||
@NotNull TypeEvalContext typeEvalContext) {
|
||||
for (PyExpression expression : myClass.getSuperClassExpressions()) {
|
||||
final PsiReference reference = expression.getReference();
|
||||
PsiElement element = null;
|
||||
if (reference != null) {
|
||||
element = reference.resolve();
|
||||
for (PyType type : myClass.getSuperClassTypes(typeEvalContext)) {
|
||||
if (!(type instanceof PyClassLikeType)) {
|
||||
continue;
|
||||
}
|
||||
PyType type;
|
||||
if (element instanceof PyClass) {
|
||||
type = new PyClassTypeImpl((PyClass)element, myIsDefinition);
|
||||
|
||||
final PyClassLikeType classLikeType = (PyClassLikeType)type;
|
||||
if (classLikeType.isDefinition() && !myIsDefinition) {
|
||||
type = classLikeType.toInstance();
|
||||
}
|
||||
else {
|
||||
type = typeEvalContext.getType(expression);
|
||||
if (type instanceof PyClassType && !myIsDefinition) {
|
||||
type = ((PyClassType)type).toInstance();
|
||||
|
||||
Object[] ancestry = type.getCompletionVariants(name, expressionHook, context);
|
||||
for (Object ob : ancestry) {
|
||||
String inheritedName = ob.toString();
|
||||
if (!namesAlready.contains(inheritedName) && !isClassPrivate(inheritedName)) {
|
||||
ret.add(ob);
|
||||
namesAlready.add(inheritedName);
|
||||
}
|
||||
}
|
||||
if (type != null) {
|
||||
Object[] ancestry = type.getCompletionVariants(name, expressionHook, context);
|
||||
for (Object ob : ancestry) {
|
||||
String inheritedName = ob.toString();
|
||||
if (!namesAlready.contains(inheritedName) && !isClassPrivate(inheritedName)) {
|
||||
ret.add(ob);
|
||||
namesAlready.add(inheritedName);
|
||||
}
|
||||
}
|
||||
ContainerUtil.addAll(ret, ancestry);
|
||||
}
|
||||
ContainerUtil.addAll(ret, ancestry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import six
|
||||
|
||||
class MyType(type):
|
||||
pass
|
||||
|
||||
class Parent(object):
|
||||
def parent(self):
|
||||
pass
|
||||
|
||||
|
||||
class Child(six.with_metaclass(MyType, Parent)):
|
||||
pass
|
||||
|
||||
|
||||
Child().parent()
|
||||
@@ -0,0 +1,15 @@
|
||||
import six
|
||||
|
||||
class MyType(type):
|
||||
pass
|
||||
|
||||
class Parent(object):
|
||||
def parent(self):
|
||||
pass
|
||||
|
||||
|
||||
class Child(six.with_metaclass(MyType, Parent)):
|
||||
pass
|
||||
|
||||
|
||||
Child().paren<caret>
|
||||
@@ -178,6 +178,10 @@ public class PythonCompletionTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testPySixTest() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSeenMembers() { // PY-1181
|
||||
final String testName = getTestName(true);
|
||||
myFixture.configureByFile(testName + ".py");
|
||||
|
||||
Reference in New Issue
Block a user