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:
Ilya.Kazakevich
2016-01-27 23:53:25 +03:00
parent 6ce5184d93
commit a07a56298f
4 changed files with 49 additions and 24 deletions
@@ -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()
+15
View File
@@ -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");