Inline Property: Support "Do not show this dialog" and "Inline this occurrence" options

#KT-12017 Fixed
(cherry picked from commit b53d8da)
This commit is contained in:
Alexey Sedunov
2016-06-24 16:24:58 +03:00
parent 59f37a8291
commit dd7bd2b869
3 changed files with 101 additions and 9 deletions
+4
View File
@@ -121,6 +121,10 @@ These artifacts include extensions for the types available in the latter JDKs, s
- [`KT-12413`](https://youtrack.jetbrains.com/issue/KT-12413) Change Signature: Fix bogus warning about unresolved type parameters/invalid functional type replacement
- [`KT-12084`](https://youtrack.jetbrains.com/issue/KT-12084) Introduce Property: Do not skip outer classes if extractable expression is contained in object literal
###### New features
- [`KT-12017`](https://youtrack.jetbrains.com/issue/KT-12017) Inline Property: Support "Do not show this dialog" and "Inline this occurrence" options
## 1.0.3
### Compiler
@@ -0,0 +1,64 @@
/*
* Copyright 2010-2016 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.util.text.StringUtil
import com.intellij.psi.PsiReference
import com.intellij.refactoring.JavaRefactoringSettings
import com.intellij.refactoring.inline.AbstractInlineLocalDialog
import org.jetbrains.kotlin.psi.KtProperty
class KotlinInlineValDialog(
element: KtProperty,
ref: PsiReference?,
private val occurrenceCount: Int
) : AbstractInlineLocalDialog(element.project, element, ref, occurrenceCount) {
private val property: KtProperty get() = myElement as KtProperty
private val kind = if (property.isLocal) "local variable" else "property"
private val refactoringName = "Inline ${StringUtil.capitalizeWords(kind, true)}"
init {
myInvokedOnReference = ref != null
title = refactoringName
init()
}
override fun getBorderTitle() = refactoringName
override fun getNameLabelText() = "${kind.capitalize()} ${property.name}"
override fun getInlineAllText(): String? {
val occurrencesString = if (occurrenceCount >= 0) {
" (" + occurrenceCount + " occurrence" + (if (occurrenceCount == 1) ")" else "s)")
} else ""
return "Inline all references and remove the $kind" + occurrencesString
}
override fun isInlineThis() = JavaRefactoringSettings.getInstance().INLINE_LOCAL_THIS
override fun getInlineThisText() = "Inline this occurrence and leave the $kind"
override fun doAction() {
val settings = JavaRefactoringSettings.getInstance()
if (myRbInlineThisOnly.isEnabled && myRbInlineAll.isEnabled) {
settings.INLINE_LOCAL_THIS = isInlineThisOnly
}
close(OK_EXIT_CODE)
}
}
@@ -19,13 +19,17 @@ package org.jetbrains.kotlin.idea.refactoring.inline
import com.google.common.collect.Sets
import com.intellij.lang.Language
import com.intellij.lang.refactoring.InlineActionHandler
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.WindowManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.refactoring.HelpID
import com.intellij.refactoring.JavaRefactoringSettings
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.util.containers.MultiMap
@@ -55,6 +59,10 @@ import org.jetbrains.kotlin.utils.sure
import java.util.*
class KotlinInlineValHandler : InlineActionHandler() {
enum class InlineMode {
ALL, PRIMARY, NONE
}
override fun isEnabledForLanguage(l: Language) = l == KotlinLanguage.INSTANCE
override fun canInlineElement(element: PsiElement): Boolean {
@@ -152,12 +160,15 @@ class KotlinInlineValHandler : InlineActionHandler() {
}
fun performRefactoring() {
if (!showDialog(project,
name,
RefactoringBundle.message("inline.variable.title"),
declaration,
referenceExpressions,
HelpID.INLINE_VARIABLE)) {
val primaryExpression = if (editor != null) {
val offset = editor.caretModel.offset
referenceExpressions.firstOrNull { it.textRange.contains(offset) }
}
else null
val primaryRef = primaryExpression?.mainReference
val inlineMode = showDialog(declaration, primaryRef, referenceExpressions.size)
if (inlineMode == InlineMode.NONE) {
if (isHighlighting) {
val statusBar = WindowManager.getInstance().getStatusBar(project)
statusBar?.info = RefactoringBundle.message("press.escape.to.remove.the.highlighting")
@@ -165,8 +176,10 @@ class KotlinInlineValHandler : InlineActionHandler() {
return
}
val chosenExpressions = if (inlineMode == InlineMode.ALL) referenceExpressions else listOf(primaryExpression)
project.executeWriteCommand(RefactoringBundle.message("inline.command", name)) {
val inlinedExpressions = referenceExpressions
val inlinedExpressions = chosenExpressions
.flatMap { referenceExpression ->
if (assignments.contains(referenceExpression.parent)) return@flatMap emptyList<KtExpression>()
@@ -184,8 +197,10 @@ class KotlinInlineValHandler : InlineActionHandler() {
}
.mapNotNull { postProcessInternalReferences(it) }
assignments.forEach { it.delete() }
declaration.delete()
if (inlineMode == InlineMode.ALL) {
assignments.forEach { it.delete() }
declaration.delete()
}
if (inlinedExpressions.isNotEmpty()) {
if (typeArgumentsForCall != null) {
@@ -224,6 +239,15 @@ class KotlinInlineValHandler : InlineActionHandler() {
CommonRefactoringUtil.showErrorHint(project, editor, message, RefactoringBundle.message("inline.variable.title"), HelpID.INLINE_VARIABLE)
}
private fun showDialog(property: KtProperty, ref: PsiReference?, occurrenceCount: Int): InlineMode {
if (ApplicationManager.getApplication().isUnitTestMode) return InlineMode.ALL
if ((ref == null || occurrenceCount <= 1) && !EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog) return InlineMode.ALL
val dialog = KotlinInlineValDialog(property, ref, occurrenceCount)
if (!dialog.showAndGet()) return InlineMode.NONE
return if (JavaRefactoringSettings.getInstance().INLINE_LOCAL_THIS) InlineMode.PRIMARY else InlineMode.ALL
}
private fun getParametersForFunctionLiteral(initializer: KtExpression): String? {
val functionLiteralExpression = initializer.unpackFunctionLiteral(true) ?: return null
val context = initializer.analyze(BodyResolveMode.PARTIAL)