mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 19:02:13 +07:00
[groovy] handle raw paste in single and double quoted string literals (IDEA-223211)
GitOrigin-RevId: 12ae0f67a5092bade271a23100bf1ec2835d9fa5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
57ece59604
commit
f94a007182
+28
@@ -0,0 +1,28 @@
|
||||
// Copyright 2000-2019 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 org.jetbrains.plugins.groovy.lang.psi.util
|
||||
|
||||
fun isValidSingleQuotedStringContent(text: String): Boolean = isValidContent(text, '\'', '\n')
|
||||
|
||||
fun isValidDoubleQuotedStringContent(text: String): Boolean = isValidContent(text, '"', '$', '\n')
|
||||
|
||||
private fun isValidContent(text: String, vararg escapedChars: Char): Boolean {
|
||||
val length: Int = text.length
|
||||
var idx = 0
|
||||
while (idx < length) {
|
||||
val ch: Char = text[idx]
|
||||
if (ch in escapedChars) {
|
||||
return false
|
||||
}
|
||||
if (ch == '\\') {
|
||||
if (idx + 1 < length) {
|
||||
val nextCh: Char = text[idx + 1]
|
||||
if (nextCh == '\\' || nextCh in escapedChars) {
|
||||
idx += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
idx++
|
||||
}
|
||||
return true
|
||||
}
|
||||
+20
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyTokenSets;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.StringKind;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.StringUtilKt;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.GroovyStringLiteralManipulator;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.GroovyElementTypes.*;
|
||||
@@ -68,6 +69,10 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce
|
||||
return text;
|
||||
}
|
||||
|
||||
if (rawText != null && canPasteRaw(text, rawText.rawText, stringKind)) {
|
||||
return rawText.rawText;
|
||||
}
|
||||
|
||||
StringBuilder buffer = new StringBuilder(text.length());
|
||||
@NonNls String breaker = stringKind.getLineBreaker();
|
||||
final String[] lines = LineTokenizer.tokenize(text.toCharArray(), false, true);
|
||||
@@ -80,6 +85,21 @@ public class GroovyLiteralCopyPasteProcessor extends StringLiteralCopyPasteProce
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static boolean canPasteRaw(String text, String rawText, StringKind kind) {
|
||||
if (!text.equals(kind.unescape(rawText))) {
|
||||
return false;
|
||||
}
|
||||
if (kind == StringKind.SINGLE_QUOTED) {
|
||||
return StringUtilKt.isValidSingleQuotedStringContent(rawText);
|
||||
}
|
||||
else if (kind == StringKind.DOUBLE_QUOTED) {
|
||||
return StringUtilKt.isValidDoubleQuotedStringContent(rawText);
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String escape(@NotNull StringKind kind, @NotNull String s) {
|
||||
if (kind != StringKind.DOUBLE_QUOTED && kind != StringKind.TRIPLE_DOUBLE_QUOTED) {
|
||||
|
||||
@@ -177,6 +177,17 @@ class GroovyCopyPasteStringTest extends GroovyLatestTest implements BaseTest {
|
||||
}.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'paste raw'() {
|
||||
def data = [
|
||||
['\'<selection>\\$ \\\' \\" \\\n \\u2318</selection>\'', '"<caret>"', '"\\$ \\\' \\" \\\n \\u2318"'],
|
||||
['"<selection>\\$ \\\' \\" \\\n \\u2318</selection>"', "'<caret>'", '\'\\$ \\\' \\" \\\n \\u2318\'']
|
||||
]
|
||||
RunAll.runAll(data) { List<String> entry ->
|
||||
doCopyPasteTest(entry[0], entry[1], entry[2])
|
||||
}.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'multiline paste'() {
|
||||
def from = '<selection>hi\nthere</selection>'
|
||||
@@ -193,6 +204,22 @@ class GroovyCopyPasteStringTest extends GroovyLatestTest implements BaseTest {
|
||||
}.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'multiline paste raw'() {
|
||||
def from = '$/<selection>hi\nthere\\u2318</selection>/$'
|
||||
def data = [
|
||||
/'<caret>'/ : "'hi\\n' +\n 'there⌘'", // cannot paste raw
|
||||
/'''<caret>'''/: "'''hi\nthere\\u2318'''",
|
||||
/"<caret>"/ : '"hi\\n" +\n "there⌘"', // cannot paste raw
|
||||
/"""<caret>"""/: '"""hi\nthere\\u2318"""',
|
||||
'/ <caret>/' : '/ hi\nthere\\u2318/',
|
||||
'$/<caret>/$' : '$/hi\nthere\\u2318/$',
|
||||
]
|
||||
RunAll.runAll(data) { to, expected ->
|
||||
doCopyPasteTest(from, to, expected)
|
||||
}.run()
|
||||
}
|
||||
|
||||
@Test
|
||||
void 'paste injection'() {
|
||||
def data = [
|
||||
|
||||
Reference in New Issue
Block a user