ConvertToConcatenatedStringIntention - minor code improvements + fixed bug

This commit is contained in:
Valentin Kipyatkov
2015-04-14 22:04:40 +03:00
parent b980d98af6
commit 0334ad1152
5 changed files with 34 additions and 27 deletions
@@ -339,8 +339,6 @@ convert.to.for.each.function.call.intention=Replace with a forEach function call
convert.to.for.each.function.call.intention.family=Replace with a forEach Function Call
convert.to.string.template=Convert concatenation to template
convert.to.string.template.family=Convert Concatenation to Template
convert.to.concatenated.string.intention=Convert template to concatenated string
convert.to.concatenated.string.intention.family=Convert Template to Concatenated String
property.is.implemented.too.many=Has implementations
property.is.overridden.too.many=Is overridden in subclasses
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.lexer.JetTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContextUtils
public class ConvertToConcatenatedStringIntention : JetSelfTargetingOffsetIndependentIntention<JetStringTemplateExpression>("convert.to.concatenated.string.intention", javaClass()) {
public class ConvertToConcatenatedStringIntention : JetSelfTargetingOffsetIndependentIntention<JetStringTemplateExpression>(javaClass(), "Convert template to concatenated string") {
override fun isApplicableTo(element: JetStringTemplateExpression): Boolean {
if (element.getLastChild().getNode().getElementType() != JetTokens.CLOSING_QUOTE) return false // not available for unclosed literal
return element.getEntries().any { it is JetStringTemplateEntryWithExpression }
@@ -34,46 +34,47 @@ public class ConvertToConcatenatedStringIntention : JetSelfTargetingOffsetIndepe
val quote = if (tripleQuoted) "\"\"\"" else "\""
val entries = element.getEntries()
val result = entries.sequence()
val text = entries
.filterNot { it is JetStringTemplateEntryWithExpression && it.getExpression() == null }
.mapIndexed { index, entry ->
entry.toSeparateString(quote, convertExplicitly = index == 0, isFinalEntry = index == entries.size() - 1)
entry.toSeparateString(quote, convertExplicitly = (index == 0), isFinalEntry = (index == entries.lastIndex))
}
.join(separator = "+")
.replaceAll("""$quote\+$quote""", "")
val replacement = JetPsiFactory(element).createExpression(result)
val replacement = JetPsiFactory(element).createExpression(text)
element.replace(replacement)
}
private fun isTripleQuoted(str: String) = str.startsWith("\"\"\"") && str.endsWith("\"\"\"")
private fun JetStringTemplateEntry.toSeparateString(quote: String, convertExplicitly: Boolean, isFinalEntry: Boolean): String {
if (this !is JetStringTemplateEntryWithExpression) return getText()!!.quote(quote)
val expression = getExpression()!!
val expressionText = if (needsParenthesis(expression, isFinalEntry)) "(${expression.getText()})" else expression.getText()!!
return if (convertExplicitly && !expression.isStringExpression()) {
expressionText + ".toString()"
}
else {
expressionText
if (this !is JetStringTemplateEntryWithExpression) {
return getText().quote(quote)
}
val expression = getExpression()!! // checked before
val text = if (needsParenthesis(expression, isFinalEntry))
"(" + expression.getText() + ")"
else
expression.getText()
return if (convertExplicitly && !expression.isStringExpression())
text + ".toString()"
else
text
}
private fun needsParenthesis(expression: JetExpression, isFinalEntry: Boolean) = when (expression) {
is JetBinaryExpression -> true
is JetIfExpression -> expression.getElse() !is JetBlockExpression && !isFinalEntry
else -> false
private fun needsParenthesis(expression: JetExpression, isFinalEntry: Boolean): Boolean {
return when (expression) {
is JetBinaryExpression -> true
is JetIfExpression -> expression.getElse() !is JetBlockExpression && !isFinalEntry
else -> false
}
}
private fun String.quote(quote: String) = quote + this + quote
private fun JetExpression.isStringExpression(): Boolean {
val context = this.analyze()
val elementType = BindingContextUtils.getRecordedTypeInfo(this, context)?.getType()
return KotlinBuiltIns.isString(elementType)
}
private fun JetExpression.isStringExpression() = KotlinBuiltIns.isString(BindingContextUtils.getRecordedTypeInfo(this, analyze())?.getType())
}
@@ -0,0 +1 @@
val v = <caret>"${}saasd"
@@ -0,0 +1 @@
val v = "saasd"
@@ -3214,6 +3214,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("emptyBraces.kt")
public void testEmptyBraces() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToConcatenatedStringIntention/emptyBraces.kt");
doTest(fileName);
}
@TestMetadata("handlesEscapeString.kt")
public void testHandlesEscapeString() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToConcatenatedStringIntention/handlesEscapeString.kt");