Fixed Jython resolve test for Java superclasses

This commit is contained in:
Andrey Vlasovskikh
2013-04-17 17:22:56 +04:00
parent 55e1379cb0
commit ebab3b5c1e
4 changed files with 45 additions and 33 deletions
@@ -15,6 +15,7 @@ import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
/**
@@ -101,6 +102,16 @@ public class PyJavaClassType implements PyClassLikeType {
return myClass.getQualifiedName();
}
@NotNull
@Override
public List<PyClassLikeType> getSuperClassTypes(@NotNull TypeEvalContext context) {
final List<PyClassLikeType> result = new ArrayList<PyClassLikeType>();
for (PsiClass cls : myClass.getSupers()) {
result.add(new PyJavaClassType(cls, myDefinition));
}
return result;
}
@Override
public boolean isValid() {
return myClass.isValid();
@@ -1,7 +1,10 @@
package com.jetbrains.python.psi.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author vlan
*/
@@ -13,5 +16,8 @@ public interface PyClassLikeType extends PyCallableType {
@Nullable
String getClassQName();
@NotNull
List<PyClassLikeType> getSuperClassTypes(@NotNull TypeEvalContext context);
boolean isValid();
}
@@ -1128,25 +1128,23 @@ public class PyClassImpl extends PyPresentableElementImpl<PyClassStub> implement
@Override
public List<PyClassLikeType> getAncestorTypes(@NotNull TypeEvalContext context) {
final List<PyClassLikeType> results = new ArrayList<PyClassLikeType>();
final List<PyClass> toProcess = new ArrayList<PyClass>();
final List<PyClassLikeType> toProcess = new ArrayList<PyClassLikeType>();
final Set<PyClassLikeType> seen = new HashSet<PyClassLikeType>();
final Set<PyClass> visited = new HashSet<PyClass>();
toProcess.add(this);
final Set<PyClassLikeType> visited = new HashSet<PyClassLikeType>();
final PyType thisType = context.getType(this);
if (thisType instanceof PyClassLikeType) {
toProcess.add((PyClassLikeType)thisType);
}
while (!toProcess.isEmpty()) {
final PyClass cls = toProcess.remove(0);
visited.add(cls);
final List<PyClassLikeType> types = cls.getSuperClassTypes(context);
for (PyClassLikeType type : types) {
if (type == null || !seen.contains(type)) {
results.add(type);
seen.add(type);
final PyClassLikeType currentType = toProcess.remove(0);
visited.add(currentType);
for (PyClassLikeType superType : currentType.getSuperClassTypes(context)) {
if (superType == null || !seen.contains(superType)) {
results.add(superType);
seen.add(superType);
}
if (type instanceof PyClassType) {
// TODO: process PyClassType instead of PyClass
final PyClass superClass = ((PyClassType)type).getPyClass();
if (!visited.contains(superClass)) {
toProcess.add(superClass);
}
if (superType != null && !visited.contains(superType)) {
toProcess.add(superType);
}
}
}
@@ -20,7 +20,6 @@ import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyTypeProvider;
import com.jetbrains.python.psi.impl.ResolveResultList;
import com.jetbrains.python.psi.resolve.*;
import com.jetbrains.python.psi.stubs.PyClassNameIndex;
@@ -93,6 +92,12 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
return myClass.getQualifiedName();
}
@NotNull
@Override
public List<PyClassLikeType> getSuperClassTypes(@NotNull TypeEvalContext context) {
return myClass.getSuperClassTypes(context);
}
@Nullable
public List<? extends RatedResolveResult> resolveMember(@NotNull final String name,
@Nullable PyExpression location,
@@ -165,28 +170,21 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
return ResolveResultList.to(classMember);
}
for (PyClassRef superClass : myClass.iterateAncestors()) {
final PyClass pyClass = superClass.getPyClass();
final PsiElement element = superClass.getElement();
final PyClassType type = superClass.getType();
if (pyClass != null) {
PsiElement superMember = resolveClassMember(pyClass, myIsDefinition, name, null);
for (PyClassLikeType type : myClass.getAncestorTypes(resolveContext.getTypeEvalContext())) {
if (type instanceof PyClassType) {
PsiElement superMember = resolveClassMember(((PyClassType)type).getPyClass(), myIsDefinition, name, null);
if (superMember != null) {
return ResolveResultList.to(superMember);
}
}
else if (element != null) {
for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
final PyType refType = typeProvider.getReferenceType(element, resolveContext.getTypeEvalContext(), myClass);
if (refType != null) {
return refType.resolveMember(name, location, direction, resolveContext);
}
if (type != null) {
final List<? extends RatedResolveResult> results = type.resolveMember(name, location, direction, resolveContext);
if (results != null && !results.isEmpty()) {
return results;
}
}
else if (type != null) {
return type.resolveMember(name, location, direction, resolveContext);
}
}
if (isDefinition() && myClass.isNewStyleClass()) {
PyClassType typeType = getMetaclassType();
if (typeType != null) {
@@ -214,7 +212,6 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
}
}
return Collections.emptyList();
}