From bd46ea9bf23b12643f644a89b3dd0fa4ad3fafd7 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 1 Nov 2010 15:33:22 +0300 Subject: [PATCH] don't add parentheses when completing single-arg decorator (PY-2210) --- .../python/psi/impl/PyCallExpressionHelper.java | 4 ++++ .../python/psi/resolve/VariantsProcessor.java | 15 ++++++++++++++- .../completion/noParensForDecorator.after.py | 4 ++++ .../testData/completion/noParensForDecorator.py | 4 ++++ .../jetbrains/python/PythonCompletionTest.java | 5 ++++- 5 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 python/testData/completion/noParensForDecorator.after.py create mode 100644 python/testData/completion/noParensForDecorator.py diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java index 4ce0563223c6..366dc9a33c3c 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java @@ -176,6 +176,10 @@ public class PyCallExpressionHelper { ) { //return getImplicitArgumentCount(functionBeingCalled, null, null, qualifierIsAnInstance(callReference, TypeEvalContext.fast())); if (typeContext == null) typeContext = TypeEvalContext.fast(); + final PyDecorator decorator = PsiTreeUtil.getParentOfType(callReference, PyDecorator.class); + if (decorator != null && PsiTreeUtil.isAncestor(decorator.getCallee(), callReference, false)) { + return 1; + } QualifiedResolveResult followed = callReference.followAssignmentsChain(typeContext); return getImplicitArgumentCount(functionBeingCalled, null, null, isQualifiedByInstance(functionBeingCalled, followed.getLastQualifier(), typeContext)); } diff --git a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java index 9045d0cc0c6e..14f0822f9eab 100644 --- a/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java +++ b/python/src/com/jetbrains/python/psi/resolve/VariantsProcessor.java @@ -8,6 +8,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.ResolveState; import com.intellij.psi.scope.PsiScopeProcessor; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Icons; import com.jetbrains.python.codeInsight.PyClassInsertHandler; import com.jetbrains.python.codeInsight.PyFunctionInsertHandler; @@ -56,7 +57,8 @@ public class VariantsProcessor implements PsiScopeProcessor { protected LookupElementBuilder setupItem(LookupElementBuilder item) { if (!myPlainNamesOnly) { - if (item.getObject() instanceof PyFunction && ((PyFunction) item.getObject()).getProperty() == null) { + if (item.getObject() instanceof PyFunction && ((PyFunction) item.getObject()).getProperty() == null && + !isSingleArgDecoratorCall(myContext, (PyFunction)item.getObject())) { item = item.setInsertHandler(PyFunctionInsertHandler.INSTANCE); } else if (item.getObject() instanceof PyClass) { @@ -69,6 +71,17 @@ public class VariantsProcessor implements PsiScopeProcessor { return item; } + private static boolean isSingleArgDecoratorCall(PsiElement elementInCall, PyFunction callee) { + if (callee.getParameterList().getParameters().length > 1) { + return false; + } + PyDecorator decorator = PsiTreeUtil.getParentOfType(elementInCall, PyDecorator.class); + if (decorator == null) { + return false; + } + return PsiTreeUtil.isAncestor(decorator.getCallee(), elementInCall, false); + } + protected static LookupElementBuilder setItemNotice(final LookupElementBuilder item, String notice) { return item.setTypeText(notice); } diff --git a/python/testData/completion/noParensForDecorator.after.py b/python/testData/completion/noParensForDecorator.after.py new file mode 100644 index 000000000000..d7fd3c622d19 --- /dev/null +++ b/python/testData/completion/noParensForDecorator.after.py @@ -0,0 +1,4 @@ +def my_decorator(f): + return f + +@my_decorator \ No newline at end of file diff --git a/python/testData/completion/noParensForDecorator.py b/python/testData/completion/noParensForDecorator.py new file mode 100644 index 000000000000..45ab84730c86 --- /dev/null +++ b/python/testData/completion/noParensForDecorator.py @@ -0,0 +1,4 @@ +def my_decorator(f): + return f + +@my_deco \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index e3244ccd3e5b..0244f2fd1d50 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -5,7 +5,6 @@ package com.jetbrains.python; import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.openapi.application.ApplicationManager; import com.jetbrains.python.fixtures.PyLightFixtureTestCase; import java.util.Arrays; @@ -224,4 +223,8 @@ public class PythonCompletionTest extends PyLightFixtureTestCase { myFixture.completeBasic(); myFixture.checkResultByFile(dirname + "importedModule.after.py"); } + + public void testNoParensForDecorator() { // PY-2210 + doTest(); + } }