diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtExpressionImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtExpressionImpl.kt index 0c17467a0bd..9861a35a8f3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtExpressionImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtExpressionImpl.kt @@ -19,7 +19,6 @@ package org.jetbrains.kotlin.psi import com.intellij.lang.ASTNode import com.intellij.psi.PsiElement import org.jetbrains.kotlin.KtNodeType -import org.jetbrains.kotlin.psi.psiUtil.canPlaceAfterSimpleNameEntry public abstract class KtExpressionImpl(node: ASTNode) : KtElementImpl(node), KtExpression { @@ -39,33 +38,13 @@ public abstract class KtExpressionImpl(node: ASTNode) : KtElementImpl(node), KtE val parent = expression.getParent() if (newElement is KtExpression) { - when { - parent is KtStringTemplateEntryWithExpression && - newElement is KtStringTemplateExpression && - // Do not mix raw and non-raw templates - parent.parent.firstChild.text == newElement.firstChild.text -> { - val entriesToAdd = newElement.entries - val templateExpression = parent.parent as KtStringTemplateExpression - if (entriesToAdd.size > 0) { - templateExpression.addRangeBefore(entriesToAdd.first(), entriesToAdd.last(), parent) - val lastNewEntry = parent.prevSibling - val nextElement = parent.nextSibling - if (lastNewEntry is KtSimpleNameStringTemplateEntry && - lastNewEntry.expression != null && - !canPlaceAfterSimpleNameEntry(nextElement)) { - lastNewEntry.replace(KtPsiFactory(expression).createBlockStringTemplateEntry(lastNewEntry.expression!!)) - } - } - parent.delete() - } - - parent is KtExpression || parent is KtValueArgument -> { + when (parent) { + is KtExpression, is KtValueArgument -> { if (KtPsiUtil.areParenthesesNecessary(newElement, expression, parent as KtElement)) { return rawReplaceHandler(KtPsiFactory(expression).createExpressionByPattern("($0)", newElement)) } } - - parent is KtSimpleNameStringTemplateEntry -> { + is KtSimpleNameStringTemplateEntry -> { if (newElement !is KtSimpleNameExpression) { val newEntry = parent.replace(KtPsiFactory(expression).createBlockStringTemplateEntry(newElement)) as KtBlockStringTemplateEntry return newEntry.getExpression()!! diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt index 8f5742f7b19..e6ce10e9e22 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValHandler.kt @@ -45,9 +45,7 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.idea.util.ShortenReferences import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS -import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis -import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall @@ -55,6 +53,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.utils.addIfNotNull +import org.jetbrains.kotlin.utils.addToStdlib.singletonList import org.jetbrains.kotlin.utils.sure import java.util.* @@ -66,6 +65,38 @@ class KotlinInlineValHandler : InlineActionHandler() { return element.getter == null && element.receiverTypeReference == null } + private fun doReplace(expression: KtExpression, replacement: KtExpression): List { + val parent = expression.parent + + if (parent is KtStringTemplateEntryWithExpression && + replacement is KtStringTemplateExpression && + // Do not mix raw and non-raw templates + parent.parent.firstChild.text == replacement.firstChild.text) { + val entriesToAdd = replacement.entries + val templateExpression = parent.parent as KtStringTemplateExpression + val inlinedExpressions = if (entriesToAdd.size > 0) { + val firstAddedEntry = templateExpression.addRangeBefore(entriesToAdd.first(), entriesToAdd.last(), parent) + val lastNewEntry = parent.prevSibling + val nextElement = parent.nextSibling + if (lastNewEntry is KtSimpleNameStringTemplateEntry && + lastNewEntry.expression != null && + !canPlaceAfterSimpleNameEntry(nextElement)) { + lastNewEntry.replace(KtPsiFactory(expression).createBlockStringTemplateEntry(lastNewEntry.expression!!)) + } + firstAddedEntry.siblings() + .take(entriesToAdd.size) + .mapNotNull { (it as? KtStringTemplateEntryWithExpression)?.expression } + .toList() + } + else emptyList() + + parent.delete() + return inlinedExpressions + } + + return expression.replaced(replacement).singletonList() + } + override fun inlineElement(project: Project, editor: Editor, element: PsiElement) { val declaration = element as KtProperty val file = declaration.getContainingKtFile() @@ -130,9 +161,9 @@ class KotlinInlineValHandler : InlineActionHandler() { } project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) { - val inlinedExpressions = referenceExpressions.mapNotNull { referenceExpression -> - if (assignments.contains(referenceExpression.parent)) return@mapNotNull null - referenceExpression.replaced(initializer) + val inlinedExpressions = referenceExpressions.flatMap { referenceExpression -> + if (assignments.contains(referenceExpression.parent)) return@flatMap emptyList() + doReplace(referenceExpression, initializer) } assignments.forEach { it.delete() }