From fefba3ab2b2e3dd12eeb79bd3d4491580142c217 Mon Sep 17 00:00:00 2001 From: AMalykh Date: Tue, 23 Apr 2019 20:41:45 +0300 Subject: [PATCH] PY-32269: Fixed bug with completion of parameters before `=` sign. GitOrigin-RevId: bb619c210c66a595ff015494b4b553a15cf24c1e --- .../src/com/jetbrains/python/psi/PyUtil.java | 16 +++++++++------ .../psi/impl/PyKeywordArgumentReference.java | 20 ++++++++++++++++++- .../KeywordArgumentCompletionUtil.java | 4 ++-- .../psi/impl/references/PyReferenceImpl.java | 3 +-- .../paramCompletionWithEquals.after.py | 3 +++ .../completion/paramCompletionWithEquals.py | 3 +++ .../python/PythonCompletionTest.java | 5 +++++ 7 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 python/testData/completion/paramCompletionWithEquals.after.py create mode 100644 python/testData/completion/paramCompletionWithEquals.py diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 7766dc8582eb..129f4b253cae 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1139,13 +1139,17 @@ public class PyUtil { * @return lookup element */ @NotNull - public static LookupElement createNamedParameterLookup(@NotNull String name, @NotNull PsiFile settingsAnchor) { + public static LookupElement createNamedParameterLookup(@NotNull String name, @NotNull PsiFile settingsAnchor, boolean addSuffix) { final String suffix; - if (CodeStyle.getCustomSettings(settingsAnchor, PyCodeStyleSettings.class).SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT) { - suffix = " = "; - } - else { - suffix = "="; + if (addSuffix) { + if (CodeStyle.getCustomSettings(settingsAnchor, PyCodeStyleSettings.class).SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT) { + suffix = " = "; + } + else { + suffix = "="; + } + } else { + suffix = ""; } LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name + suffix).withIcon(PlatformIcons.PARAMETER_ICON); lookupElementBuilder = lookupElementBuilder.withInsertHandler(OverwriteEqualsInsertHandler.INSTANCE); diff --git a/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentReference.java b/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentReference.java index 2f324ebd93a5..90798123e074 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentReference.java +++ b/python/src/com/jetbrains/python/psi/impl/PyKeywordArgumentReference.java @@ -15,10 +15,15 @@ */ package com.jetbrains.python.psi.impl; +import com.google.common.collect.Lists; +import com.intellij.codeInsight.completion.CompletionUtil; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.impl.references.KeywordArgumentCompletionUtil; +import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,6 +39,19 @@ public class PyKeywordArgumentReference extends PsiReferenceBase.Poly ret = Lists.newArrayList(); + + final PyKeywordArgument originalElement = CompletionUtil.getOriginalElement(myElement); + final PyKeywordArgument element = originalElement != null ? originalElement : myElement; + + KeywordArgumentCompletionUtil + .collectFunctionArgNames(element, ret, TypeEvalContext.codeCompletion(element.getProject(), element.getContainingFile()), false); + + return ret.toArray(); + } + + @NotNull @Override public ResolveResult[] multiResolve(boolean incompleteCode) { @@ -47,7 +65,7 @@ public class PyKeywordArgumentReference extends PsiReferenceBase.Poly resultList = new ArrayList<>(); diff --git a/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java b/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java index 25697f82d14d..7715e60935f0 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java +++ b/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java @@ -24,7 +24,7 @@ import java.util.Set; import static com.jetbrains.python.psi.PyUtil.as; public class KeywordArgumentCompletionUtil { - public static void collectFunctionArgNames(PyElement element, List ret, @NotNull final TypeEvalContext context) { + public static void collectFunctionArgNames(PyElement element, List ret, @NotNull final TypeEvalContext context, final boolean addSuffix) { PyCallExpression callExpr = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); if (callExpr != null) { PyExpression callee = callExpr.getCallee(); @@ -39,7 +39,7 @@ public class KeywordArgumentCompletionUtil { final List extra = PyTypeUtil.toStream(calleeType) .select(PyCallableType.class) .flatMap(type -> collectParameterNamesFromType(type, callExpr, context).stream()) - .map(name -> PyUtil.createNamedParameterLookup(name, element.getContainingFile())) + .map(name -> PyUtil.createNamedParameterLookup(name, element.getContainingFile(), addSuffix)) .toList(); ret.addAll(extra); diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java index b121e5596727..e9eb563783e2 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java @@ -707,8 +707,7 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference // This method is probably called for completion, so use appropriate context here // in a call, include function's arg names - KeywordArgumentCompletionUtil.collectFunctionArgNames(element, ret, TypeEvalContext.codeCompletion(element.getProject(), element.getContainingFile())); - + KeywordArgumentCompletionUtil.collectFunctionArgNames(element, ret, TypeEvalContext.codeCompletion(element.getProject(), element.getContainingFile()), true); // include builtin names final PyFile builtinsFile = builtinCache.getBuiltinsFile(); if (builtinsFile != null) { diff --git a/python/testData/completion/paramCompletionWithEquals.after.py b/python/testData/completion/paramCompletionWithEquals.after.py new file mode 100644 index 000000000000..8c2a8b6cfbd7 --- /dev/null +++ b/python/testData/completion/paramCompletionWithEquals.after.py @@ -0,0 +1,3 @@ +def func(myArg) : pass + +func(myArg=) \ No newline at end of file diff --git a/python/testData/completion/paramCompletionWithEquals.py b/python/testData/completion/paramCompletionWithEquals.py new file mode 100644 index 000000000000..2884ae37337e --- /dev/null +++ b/python/testData/completion/paramCompletionWithEquals.py @@ -0,0 +1,3 @@ +def func(myArg) : pass + +func(my=) \ 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 68ac812ce4b9..90af39ef4b33 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -1524,6 +1524,11 @@ public class PythonCompletionTest extends PyTestCase { assertDoesntContain(suggested, "foo"); } + // PY-32269 + public void testParamCompletionWithEquals() { + doTest(); + } + private void assertNoVariantsInExtendedCompletion() { myFixture.copyDirectoryToProject(getTestName(true), "");