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");