From 55e1379cb0f90b88f6be43372f30d0cf977b396c Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Wed, 17 Apr 2013 16:51:05 +0400 Subject: [PATCH] Added common ancestor PyClassLikeType of PyClassType and PyJavaClassType --- .../python/psi/impl/PyJavaClassType.java | 27 ++++++++-- .../src/com/jetbrains/python/psi/PyClass.java | 6 +-- .../python/psi/types/PyClassLikeType.java | 17 ++++++ .../python/psi/types/PyClassType.java | 12 +---- .../python/psi/impl/PyClassImpl.java | 53 +++++++++---------- 5 files changed, 68 insertions(+), 47 deletions(-) create mode 100644 python/psi-api/src/com/jetbrains/python/psi/types/PyClassLikeType.java diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java index c9d212cb6ddd..368f4de8d95e 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java @@ -11,9 +11,7 @@ import com.jetbrains.python.psi.PyQualifiedExpression; import com.jetbrains.python.psi.resolve.CompletionVariantsProcessor; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; -import com.jetbrains.python.psi.types.PyCallableType; -import com.jetbrains.python.psi.types.PyType; -import com.jetbrains.python.psi.types.TypeEvalContext; +import com.jetbrains.python.psi.types.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,7 +20,7 @@ import java.util.List; /** * @author yole */ -public class PyJavaClassType implements PyCallableType { +public class PyJavaClassType implements PyClassLikeType { private final PsiClass myClass; private final boolean myDefinition; @@ -86,4 +84,25 @@ public class PyJavaClassType implements PyCallableType { } return null; } + + @Override + public boolean isDefinition() { + return myDefinition; + } + + @Override + public PyClassLikeType toInstance() { + return myDefinition ? new PyJavaClassType(myClass, false) : this; + } + + @Nullable + @Override + public String getClassQName() { + return myClass.getQualifiedName(); + } + + @Override + public boolean isValid() { + return myClass.isValid(); + } } diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java index 2e07e9ea19e1..982252d3e574 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java @@ -9,7 +9,7 @@ import com.intellij.util.ArrayFactory; import com.intellij.util.Processor; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.stubs.PyClassStub; -import com.jetbrains.python.psi.types.PyClassType; +import com.jetbrains.python.psi.types.PyClassLikeType; import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -45,7 +45,7 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine PsiElement[] getSuperClassElements(); @NotNull - List getSuperClassTypes(@NotNull TypeEvalContext context); + List getSuperClassTypes(@NotNull TypeEvalContext context); @NotNull PyClass[] getSuperClasses(); @@ -122,7 +122,7 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine * Get a list of all ancestor types. */ @NotNull - List getAncestorTypes(@NotNull TypeEvalContext context); + List getAncestorTypes(@NotNull TypeEvalContext context); /** * Return the method resolution order list for this class. diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassLikeType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassLikeType.java new file mode 100644 index 000000000000..02afcc190a37 --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassLikeType.java @@ -0,0 +1,17 @@ +package com.jetbrains.python.psi.types; + +import org.jetbrains.annotations.Nullable; + +/** + * @author vlan + */ +public interface PyClassLikeType extends PyCallableType { + boolean isDefinition(); + + PyClassLikeType toInstance(); + + @Nullable + String getClassQName(); + + boolean isValid(); +} diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassType.java index 39a6d40c5ec6..d70ba1b6fb99 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassType.java @@ -3,21 +3,11 @@ package com.jetbrains.python.psi.types; import com.intellij.openapi.util.UserDataHolder; import com.jetbrains.python.psi.PyClass; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author yole */ -public interface PyClassType extends PyCallableType, UserDataHolder { +public interface PyClassType extends PyClassLikeType, UserDataHolder { @NotNull PyClass getPyClass(); - - boolean isDefinition(); - - PyClassType toInstance(); - - @Nullable - String getClassQName(); - - boolean isValid(); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index a709cded9ccd..40e489083e66 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -26,10 +26,7 @@ import com.jetbrains.python.psi.stubs.PropertyStubStorage; import com.jetbrains.python.psi.stubs.PyClassStub; import com.jetbrains.python.psi.stubs.PyFunctionStub; import com.jetbrains.python.psi.stubs.PyTargetExpressionStub; -import com.jetbrains.python.psi.types.PyClassType; -import com.jetbrains.python.psi.types.PyClassTypeImpl; -import com.jetbrains.python.psi.types.PyType; -import com.jetbrains.python.psi.types.TypeEvalContext; +import com.jetbrains.python.psi.types.*; import com.jetbrains.python.toolbox.Maybe; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -181,12 +178,12 @@ public class PyClassImpl extends PyPresentableElementImpl implement // TODO: Change this method to getAncestorTypes() // Implementation is no longer lazy, because C3 resolve for new-style classes will not be lazy final List results = new ArrayList(); - for (PyClassType type : getAncestorTypes(TypeEvalContext.fastStubOnly(null))) { - if (type != null) { - results.add(new PyClassRef(type.getPyClass())); + for (PyClassLikeType type : getAncestorTypes(TypeEvalContext.fastStubOnly(null))) { + if (type instanceof PyClassType) { + results.add(new PyClassRef(((PyClassType)type).getPyClass())); } else { - results.add(new PyClassRef(type)); + results.add(new PyClassRef((PyClass)null)); } } return results; @@ -195,9 +192,9 @@ public class PyClassImpl extends PyPresentableElementImpl implement @Override public Iterable iterateAncestorClasses() { final List results = new ArrayList(); - for (PyClassType type : getAncestorTypes(TypeEvalContext.fastStubOnly(null))) { - if (type != null) { - results.add(type.getPyClass()); + for (PyClassLikeType type : getAncestorTypes(TypeEvalContext.fastStubOnly(null))) { + if (type instanceof PyClassType) { + results.add(((PyClassType)type).getPyClass()); } } return results; @@ -1092,12 +1089,12 @@ public class PyClassImpl extends PyPresentableElementImpl implement @NotNull @Override - public List getSuperClassTypes(@NotNull TypeEvalContext context) { + public List getSuperClassTypes(@NotNull TypeEvalContext context) { if (PyNames.FAKE_OLD_BASE.equals(getName())) { return Collections.emptyList(); } final PyClassStub stub = getStub(); - final List result = new ArrayList(); + final List result = new ArrayList(); if (stub != null) { final PsiElement parent = stub.getParentStub().getPsi(); if (parent instanceof PyFile) { @@ -1110,8 +1107,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement else { for (PyExpression expression : getSuperClassExpressions()) { final PyType type = context.getType(expression); - result.add(type instanceof PyClassType ? (PyClassType)type : null); - // TODO: PyUnknownClassType(expression, expression.getName())? + result.add(type instanceof PyClassLikeType ? (PyClassLikeType)type : null); } } final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this); @@ -1120,8 +1116,8 @@ public class PyClassImpl extends PyPresentableElementImpl implement final PyClass implicitSuper = builtinCache.getClass(implicitSuperName); if (implicitSuper != null) { final PyType type = context.getType(implicitSuper); - if (type instanceof PyClassType) { - result.add((PyClassType)type); + if (type instanceof PyClassLikeType) { + result.add((PyClassLikeType)type); } } } @@ -1130,24 +1126,24 @@ public class PyClassImpl extends PyPresentableElementImpl implement @NotNull @Override - public List getAncestorTypes(@NotNull TypeEvalContext context) { - final List results = new ArrayList(); + public List getAncestorTypes(@NotNull TypeEvalContext context) { + final List results = new ArrayList(); final List toProcess = new ArrayList(); - final Set seen = new HashSet(); + final Set seen = new HashSet(); final Set visited = new HashSet(); toProcess.add(this); while (!toProcess.isEmpty()) { final PyClass cls = toProcess.remove(0); visited.add(cls); - final List types = cls.getSuperClassTypes(context); - for (PyClassType type : types) { + final List types = cls.getSuperClassTypes(context); + for (PyClassLikeType type : types) { if (type == null || !seen.contains(type)) { results.add(type); seen.add(type); } - if (type != null) { + if (type instanceof PyClassType) { // TODO: process PyClassType instead of PyClass - final PyClass superClass = type.getPyClass(); + final PyClass superClass = ((PyClassType)type).getPyClass(); if (!visited.contains(superClass)) { toProcess.add(superClass); } @@ -1196,16 +1192,15 @@ public class PyClassImpl extends PyPresentableElementImpl implement } @Nullable - private static PyClassType classTypeFromQName(@NotNull PyQualifiedName qualifiedName, @NotNull PyFile containingFile, - @NotNull TypeEvalContext context) { + private static PyClassLikeType classTypeFromQName(@NotNull PyQualifiedName qualifiedName, @NotNull PyFile containingFile, + @NotNull TypeEvalContext context) { final PsiElement element = getElementQNamed(containingFile, qualifiedName); if (element instanceof PyTypedElement) { final PyType type = context.getType((PyTypedElement)element); - if (type instanceof PyClassType) { - return (PyClassType)type; + if (type instanceof PyClassLikeType) { + return (PyClassLikeType)type; } } - // TODO: PyUnknownClassType(element, qualifiedName)? return null; } }