* @author yole
*/
public class PySuperMethodsSearchExecutor implements QueryExecutor<PsiElement, PySuperMethodsSearch.SearchParameters> {
+ @Override
public boolean execute(@NotNull final PySuperMethodsSearch.SearchParameters queryParameters,
@NotNull final Processor<PsiElement> consumer) {
- PyFunction func = queryParameters.getDerivedMethod();
- String name = func.getName();
- PyClass containingClass = func.getContainingClass();
- Set<PyClass> foundMethodContainingClasses = new HashSet<PyClass>();
+ final PyFunction func = queryParameters.getDerivedMethod();
+ final String name = func.getName();
+ final PyClass containingClass = func.getContainingClass();
+ final Set<PyClass> foundMethodContainingClasses = new HashSet<PyClass>();
+ final TypeEvalContext context = queryParameters.getContext();
if (name != null && containingClass != null) {
- for (PyClass superClass : containingClass.getAncestorClasses(null)) {
+ for (PyClass superClass : containingClass.getAncestorClasses(context)) {
if (!queryParameters.isDeepSearch()) {
boolean isAlreadyFound = false;
for (PyClass alreadyFound : foundMethodContainingClasses) {
}
- final TypeEvalContext context = queryParameters.getContext();
if (superMethod == null && context != null) {
// If super method still not found and we have context, we may use it to find method
final PyClassLikeType classLikeType = PyUtil.as(context.getType(superClass), PyClassLikeType.class);
if (classLikeType != null) {
- for (final PyFunction function : PyClassLikeTypeUtil.getMembersOfType(classLikeType, PyFunction.class, context)) {
+ for (PyFunction function : PyClassLikeTypeUtil.getMembersOfType(classLikeType, PyFunction.class, context)) {
final String elemName = function.getName();
- if (elemName != null && elemName.equals(queryParameters.getDerivedMethod().getName())) {
+ if (elemName != null && elemName.equals(func.getName())) {
consumer.process(function);
}
}
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyReferenceExpression;
import com.jetbrains.python.psi.PyUtil;
+import com.jetbrains.python.psi.search.PyOverridingMethodsSearch;
+import com.jetbrains.python.psi.search.PySuperMethodsSearch;
+import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.refactoring.PyBaseRefactoringAction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Nullable
private static PyFunction findTargetFunction(@NotNull PsiElement element) {
- if (isLocalFunction(element) || isInstanceMethod(element)) {
+ if (isLocalFunction(element) || isSuitableInstanceMethod(element)) {
return (PyFunction)element;
}
final PyReferenceExpression refExpr = PsiTreeUtil.getParentOfType(element, PyReferenceExpression.class);
return null;
}
final PsiElement resolved = refExpr.getReference().resolve();
- if (isLocalFunction(resolved) || isInstanceMethod(resolved)) {
+ if (isLocalFunction(resolved) || isSuitableInstanceMethod(resolved)) {
return (PyFunction)resolved;
}
return null;
}
- private static boolean isInstanceMethod(@Nullable PsiElement element) {
+ private static boolean isSuitableInstanceMethod(@Nullable PsiElement element) {
final PyFunction function = as(element, PyFunction.class);
- if (function == null) {
+ if (function == null || function.getContainingClass() == null) {
return false;
}
- final PyUtil.MethodFlags flags = PyUtil.MethodFlags.of(function);
- return flags != null && flags.isInstanceMethod();
+ final String funcName = function.getName();
+ if (funcName == null || PyUtil.isSpecialName(funcName)) {
+ return false;
+ }
+ final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(function.getProject(), function.getContainingFile());
+ if (PySuperMethodsSearch.search(function, typeEvalContext).findFirst() != null) return false;
+ if (PyOverridingMethodsSearch.search(function, true).findFirst() != null) return false;
+ if (function.getDecoratorList() != null || function.getModifier() != null) return false;
+ if (function.getContainingClass().findPropertyByCallable(function) != null) return false;
+ return true;
}
private static boolean isLocalFunction(@Nullable PsiElement resolved) {
final PyFunction function = findTargetFunction(element);
if (function != null) {
final PyBaseMakeFunctionTopLevelProcessor processor;
- if (isInstanceMethod(function)) {
+ if (isSuitableInstanceMethod(function)) {
processor = new PyMakeMethodTopLevelProcessor(function, editor);
}
else {
-def fu<caret>nc():
+def func():
def local():
pass
-
+
class C:
def method(self):
pass
-
+
@staticmethod
def static_method(x):
pass
-
+
@classmethod
def class_method(self):
- pass
\ No newline at end of file
+ pass
+
+ @property
+ def field(self):
+ return self._x
+
+ def __magic__(self):
+ pass
+
+
+class Base:
+ def overridden_method(self):
+ pass
+
+
+class Subclass(Base):
+ def overridden_method(self):
+ super(Subclass, self).overridden_method()
assertFalse(isActionEnabled());
moveByText("class_method");
assertFalse(isActionEnabled());
+
+ // Super method
+ moveByText("overridden_method");
+ assertFalse(isActionEnabled());
+
+ moveByText("property");
+ assertFalse(isActionEnabled());
+ moveByText("__magic__");
+ assertFalse(isActionEnabled());
}
// PY-6637