Add "Copy concatenation text to clipboard" intention #KT-13744 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
023c02deb3
commit
391a0fdde5
@@ -90,6 +90,7 @@ import org.jetbrains.kotlin.idea.imports.AbstractOptimizeImportsTest
|
||||
import org.jetbrains.kotlin.idea.intentions.AbstractIntentionTest
|
||||
import org.jetbrains.kotlin.idea.intentions.AbstractIntentionTest2
|
||||
import org.jetbrains.kotlin.idea.intentions.AbstractMultiFileIntentionTest
|
||||
import org.jetbrains.kotlin.idea.intentions.AbstractConcatenatedStringGeneratorTest
|
||||
import org.jetbrains.kotlin.idea.intentions.declarations.AbstractJoinLinesTest
|
||||
import org.jetbrains.kotlin.idea.internal.AbstractBytecodeToolWindowTest
|
||||
import org.jetbrains.kotlin.idea.kdoc.AbstractKDocHighlightingTest
|
||||
@@ -529,6 +530,10 @@ fun main(args: Array<String>) {
|
||||
model("intentions/loopToCallChain", pattern = "^([\\w\\-_]+)\\.kt$")
|
||||
}
|
||||
|
||||
testClass<AbstractConcatenatedStringGeneratorTest> {
|
||||
model("concatenatedStringGenerator", pattern = "^([\\w\\-_]+)\\.kt$")
|
||||
}
|
||||
|
||||
testClass<AbstractInspectionTest>() {
|
||||
model("intentions", pattern = "^(inspections\\.test)$", singleClass = true)
|
||||
model("inspections", pattern = "^(inspections\\.test)$", singleClass = true)
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
the following text is copied to the clipboard:
|
||||
s: ? t: ?
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun p(s: String, t: String) {
|
||||
println(<spot>"s: $s t: $t"</spot>)
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention copies the text of a <b>String</b> concatenation
|
||||
to the system clipboard. This can be useful for example when you have a multi-line SQL query in
|
||||
your code, split into concatenated lines which you need to copy to an external application.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1354,6 +1354,11 @@
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard.CopyConcatenatedStringToClipboardIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupName="Kotlin"
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard
|
||||
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
|
||||
class ConcatenatedStringGenerator {
|
||||
fun create(element: KtBinaryExpression): String {
|
||||
val binaryExpression = KtPsiUtil.getTopmostParentOfTypes(element, KtBinaryExpression::class.java) as? KtBinaryExpression ?: element
|
||||
val stringBuilder = StringBuilder()
|
||||
binaryExpression.appendTo(stringBuilder)
|
||||
return stringBuilder.toString()
|
||||
}
|
||||
|
||||
private fun KtBinaryExpression.appendTo(sb: StringBuilder) {
|
||||
left?.appendTo(sb)
|
||||
right?.appendTo(sb)
|
||||
}
|
||||
|
||||
private fun KtExpression.appendTo(sb: StringBuilder) {
|
||||
when (this) {
|
||||
is KtBinaryExpression -> this.appendTo(sb)
|
||||
is KtConstantExpression -> sb.append(text)
|
||||
is KtStringTemplateExpression -> this.appendTo(sb)
|
||||
else -> sb.append("?")
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtStringTemplateExpression.appendTo(sb: StringBuilder) {
|
||||
collectDescendantsOfType<KtStringTemplateEntry>().forEach {
|
||||
stringTemplate ->
|
||||
when (stringTemplate) {
|
||||
is KtLiteralStringTemplateEntry -> sb.append(stringTemplate.text)
|
||||
is KtEscapeStringTemplateEntry -> sb.append(stringTemplate.unescapedValue)
|
||||
else -> sb.append("?")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.ide.CopyPasteManager
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.intentions.SelfTargetingOffsetIndependentIntention
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import java.awt.datatransfer.StringSelection
|
||||
|
||||
class CopyConcatenatedStringToClipboardIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
|
||||
KtBinaryExpression::class.java, "Copy concatenation text to clipboard") {
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
|
||||
val text = ConcatenatedStringGenerator().create(element)
|
||||
CopyPasteManager.getInstance().setContents(StringSelection(text))
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
||||
if (element.operationToken != KtTokens.PLUS) return false
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return false
|
||||
return KotlinBuiltIns.isString(resolvedCall.candidateDescriptor.returnType)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
"" + 1 + 1.1 + "foo"
|
||||
@@ -0,0 +1 @@
|
||||
11.1foo
|
||||
@@ -0,0 +1 @@
|
||||
"foo" + "bar"
|
||||
@@ -0,0 +1 @@
|
||||
foobar
|
||||
@@ -0,0 +1 @@
|
||||
"foo$foo$bar" + "${bar}${bar2()}bar"
|
||||
@@ -0,0 +1 @@
|
||||
foo????bar
|
||||
@@ -0,0 +1 @@
|
||||
"" + b<caret> + "foo"
|
||||
@@ -0,0 +1 @@
|
||||
?foo
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard.CopyConcatenatedStringToClipboardIntention
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: true
|
||||
// INTENTION_TEXT: Copy concatenation text to clipboard
|
||||
|
||||
val s = "" + 1<caret> + 1.1 + "foo"
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: true
|
||||
// INTENTION_TEXT: Copy concatenation text to clipboard
|
||||
|
||||
val s = "" + 1 + 1.1 + "foo"
|
||||
@@ -0,0 +1,3 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
val foo = 1 + <caret>1
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: true
|
||||
// INTENTION_TEXT: Copy concatenation text to clipboard
|
||||
|
||||
val foo = "foo"<caret> + "bar"
|
||||
@@ -0,0 +1,4 @@
|
||||
// IS_APPLICABLE: true
|
||||
// INTENTION_TEXT: Copy concatenation text to clipboard
|
||||
|
||||
val foo = "foo" + "bar"
|
||||
@@ -0,0 +1,3 @@
|
||||
// IS_APPLICABLE: false
|
||||
|
||||
val foo = "foo"<caret>
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: true
|
||||
// INTENTION_TEXT: Copy concatenation text to clipboard
|
||||
|
||||
val b = 100
|
||||
val s = "" + b<caret> + "foo"
|
||||
@@ -0,0 +1,5 @@
|
||||
// IS_APPLICABLE: true
|
||||
// INTENTION_TEXT: Copy concatenation text to clipboard
|
||||
|
||||
val b = 100
|
||||
val s = "" + b + "foo"
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard.ConcatenatedStringGenerator
|
||||
import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractConcatenatedStringGeneratorTest : KotlinCodeInsightTestCase() {
|
||||
|
||||
@Throws(Exception::class)
|
||||
protected fun doTest(path: String) {
|
||||
val mainFile = File(path)
|
||||
val readText = mainFile.readText()
|
||||
val resultFile = File("$path.result")
|
||||
val expectedText = resultFile.readText()
|
||||
val expression = KtPsiFactory(project).createExpression(readText) as? KtBinaryExpression
|
||||
TestCase.assertNotNull("Invalid expression: $readText", expression)
|
||||
val generatedString = ConcatenatedStringGenerator().create(expression!!)
|
||||
TestCase.assertEquals("mismatch '$expectedText' - '$generatedString'", expectedText, generatedString)
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("idea/testData/concatenatedStringGenerator")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class ConcatenatedStringGeneratorTestGenerated extends AbstractConcatenatedStringGeneratorTest {
|
||||
public void testAllFilesPresentInConcatenatedStringGenerator() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/concatenatedStringGenerator"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/constants.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("stringtemplate.kt")
|
||||
public void testStringtemplate() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/stringtemplate.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("variables.kt")
|
||||
public void testVariables() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/variables.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
@@ -5490,6 +5490,45 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CopyConcatenatedStringToClipboard extends AbstractIntentionTest {
|
||||
public void testAllFilesPresentInCopyConcatenatedStringToClipboard() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/copyConcatenatedStringToClipboard"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("constants.kt")
|
||||
public void testConstants() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard/constants.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("numbers.kt")
|
||||
public void testNumbers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard/numbers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simpleString.kt")
|
||||
public void testSimpleString() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard/simpleString.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("variables.kt")
|
||||
public void testVariables() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard/variables.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/declarations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user