PY-15197 Completion for keyword argument has spaces around '=' if required by code style settings

This commit is contained in:
Mikhail Golubev
2015-07-31 17:50:04 +03:00
parent b78e0ab785
commit 7d4bd2b487
6 changed files with 41 additions and 9 deletions
@@ -16,6 +16,7 @@
package com.jetbrains.python.psi.impl;
import com.intellij.codeInsight.completion.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyUtil;
@@ -60,9 +61,10 @@ public class PyConstructorArgumentCompletionContributor extends CompletionContri
private static void addSettersAndListeners(CompletionResultSet result, PsiClass containingClass) {
// see PyJavaType.init() in Jython source code for matching logic
for (PsiMethod method : containingClass.getAllMethods()) {
final Project project = containingClass.getProject();
if (PropertyUtil.isSimplePropertySetter(method)) {
final String propName = PropertyUtil.getPropertyName(method);
result.addElement(PyUtil.createNamedParameterLookup(propName));
result.addElement(PyUtil.createNamedParameterLookup(propName, project));
}
else if (method.getName().startsWith("add") && method.getName().endsWith("Listener") && PsiType.VOID.equals(method.getReturnType())) {
final PsiParameter[] parameters = method.getParameterList().getParameters();
@@ -71,9 +73,9 @@ public class PyConstructorArgumentCompletionContributor extends CompletionContri
if (type instanceof PsiClassType) {
final PsiClass parameterClass = ((PsiClassType)type).resolve();
if (parameterClass != null) {
result.addElement(PyUtil.createNamedParameterLookup(StringUtil.decapitalize(parameterClass.getName())));
for (PsiMethod parameterMethod: parameterClass.getMethods()) {
result.addElement(PyUtil.createNamedParameterLookup(parameterMethod.getName()));
result.addElement(PyUtil.createNamedParameterLookup(StringUtil.decapitalize(parameterClass.getName()), project));
for (PsiMethod parameterMethod : parameterClass.getMethods()) {
result.addElement(PyUtil.createNamedParameterLookup(parameterMethod.getName(), project));
}
}
}
@@ -64,6 +64,7 @@ import com.jetbrains.python.codeInsight.completion.OverwriteEqualsInsertHandler;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.codeInsight.stdlib.PyNamedTupleType;
import com.jetbrains.python.formatter.PyCodeStyleSettings;
import com.jetbrains.python.magicLiteral.PyMagicLiteralTools;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyPsiUtils;
@@ -1085,8 +1086,23 @@ public class PyUtil {
return PyNames.isIdentifier(name);
}
public static LookupElement createNamedParameterLookup(String name) {
LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name + "=").withIcon(PlatformIcons.PARAMETER_ICON);
/**
* Constructs new lookup element for completion of keyword argument with equals sign appended.
*
* @param name name of the parameter
* @param project project instance to check code style settings and surround equals sign with spaces if necessary
* @return lookup element
*/
@NotNull
public static LookupElement createNamedParameterLookup(@NotNull String name, @Nullable Project project) {
final String suffix;
if (CodeStyleSettingsManager.getSettings(project).getCustomSettings(PyCodeStyleSettings.class).SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT) {
suffix = " = ";
}
else {
suffix = "=";
}
LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name + suffix).withIcon(PlatformIcons.PARAMETER_ICON);
lookupElementBuilder = lookupElementBuilder.withInsertHandler(OverwriteEqualsInsertHandler.INSTANCE);
return PrioritizedLookupElement.withGrouping(lookupElementBuilder, 1);
}
@@ -75,7 +75,7 @@ public class KeywordArgumentCompletionUtil {
for (PyKeywordArgumentProvider provider : Extensions.getExtensions(PyKeywordArgumentProvider.EP_NAME)) {
final List<String> arguments = provider.getKeywordArguments(def, callExpr);
for (String argument : arguments) {
ret.add(PyUtil.createNamedParameterLookup(argument));
ret.add(PyUtil.createNamedParameterLookup(argument, callExpr.getProject()));
}
}
KwArgFromStatementCallCollector fromStatementCallCollector = new KwArgFromStatementCallCollector(ret, collector.getKwArgs());
@@ -119,7 +119,7 @@ public class KeywordArgumentCompletionUtil {
PyNamedParameter namedParam = par.getAsNamed();
if (namedParam != null) {
if (!namedParam.isKeywordContainer() && !namedParam.isPositionalContainer()) {
final LookupElement item = PyUtil.createNamedParameterLookup(namedParam.getName());
final LookupElement item = PyUtil.createNamedParameterLookup(namedParam.getName(), par.getProject());
myRet.add(item);
}
else if (namedParam.isKeywordContainer()) {
@@ -202,7 +202,7 @@ public class KeywordArgumentCompletionUtil {
argument instanceof PyStringLiteralExpression) {
String name = ((PyStringLiteralExpression)argument).getStringValue();
if (PyUtil.isPythonIdentifier(name)) {
myRet.add(PyUtil.createNamedParameterLookup(name));
myRet.add(PyUtil.createNamedParameterLookup(name, argument.getProject()));
}
}
}
@@ -0,0 +1,4 @@
def func(foo):
pass
func(foo = <caret>)
@@ -0,0 +1,4 @@
def func(foo):
pass
func(foo<caret>)
@@ -771,6 +771,12 @@ public class PythonCompletionTest extends PyTestCase {
assertSameElements(myFixture.getLookupElementStrings(), "import", "subpkg1", "subpkg2", "m");
}
// PY-15197
public void testKeywordArgumentEqualsSignSurroundedWithSpaces() {
getPythonCodeStyle().SPACE_AROUND_EQ_IN_KEYWORD_ARGUMENT = true;
doTest();
}
public void testStructuralType() {
doTest();
}