KT-15553 Support compile constant for "Copy concatenation text to clipboard"

#KT-15553 Fixed
This commit is contained in:
shiraji
2017-01-14 02:31:25 +09:00
committed by Mikhail Glukhikh
parent 909007d984
commit d9ec8a92f2
11 changed files with 79 additions and 11 deletions
@@ -16,8 +16,11 @@
package org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
class ConcatenatedStringGenerator {
fun create(element: KtBinaryExpression): String {
@@ -37,7 +40,7 @@ class ConcatenatedStringGenerator {
is KtBinaryExpression -> this.appendTo(sb)
is KtConstantExpression -> sb.append(text)
is KtStringTemplateExpression -> this.appendTo(sb)
else -> sb.append("?")
else -> sb.append(convertToValueIfCompileTimeConstant() ?: "?")
}
}
@@ -47,8 +50,15 @@ class ConcatenatedStringGenerator {
when (stringTemplate) {
is KtLiteralStringTemplateEntry -> sb.append(stringTemplate.text)
is KtEscapeStringTemplateEntry -> sb.append(stringTemplate.unescapedValue)
else -> sb.append("?")
else -> sb.append(stringTemplate.expression?.convertToValueIfCompileTimeConstant() ?: "?")
}
}
}
private fun KtExpression.convertToValueIfCompileTimeConstant(): String? {
val resolvedCall = getResolvedCall(analyzeFully()) ?: return null
val propertyDescriptor = resolvedCall.resultingDescriptor as? PropertyDescriptor ?: return null
return propertyDescriptor.compileTimeInitializer?.value?.toString()
}
}
+1 -1
View File
@@ -1 +1 @@
"" + 1 + 1.1 + "foo"
val test = "" + 1 + 1.1 + "foo"
@@ -0,0 +1,2 @@
val b = 1
val test = "" + b + "foo"
@@ -0,0 +1 @@
1foo
+1 -1
View File
@@ -1 +1 @@
"foo" + "bar"
val test = "foo" + "bar"
@@ -1 +1,7 @@
"foo$foo$bar" + "${bar}${bar2()}bar"
// WITH_RUNTIME
var foo = "aaa"
var bar = "bbb"
fun bar2() = "will be ignored"
val test = "foo$foo$bar" + "${bar}${bar2()}bar"
@@ -0,0 +1,7 @@
// WITH_RUNTIME
val foo = "aaa"
val bar = "bbb"
fun bar2() = "will be ignored"
val test = "foo$foo$bar" + "${bar}${bar2()}bar"
@@ -0,0 +1 @@
fooaaabbbbbb?bar
+2 -1
View File
@@ -1 +1,2 @@
"" + b<caret> + "foo"
var b = 1
val test = "" + b + "foo"
@@ -16,24 +16,52 @@
package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.psi.PsiDocumentManager
import com.intellij.testFramework.PlatformTestUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.intentions.copyConcatenatedStringToClipboard.ConcatenatedStringGenerator
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import java.io.File
/**
* Compare xxx.kt.result file with the result of ConcatenatedStringGenerator().create(KtBinaryExpression) where KtBinaryExpression is the last KtBinaryExpression of xxx.kt file
*/
abstract class AbstractConcatenatedStringGeneratorTest : KotlinCodeInsightTestCase() {
@Throws(Exception::class)
protected fun doTest(path: String) {
val mainFile = File(path)
val readText = mainFile.readText()
val fileText = 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)
val vFile = LocalFileSystem.getInstance().findFileByPath(path) ?: return
val document = FileDocumentManager.getInstance().getDocument(vFile) ?: return
val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document) ?: return
val isWithRuntime = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// WITH_RUNTIME") != null
try {
if (isWithRuntime) ConfigLibraryUtil.configureKotlinRuntimeAndSdk(module, PluginTestCaseBase.mockJdk())
ConfigLibraryUtil.configureLibrariesByDirective(module, PlatformTestUtil.getCommunityPath(), fileText)
val ktFile = KtPsiFactory(project).createAnalyzableFile("dummy.kt", fileText, psiFile)
val expression = ktFile.collectDescendantsOfType<KtBinaryExpression>().lastOrNull()
TestCase.assertNotNull("No binary expression found: $path", expression)
val generatedString = ConcatenatedStringGenerator().create(expression!!)
TestCase.assertEquals("mismatch '$expectedText' - '$generatedString'", expectedText, generatedString)
}
finally {
ConfigLibraryUtil.unconfigureLibrariesByDirective(myModule, fileText)
if (isWithRuntime) ConfigLibraryUtil.unConfigureKotlinRuntimeAndSdk(module, testProjectJdk)
}
}
}
@@ -42,6 +42,12 @@ public class ConcatenatedStringGeneratorTestGenerated extends AbstractConcatenat
doTest(fileName);
}
@TestMetadata("constants2.kt")
public void testConstants2() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/constants2.kt");
doTest(fileName);
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/simple.kt");
@@ -54,6 +60,12 @@ public class ConcatenatedStringGeneratorTestGenerated extends AbstractConcatenat
doTest(fileName);
}
@TestMetadata("stringtemplateWithConstant.kt")
public void testStringtemplateWithConstant() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/stringtemplateWithConstant.kt");
doTest(fileName);
}
@TestMetadata("variables.kt")
public void testVariables() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/concatenatedStringGenerator/variables.kt");