diff --git a/.idea/dictionaries/valentin.xml b/.idea/dictionaries/valentin.xml
index 4d43f5a42cc..b033708428b 100644
--- a/.idea/dictionaries/valentin.xml
+++ b/.idea/dictionaries/valentin.xml
@@ -17,6 +17,7 @@
renderers
rparenth
selectioner
+ summand
unpluralize
weighers
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt
index a8729c45852..6622d26ebdd 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToStringTemplateIntention.kt
@@ -56,11 +56,19 @@ class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIntention
private fun isApplicableToNoParentCheck(expression: KtBinaryExpression): Boolean {
if (expression.operationToken != KtTokens.PLUS) return false
- if (!KotlinBuiltIns.isString(expression.analyze().getType(expression))) return false
+ val expressionType = expression.analyze(BodyResolveMode.PARTIAL).getType(expression)
+ if (!KotlinBuiltIns.isString(expressionType)) return false
+ return isSuitable(expression)
+ }
- val left = expression.left ?: return false
- val right = expression.right ?: return false
- return !PsiUtilCore.hasErrorElementChild(left) && !PsiUtilCore.hasErrorElementChild(right)
+ private fun isSuitable(expression: KtExpression): Boolean {
+ if (expression is KtBinaryExpression && expression.operationToken == KtTokens.PLUS) {
+ return isSuitable(expression.left ?: return false) && isSuitable(expression.right ?: return false)
+ }
+
+ if (PsiUtilCore.hasErrorElementChild(expression)) return false
+ if (expression.textContains('\n')) return false
+ return true
}
private fun buildReplacement(expression: KtBinaryExpression): KtStringTemplateExpression {
@@ -121,6 +129,6 @@ class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIntention
return "$" + (if (forceBraces) "{$expressionText}" else expressionText)
}
- return "\${" + expressionText.replace("\n+".toRegex(), " ") + "}"
+ return "\${$expressionText}"
}
}
diff --git a/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt b/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt
index 5eef6cf6e1a..c60d93b6277 100644
--- a/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt
+++ b/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt
@@ -1,3 +1,4 @@
+// IS_APPLICABLE: false
fun main(args: Array){
val x = "foo" + """bar\n
"""
diff --git a/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt.after b/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt.after
deleted file mode 100644
index d34755ac9da..00000000000
--- a/idea/testData/intentions/convertToStringTemplate/backslashNMultilineString.kt.after
+++ /dev/null
@@ -1,3 +0,0 @@
-fun main(args: Array){
- val x = "foobar\\n\n "
-}
diff --git a/idea/testData/intentions/convertToStringTemplate/comment.kt b/idea/testData/intentions/convertToStringTemplate/comment.kt
new file mode 100644
index 00000000000..edf8356ebf6
--- /dev/null
+++ b/idea/testData/intentions/convertToStringTemplate/comment.kt
@@ -0,0 +1 @@
+val v = "a" + (1.hashCode() /*comment*/ * 2)
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToStringTemplate/comment.kt.after b/idea/testData/intentions/convertToStringTemplate/comment.kt.after
new file mode 100644
index 00000000000..d4a33e8f476
--- /dev/null
+++ b/idea/testData/intentions/convertToStringTemplate/comment.kt.after
@@ -0,0 +1 @@
+val v = "a${1.hashCode() /*comment*/ * 2}"
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt b/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt
index b2840bff266..89edcd85c06 100644
--- a/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt
+++ b/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt
@@ -1,4 +1,5 @@
// WITH_RUNTIME
+// IS_APPLICABLE: false
fun main(args: Array){
val y = "abcd" + listOf( 1,
diff --git a/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt.after b/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt.after
deleted file mode 100644
index de7014c9f15..00000000000
--- a/idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt.after
+++ /dev/null
@@ -1,4 +0,0 @@
-// WITH_RUNTIME
-fun main(args: Array){
- val y = "abcd${listOf(1, 2)}"
-}
diff --git a/idea/testData/intentions/convertToStringTemplate/endOfLineComment.kt b/idea/testData/intentions/convertToStringTemplate/endOfLineComment.kt
new file mode 100644
index 00000000000..f3835456f03
--- /dev/null
+++ b/idea/testData/intentions/convertToStringTemplate/endOfLineComment.kt
@@ -0,0 +1,3 @@
+// IS_APPLICABLE: false
+val v = "a" + (1.hashCode() // comment
+ * 2)
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToStringTemplate/inspectionData/expected.xml b/idea/testData/intentions/convertToStringTemplate/inspectionData/expected.xml
index 124d5c466eb..755d6ca805f 100644
--- a/idea/testData/intentions/convertToStringTemplate/inspectionData/expected.xml
+++ b/idea/testData/intentions/convertToStringTemplate/inspectionData/expected.xml
@@ -1,9 +1,9 @@
- multilineString.kt
- 3
+ simple.kt
+ 2
light_idea_test_case
-
+
Convert string concatenation to string template
Convert concatenation to template
diff --git a/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt b/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt
index 9d9caea5c9b..a72fb0154e1 100644
--- a/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt
+++ b/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt
@@ -1,4 +1,5 @@
// WITH_RUNTIME
+// IS_APPLICABLE: false
fun main(args: Array){
val y = "abcd" + listOf( 1,
2 )
diff --git a/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt.after b/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt.after
deleted file mode 100644
index de7014c9f15..00000000000
--- a/idea/testData/intentions/convertToStringTemplate/interpolateMultiline.kt.after
+++ /dev/null
@@ -1,4 +0,0 @@
-// WITH_RUNTIME
-fun main(args: Array){
- val y = "abcd${listOf(1, 2)}"
-}
diff --git a/idea/testData/intentions/convertToStringTemplate/multilineString.kt b/idea/testData/intentions/convertToStringTemplate/multilineString.kt
index 3198daba8bf..5450c8623e2 100644
--- a/idea/testData/intentions/convertToStringTemplate/multilineString.kt
+++ b/idea/testData/intentions/convertToStringTemplate/multilineString.kt
@@ -1,3 +1,4 @@
+// IS_APPLICABLE: false
fun main(args: Array){
var r = "a"
val x = "foo" + """bar
diff --git a/idea/testData/intentions/convertToStringTemplate/multilineString.kt.after b/idea/testData/intentions/convertToStringTemplate/multilineString.kt.after
deleted file mode 100644
index c5238959521..00000000000
--- a/idea/testData/intentions/convertToStringTemplate/multilineString.kt.after
+++ /dev/null
@@ -1,4 +0,0 @@
-fun main(args: Array){
- var r = "a"
- val x = "foobar\n $r"
-}
diff --git a/idea/testData/intentions/convertToStringTemplate/simple.kt b/idea/testData/intentions/convertToStringTemplate/simple.kt
new file mode 100644
index 00000000000..96afdcad55b
--- /dev/null
+++ b/idea/testData/intentions/convertToStringTemplate/simple.kt
@@ -0,0 +1,3 @@
+fun foo(p: Int) {
+ val v = "(" + p + ")"
+}
diff --git a/idea/testData/intentions/convertToStringTemplate/simple.kt.after b/idea/testData/intentions/convertToStringTemplate/simple.kt.after
new file mode 100644
index 00000000000..c9427036f58
--- /dev/null
+++ b/idea/testData/intentions/convertToStringTemplate/simple.kt.after
@@ -0,0 +1,3 @@
+fun foo(p: Int) {
+ val v = "($p)"
+}
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 9381fcdf2a4..49f5384f44b 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -4561,6 +4561,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
+ @TestMetadata("comment.kt")
+ public void testComment() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToStringTemplate/comment.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("consecutiveNewlines.kt")
public void testConsecutiveNewlines() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToStringTemplate/consecutiveNewlines.kt");
@@ -4579,6 +4585,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
+ @TestMetadata("endOfLineComment.kt")
+ public void testEndOfLineComment() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToStringTemplate/endOfLineComment.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("insertBracesForSimpleNamedExpression.kt")
public void testInsertBracesForSimpleNamedExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToStringTemplate/insertBracesForSimpleNamedExpression.kt");
@@ -4699,6 +4711,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToStringTemplate/simple.kt");
+ doTest(fileName);
+ }
+
@TestMetadata("specialCharsInCharLiteral.kt")
public void testSpecialCharsInCharLiteral() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToStringTemplate/specialCharsInCharLiteral.kt");