diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt index b37a6ee83ae..133e715d991 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt @@ -22,10 +22,7 @@ import org.jetbrains.kotlin.idea.util.ShadowedDeclarationsFilter import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer -import org.jetbrains.kotlin.psi.psiUtil.getParentOfType -import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver -import org.jetbrains.kotlin.psi.psiUtil.parents +import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getCall @@ -578,7 +575,11 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT val parens = element.parent as? KtParenthesizedExpression val requiredParens = parens != null && !KtPsiUtil.areParenthesesUseless(parens) val shortenedElement = element.replace(element.selectorExpression!!) as KtElement - if (requiredParens) return shortenedElement.parent.replaced(shortenedElement) + val newParent = shortenedElement.parent + if (requiredParens) return newParent.replaced(shortenedElement) + if (newParent is KtBlockStringTemplateEntry && newParent.canDropBraces()) { + newParent.dropBraces() + } return shortenedElement } } diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt index c71681de792..a8a503dad32 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/psiModificationUtils.kt @@ -462,4 +462,13 @@ fun KtModifierList.normalize(): KtModifierList { modifiers.sortBy { MODIFIERS_ORDER.indexOf(it.node.elementType) } modifiers.forEach { newList.add(it) } } +} + +fun KtBlockStringTemplateEntry.canDropBraces() = + expression is KtNameReferenceExpression && canPlaceAfterSimpleNameEntry(nextSibling) + +fun KtBlockStringTemplateEntry.dropBraces(): KtSimpleNameStringTemplateEntry { + val name = (expression as KtNameReferenceExpression).getReferencedName() + val newEntry = KtPsiFactory(this).createSimpleNameStringTemplateEntry(name) + return replaced(newEntry) } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt index ed4626226ae..7506dd83640 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/ReplacementPerformer.kt @@ -20,6 +20,7 @@ import com.intellij.openapi.util.Key import com.intellij.psi.PsiTreeChangeAdapter import com.intellij.psi.PsiTreeChangeEvent import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.core.dropBraces import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.idea.intentions.ConvertToBlockBodyIntention import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention @@ -171,7 +172,7 @@ internal class ExpressionReplacementPerformer( if (templateEntry != null) { val intention = RemoveCurlyBracesFromTemplateIntention() if (intention.isApplicableTo(templateEntry)) { - val newEntry = intention.applyTo(templateEntry) + val newEntry = templateEntry.dropBraces() return newEntry.expression } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveCurlyBracesFromTemplateIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveCurlyBracesFromTemplateIntention.kt index d4cb958a624..db2db8bcc86 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveCurlyBracesFromTemplateIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/RemoveCurlyBracesFromTemplateIntention.kt @@ -17,29 +17,17 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.editor.Editor -import org.jetbrains.kotlin.idea.core.replaced +import org.jetbrains.kotlin.idea.core.canDropBraces +import org.jetbrains.kotlin.idea.core.dropBraces import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.psi.KtBlockStringTemplateEntry -import org.jetbrains.kotlin.psi.KtNameReferenceExpression -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.psi.KtSimpleNameStringTemplateEntry -import org.jetbrains.kotlin.psi.psiUtil.canPlaceAfterSimpleNameEntry class RemoveCurlyBracesFromTemplateInspection : IntentionBasedInspection(RemoveCurlyBracesFromTemplateIntention::class) class RemoveCurlyBracesFromTemplateIntention : SelfTargetingOffsetIndependentIntention(KtBlockStringTemplateEntry::class.java, "Remove curly braces") { - override fun isApplicableTo(element: KtBlockStringTemplateEntry): Boolean { - if (element.expression !is KtNameReferenceExpression) return false - return canPlaceAfterSimpleNameEntry(element.nextSibling) - } + override fun isApplicableTo(element: KtBlockStringTemplateEntry) = element.canDropBraces() override fun applyTo(element: KtBlockStringTemplateEntry, editor: Editor?) { - applyTo(element) - } - - fun applyTo(element: KtBlockStringTemplateEntry): KtSimpleNameStringTemplateEntry { - val name = (element.expression as KtNameReferenceExpression).getReferencedName() - val newEntry = KtPsiFactory(element).createSimpleNameStringTemplateEntry(name) - return element.replaced(newEntry) + element.dropBraces() } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index 96313212352..c2625848824 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -61,13 +61,10 @@ import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.caches.resolve.* import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde -import org.jetbrains.kotlin.idea.core.ShortenReferences -import org.jetbrains.kotlin.idea.core.getPackage -import org.jetbrains.kotlin.idea.core.quoteSegmentsIfNeeded +import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.core.util.showYesNoCancelDialog import org.jetbrains.kotlin.idea.highlighter.markers.actualsForExpected import org.jetbrains.kotlin.idea.highlighter.markers.liftToExpected -import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar @@ -779,11 +776,8 @@ fun Pass(body: (T) -> Unit) = object : Pass() { } fun KtExpression.removeTemplateEntryBracesIfPossible(): KtExpression { - val parent = parent - if (parent !is KtBlockStringTemplateEntry) return this - - val intention = RemoveCurlyBracesFromTemplateIntention() - val newEntry = if (intention.isApplicableTo(parent)) intention.applyTo(parent) else parent + val parent = parent as? KtBlockStringTemplateEntry ?: return this + val newEntry = if (parent.canDropBraces()) parent.dropBraces() else parent return newEntry.expression!! } diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/bar/dummy.txt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/bar/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/bar/someVal.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/bar/someVal.kt new file mode 100644 index 00000000000..000e702d5ad --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/bar/someVal.kt @@ -0,0 +1,3 @@ +package bar + +val someVal = "" \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/foo/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/foo/test.kt new file mode 100644 index 00000000000..437226300ef --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/after/foo/test.kt @@ -0,0 +1,7 @@ +package foo + +import bar.someVal + +fun usage() { + println("Usage: $someVal") +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/before/bar/dummy.txt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/before/bar/dummy.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/before/foo/test.kt b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/before/foo/test.kt new file mode 100644 index 00000000000..04b65761764 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/before/foo/test.kt @@ -0,0 +1,7 @@ +package foo + +val someVal = "" + +fun usage() { + println("Usage: $someVal") +} \ No newline at end of file diff --git a/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/shortenStringTemplateEntry.test b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/shortenStringTemplateEntry.test new file mode 100644 index 00000000000..3e3d7eb8a06 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/shortenStringTemplateEntry.test @@ -0,0 +1,5 @@ +{ + "mainFile": "foo/test.kt", + "type": "MOVE_KOTLIN_TOP_LEVEL_DECLARATIONS", + "targetPackage": "bar" +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java index fa5aa6c42f2..01a550850c3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java @@ -697,6 +697,12 @@ public class MoveTestGenerated extends AbstractMoveTest { doTest(fileName); } + @TestMetadata("kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/shortenStringTemplateEntry.test") + public void testKotlin_moveTopLevelDeclarations_misc_shortenStringTemplateEntry_ShortenStringTemplateEntry() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/shortenStringTemplateEntry/shortenStringTemplateEntry.test"); + doTest(fileName); + } + @TestMetadata("kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/singletonsAndStatics.test") public void testKotlin_moveTopLevelDeclarations_misc_singletonsAndStatics_SingletonsAndStatics() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/move/kotlin/moveTopLevelDeclarations/misc/singletonsAndStatics/singletonsAndStatics.test");