diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties
index 93dab333a159..6559bc35559c 100644
--- a/python/src/com/jetbrains/python/PyBundle.properties
+++ b/python/src/com/jetbrains/python/PyBundle.properties
@@ -125,6 +125,8 @@ QFIX.NAME.remove.assignment=Remove assignment
QFIX.NAME.remove.statement=Remove statement
+QFIX.NAME.remove.call=Remove call
+
QFIX.NAME.move.except.up=Move except clause up
QFIX.NAME.remove.dict.key=Remove this key
diff --git a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java
index 4af6767fbcb2..04477b1be313 100644
--- a/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyCallingNonCallableInspection.java
@@ -19,6 +19,7 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.python.PyNames;
+import com.jetbrains.python.inspections.quickfix.PyRemoveCallQuickFix;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyClassType;
import com.jetbrains.python.psi.types.PyType;
@@ -78,13 +79,13 @@ public class PyCallingNonCallableInspection extends PyInspection {
if (!callable) {
final PyType calleeType = callee != null ? myTypeEvalContext.getType(callee) : type;
if (calleeType instanceof PyClassType) {
- registerProblem(node, String.format("'%s' object is not callable", calleeType.getName()));
+ registerProblem(node, String.format("'%s' object is not callable", calleeType.getName()), new PyRemoveCallQuickFix());
}
else if (callee != null) {
- registerProblem(node, String.format("'%s' is not callable", callee.getName()));
+ registerProblem(node, String.format("'%s' is not callable", callee.getName()), new PyRemoveCallQuickFix());
}
else {
- registerProblem(node, "Expression is not callable");
+ registerProblem(node, "Expression is not callable", new PyRemoveCallQuickFix());
}
}
}
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveCallQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveCallQuickFix.java
new file mode 100644
index 000000000000..9753f258fc31
--- /dev/null
+++ b/python/src/com/jetbrains/python/inspections/quickfix/PyRemoveCallQuickFix.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.inspections.quickfix;
+
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.psi.PyArgumentList;
+import com.jetbrains.python.psi.PyCallExpression;
+import com.jetbrains.python.psi.PyDecorator;
+import org.jetbrains.annotations.NotNull;
+
+public class PyRemoveCallQuickFix implements LocalQuickFix {
+ @NotNull
+ @Override
+ public String getName() {
+ return PyBundle.message("QFIX.NAME.remove.call");
+ }
+
+ @NotNull
+ public String getFamilyName() {
+ return getName();
+ }
+
+ @Override
+ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+ final PsiElement call = descriptor.getPsiElement();
+ assert call instanceof PyCallExpression;
+ if (call instanceof PyDecorator) {
+ call.delete();
+ }
+ else {
+ final PyArgumentList argumentList = ((PyCallExpression)call).getArgumentList();
+ assert argumentList != null;
+ argumentList.delete();
+ }
+ }
+}
diff --git a/python/testData/quickFixes/PyRemoveCallQuickFixTest/class.py b/python/testData/quickFixes/PyRemoveCallQuickFixTest/class.py
new file mode 100644
index 000000000000..52530e7b14d1
--- /dev/null
+++ b/python/testData/quickFixes/PyRemoveCallQuickFixTest/class.py
@@ -0,0 +1,6 @@
+
+class A():
+ x = ""
+
+
+b = A().x()
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyRemoveCallQuickFixTest/class_after.py b/python/testData/quickFixes/PyRemoveCallQuickFixTest/class_after.py
new file mode 100644
index 000000000000..ee10a08744c3
--- /dev/null
+++ b/python/testData/quickFixes/PyRemoveCallQuickFixTest/class_after.py
@@ -0,0 +1,6 @@
+
+class A():
+ x = ""
+
+
+b = A().x
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyRemoveCallQuickFixTest/decorator.py b/python/testData/quickFixes/PyRemoveCallQuickFixTest/decorator.py
new file mode 100644
index 000000000000..7f8efe576fa9
--- /dev/null
+++ b/python/testData/quickFixes/PyRemoveCallQuickFixTest/decorator.py
@@ -0,0 +1,12 @@
+
+a = ""
+
+def b(c):
+ pass
+
+
+@a
+@b
+def foo():
+ pass
+
diff --git a/python/testData/quickFixes/PyRemoveCallQuickFixTest/decorator_after.py b/python/testData/quickFixes/PyRemoveCallQuickFixTest/decorator_after.py
new file mode 100644
index 000000000000..9bcfe6741bcf
--- /dev/null
+++ b/python/testData/quickFixes/PyRemoveCallQuickFixTest/decorator_after.py
@@ -0,0 +1,11 @@
+
+a = ""
+
+def b(c):
+ pass
+
+
+@b
+def foo():
+ pass
+
diff --git a/python/testData/quickFixes/PyRemoveCallQuickFixTest/expression.py b/python/testData/quickFixes/PyRemoveCallQuickFixTest/expression.py
new file mode 100644
index 000000000000..7b9faddb5789
--- /dev/null
+++ b/python/testData/quickFixes/PyRemoveCallQuickFixTest/expression.py
@@ -0,0 +1,4 @@
+
+a = "string"
+
+b = a()
\ No newline at end of file
diff --git a/python/testData/quickFixes/PyRemoveCallQuickFixTest/expression_after.py b/python/testData/quickFixes/PyRemoveCallQuickFixTest/expression_after.py
new file mode 100644
index 000000000000..f1bae37c79e8
--- /dev/null
+++ b/python/testData/quickFixes/PyRemoveCallQuickFixTest/expression_after.py
@@ -0,0 +1,4 @@
+
+a = "string"
+
+b = a
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveCallQuickFixTest.java b/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveCallQuickFixTest.java
new file mode 100644
index 000000000000..4538bf384e8b
--- /dev/null
+++ b/python/testSrc/com/jetbrains/python/quickFixes/PyRemoveCallQuickFixTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.quickFixes;
+
+import com.intellij.testFramework.TestDataPath;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.PyQuickFixTestCase;
+import com.jetbrains.python.inspections.PyCallingNonCallableInspection;
+
+@TestDataPath("$CONTENT_ROOT/../testData/quickFixes/PyRemoveCallQuickFixTest/")
+public class PyRemoveCallQuickFixTest extends PyQuickFixTestCase {
+
+ public void testExpression() {
+ doQuickFixTest(PyCallingNonCallableInspection.class, PyBundle.message("QFIX.NAME.remove.call"));
+ }
+
+ public void testDecorator() {
+ doQuickFixTest(PyCallingNonCallableInspection.class, PyBundle.message("QFIX.NAME.remove.call"));
+ }
+
+ public void testClass() {
+ doQuickFixTest(PyCallingNonCallableInspection.class, PyBundle.message("QFIX.NAME.remove.call"));
+ }
+
+}