mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Completion for classes with non-class expressions in their base class list (PY-4345)
This commit is contained in:
@@ -11,6 +11,7 @@ import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.psi.PsiElement;
|
||||
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;
|
||||
@@ -369,16 +370,33 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
|
||||
Set<String> namesAlready,
|
||||
ProcessingContext context,
|
||||
List<Object> ret) {
|
||||
for (PyClass ancestor : myClass.getSuperClasses()) {
|
||||
Object[] ancestry = (new PyClassTypeImpl(ancestor, myIsDefinition)).getCompletionVariants(name, expressionHook, context);
|
||||
for (Object ob : ancestry) {
|
||||
String inheritedName = ob.toString();
|
||||
if (!namesAlready.contains(inheritedName) && !isClassPrivate(inheritedName)) {
|
||||
ret.add(ob);
|
||||
namesAlready.add(inheritedName);
|
||||
for (PyExpression expression : myClass.getSuperClassExpressions()) {
|
||||
final PsiReference reference = expression.getReference();
|
||||
PsiElement element = null;
|
||||
if (reference != null) {
|
||||
element = reference.resolve();
|
||||
}
|
||||
PyType type;
|
||||
if (element instanceof PyClass) {
|
||||
type = new PyClassTypeImpl((PyClass)element, myIsDefinition);
|
||||
}
|
||||
else {
|
||||
type = expression.getType(TypeEvalContext.fastStubOnly(myClass.getContainingFile()));
|
||||
if (type instanceof PyClassType && !myIsDefinition) {
|
||||
type = ((PyClassType)type).toInstance();
|
||||
}
|
||||
}
|
||||
ContainerUtil.addAll(ret, ancestry);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
class C(namedtuple('Coord', 'latitude longitude')):
|
||||
def foo(self):
|
||||
return -1
|
||||
|
||||
|
||||
c = C()
|
||||
c.latitude
|
||||
@@ -0,0 +1,10 @@
|
||||
from collections import namedtuple
|
||||
|
||||
|
||||
class C(namedtuple('Coord', 'latitude longitude')):
|
||||
def foo(self):
|
||||
return -1
|
||||
|
||||
|
||||
c = C()
|
||||
c.lat<caret>
|
||||
@@ -33,6 +33,10 @@ public class Py3CompletionTest extends PyTestCase {
|
||||
assertTrue(strings.contains("long"));
|
||||
}
|
||||
|
||||
public void testNamedTupleBaseClass() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
CamelHumpMatcher.forceStartMatching(getTestRootDisposable());
|
||||
final String testName = "completion/" + getTestName(true);
|
||||
|
||||
Reference in New Issue
Block a user