diff --git a/python/pluginSrc/META-INF/plugin.xml b/python/pluginSrc/META-INF/plugin.xml
index fd52a7b39285..7b161e73b4e9 100644
--- a/python/pluginSrc/META-INF/plugin.xml
+++ b/python/pluginSrc/META-INF/plugin.xml
@@ -7,5 +7,6 @@
+
\ No newline at end of file
diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java
new file mode 100644
index 000000000000..5d627b1bfd8a
--- /dev/null
+++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java
@@ -0,0 +1,36 @@
+package com.jetbrains.python.psi.impl;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.util.Processor;
+import com.intellij.util.QueryExecutor;
+import com.jetbrains.python.psi.PyClass;
+import com.jetbrains.python.psi.PyFunction;
+import com.jetbrains.python.psi.search.PySuperMethodsSearch;
+
+/**
+ * @author yole
+ */
+public class PyJavaSuperMethodsSearchExecutor implements QueryExecutor {
+ public boolean execute(final PySuperMethodsSearch.SearchParameters queryParameters, final Processor consumer) {
+ PyFunction func = queryParameters.getDerivedMethod();
+ PyClass containingClass = func.getContainingClass();
+ if (containingClass != null) {
+ PsiElement[] superClassElements = containingClass.getSuperClassElements();
+ if (superClassElements != null) {
+ for(PsiElement element: superClassElements) {
+ if (element instanceof PsiClass) {
+ PsiClass psiClass = (PsiClass) element;
+ PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
+ // the Python method actually does override/implement all of Java super methods with the same name
+ for(PsiMethod method: methods) {
+ if (!consumer.process(method)) return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/python/src/com/jetbrains/python/PyLineMarkerNavigator.java b/python/src/com/jetbrains/python/PyLineMarkerNavigator.java
index 2cca4b3fe410..e25f31123074 100644
--- a/python/src/com/jetbrains/python/PyLineMarkerNavigator.java
+++ b/python/src/com/jetbrains/python/PyLineMarkerNavigator.java
@@ -2,12 +2,16 @@ package com.jetbrains.python;
import com.intellij.codeInsight.daemon.impl.GutterIconNavigationHandler;
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator;
-import com.intellij.psi.PsiElement;
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
+import com.intellij.psi.NavigatablePsiElement;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.Processor;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import java.awt.event.MouseEvent;
+import java.util.List;
+import java.util.ArrayList;
/**
* @author yole
@@ -16,7 +20,16 @@ public class PyLineMarkerNavigator implements GutterIconNavigationHandler {
public void navigate(final MouseEvent e, final PsiElement elt) {
if (elt.getParent() instanceof PyFunction) {
final PyFunction function = (PyFunction)elt.getParent();
- final PyFunction[] methods = PySuperMethodsSearch.search(function).toArray(new PyFunction[0]);
+ final List navElements = new ArrayList();
+ PySuperMethodsSearch.search(function).forEach(new Processor() {
+ public boolean process(final PsiElement psiElement) {
+ if (psiElement instanceof NavigatablePsiElement) {
+ navElements.add((NavigatablePsiElement) psiElement);
+ }
+ return true;
+ }
+ });
+ final NavigatablePsiElement[] methods = navElements.toArray(new NavigatablePsiElement[navElements.size()]);
PsiElementListNavigator.openTargets(e, methods, "Choose Super Method of " + function.getName(),
new DefaultPsiElementCellRenderer());
}
diff --git a/python/src/com/jetbrains/python/PyLineMarkerProvider.java b/python/src/com/jetbrains/python/PyLineMarkerProvider.java
index e6cbb8cf7a12..e901bfb2297c 100644
--- a/python/src/com/jetbrains/python/PyLineMarkerProvider.java
+++ b/python/src/com/jetbrains/python/PyLineMarkerProvider.java
@@ -30,6 +30,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider {
@Nullable
private static LineMarkerInfo getMethodMarker(final PsiElement element, final PyFunction function) {
if (PySuperMethodsSearch.search(function).findFirst() != null) {
+ // TODO: show "implementing" instead of "overriding" icon for Python implementations of Java interface methods
LineMarkerInfo info = new LineMarkerInfo(element, element.getTextRange().getStartOffset(),
OVERRIDING_METHOD_ICON, Pass.UPDATE_ALL, null, new PyLineMarkerNavigator());
return info;
diff --git a/python/src/com/jetbrains/python/psi/PyClass.java b/python/src/com/jetbrains/python/psi/PyClass.java
index befbfd99b10f..a503b1fa93d0 100644
--- a/python/src/com/jetbrains/python/psi/PyClass.java
+++ b/python/src/com/jetbrains/python/psi/PyClass.java
@@ -16,6 +16,7 @@
package com.jetbrains.python.psi;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.stubs.MayHaveStubsInside;
@@ -38,6 +39,9 @@ public interface PyClass extends PsiNamedElement, PyElement, PyDocStringOwner, S
@Nullable
PyExpression[] getSuperClassExpressions();
+ @Nullable
+ PsiElement[] getSuperClassElements();
+
@Nullable
PyClass[] getSuperClasses();
diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
index dd38697269af..a53808478cec 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
@@ -32,8 +32,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import java.util.List;
import java.util.ArrayList;
+import java.util.List;
/**
* Created by IntelliJ IDEA.
@@ -104,20 +104,34 @@ public class PyClassImpl extends PyPresentableElementImpl implement
return null;
}
- public PyClass[] getSuperClasses() {
+ public PsiElement[] getSuperClassElements() {
final PyExpression[] superExpressions = getSuperClassExpressions();
if (superExpressions != null) {
- List superClasses = new ArrayList();
+ List superClasses = new ArrayList();
for(PyExpression expr: superExpressions) {
if (expr instanceof PyReferenceExpression && !"object".equals(expr.getText())) {
PyReferenceExpression ref = (PyReferenceExpression) expr;
final PsiElement result = ref.resolve();
- if (result instanceof PyClass) {
- superClasses.add((PyClass) result);
+ if (result != null) {
+ superClasses.add(result);
}
}
}
- return superClasses.toArray(new PyClass[superClasses.size()]);
+ return superClasses.toArray(new PsiElement[superClasses.size()]);
+ }
+ return null;
+ }
+
+ public PyClass[] getSuperClasses() {
+ PsiElement[] superClassElements = getSuperClassElements();
+ if (superClassElements != null) {
+ List result = new ArrayList();
+ for(PsiElement element: superClassElements) {
+ if (element instanceof PyClass) {
+ result.add((PyClass) element);
+ }
+ }
+ return result.toArray(new PyClass[result.size()]);
}
return null;
}
diff --git a/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearch.java b/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearch.java
index 314c33547ffa..a987d6a4af6d 100644
--- a/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearch.java
+++ b/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearch.java
@@ -1,5 +1,6 @@
package com.jetbrains.python.psi.search;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.search.searches.ExtensibleQueryFactory;
import com.intellij.util.Query;
import com.jetbrains.python.psi.PyFunction;
@@ -7,7 +8,7 @@ import com.jetbrains.python.psi.PyFunction;
/**
* @author yole
*/
-public class PySuperMethodsSearch extends ExtensibleQueryFactory {
+public class PySuperMethodsSearch extends ExtensibleQueryFactory {
public static PySuperMethodsSearch INSTANCE = new PySuperMethodsSearch();
public static class SearchParameters {
@@ -26,7 +27,7 @@ public class PySuperMethodsSearch extends ExtensibleQueryFactory search(final PyFunction derivedMethod) {
+ public static Query search(final PyFunction derivedMethod) {
final SearchParameters parameters = new SearchParameters(derivedMethod);
return INSTANCE.createUniqueResultsQuery(parameters);
}
diff --git a/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearchExecutor.java b/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearchExecutor.java
index af91dc662917..a651ffa31660 100644
--- a/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearchExecutor.java
+++ b/python/src/com/jetbrains/python/psi/search/PySuperMethodsSearchExecutor.java
@@ -1,5 +1,6 @@
package com.jetbrains.python.psi.search;
+import com.intellij.psi.PsiElement;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import com.jetbrains.python.psi.PyClass;
@@ -8,8 +9,8 @@ import com.jetbrains.python.psi.PyFunction;
/**
* @author yole
*/
-public class PySuperMethodsSearchExecutor implements QueryExecutor {
- public boolean execute(final PySuperMethodsSearch.SearchParameters queryParameters, final Processor consumer) {
+public class PySuperMethodsSearchExecutor implements QueryExecutor {
+ public boolean execute(final PySuperMethodsSearch.SearchParameters queryParameters, final Processor consumer) {
PyFunction func = queryParameters.getDerivedMethod();
String name = func.getName();
PyClass containingClass = func.getContainingClass();