diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/AbstractKotlinInlineDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/AbstractKotlinInlineDialog.kt new file mode 100644 index 00000000000..b5561c1432a --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/AbstractKotlinInlineDialog.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.refactoring.inline + +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.text.StringUtil +import com.intellij.psi.ElementDescriptionUtil +import com.intellij.refactoring.inline.InlineOptionsDialog +import com.intellij.usageView.UsageViewTypeLocation +import org.jetbrains.kotlin.idea.references.KtSimpleNameReference +import org.jetbrains.kotlin.psi.KtCallableDeclaration + +abstract class AbstractKotlinInlineDialog( + protected val callable: KtCallableDeclaration, + protected val reference: KtSimpleNameReference?, + project: Project = callable.project +) : InlineOptionsDialog(project, true, callable) { + + protected val occurrencesNumber = initOccurrencesNumber(callable) + + private val occurrencesString get() = if (occurrencesNumber >= 0) { + "" + occurrencesNumber + " " + StringUtil.pluralize("occurrence", occurrencesNumber) + } else null + + private val kind: String = ElementDescriptionUtil.getElementDescription(callable, UsageViewTypeLocation.INSTANCE) + + private val refactoringName get() = "Inline ${StringUtil.capitalizeWords(kind, true)}" + + init { + myInvokedOnReference = reference != null + title = refactoringName + } + + // If this is true, "inline all & remove" is disabled, + // "inline all and keep" is disabled on references and enabled on original declaration. + // Independent on this, "inline this only" is enabled on references and disabled on original declaration + // If this is false, "inline all & remove" is dependent on next flag (allowInlineAll), + // "inline all and keep" is enabled + override fun canInlineThisOnly() = false + + // If this is false, "inline all & remove" is disabled + // If this is true, it can be enabled if 'canInlineThisOnly' is false (see above) + override fun allowInlineAll() = true + + override fun getBorderTitle() = refactoringName + + override fun getNameLabelText(): String { + val occurrencesString = + if (occurrencesNumber >= 0) " - $occurrencesString" + else "" + return "${kind.capitalize()} ${callable.nameAsSafeName} $occurrencesString" + } + + override fun getInlineAllText() = + "Inline all references and remove the $kind ($occurrencesString)" + + override fun getKeepTheDeclarationText(): String? = + // With non-writable callable refactoring does not work anyway (for both property or function) + if (callable.isWritable && occurrencesNumber > 1) "Inline all references and keep the $kind ($occurrencesString)" + else null + + override fun getInlineThisText() = "Inline this occurrence and leave the $kind" +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionDialog.kt index a62cf22f4c9..cda8face192 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineFunctionDialog.kt @@ -20,58 +20,28 @@ import com.intellij.openapi.help.HelpManager import com.intellij.openapi.project.Project import com.intellij.refactoring.HelpID import com.intellij.refactoring.JavaRefactoringSettings -import com.intellij.refactoring.inline.InlineOptionsDialog -import org.jetbrains.kotlin.idea.codeInliner.PropertyUsageReplacementStrategy import org.jetbrains.kotlin.idea.codeInliner.UsageReplacementStrategy -import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.getReturnTypeReference import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.psi.KtConstructor import org.jetbrains.kotlin.psi.KtNamedFunction -// NB: similar to IDEA InlineMethodDialog / KotlinInlineValDialog class KotlinInlineFunctionDialog( project: Project, - private val function: KtNamedFunction, - private val reference: KtSimpleNameReference?, + function: KtNamedFunction, + reference: KtSimpleNameReference?, private val replacementStrategy: UsageReplacementStrategy, private val allowInlineThisOnly: Boolean -) : InlineOptionsDialog(project, true, function) { - - private var occurrencesNumber = initOccurrencesNumber(function) +) : AbstractKotlinInlineDialog(function, reference, project) { init { - myInvokedOnReference = reference != null - title = "Inline function" init() } - override fun allowInlineAll() = true - - override fun getNameLabelText(): String { - val occurrencesString = - if (occurrencesNumber > -1) " - $occurrencesNumber occurrence${if (occurrencesNumber == 1) "" else "s"}" - else "" - val functionText = "${function.nameAsSafeName}" + function.valueParameters.joinToString(prefix = "(", postfix = ")") { - "${it.nameAsSafeName}: ${it.typeReference?.text}" - } + (function.getReturnTypeReference()?.let { ": " + it.text } ?: "") - return "Function $functionText $occurrencesString" - } - - override fun getBorderTitle() = "Inline" - - override fun getInlineThisText() = "Inline this only and keep the function" - - override fun getInlineAllText() = - if (function.isWritable) "Inline all and remove the function" - else "All invocations in project" - - override fun getKeepTheDeclarationText(): String? = - if (function.isWritable) "Inline all and keep the function" - else super.getKeepTheDeclarationText() + override fun isInlineThis() = JavaRefactoringSettings.getInstance().INLINE_METHOD_THIS public override fun doAction() { invokeRefactoring( - KotlinInlineCallableProcessor(project, replacementStrategy, function, reference, + KotlinInlineCallableProcessor(project, replacementStrategy, callable, reference, inlineThisOnly = isInlineThisOnly || allowInlineThisOnly, deleteAfter = !isInlineThisOnly && !isKeepTheDeclaration && !allowInlineThisOnly) ) @@ -83,9 +53,7 @@ class KotlinInlineFunctionDialog( } override fun doHelpAction() = - HelpManager.getInstance().invokeHelp(if (function is KtConstructor<*>) HelpID.INLINE_CONSTRUCTOR else HelpID.INLINE_METHOD) + HelpManager.getInstance().invokeHelp(if (callable is KtConstructor<*>) HelpID.INLINE_CONSTRUCTOR else HelpID.INLINE_METHOD) override fun canInlineThisOnly() = allowInlineThisOnly - - override fun isInlineThis() = JavaRefactoringSettings.getInstance().INLINE_METHOD_THIS } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValDialog.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValDialog.kt index b4465e6118b..2a5ea6fbaa0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValDialog.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/inline/KotlinInlineValDialog.kt @@ -18,33 +18,27 @@ package org.jetbrains.kotlin.idea.refactoring.inline import com.intellij.openapi.editor.ex.EditorSettingsExternalizable import com.intellij.openapi.ui.DialogWrapper -import com.intellij.openapi.util.text.StringUtil import com.intellij.refactoring.JavaRefactoringSettings -import com.intellij.refactoring.inline.InlineOptionsDialog import org.jetbrains.kotlin.idea.codeInliner.UsageReplacementStrategy import org.jetbrains.kotlin.idea.references.KtSimpleNameReference import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtProperty class KotlinInlineValDialog( - private val property: KtProperty, - private val reference: KtSimpleNameReference?, + property: KtProperty, + reference: KtSimpleNameReference?, private val replacementStrategy: UsageReplacementStrategy, private val assignmentToDelete: KtBinaryExpression?, withPreview: Boolean = true -) : InlineOptionsDialog(property.project, true, property) { +) : AbstractKotlinInlineDialog(property, reference) { - private var occurrenceCount = initOccurrencesNumber(property) + private val isLocal = (callable as KtProperty).isLocal - private val kind = if (property.isLocal) "local variable" else "property" - - private val refactoringName = "Inline ${StringUtil.capitalizeWords(kind, true)}" + private val simpleLocal = isLocal && (reference == null || occurrencesNumber == 1) init { - myInvokedOnReference = reference != null - title = refactoringName setPreviewResults(withPreview && shouldBeShown()) - if (forSimpleLocal()) { + if (simpleLocal) { setDoNotAskOption(object : DialogWrapper.DoNotAskOption { override fun isToBeShown() = EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog @@ -62,34 +56,13 @@ class KotlinInlineValDialog( init() } - private fun forSimpleLocal() = property.isLocal && (reference == null || occurrenceCount == 1) - - fun shouldBeShown() = !forSimpleLocal() || EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog - - override fun allowInlineAll() = true - - override fun getBorderTitle() = refactoringName - - override fun getNameLabelText() = "${kind.capitalize()} ${property.name}" - - private val occurrencesString get() = if (occurrenceCount >= 0) { - " (" + occurrenceCount + " occurrence" + (if (occurrenceCount == 1) ")" else "s)") - } else "" - - override fun getInlineAllText() = - "Inline all references and remove the $kind" + occurrencesString - - override fun getKeepTheDeclarationText(): String? = - if (property.isWritable) "Inline all references and keep the $kind" + occurrencesString - else super.getKeepTheDeclarationText() + fun shouldBeShown() = !simpleLocal || EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog override fun isInlineThis() = JavaRefactoringSettings.getInstance().INLINE_LOCAL_THIS - override fun getInlineThisText() = "Inline this occurrence and leave the $kind" - public override fun doAction() { invokeRefactoring( - KotlinInlineCallableProcessor(project, replacementStrategy, property, reference, + KotlinInlineCallableProcessor(project, replacementStrategy, callable, reference, inlineThisOnly = isInlineThisOnly, deleteAfter = !isInlineThisOnly && !isKeepTheDeclaration, statementToDelete = assignmentToDelete)