added (PY-1589) Intention to convert between single-quoted and double-quoted strings

This commit is contained in:
Ekaterina Tuzova
2010-11-25 13:59:52 +03:00
parent af06ed5392
commit 99d32d0cd5
7 changed files with 121 additions and 4 deletions
@@ -138,6 +138,11 @@
<category>Python</category>
</intentionAction>
<intentionAction>
<className>com.jetbrains.python.codeInsight.intentions.PyQuotedStringIntention</className>
<category>Python</category>
</intentionAction>
<stubElementTypeHolder class="com.jetbrains.python.PyElementTypes"/>
<inspectionToolProvider implementation="com.jetbrains.python.inspections.PythonInspectionToolProvider"/>
@@ -129,6 +129,10 @@ INTN.convert.dict.constructor.to.dict.literal=Convert dict constructor to dict l
INTN.convert.dict.literal.to.dict.constructor=Convert dict literal to dict constructor
INTN.convert.dict=Convert dict back and forth between literal dict and dict(**kwargs)
INTN.quoted.string=Convert between single-quoted and double-quoted strings
INTN.quoted.string.single.to.double=Convert single-quoted string to double-quoted string
INTN.quoted.string.double.to.single=Convert double-quoted string to sungle-quoted string
# Conflict checker
CONFLICT.name.$0.obscured=Name ''{0}'' obscured by local definitions
CONFLICT.name.$0.obscured.cannot.convert=Name ''{0}'' obscured. Cannot convert.
@@ -4,9 +4,6 @@ import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.PsiReference;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyBundle;
@@ -14,7 +11,6 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* User: catherine
@@ -0,0 +1,106 @@
package com.jetbrains.python.codeInsight.intentions;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* User: catherine
*/
public class PyQuotedStringIntention extends BaseIntentionAction {
@NotNull
public String getFamilyName() {
return PyBundle.message("INTN.quoted.string");
}
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
PyStringLiteralExpression string = PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyStringLiteralExpression.class);
if (string != null) {
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(string, PyDocStringOwner.class);
if (docStringOwner != null) {
if (docStringOwner.getDocStringExpression() == string) return false;
}
String stringText = string.getText();
if (stringText.length() >= 6) {
if (stringText.startsWith("'''") && stringText.endsWith("'''") ||
stringText.startsWith("\"\"\"") && stringText.endsWith("\"\"\"")) return false;
}
if (stringText.length() > 2) {
if (stringText.startsWith("'") && stringText.endsWith("'")) {
setText(PyBundle.message("INTN.quoted.string.single.to.double"));
return true;
}
if (stringText.startsWith("\"") && stringText.endsWith("\"")) {
setText(PyBundle.message("INTN.quoted.string.double.to.single"));
return true;
}
}
}
return false;
}
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
PyStringLiteralExpression string = PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyStringLiteralExpression.class);
PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project);
if (string != null) {
String stringText = string.getText();
if (stringText.startsWith("'") && stringText.endsWith("'")) {
String result = convertSingleToDoubleQuoted(stringText);
PyStringLiteralExpression st = elementGenerator.createStringLiteralAlreadyEscaped(result);
string.replace(st);
}
if (stringText.startsWith("\"") && stringText.endsWith("\"")) {
String result = convertDoubleToSingleQuoted(stringText);
PyStringLiteralExpression st = elementGenerator.createStringLiteralAlreadyEscaped(result);
string.replace(st);
}
}
}
private static String convertDoubleToSingleQuoted(String stringText) {
StringBuilder stringBuilder = new StringBuilder();
for (char ch : stringText.toCharArray()) {
if (ch == '"') {
stringBuilder.append('\'');
}
else if (ch == '\'') {
stringBuilder.append("\\\'");
}
else {
stringBuilder.append(ch);
}
}
return stringBuilder.toString();
}
private static String convertSingleToDoubleQuoted(String stringText) {
StringBuilder stringBuilder = new StringBuilder();
for (char ch : stringText.toCharArray()) {
if (ch == '\'') {
stringBuilder.append('"');
}
else if (ch == '"') {
stringBuilder.append("\\\"");
}
else {
stringBuilder.append(ch);
}
}
return stringBuilder.toString();
}
}
@@ -0,0 +1 @@
a = '\'Hello\' - said man.'
@@ -0,0 +1 @@
a = "'Hello'<caret> - said man."
@@ -116,4 +116,8 @@ public class PyIntentionTest extends PyLightFixtureTestCase {
public void testDictConstructor() {
doTest(PyBundle.message("INTN.convert.dict.constructor.to.dict.literal"));
}
public void testQuotedString() {
doTest(PyBundle.message("INTN.quoted.string.double.to.single"));
}
}