Adapt PyQuotedStringIntention to use as public API

PY-65297

GitOrigin-RevId: 0d5184be120393144eaf10c66d7dd2c1ed219ede
This commit is contained in:
Georgii Ustinov
2024-02-12 10:38:29 +02:00
committed by intellij-monorepo-bot
parent 79b0c8f4ce
commit ad7870a802

View File

@@ -5,9 +5,12 @@ import com.intellij.modcommand.ActionContext;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.Presentation;
import com.intellij.modcommand.PsiUpdateModCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.PyTokenTypes;
@@ -15,6 +18,8 @@ import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import static com.jetbrains.python.psi.PyUtil.as;
/**
@@ -28,19 +33,11 @@ public final class PyQuotedStringIntention extends PsiUpdateModCommandAction<Psi
@Override
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiElement element) {
if (!(context.file() instanceof PyFile)) {
return null;
}
PyStringElement stringElement = findConvertibleStringElementUnderCaret(element);
if (stringElement == null) return null;
PyStringLiteralExpression stringLiteral = as(stringElement.getParent(), PyStringLiteralExpression.class);
if (stringLiteral == null) return null;
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(stringLiteral, PyDocStringOwner.class);
if (docStringOwner != null && docStringOwner.getDocStringExpression() == stringLiteral) return null;
if (!isAvailable(context.file(), element)) return null;
PyStringElement stringElement = Objects.requireNonNull(findConvertibleStringElementUnderCaret(element));
String currentQuote = stringElement.getQuote();
if (currentQuote.equals("'")) {
return Presentation.of(PyPsiBundle.message("INTN.quoted.string.single.to.double"));
}
@@ -65,6 +62,35 @@ public final class PyQuotedStringIntention extends PsiUpdateModCommandAction<Psi
@Override
protected void invoke(@NotNull ActionContext context, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
invoke(element);
}
public static void invoke(@NotNull Editor editor, @NotNull PsiFile file) throws IncorrectOperationException {
PsiElement elementUnderCaret = file.findElementAt(editor.getCaretModel().getOffset());
if (elementUnderCaret == null) return;
invoke(elementUnderCaret);
}
public static boolean isAvailable(@NotNull Editor editor, @NotNull PsiFile file) {
PsiElement elementUnderCaret = file.findElementAt(editor.getCaretModel().getOffset());
if (elementUnderCaret == null) return false;
return isAvailable(file, elementUnderCaret);
}
private static boolean isAvailable(@NotNull PsiFile file, @NotNull PsiElement element) {
if (!(file instanceof PyFile)) return false;
PyStringElement stringElement = findConvertibleStringElementUnderCaret(element);
if (stringElement == null) return false;
PyStringLiteralExpression stringLiteral = as(stringElement.getParent(), PyStringLiteralExpression.class);
if (stringLiteral == null) return false;
final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(stringLiteral, PyDocStringOwner.class);
if (docStringOwner != null && docStringOwner.getDocStringExpression() == stringLiteral) return false;
return true;
}
private static void invoke(@NotNull PsiElement element) {
PyStringElement stringElement = PsiTreeUtil.getParentOfType(element, PyStringElement.class, false, PyExpression.class);
if (stringElement == null) return;
PyStringLiteralExpression stringLiteral = as(stringElement.getParent(), PyStringLiteralExpression.class);
@@ -72,7 +98,8 @@ public final class PyQuotedStringIntention extends PsiUpdateModCommandAction<Psi
String originalQuote = stringElement.getQuote();
boolean entireLiteralCanBeConverted = ContainerUtil.all(stringLiteral.getStringElements(),
s -> s.getQuote().equals(originalQuote) && PyQuotesUtil.canBeConverted(s, true));
s -> s.getQuote().equals(originalQuote) &&
PyQuotesUtil.canBeConverted(s, true));
if (entireLiteralCanBeConverted) {
stringLiteral.getStringElements().forEach(PyQuotedStringIntention::convertStringElement);
}