mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
correctly check if we need to insert a backslash when wrapping (PY-7039)
This commit is contained in:
@@ -8,6 +8,7 @@ import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.editor.PythonEnterHandler;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -30,13 +31,12 @@ public class RemoveUnnecessaryBackslashQuickFix implements LocalQuickFix {
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
PsiElement problemElement = descriptor.getPsiElement();
|
||||
if (problemElement != null) {
|
||||
PyElement parent = PsiTreeUtil.getParentOfType(problemElement, PySequenceExpression.class, PyDictLiteralExpression.class,
|
||||
PyParenthesizedExpression.class, PyArgumentList.class, PyParameterList.class);
|
||||
PsiElement parent = PsiTreeUtil.getParentOfType(problemElement, PythonEnterHandler.IMPLICIT_WRAP_CLASSES);
|
||||
removeBackSlash(parent);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeBackSlash(PyElement parent) {
|
||||
private static void removeBackSlash(PsiElement parent) {
|
||||
if (parent != null) {
|
||||
Stack<PsiElement> stack = new Stack<PsiElement>();
|
||||
if (parent instanceof PyParenthesizedExpression)
|
||||
|
||||
@@ -29,7 +29,15 @@ import org.jetbrains.annotations.Nullable;
|
||||
public class PythonEnterHandler extends EnterHandlerDelegateAdapter {
|
||||
private boolean needPostProcess = false;
|
||||
|
||||
private static final Class[] IMPLICIT_WRAP_CLASSES = new Class[]{
|
||||
public static final Class[] IMPLICIT_WRAP_CLASSES = new Class[] {
|
||||
PySequenceExpression.class,
|
||||
PyDictLiteralExpression.class,
|
||||
PyParenthesizedExpression.class,
|
||||
PyArgumentList.class,
|
||||
PyParameterList.class
|
||||
};
|
||||
|
||||
private static final Class[] WRAPPABLE_CLASSES = new Class[]{
|
||||
PsiComment.class,
|
||||
PyParenthesizedExpression.class,
|
||||
PyListCompExpression.class,
|
||||
@@ -116,13 +124,11 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter {
|
||||
final boolean isEscapedBackslash = "\\".equals(doc.getText(TextRange.create(offset-2, offset - 1))) && nextIsBackslash;
|
||||
if (nextIsBackslash && !isEscapedQuote && !isEscapedBackslash) return Result.Continue;
|
||||
|
||||
final PsiElement parent = string.getParent();
|
||||
final StringBuilder replacementString = new StringBuilder();
|
||||
needPostProcess = true;
|
||||
if (parent instanceof PySequenceExpression || parent instanceof PyParenthesizedExpression ||
|
||||
parent instanceof PyBinaryExpression || parent instanceof PyKeyValueExpression ||
|
||||
parent instanceof PyNamedParameter || parent instanceof PyArgumentList) {
|
||||
replacementString.append(quote + pref + quote);
|
||||
|
||||
if (PsiTreeUtil.getParentOfType(string, IMPLICIT_WRAP_CLASSES) != null) {
|
||||
replacementString.append(quote).append(pref).append(quote);
|
||||
doc.insertString(offset, replacementString);
|
||||
caretOffset.set(caretOffset.get() + 1);
|
||||
return Result.Continue;
|
||||
@@ -132,7 +138,7 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter {
|
||||
replacementString.append(quote);
|
||||
caretOffset.set(caretOffset.get() + 1);
|
||||
}
|
||||
replacementString.append(quote + " \\" + pref);
|
||||
replacementString.append(quote).append(" \\").append(pref);
|
||||
if (!isEscapedQuote)
|
||||
replacementString.append(quote);
|
||||
doc.insertString(offset, replacementString.toString());
|
||||
@@ -187,7 +193,7 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter {
|
||||
PsiElement wrappableAfter = findWrappable(file, offset, false);
|
||||
if (!(wrappableBefore instanceof PsiComment)) {
|
||||
while (wrappableBefore != null) {
|
||||
PsiElement next = PsiTreeUtil.getParentOfType(wrappableBefore, IMPLICIT_WRAP_CLASSES);
|
||||
PsiElement next = PsiTreeUtil.getParentOfType(wrappableBefore, WRAPPABLE_CLASSES);
|
||||
if (next == null) {
|
||||
break;
|
||||
}
|
||||
@@ -196,7 +202,7 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter {
|
||||
}
|
||||
if (!(wrappableAfter instanceof PsiComment)) {
|
||||
while (wrappableAfter != null) {
|
||||
PsiElement next = PsiTreeUtil.getParentOfType(wrappableAfter, IMPLICIT_WRAP_CLASSES);
|
||||
PsiElement next = PsiTreeUtil.getParentOfType(wrappableAfter, WRAPPABLE_CLASSES);
|
||||
if (next == null) {
|
||||
break;
|
||||
}
|
||||
@@ -234,8 +240,8 @@ public class PythonEnterHandler extends EnterHandlerDelegateAdapter {
|
||||
@Nullable
|
||||
private static PsiElement findWrappable(PsiFile file, int offset, boolean before) {
|
||||
PsiElement wrappable = before
|
||||
? findBeforeCaret(file, offset, IMPLICIT_WRAP_CLASSES)
|
||||
: findAfterCaret(file, offset, IMPLICIT_WRAP_CLASSES);
|
||||
? findBeforeCaret(file, offset, WRAPPABLE_CLASSES)
|
||||
: findAfterCaret(file, offset, WRAPPABLE_CLASSES);
|
||||
if (wrappable == null) {
|
||||
PsiElement emptyTuple = before
|
||||
? findBeforeCaret(file, offset, PyTupleExpression.class)
|
||||
|
||||
@@ -111,6 +111,12 @@ public class PyEditingTest extends PyTestCase {
|
||||
" r'string'");
|
||||
}
|
||||
|
||||
public void testEnterInStringFormatting() { // PY-7039
|
||||
doTestEnter("foo += \"fooba<caret>r\" % foo\n",
|
||||
"foo += \"fooba\" \\\n" +
|
||||
" \"r\" % foo\n");
|
||||
}
|
||||
|
||||
public void testEnterInStatement() {
|
||||
doTestEnter("if a <caret>and b: pass", "if a \\\nand b: pass");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user