mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
string -> raw: process leading/tailing tics (IDEA-189855)
This commit is contained in:
+22
-5
@@ -2,7 +2,6 @@
|
||||
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;
|
||||
@@ -33,8 +32,15 @@ public class ConvertStringLiteralToRawAction implements IntentionAction, LowPrio
|
||||
@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;
|
||||
if (PsiUtil.isJavaToken(element, JavaTokenType.STRING_LITERAL) &&
|
||||
PsiUtil.getLanguageLevel(file) == LanguageLevel.JDK_11_PREVIEW) {
|
||||
PsiElement parent = element.getParent();
|
||||
if (parent instanceof PsiLiteralExpressionImpl) {
|
||||
String text = ((PsiLiteralExpressionImpl)parent).getInnerText();
|
||||
return text != null && PsiRawStringLiteralUtil.getLeadingTicsSequence(text) < text.length();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,10 +61,21 @@ public class ConvertStringLiteralToRawAction implements IntentionAction, LowPrio
|
||||
if (innerText == null) return;
|
||||
text = StringUtil.unescapeStringCharacters(innerText);
|
||||
}
|
||||
String additionalQuotes = RawStringLiteralPasteProcessor.getAdditionalQuotes(text, "`");
|
||||
String prefix = "";
|
||||
int startingSeq = PsiRawStringLiteralUtil.getLeadingTicsSequence(text);
|
||||
if (startingSeq > 0) {
|
||||
prefix = "\"" + StringUtil.repeat("`", startingSeq) + "\" + ";
|
||||
}
|
||||
String suffix = "";
|
||||
int tailingSequence = PsiRawStringLiteralUtil.getTailingTicsSequence(text);
|
||||
if (tailingSequence > 0) {
|
||||
suffix = "+ \"" + StringUtil.repeat("`", tailingSequence) + "\"";
|
||||
}
|
||||
String textTicsTrimmed = text.substring(Math.max(startingSeq, 0), text.length() - Math.max(tailingSequence, 0));
|
||||
String additionalQuotes = PsiRawStringLiteralUtil.getAdditionalTics(textTicsTrimmed, "`");
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
CodeStyleManager.getInstance(project).reformat(
|
||||
elementToReplace.replace(elementFactory.createExpressionFromText('`' + additionalQuotes + text + additionalQuotes + '`', null)));
|
||||
elementToReplace.replace(elementFactory.createExpressionFromText(prefix + '`' + additionalQuotes + textTicsTrimmed + additionalQuotes + '`' + suffix, null)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-34
@@ -13,11 +13,7 @@ import com.intellij.openapi.editor.EditorModificationUtil;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -45,38 +41,12 @@ public class RawStringLiteralPasteProcessor implements PasteProvider {
|
||||
if (stringLiteral == null) return;
|
||||
|
||||
String literalText = stringLiteral.getText();
|
||||
int length = literalText.length();
|
||||
int quotesLength = getQuotesSequence(literalText, length, 0);
|
||||
|
||||
String quotes = literalText.substring(0, quotesLength);
|
||||
String additionalQuotes = getAdditionalQuotes(text, quotes);
|
||||
int ticsLength = PsiRawStringLiteralUtil.getLeadingTicsSequence(literalText);
|
||||
String quotes = literalText.substring(0, ticsLength);
|
||||
String additionalQuotes = PsiRawStringLiteralUtil.getAdditionalTics(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;
|
||||
boolean hasToReplace = false;
|
||||
while ((idx = text.indexOf(quotes, idx)) > 0 && idx < textLength) {
|
||||
int additionalQuotesLength = getQuotesSequence(text, textLength, idx + quotesLength);
|
||||
if (additionalQuotesLength == 0) {
|
||||
hasToReplace = true;
|
||||
}
|
||||
maxQuotesNumber = Math.max(maxQuotesNumber, additionalQuotesLength);
|
||||
idx += additionalQuotesLength + quotesLength;
|
||||
}
|
||||
|
||||
return hasToReplace ? StringUtil.repeat("`", maxQuotesNumber + 1) : "";
|
||||
}
|
||||
|
||||
private static int getQuotesSequence(String literalText, int length, int startIndex) {
|
||||
int quotesLength = startIndex;
|
||||
while (quotesLength < length && literalText.charAt(quotesLength) == '`') quotesLength++;
|
||||
return quotesLength - startIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPastePossible(@NotNull DataContext dataContext) {
|
||||
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
// 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.psi;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
|
||||
public class PsiRawStringLiteralUtil {
|
||||
/**
|
||||
* Check if <code>text</code> contains <code>tics</code>, and
|
||||
* if yes, returns the number of additional tics required around text to have a valid raw string literal
|
||||
* empty string otherwise
|
||||
*/
|
||||
public static String getAdditionalTics(String text, String tics) {
|
||||
int quotesLength = tics.length();
|
||||
int textLength = text.length();
|
||||
int idx = quotesLength;
|
||||
int maxQuotesNumber = -1;
|
||||
boolean hasToReplace = false;
|
||||
while ((idx = text.indexOf(tics, idx)) > 0 && idx < textLength) {
|
||||
int additionalQuotesLength = getTicsSequence(text, textLength, idx + quotesLength);
|
||||
if (additionalQuotesLength == 0) {
|
||||
hasToReplace = true;
|
||||
}
|
||||
maxQuotesNumber = Math.max(maxQuotesNumber, additionalQuotesLength);
|
||||
idx += additionalQuotesLength + quotesLength;
|
||||
}
|
||||
|
||||
return hasToReplace ? StringUtil.repeat("`", maxQuotesNumber + 1) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of leading tics in the <code>text</code>
|
||||
*/
|
||||
public static int getLeadingTicsSequence(String text) {
|
||||
return getTicsSequence(text, text.length(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of tailing tics in the <code>text</code>
|
||||
*/
|
||||
public static int getTailingTicsSequence(String text) {
|
||||
int length = text.length();
|
||||
while (length > 0 && text.charAt(length - 1) == '`') length--;
|
||||
return text.length() - length;
|
||||
}
|
||||
|
||||
private static int getTicsSequence(String literalText, int length, int startIndex) {
|
||||
int quotesLength = startIndex;
|
||||
while (quotesLength < length && literalText.charAt(quotesLength) == '`') quotesLength++;
|
||||
return quotesLength - startIndex;
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
{
|
||||
String s = "````" + `a` + "`";
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
{
|
||||
String s = "````<caret>a`";
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
{
|
||||
String s = "````<caret>`";
|
||||
}
|
||||
}
|
||||
+9
@@ -40,6 +40,15 @@ public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCa
|
||||
doTestIntention(QuickFixBundle.message("convert.to.raw.string.text"));
|
||||
}
|
||||
|
||||
public void testStringToRawTransformationLeadingTics() {
|
||||
doTestIntention(QuickFixBundle.message("convert.to.raw.string.text"));
|
||||
}
|
||||
|
||||
public void testStringToRawTransformationOnlyTics() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
assertEmpty(myFixture.filterAvailableIntentions(QuickFixBundle.message("convert.to.raw.string.text")));
|
||||
}
|
||||
|
||||
public void testStringToRawTransformationWithTicsInside() {
|
||||
doTestIntention(QuickFixBundle.message("convert.to.raw.string.text"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user