Fix according to review IDEA-CR-13654

This commit is contained in:
Valentina Kiryushkina
2016-09-26 18:53:48 +03:00
parent feaad68b7e
commit 5d9d21eb0d
4 changed files with 27 additions and 11 deletions

View File

@@ -37,7 +37,6 @@ import com.jetbrains.python.psi.impl.PyPsiUtils;
import com.jetbrains.python.psi.impl.PyStringLiteralExpressionImpl;
import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
@@ -132,27 +131,27 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
final String f_key = scanner.group(1);
final String f_modifier = scanner.group(2);
final String f_width = scanner.group(3);
String f_conversion = scanner.group(4);
String fConversion = scanner.group(4);
// convert to format()'s
if ("%%".equals(scanner.group(0))) {
// shortcut to put a literal %
out.append("%");
}
else {
sure(f_conversion);
sure(!"%".equals(f_conversion)); // a padded percent literal; can't bother to autoconvert, and in 3k % is different.
sure(fConversion);
sure(!"%".equals(fConversion)); // a padded percent literal; can't bother to autoconvert, and in 3k % is different.
out.append("{");
if (f_key != null) {
out.append(f_key);
usesNamedFormat = true;
}
if ("r".equals(f_conversion)) out.append("!r");
if ("r".equals(fConversion)) out.append("!r");
// don't convert %s -> !s, for %s is the normal way to output the default representation
out.append(":");
if (f_modifier != null) {
// in strict order
if (has(f_modifier, '-')) out.append("<"); // left align
else if ("s".equals(f_conversion) && !StringUtil.isEmptyOrSpaces(f_width)) {
else if ("s".equals(fConversion) && !StringUtil.isEmptyOrSpaces(f_width)) {
// "%20s" aligns right, "{0:20s}" aligns left; to preserve align, make it explicit
out.append(">");
}
@@ -165,8 +164,8 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
if (f_width != null) {
out.append(f_width);
}
if ("i".equals(f_conversion) || "u".equals(f_conversion)) out.append("d");
else if (!"s".equals(f_conversion) && !"r".equals(f_conversion)) out.append(f_conversion);
if ("i".equals(fConversion) || "u".equals(fConversion)) out.append("d");
else if (!"s".equals(fConversion) && !"r".equals(fConversion)) out.append(fConversion);
final int lastIndexOf = out.lastIndexOf(":");
if (lastIndexOf == out.length() - 1) {
@@ -287,9 +286,8 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
else if (rhs instanceof PyCallExpression) { // potential dict(foo=1) -> format(foo=1)
final PyCallExpression callExpression = (PyCallExpression)rhs;
final PyExpression callee = callExpression.getCallee();
final PyClassType dictType = PyBuiltinCache.getInstance(file).getDictType();
final PyClassType classType = PyUtil.as(rhsType, PyClassType.class);
if (classType != null && callee != null && isDictCall(callee, classType, dictType)) {
if (classType != null && callee != null && isDictCall(callee, classType)) {
target.append(sure(sure(callExpression.getArgumentList()).getNode()).getChars());
}
else { // just a call, reuse
@@ -308,7 +306,9 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
element.replace(sure(((PyParenthesizedExpression)parenthesized).getContainedExpression()));
}
private static boolean isDictCall(@NotNull PyExpression callee, @NotNull PyClassType classType, @Nullable PyClassType dictType) {
private static boolean isDictCall(@NotNull PyExpression callee,
@NotNull PyClassType classType) {
final PyClassType dictType = PyBuiltinCache.getInstance(callee.getContainingFile()).getDictType();
if (dictType != null && classType.getPyClass() == dictType.getPyClass()) {
if (callee instanceof PyReferenceExpression) {
PsiElement maybeDict = ((PyReferenceExpression)callee).getReference().resolve();

View File

@@ -0,0 +1,6 @@
class MyDict(dict):
def __init__(self, **kwargs):
super().__init__(**kwargs)
"%(a)s" <caret>% MyDict(a=1)

View File

@@ -0,0 +1,6 @@
class MyDict(dict):
def __init__(self, **kwargs):
super().__init__(**kwargs)
"{a}".format(**MyDict(a=1))

View File

@@ -98,4 +98,8 @@ public class PyConvertFormatOperatorToMethodIntentionTest extends PyIntentionTes
public void testCallWithNoneReturnType() {
doTest(PyBundle.message("INTN.replace.with.method"), LanguageLevel.PYTHON26);
}
public void testDictSubclass() {
doTest(PyBundle.message("INTN.replace.with.method"), LanguageLevel.PYTHON26);
}
}