split raw string literal (IDEA-190765)

This commit is contained in:
Anna Kozlova
2018-04-28 10:53:28 +03:00
parent e137127cc1
commit ef1a26388f
9 changed files with 119 additions and 3 deletions

View File

@@ -987,6 +987,10 @@
<className>com.intellij.codeInsight.intention.impl.BreakStringOnLineBreaksIntentionAction</className>
<category>Java/Strings</category>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.intention.impl.SplitRawStringIntentionAction</className>
<category>Java/Strings</category>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.intention.impl.ReplaceCastWithVariableAction</className>
<category>Java/Imports</category>

View File

@@ -0,0 +1,86 @@
// 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.intention.impl;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
public class SplitRawStringIntentionAction extends PsiElementBaseIntentionAction {
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
if (!(element instanceof PsiJavaToken)) {
return false;
}
final PsiJavaToken token = (PsiJavaToken)element;
if (token.getTokenType() != JavaTokenType.RAW_STRING_LITERAL) {
return false;
}
final String text = token.getText();
if (text == null) {
return false;
}
int leadingTicsSequence = PsiRawStringLiteralUtil.getLeadingTicsSequence(text);
int trailingTicsSequence = PsiRawStringLiteralUtil.getTrailingTicsSequence(text);
if (leadingTicsSequence == trailingTicsSequence) {
int offset = editor.getCaretModel().getOffset();
int caretInTokenIdx = offset - token.getTextOffset();
if (caretInTokenIdx > leadingTicsSequence &&
offset < token.getTextRange().getEndOffset() - trailingTicsSequence &&
text.charAt(caretInTokenIdx) != '`' &&
text.charAt(caretInTokenIdx - 1) != '`') {
return true;
}
}
return false;
}
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
if (!(element instanceof PsiJavaToken)) {
return;
}
final PsiJavaToken token = (PsiJavaToken)element;
if (token.getTokenType() != JavaTokenType.RAW_STRING_LITERAL) {
return;
}
final String text = token.getText();
if (text == null) {
return;
}
int ticsSequenceLength = PsiRawStringLiteralUtil.getLeadingTicsSequence(text);
String breakSequence = StringUtil.repeat("`", ticsSequenceLength);
int offset = editor.getCaretModel().getOffset();
int splitIdx = offset - token.getTextOffset();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiBinaryExpression concatenation =
(PsiBinaryExpression)token.getParent().replace(factory.createExpressionFromText(text.substring(0, splitIdx) + breakSequence + " + " +
breakSequence + text.substring(splitIdx), element));
editor.getCaretModel().moveToOffset(concatenation.getOperationSign().getTextOffset());
}
@NotNull
@Override
public String getText() {
return getFamilyName();
}
@NotNull
@Override
public String getFamilyName() {
return "Split raw string literal";
}
}

View File

@@ -0,0 +1 @@
String s = ```Hello, ``` + ```world!```;

View File

@@ -0,0 +1 @@
String s = <spot>```Hello, <caret>world!```</spot>;

View File

@@ -0,0 +1,5 @@
<html>
<body>
This intention allows to break raw string literal into 2 parts at caret position.
</body>
</html>

View File

@@ -0,0 +1,5 @@
class Test {
{
String s = ```ab``` <caret>+ ```c```;
}
}

View File

@@ -0,0 +1,5 @@
class Test {
{
String s = ```ab<caret>c```;
}
}

View File

@@ -0,0 +1,5 @@
class Test {
{
String s = ```ab<caret>`c```;
}
}

View File

@@ -40,9 +40,7 @@ public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCa
public void testStringToRawTransformation() { doTestIntention(QuickFixBundle.message("convert.to.raw.string.text")); }
public void testStringToRawTransformationWithWrongSeparators() { doTestIntention(QuickFixBundle.message("convert.to.raw.string.text")); }
public void testStringToRawTransformationLeadingTics() {
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");
@@ -53,6 +51,12 @@ public class LightAdvRawStringLiteralsTest extends LightCodeInsightFixtureTestCa
doTestIntention(QuickFixBundle.message("convert.to.raw.string.text"));
}
public void testSplitRawStringLiteral() { doTestIntention("Split raw string literal"); }
public void testSplitRawStringLiteralDisabledOnTic() {
myFixture.configureByFile(getTestName(false) + ".java");
assertEmpty(myFixture.filterAvailableIntentions("Split raw string literal"));
}
public void testPasteInRawStringLiteral() {
doTestPaste("class A {{String s = `q<caret>`;}}", "a\nb`\nc", "class A {{String s = ``qa\nb`\nc``;}}");
}