Introduce Parameter: Fix exceptions caused by write actions in dialogs
#KT-24992 Fixed
This commit is contained in:
+2
-3
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.refactoring.introduce.extractClass
|
||||
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.editor.ScrollType
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -35,6 +34,7 @@ import org.jetbrains.kotlin.idea.refactoring.SeparateFileWrapper
|
||||
import org.jetbrains.kotlin.idea.refactoring.chooseContainerElementIfNecessary
|
||||
import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractClass.ui.KotlinExtractSuperDialogBase
|
||||
import org.jetbrains.kotlin.idea.refactoring.showWithTransaction
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
@@ -79,8 +79,7 @@ abstract class KotlinExtractSuperHandlerBase(private val isExtractInterface: Boo
|
||||
}
|
||||
|
||||
private fun doInvoke(klass: KtClassOrObject, targetParent: PsiElement) {
|
||||
val dialog = createDialog(klass, targetParent)
|
||||
TransactionGuard.submitTransaction(dialog.disposable, Runnable { dialog.show() })
|
||||
createDialog(klass, targetParent).showWithTransaction()
|
||||
}
|
||||
|
||||
private fun selectElements(klass: KtClassOrObject, editor: Editor?) {
|
||||
|
||||
+74
-80
@@ -20,12 +20,10 @@ import com.intellij.openapi.command.impl.FinishMarkAction
|
||||
import com.intellij.openapi.command.impl.StartMarkAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.refactoring.ui.NameSuggestionsField
|
||||
import com.intellij.refactoring.ui.RefactoringDialog
|
||||
import com.intellij.ui.NonFocusableCheckBox
|
||||
import com.intellij.usageView.BaseUsageViewDescriptor
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.ExtractFunctionParameterTablePanel
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinExtractFunctionDialog
|
||||
@@ -34,6 +32,8 @@ import org.jetbrains.kotlin.idea.refactoring.isMultiLine
|
||||
import org.jetbrains.kotlin.idea.refactoring.runRefactoringWithPostprocessing
|
||||
import org.jetbrains.kotlin.idea.refactoring.validateElement
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.application.executeCommand
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
|
||||
@@ -241,88 +241,82 @@ class KotlinIntroduceParameterDialog private constructor(
|
||||
}
|
||||
|
||||
fun performRefactoring() {
|
||||
invokeRefactoring(
|
||||
object : BaseRefactoringProcessor(myProject) {
|
||||
override fun findUsages() = UsageInfo.EMPTY_ARRAY
|
||||
close(DialogWrapper.OK_EXIT_CODE)
|
||||
|
||||
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
||||
fun createLambdaForArgument(function: KtFunction): KtExpression {
|
||||
val statement = (function.bodyExpression as KtBlockExpression).statements.single()
|
||||
val space = if (statement.isMultiLine()) "\n" else " "
|
||||
val parameters = function.valueParameters
|
||||
val parametersText = if (parameters.isNotEmpty()) {
|
||||
" " + parameters.map { it.name }.joinToString() + " ->"
|
||||
} else ""
|
||||
val text = "{$parametersText$space${statement.text}$space}"
|
||||
project.executeCommand(commandName) {
|
||||
fun createLambdaForArgument(function: KtFunction): KtExpression {
|
||||
val statement = (function.bodyExpression as KtBlockExpression).statements.single()
|
||||
val space = if (statement.isMultiLine()) "\n" else " "
|
||||
val parameters = function.valueParameters
|
||||
val parametersText = if (parameters.isNotEmpty()) {
|
||||
" " + parameters.map { it.name }.joinToString() + " ->"
|
||||
} else ""
|
||||
val text = "{$parametersText$space${statement.text}$space}"
|
||||
|
||||
return KtPsiFactory(myProject).createExpression(text)
|
||||
return KtPsiFactory(myProject).createExpression(text)
|
||||
}
|
||||
|
||||
val chosenName = nameField.enteredName.quoteIfNeeded()
|
||||
var chosenType = typeField.enteredName
|
||||
var newArgumentValue = descriptor.newArgumentValue
|
||||
var newReplacer = descriptor.occurrenceReplacer
|
||||
|
||||
val startMarkAction = StartMarkAction.start(editor, myProject, this@KotlinIntroduceParameterDialog.commandName)
|
||||
|
||||
lambdaExtractionDescriptor?.let { oldDescriptor ->
|
||||
val newDescriptor = KotlinExtractFunctionDialog.createNewDescriptor(
|
||||
oldDescriptor,
|
||||
chosenName,
|
||||
null,
|
||||
parameterTablePanel?.selectedReceiverInfo,
|
||||
parameterTablePanel?.selectedParameterInfos ?: listOf(),
|
||||
null
|
||||
)
|
||||
val options = ExtractionGeneratorOptions.DEFAULT.copy(
|
||||
target = ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION,
|
||||
allowExpressionBody = false
|
||||
)
|
||||
runWriteAction {
|
||||
with (ExtractionGeneratorConfiguration(newDescriptor, options).generateDeclaration()) {
|
||||
val function = declaration as KtFunction
|
||||
val receiverType = function.receiverTypeReference?.text
|
||||
val parameterTypes = function
|
||||
.valueParameters.joinToString { it.typeReference!!.text }
|
||||
val returnType = function.typeReference?.text ?: "Unit"
|
||||
|
||||
chosenType = (receiverType?.let { "$it." } ?: "") + "($parameterTypes) -> $returnType"
|
||||
if (KtTokens.SUSPEND_KEYWORD in newDescriptor.modifiers) {
|
||||
chosenType = "${KtTokens.SUSPEND_KEYWORD} $chosenType"
|
||||
}
|
||||
newArgumentValue = createLambdaForArgument(function)
|
||||
newReplacer = { }
|
||||
|
||||
val chosenName = nameField.enteredName.quoteIfNeeded()
|
||||
var chosenType = typeField.enteredName
|
||||
var newArgumentValue = descriptor.newArgumentValue
|
||||
var newReplacer = descriptor.occurrenceReplacer
|
||||
|
||||
val startMarkAction = StartMarkAction.start(editor, myProject, this@KotlinIntroduceParameterDialog.commandName)
|
||||
|
||||
lambdaExtractionDescriptor?.let { oldDescriptor ->
|
||||
val newDescriptor = KotlinExtractFunctionDialog.createNewDescriptor(
|
||||
oldDescriptor,
|
||||
chosenName,
|
||||
null,
|
||||
parameterTablePanel?.selectedReceiverInfo,
|
||||
parameterTablePanel?.selectedParameterInfos ?: listOf(),
|
||||
null
|
||||
)
|
||||
val options = ExtractionGeneratorOptions.DEFAULT.copy(
|
||||
target = ExtractionTarget.FAKE_LAMBDALIKE_FUNCTION,
|
||||
allowExpressionBody = false
|
||||
)
|
||||
with (ExtractionGeneratorConfiguration(newDescriptor, options).generateDeclaration()) {
|
||||
val function = declaration as KtFunction
|
||||
val receiverType = function.receiverTypeReference?.text
|
||||
val parameterTypes = function
|
||||
.valueParameters.joinToString { it.typeReference!!.text }
|
||||
val returnType = function.typeReference?.text ?: "Unit"
|
||||
|
||||
chosenType = (receiverType?.let { "$it." } ?: "") + "($parameterTypes) -> $returnType"
|
||||
if (KtTokens.SUSPEND_KEYWORD in newDescriptor.modifiers) {
|
||||
chosenType = "${KtTokens.SUSPEND_KEYWORD} $chosenType"
|
||||
}
|
||||
newArgumentValue = createLambdaForArgument(function)
|
||||
newReplacer = { }
|
||||
|
||||
processDuplicates(duplicateReplacers, myProject, editor)
|
||||
}
|
||||
}
|
||||
|
||||
val descriptorToRefactor = descriptor.copy(
|
||||
newParameterName = chosenName,
|
||||
newParameterTypeText = chosenType,
|
||||
argumentValue = newArgumentValue,
|
||||
withDefaultValue = defaultValueCheckBox!!.isSelected,
|
||||
occurrencesToReplace = with(descriptor) {
|
||||
if (replaceAllCheckBox?.isSelected ?: true) {
|
||||
occurrencesToReplace
|
||||
}
|
||||
else {
|
||||
Collections.singletonList(originalOccurrence)
|
||||
}
|
||||
},
|
||||
parametersToRemove = removeParamsCheckBoxes.filter { it.key.isEnabled && it.key.isSelected }.map { it.value },
|
||||
occurrenceReplacer = newReplacer
|
||||
)
|
||||
|
||||
val introduceParameter = { helper.configure(descriptorToRefactor).performRefactoring() }
|
||||
introduceParameter.runRefactoringWithPostprocessing(myProject, INTRODUCE_PARAMETER_REFACTORING_ID) {
|
||||
FinishMarkAction.finish(myProject, editor, startMarkAction)
|
||||
}
|
||||
processDuplicates(duplicateReplacers, myProject, editor)
|
||||
}
|
||||
|
||||
override fun createUsageViewDescriptor(usages: Array<out UsageInfo>) = BaseUsageViewDescriptor()
|
||||
|
||||
override fun getCommandName(): String = this@KotlinIntroduceParameterDialog.commandName
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val descriptorToRefactor = descriptor.copy(
|
||||
newParameterName = chosenName,
|
||||
newParameterTypeText = chosenType,
|
||||
argumentValue = newArgumentValue,
|
||||
withDefaultValue = defaultValueCheckBox!!.isSelected,
|
||||
occurrencesToReplace = with(descriptor) {
|
||||
if (replaceAllCheckBox?.isSelected ?: true) {
|
||||
occurrencesToReplace
|
||||
}
|
||||
else {
|
||||
Collections.singletonList(originalOccurrence)
|
||||
}
|
||||
},
|
||||
parametersToRemove = removeParamsCheckBoxes.filter { it.key.isEnabled && it.key.isSelected }.map { it.value },
|
||||
occurrenceReplacer = newReplacer
|
||||
)
|
||||
|
||||
val introduceParameter = { helper.configure(descriptorToRefactor).performRefactoring() }
|
||||
introduceParameter.runRefactoringWithPostprocessing(myProject, INTRODUCE_PARAMETER_REFACTORING_ID) {
|
||||
FinishMarkAction.finish(myProject, editor, startMarkAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-7
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.removeTemplateEntryBracesIfPossible
|
||||
import org.jetbrains.kotlin.idea.refactoring.runRefactoringWithPostprocessing
|
||||
import org.jetbrains.kotlin.idea.refactoring.showWithTransaction
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
@@ -355,12 +357,15 @@ open class KotlinIntroduceParameterHandler(
|
||||
if (introducer.startInplaceIntroduceTemplate()) return
|
||||
}
|
||||
|
||||
KotlinIntroduceParameterDialog(project,
|
||||
editor,
|
||||
introduceParameterDescriptor,
|
||||
suggestedNames.toTypedArray(),
|
||||
listOf(replacementType) + replacementType.supertypes(),
|
||||
helper).show()
|
||||
val dialog = KotlinIntroduceParameterDialog(
|
||||
project,
|
||||
editor,
|
||||
introduceParameterDescriptor,
|
||||
suggestedNames.toTypedArray(),
|
||||
listOf(replacementType) + replacementType.supertypes(),
|
||||
helper
|
||||
)
|
||||
dialog.showWithTransaction()
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -508,7 +513,7 @@ open class KotlinIntroduceLambdaParameterHandler(
|
||||
dialog.performRefactoring()
|
||||
}
|
||||
else {
|
||||
dialog.show()
|
||||
dialog.showWithTransaction()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.intellij.ide.util.PsiElementListCellRenderer
|
||||
import com.intellij.lang.injection.InjectedLanguageManager
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.command.CommandAdapter
|
||||
import com.intellij.openapi.command.CommandEvent
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
@@ -25,6 +26,7 @@ import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.openapi.options.ConfigurationException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.JavaProjectRootsUtil
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.ui.popup.*
|
||||
import com.intellij.openapi.util.Pass
|
||||
@@ -74,8 +76,6 @@ import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar
|
||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
||||
import org.jetbrains.kotlin.idea.util.liftToExpected
|
||||
import org.jetbrains.kotlin.idea.util.string.collapseSpaces
|
||||
import org.jetbrains.kotlin.j2k.ConverterSettings
|
||||
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
|
||||
@@ -981,13 +981,6 @@ fun KtNamedDeclaration.isCompanionMemberOf(klass: KtClassOrObject): Boolean {
|
||||
return containingObject.isCompanion() && containingObject.containingClassOrObject == klass
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.withExpectedActuals(): List<KtDeclaration> {
|
||||
val expect = liftToExpected() ?: return listOf(this)
|
||||
val actuals = expect.actualsForExpected()
|
||||
return listOf(expect) + actuals
|
||||
}
|
||||
|
||||
internal fun KtDeclaration.resolveToExpectedDescriptorIfPossible(): DeclarationDescriptor {
|
||||
val descriptor = unsafeResolveToDescriptor()
|
||||
return descriptor.liftToExpected() ?: descriptor
|
||||
fun DialogWrapper.showWithTransaction() {
|
||||
TransactionGuard.submitTransaction(disposable, Runnable { show() })
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import com.intellij.ide.util.PsiElementListCellRenderer
|
||||
import com.intellij.lang.injection.InjectedLanguageManager
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.command.CommandAdapter
|
||||
import com.intellij.openapi.command.CommandEvent
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
@@ -25,6 +26,7 @@ import com.intellij.openapi.editor.markup.TextAttributes
|
||||
import com.intellij.openapi.options.ConfigurationException
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.JavaProjectRootsUtil
|
||||
import com.intellij.openapi.ui.DialogWrapper
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.ui.popup.*
|
||||
import com.intellij.openapi.util.Pass
|
||||
@@ -990,4 +992,8 @@ internal fun KtDeclaration.withExpectedActuals(): List<KtDeclaration> {
|
||||
internal fun KtDeclaration.resolveToExpectedDescriptorIfPossible(): DeclarationDescriptor {
|
||||
val descriptor = unsafeResolveToDescriptor()
|
||||
return descriptor.liftToExpected() ?: descriptor
|
||||
}
|
||||
|
||||
fun DialogWrapper.showWithTransaction() {
|
||||
TransactionGuard.submitTransaction(disposable, Runnable { show() })
|
||||
}
|
||||
Reference in New Issue
Block a user