convert string to raw string literal intention (IDEA-189855)

This commit is contained in:
Anna.Kozlova
2018-04-13 20:06:15 +02:00
parent 9bc349a38b
commit 3de00fcc41
13 changed files with 136 additions and 5 deletions
@@ -270,6 +270,7 @@ change.to.append.text=Change to ''{0}''
convert.to.string.family=Fix Character Literal
convert.to.string.text=Convert to string literal
convert.to.raw.string.text=Convert to raw string literal
initialize.final.field.in.constructor.name=Initialize in constructor
initialize.final.field.in.constructor.choose.dialog.title=Choose constructors to add initialization to
@@ -949,6 +949,10 @@
<className>com.intellij.codeInsight.daemon.impl.quickfix.ConvertRawToStringLiteralAction</className>
<category>Java/Strings</category>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.daemon.impl.quickfix.ConvertStringLiteralToRawAction</className>
<category>Java/Strings</category>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.intention.impl.InsertLiteralUnderscoresAction</className>
<category>Java/Numbers</category>
@@ -0,0 +1,70 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.editorActions.RawStringLiteralPasteProcessor;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.LowPriorityAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ipp.concatenation.CopyConcatenatedStringToClipboardIntention;
import org.jetbrains.annotations.NotNull;
public class ConvertStringLiteralToRawAction implements IntentionAction, LowPriorityAction {
@NotNull
@Override
public String getText() {
return QuickFixBundle.message("convert.to.raw.string.text");
}
@NotNull
@Override
public String getFamilyName() {
return "Convert to raw string literal";
}
@Override
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
return PsiUtil.isJavaToken(element, JavaTokenType.STRING_LITERAL) &&
PsiUtil.getLanguageLevel(file) == LanguageLevel.JDK_11_PREVIEW;
}
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
final PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
if (element != null && PsiUtil.isJavaToken(element, JavaTokenType.STRING_LITERAL)) {
PsiElement parent = element.getParent();
if (parent instanceof PsiLiteralExpressionImpl) {
PsiElement elementToReplace = parent;
String text;
PsiElement gParent = PsiUtil.skipParenthesizedExprUp(parent.getParent());
if (gParent instanceof PsiPolyadicExpression) {
text = CopyConcatenatedStringToClipboardIntention.buildConcatenationText((PsiPolyadicExpression)gParent);
elementToReplace = gParent;
}
else {
String innerText = ((PsiLiteralExpressionImpl)parent).getInnerText();
if (innerText == null) return;
text = StringUtil.unescapeStringCharacters(innerText);
}
String additionalQuotes = RawStringLiteralPasteProcessor.getAdditionalQuotes(text, "`");
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
CodeStyleManager.getInstance(project).reformat(
elementToReplace.replace(elementFactory.createExpressionFromText('`' + additionalQuotes + text + additionalQuotes + '`', null)));
}
}
}
@Override
public boolean startInWriteAction() {
return true;
}
}
@@ -49,6 +49,12 @@ public class RawStringLiteralPasteProcessor implements PasteProvider {
int quotesLength = getQuotesSequence(literalText, length, 0);
String quotes = literalText.substring(0, quotesLength);
String additionalQuotes = getAdditionalQuotes(text, quotes);
insertAtCaret(text, additionalQuotes, stringLiteral, editor);
}
public static String getAdditionalQuotes(String text, String quotes) {
int quotesLength = quotes.length();
int textLength = text.length();
int idx = quotesLength;
int maxQuotesNumber = -1;
@@ -62,7 +68,7 @@ public class RawStringLiteralPasteProcessor implements PasteProvider {
idx += additionalQuotesLength + quotesLength;
}
insertAtCaret(text, hasToReplace ? StringUtil.repeat("`", maxQuotesNumber + 1) : "", stringLiteral, editor);
return hasToReplace ? StringUtil.repeat("`", maxQuotesNumber + 1) : "";
}
private static int getQuotesSequence(String literalText, int length, int startIndex) {
@@ -0,0 +1,5 @@
String s = <spot>`</spot>raw
string
literal
<spot>`</spot>;
@@ -0,0 +1,3 @@
String s = <spot>"</spot>raw<spot>\n"</spot> +
"string\n" +
"literal";
@@ -0,0 +1,5 @@
<html>
<body>
This intention converts (multi-line) string literal into raw string literal.
</body>
</html>
@@ -0,0 +1,7 @@
class A {
{
String s = `a"
"b
c \`;
}
}
@@ -0,0 +1,7 @@
class A {
{
String s = "a<caret>\"\n" +
"\"b\n" +
"c \\";
}
}
@@ -0,0 +1,7 @@
class A {
{
String s = ``a"
"b`
c \``;
}
}
@@ -0,0 +1,7 @@
class A {
{
String s = "a<caret>\"\n" +
"\"b`\n" +
"c \\";
}
}
@@ -36,6 +36,14 @@ public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCa
doTestIntention(QuickFixBundle.message("convert.to.string.text"));
}
public void testStringToRawTransformation() {
doTestIntention(QuickFixBundle.message("convert.to.raw.string.text"));
}
public void testStringToRawTransformationWithTicsInside() {
doTestIntention(QuickFixBundle.message("convert.to.raw.string.text"));
}
public void testPasteInRawStringLiteral() {
doTestPaste("class A {{String s = `q<caret>`;}}", "a\nb`\nc", "class A {{String s = ``qa\nb`\nc``;}}");
}
@@ -54,11 +54,12 @@ public class CopyConcatenatedStringToClipboardIntention extends Intention {
if (type == null || !type.equalsToText(JAVA_LANG_STRING)) {
return;
}
final StringBuilder text = buildConcatenationText(concatenationExpression, new StringBuilder());
CopyPasteManager.getInstance().setContents(new StringSelection(text.toString()));
final String text = buildConcatenationText(concatenationExpression);
CopyPasteManager.getInstance().setContents(new StringSelection(text));
}
private static StringBuilder buildConcatenationText(PsiPolyadicExpression polyadicExpression, StringBuilder out) {
public static String buildConcatenationText(PsiPolyadicExpression polyadicExpression) {
StringBuilder out = new StringBuilder();
for (PsiElement element : polyadicExpression.getChildren()) {
if (element instanceof PsiExpression) {
final PsiExpression expression = (PsiExpression)element;
@@ -75,6 +76,6 @@ public class CopyConcatenatedStringToClipboardIntention extends Intention {
out.append('\n');
}
}
return out;
return out.toString();
}
}