Inline Variable: Move string template processing to InlineValHandler as it violates contract of the PsiElement.replace()
This commit is contained in:
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.psi
|
|||||||
import com.intellij.lang.ASTNode
|
import com.intellij.lang.ASTNode
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.KtNodeType
|
import org.jetbrains.kotlin.KtNodeType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.canPlaceAfterSimpleNameEntry
|
|
||||||
|
|
||||||
public abstract class KtExpressionImpl(node: ASTNode) : KtElementImpl(node), KtExpression {
|
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()
|
val parent = expression.getParent()
|
||||||
|
|
||||||
if (newElement is KtExpression) {
|
if (newElement is KtExpression) {
|
||||||
when {
|
when (parent) {
|
||||||
parent is KtStringTemplateEntryWithExpression &&
|
is KtExpression, is KtValueArgument -> {
|
||||||
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 -> {
|
|
||||||
if (KtPsiUtil.areParenthesesNecessary(newElement, expression, parent as KtElement)) {
|
if (KtPsiUtil.areParenthesesNecessary(newElement, expression, parent as KtElement)) {
|
||||||
return rawReplaceHandler(KtPsiFactory(expression).createExpressionByPattern("($0)", newElement))
|
return rawReplaceHandler(KtPsiFactory(expression).createExpressionByPattern("($0)", newElement))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is KtSimpleNameStringTemplateEntry -> {
|
||||||
parent is KtSimpleNameStringTemplateEntry -> {
|
|
||||||
if (newElement !is KtSimpleNameExpression) {
|
if (newElement !is KtSimpleNameExpression) {
|
||||||
val newEntry = parent.replace(KtPsiFactory(expression).createBlockStringTemplateEntry(newElement)) as KtBlockStringTemplateEntry
|
val newEntry = parent.replace(KtPsiFactory(expression).createBlockStringTemplateEntry(newElement)) as KtBlockStringTemplateEntry
|
||||||
return newEntry.getExpression()!!
|
return newEntry.getExpression()!!
|
||||||
|
|||||||
@@ -45,9 +45,7 @@ import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
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.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
import org.jetbrains.kotlin.utils.sure
|
import org.jetbrains.kotlin.utils.sure
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -66,6 +65,38 @@ class KotlinInlineValHandler : InlineActionHandler() {
|
|||||||
return element.getter == null && element.receiverTypeReference == null
|
return element.getter == null && element.receiverTypeReference == null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun doReplace(expression: KtExpression, replacement: KtExpression): List<KtExpression> {
|
||||||
|
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) {
|
override fun inlineElement(project: Project, editor: Editor, element: PsiElement) {
|
||||||
val declaration = element as KtProperty
|
val declaration = element as KtProperty
|
||||||
val file = declaration.getContainingKtFile()
|
val file = declaration.getContainingKtFile()
|
||||||
@@ -130,9 +161,9 @@ class KotlinInlineValHandler : InlineActionHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) {
|
project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) {
|
||||||
val inlinedExpressions = referenceExpressions.mapNotNull { referenceExpression ->
|
val inlinedExpressions = referenceExpressions.flatMap { referenceExpression ->
|
||||||
if (assignments.contains(referenceExpression.parent)) return@mapNotNull null
|
if (assignments.contains(referenceExpression.parent)) return@flatMap emptyList<KtExpression>()
|
||||||
referenceExpression.replaced(initializer)
|
doReplace(referenceExpression, initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
assignments.forEach { it.delete() }
|
assignments.forEach { it.delete() }
|
||||||
|
|||||||
Reference in New Issue
Block a user