import com.intellij.util.ProcessingContext;
import com.jetbrains.python.psi.AccessDirection;
import com.jetbrains.python.psi.PyExpression;
+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 org.jetbrains.annotations.NotNull;
/**
* @author yole
*/
-public class PyJavaClassType implements PyType {
+public class PyJavaClassType implements PyCallableType {
private final PsiClass myClass;
+ private final boolean myDefinition;
- public PyJavaClassType(final PsiClass aClass) {
+ public PyJavaClassType(final PsiClass aClass, boolean definition) {
myClass = aClass;
+ myDefinition = definition;
}
@Nullable
@Override
public void assertValid(String message) {
}
+
+ @Override
+ public boolean isCallable() {
+ return myDefinition;
+ }
+
+ @Nullable
+ @Override
+ public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
+ if (myDefinition) {
+ return new PyJavaClassType(myClass, false);
+ }
+ return null;
+ }
}
@Nullable
public PyType getReferenceType(@NotNull final PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor) {
if (referenceTarget instanceof PsiClass) {
- return new PyJavaClassType((PsiClass) referenceTarget);
+ return new PyJavaClassType((PsiClass) referenceTarget, true);
}
if (referenceTarget instanceof PsiPackage) {
return new PyJavaPackageType((PsiPackage) referenceTarget, anchor == null ? null : ModuleUtil.findModuleForPsiElement(anchor));
final PsiClassType classType = (PsiClassType)type;
final PsiClass psiClass = classType.resolve();
if (psiClass != null) {
- return new PyJavaClassType(psiClass);
+ return new PyJavaClassType(psiClass, false);
}
}
return null;
if (paramType instanceof PsiClassType) {
final PsiClass psiClass = ((PsiClassType)paramType).resolve();
if (psiClass != null) {
- superMethodParameterTypes.add(new PyJavaClassType(psiClass));
+ superMethodParameterTypes.add(new PyJavaClassType(psiClass, false));
}
}
}
--- /dev/null
+package com.jetbrains.jython;
+
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+import com.jetbrains.python.PythonTestUtil;
+import com.jetbrains.python.inspections.PyCallingNonCallableInspection;
+
+/**
+ * @author yole
+ */
+public class PyJythonHighlightingTest extends LightCodeInsightFixtureTestCase {
+ public void testCallableJavaClass() {
+ myFixture.configureByFile("callableJavaClass.py");
+ myFixture.enableInspections(PyCallingNonCallableInspection.class);
+ myFixture.checkHighlighting(true, false, false);
+ }
+
+
+ @Override
+ protected String getTestDataPath() {
+ return PythonTestUtil.getTestDataPath() + "/highlighting/jython/";
+ }
+}
* @author yole
*/
public interface PyCallableType extends PyType {
+ /**
+ * Returns true if the type is callable.
+ */
+ boolean isCallable();
+
/**
* Returns the type which is the result of calling an instance of this type.
*
return PyBuiltinCache.getInstance(myClass).getObjectType("type");
}
+ @Override
+ public boolean isCallable() {
+ if (isDefinition()) {
+ return true;
+ }
+ if (PyTypeChecker.isMethodType(this)) {
+ return true;
+ }
+ final PyClass cls = getPyClass();
+ if (PyABCUtil.isSubclass(cls, PyNames.CALLABLE)) {
+ return true;
+ }
+ return false;
+ }
+
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
myCallable = callable;
}
+ @Override
+ public boolean isCallable() {
+ return true;
+ }
+
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
if (type == null || type instanceof PyTypeReference) {
return null;
}
- else if (type instanceof PyClassType) {
- final PyClassType classType = (PyClassType)type;
- if (classType.isDefinition()) {
- return true;
- }
- if (isMethodType(classType)) {
- return true;
- }
- final PyClass cls = classType.getPyClass();
- if (PyABCUtil.isSubclass(cls, PyNames.CALLABLE)) {
- return true;
- }
- }
else if (type instanceof PyUnionType) {
Boolean result = true;
for (PyType member : ((PyUnionType)type).getMembers()) {
return result;
}
else if (type instanceof PyCallableType) {
- return true;
+ return ((PyCallableType) type).isCallable();
}
return false;
}
- private static boolean isMethodType(@NotNull PyClassType type) {
+ public static boolean isMethodType(@NotNull PyClassType type) {
final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(type.getPyClass());
return type.equals(builtinCache.getClassMethodType()) || type.equals(builtinCache.getStaticMethodType());
}
--- /dev/null
+from java.util import ArrayList
+l = ArrayList()