mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
convert raw literal to string intention (IDEA-189855)
This commit is contained in:
@@ -945,6 +945,10 @@
|
||||
<className>com.intellij.codeInsight.daemon.impl.quickfix.ConvertToStringLiteralAction</className>
|
||||
<category>Java/Strings</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.daemon.impl.quickfix.ConvertRawToStringLiteralAction</className>
|
||||
<category>Java/Strings</category>
|
||||
</intentionAction>
|
||||
<intentionAction>
|
||||
<className>com.intellij.codeInsight.intention.impl.InsertLiteralUnderscoresAction</className>
|
||||
<category>Java/Numbers</category>
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// 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.StringLiteralCopyPasteProcessor;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ConvertRawToStringLiteralAction implements IntentionAction {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return QuickFixBundle.message("convert.to.string.text");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Convert raw to 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.RAW_STRING_LITERAL);
|
||||
}
|
||||
|
||||
@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.RAW_STRING_LITERAL)) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiLiteralExpressionImpl) {
|
||||
String text = ((PsiLiteralExpressionImpl)parent).getRawString();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
PsiElement literalToken = elementFactory.createExpressionFromText("\"\"", file).getFirstChild();
|
||||
String preprocessedValue = new StringLiteralCopyPasteProcessor().escapeAndSplit(text, literalToken);
|
||||
CodeStyleManager.getInstance(project).reformat(
|
||||
parent.replace(elementFactory.createExpressionFromText('\"' + preprocessedValue + '\"', null)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -132,19 +132,7 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
if (rawText != null && wasUnescaped(text, rawText.rawText)) return rawText.rawText;
|
||||
|
||||
if (isStringLiteral(token)) {
|
||||
StringBuilder buffer = new StringBuilder(text.length());
|
||||
@NonNls String breaker = getLineBreaker(token);
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
buffer.append(escapeCharCharacters(lines[i], token));
|
||||
if (i != lines.length - 1) {
|
||||
buffer.append(breaker);
|
||||
}
|
||||
else if (text.endsWith("\n")) {
|
||||
buffer.append("\\n");
|
||||
}
|
||||
}
|
||||
text = buffer.toString();
|
||||
text = escapeAndSplit(text, token);
|
||||
}
|
||||
else if (isCharLiteral(token)) {
|
||||
return escapeCharCharacters(text, token);
|
||||
@@ -152,6 +140,23 @@ public class StringLiteralCopyPasteProcessor implements CopyPastePreProcessor {
|
||||
return text;
|
||||
}
|
||||
|
||||
public String escapeAndSplit(String text, PsiElement token) {
|
||||
StringBuilder buffer = new StringBuilder(text.length());
|
||||
@NonNls String breaker = getLineBreaker(token);
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
buffer.append(escapeCharCharacters(lines[i], token));
|
||||
if (i != lines.length - 1) {
|
||||
buffer.append(breaker);
|
||||
}
|
||||
else if (text.endsWith("\n")) {
|
||||
buffer.append("\\n");
|
||||
}
|
||||
}
|
||||
text = buffer.toString();
|
||||
return text;
|
||||
}
|
||||
|
||||
private static boolean wasUnescaped(String text, String originalText) {
|
||||
try {
|
||||
return new TextBlockTransferable(unescapeStringCharacters(originalText), Collections.emptyList(), null)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
String s = <spot>"</spot>raw<spot>\n"</spot> +
|
||||
"string\n" +
|
||||
"literal";
|
||||
@@ -0,0 +1,4 @@
|
||||
String s = <spot>`</spot>raw
|
||||
string
|
||||
literal
|
||||
<spot>`</spot>;
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention converts raw string literal into (multi-line) string literal.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
{
|
||||
String s = "a\n" +
|
||||
" symbol to escape: \"\\\" (slash)\n" +
|
||||
" and something else as well\n" +
|
||||
" ";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
{
|
||||
String s = `a
|
||||
symbol to escape: "\" (slash)
|
||||
and somet<caret>hing else as well
|
||||
`;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
package com.intellij.java.codeInsight.daemon;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.psi.JavaPsiFacade;
|
||||
import com.intellij.psi.PsiElementFactory;
|
||||
@@ -11,6 +13,8 @@ import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
@@ -28,6 +32,10 @@ public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCa
|
||||
doTestHighlighting();
|
||||
}
|
||||
|
||||
public void testRawToStringTransformation() {
|
||||
doTestIntention(QuickFixBundle.message("convert.to.string.text"));
|
||||
}
|
||||
|
||||
public void testPasteInRawStringLiteral() {
|
||||
doTestPaste("class A {{String s = `q<caret>`;}}", "a\nb`\nc", "class A {{String s = ``qa\nb`\nc``;}}");
|
||||
}
|
||||
@@ -70,6 +78,14 @@ public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCa
|
||||
myFixture.checkResult(expectedDocumentText);
|
||||
}
|
||||
|
||||
private void doTestIntention(final String hint) {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
List<IntentionAction> actions = myFixture.filterAvailableIntentions(hint);
|
||||
assertNotEmpty(actions);
|
||||
myFixture.launchAction(actions.get(0));
|
||||
myFixture.checkResultByFile(getTestName(false) + ".after.java");
|
||||
}
|
||||
|
||||
private void performPaste() {
|
||||
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_PASTE);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user