Refactoring: Move selectElements() function to introduceUtil.kt
This commit is contained in:
+14
-102
@@ -22,17 +22,10 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.editor.ScrollType
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringUtil
|
||||
import com.intellij.refactoring.HelpID
|
||||
import org.jetbrains.kotlin.idea.refactoring.JetRefactoringBundle
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ui.KotlinExtractFunctionDialog
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.psi.JetElement
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getOutermostParentContainedIn
|
||||
import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.psi.JetBlockExpression
|
||||
@@ -46,9 +39,9 @@ import com.intellij.ui.awt.RelativePoint
|
||||
import com.intellij.openapi.ui.popup.Balloon.Position
|
||||
import org.jetbrains.kotlin.psi.JetFunctionLiteral
|
||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||
import org.jetbrains.kotlin.idea.refactoring.chooseContainerElementIfNecessary
|
||||
import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.*
|
||||
|
||||
public open class ExtractKotlinFunctionHandlerHelper {
|
||||
open fun adjustExtractionData(data: ExtractionData): ExtractionData = data
|
||||
@@ -112,7 +105,7 @@ public class ExtractKotlinFunctionHandler(
|
||||
val message = analysisResult.messages.map { it.renderMessage() }.joinToString("\n")
|
||||
when (analysisResult.status) {
|
||||
Status.CRITICAL_ERROR -> {
|
||||
showErrorHint(project, editor, message)
|
||||
showErrorHint(project, editor, message, EXTRACT_FUNCTION)
|
||||
}
|
||||
|
||||
Status.NON_CRITICAL_ERROR -> {
|
||||
@@ -141,12 +134,19 @@ public class ExtractKotlinFunctionHandler(
|
||||
}
|
||||
}
|
||||
|
||||
fun selectElements(editor: Editor, file: PsiFile, continuation: (elements: List<PsiElement>, targetSibling: PsiElement) -> Unit) {
|
||||
selectElements(
|
||||
EXTRACT_FUNCTION,
|
||||
editor,
|
||||
file,
|
||||
{(elements, parent) -> parent.getExtractionContainers(elements.size() == 1, allContainersEnabled) },
|
||||
continuation
|
||||
)
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
|
||||
if (file !is JetFile) return
|
||||
|
||||
selectElements(editor, file, allContainersEnabled) { (elements, targetSibling) ->
|
||||
doInvoke(editor, file, elements, targetSibling)
|
||||
}
|
||||
selectElements(editor, file) { (elements, targetSibling) -> doInvoke(editor, file, elements, targetSibling) }
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
|
||||
@@ -154,92 +154,4 @@ public class ExtractKotlinFunctionHandler(
|
||||
}
|
||||
}
|
||||
|
||||
private val EXTRACT_FUNCTION: String = JetRefactoringBundle.message("extract.function")!!
|
||||
|
||||
private fun showErrorHint(project: Project, editor: Editor, message: String) {
|
||||
CodeInsightUtils.showErrorHint(project, editor, message, EXTRACT_FUNCTION, HelpID.EXTRACT_METHOD)
|
||||
}
|
||||
|
||||
private fun showErrorHintByKey(project: Project, editor: Editor, key: String) {
|
||||
showErrorHint(project, editor, JetRefactoringBundle.message(key)!!)
|
||||
}
|
||||
|
||||
fun selectElements(
|
||||
editor: Editor,
|
||||
file: PsiFile,
|
||||
allContainersEnabled: Boolean = false,
|
||||
continuation: (elements: List<PsiElement>, targetSibling: PsiElement) -> Unit
|
||||
) {
|
||||
fun noExpressionError() {
|
||||
showErrorHintByKey(file.getProject(), editor, "cannot.refactor.no.expression")
|
||||
}
|
||||
|
||||
fun noContainerError() {
|
||||
showErrorHintByKey(file.getProject(), editor, "cannot.refactor.no.container")
|
||||
}
|
||||
|
||||
fun onSelectionComplete(parent: PsiElement, elements: List<PsiElement>, targetContainer: JetElement) {
|
||||
if (parent == targetContainer) {
|
||||
continuation(elements, elements.first())
|
||||
return
|
||||
}
|
||||
|
||||
val outermostParent = parent.getOutermostParentContainedIn(targetContainer)
|
||||
if (outermostParent == null) {
|
||||
noContainerError()
|
||||
return
|
||||
}
|
||||
|
||||
continuation(elements, outermostParent)
|
||||
}
|
||||
|
||||
fun selectTargetContainer(elements: List<PsiElement>) {
|
||||
val parent = PsiTreeUtil.findCommonParent(elements)
|
||||
?: throw AssertionError("Should have at least one parent: ${elements.joinToString("\n")}")
|
||||
|
||||
val containers = parent.getExtractionContainers(elements.size() == 1, allContainersEnabled)
|
||||
if (containers.isEmpty()) {
|
||||
noContainerError()
|
||||
return
|
||||
}
|
||||
|
||||
chooseContainerElementIfNecessary(
|
||||
containers,
|
||||
editor,
|
||||
"Select target code block",
|
||||
true,
|
||||
{ it },
|
||||
{ onSelectionComplete(parent, elements, it) }
|
||||
)
|
||||
}
|
||||
|
||||
fun selectMultipleExpressions() {
|
||||
val startOffset = editor.getSelectionModel().getSelectionStart()
|
||||
val endOffset = editor.getSelectionModel().getSelectionEnd()
|
||||
|
||||
val elements = CodeInsightUtils.findStatements(file, startOffset, endOffset)
|
||||
if (elements.isEmpty()) {
|
||||
noExpressionError()
|
||||
return
|
||||
}
|
||||
|
||||
selectTargetContainer(elements.toList())
|
||||
}
|
||||
|
||||
fun selectSingleExpression() {
|
||||
JetRefactoringUtil.selectExpression(editor, file, false) { expr ->
|
||||
if (expr != null) {
|
||||
selectTargetContainer(listOf(expr))
|
||||
}
|
||||
else {
|
||||
if (!editor.getSelectionModel().hasSelection()) {
|
||||
editor.getSelectionModel().selectLineAtCaret()
|
||||
}
|
||||
selectMultipleExpressions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE)
|
||||
selectSingleExpression()
|
||||
}
|
||||
private val EXTRACT_FUNCTION: String = JetRefactoringBundle.message("extract.function")
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.introduce
|
||||
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.*
|
||||
import com.intellij.openapi.editor.*
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.*
|
||||
import org.jetbrains.kotlin.idea.codeInsight.*
|
||||
import com.intellij.openapi.project.*
|
||||
|
||||
fun showErrorHint(project: Project, editor: Editor, message: String, title: String) {
|
||||
CodeInsightUtils.showErrorHint(project, editor, message, title, null)
|
||||
}
|
||||
|
||||
fun selectElements(
|
||||
operationName: String,
|
||||
editor: Editor,
|
||||
file: PsiFile,
|
||||
getContainers: (elements: List<PsiElement>, commonParent: PsiElement) -> List<PsiElement>,
|
||||
continuation: (elements: List<PsiElement>, targetSibling: PsiElement) -> Unit
|
||||
) {
|
||||
fun showErrorHintByKey(key: String) {
|
||||
showErrorHint(file.getProject(), editor, JetRefactoringBundle.message(key), operationName)
|
||||
}
|
||||
|
||||
fun onSelectionComplete(parent: PsiElement, elements: List<PsiElement>, targetContainer: PsiElement) {
|
||||
if (parent == targetContainer) {
|
||||
continuation(elements, elements.first())
|
||||
return
|
||||
}
|
||||
|
||||
val outermostParent = parent.getOutermostParentContainedIn(targetContainer)
|
||||
if (outermostParent == null) {
|
||||
showErrorHintByKey("cannot.refactor.no.container")
|
||||
return
|
||||
}
|
||||
|
||||
continuation(elements, outermostParent)
|
||||
}
|
||||
|
||||
fun selectTargetContainer(elements: List<PsiElement>) {
|
||||
val parent = PsiTreeUtil.findCommonParent(elements)
|
||||
?: throw AssertionError("Should have at least one parent: ${elements.joinToString("\n")}")
|
||||
|
||||
val containers = getContainers(elements, parent)
|
||||
if (containers.isEmpty()) {
|
||||
showErrorHintByKey("cannot.refactor.no.container")
|
||||
return
|
||||
}
|
||||
|
||||
chooseContainerElementIfNecessary(
|
||||
containers,
|
||||
editor,
|
||||
"Select target code block",
|
||||
true,
|
||||
{ it },
|
||||
{ onSelectionComplete(parent, elements, it) }
|
||||
)
|
||||
}
|
||||
|
||||
fun selectMultipleExpressions() {
|
||||
val startOffset = editor.getSelectionModel().getSelectionStart()
|
||||
val endOffset = editor.getSelectionModel().getSelectionEnd()
|
||||
|
||||
val elements = CodeInsightUtils.findStatements(file, startOffset, endOffset)
|
||||
if (elements.isEmpty()) {
|
||||
showErrorHintByKey("cannot.refactor.no.expression")
|
||||
return
|
||||
}
|
||||
|
||||
selectTargetContainer(elements.toList())
|
||||
}
|
||||
|
||||
fun selectSingleExpression() {
|
||||
JetRefactoringUtil.selectExpression(editor, file, false) { expr ->
|
||||
if (expr != null) {
|
||||
selectTargetContainer(listOf(expr))
|
||||
}
|
||||
else {
|
||||
if (!editor.getSelectionModel().hasSelection()) {
|
||||
editor.getSelectionModel().selectLineAtCaret()
|
||||
}
|
||||
selectMultipleExpressions()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE)
|
||||
selectSingleExpression()
|
||||
}
|
||||
+12
-12
@@ -21,7 +21,6 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler
|
||||
import java.io.File
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.selectElements
|
||||
import org.jetbrains.kotlin.psi.JetTreeVisitorVoid
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException
|
||||
@@ -106,12 +105,11 @@ public abstract class AbstractJetExtractionTest() : JetLightCodeInsightFixtureTe
|
||||
val renderer = DescriptorRenderer.DEBUG_TEXT
|
||||
|
||||
val editor = fixture.getEditor()
|
||||
selectElements(editor, file) {(elements, previousSibling) ->
|
||||
ExtractKotlinFunctionHandler(
|
||||
helper = object : ExtractKotlinFunctionHandlerHelper() {
|
||||
override fun adjustExtractionData(data: ExtractionData): ExtractionData {
|
||||
return data.copy(options = extractionOptions)
|
||||
}
|
||||
val handler = ExtractKotlinFunctionHandler(
|
||||
helper = object : ExtractKotlinFunctionHandlerHelper() {
|
||||
override fun adjustExtractionData(data: ExtractionData): ExtractionData {
|
||||
return data.copy(options = extractionOptions)
|
||||
}
|
||||
|
||||
override fun adjustGeneratorOptions(options: ExtractionGeneratorOptions): ExtractionGeneratorOptions {
|
||||
return options.copy(extractAsProperty = extractAsProperty)
|
||||
@@ -124,13 +122,15 @@ public abstract class AbstractJetExtractionTest() : JetLightCodeInsightFixtureTe
|
||||
it.getParameterTypeCandidates(extractionOptions.allowSpecialClassNames).map { renderer.renderType(it) }.joinToString(", ", "[", "]")
|
||||
}.joinToString()
|
||||
|
||||
assertEquals(expectedDescriptors, actualDescriptors, "Expected descriptors mismatch.")
|
||||
assertEquals(expectedTypes, actualTypes, "Expected types mismatch.")
|
||||
assertEquals(expectedDescriptors, actualDescriptors, "Expected descriptors mismatch.")
|
||||
assertEquals(expectedTypes, actualTypes, "Expected types mismatch.")
|
||||
|
||||
return if (descriptor.name == "") descriptor.copy(name = "__dummyTestFun__") else descriptor
|
||||
}
|
||||
return if (descriptor.name == "") descriptor.copy(name = "__dummyTestFun__") else descriptor
|
||||
}
|
||||
).doInvoke(editor, file, elements, explicitPreviousSibling ?: previousSibling)
|
||||
}
|
||||
)
|
||||
handler.selectElements(editor, file) {(elements, previousSibling) ->
|
||||
handler.doInvoke(editor, file, elements, explicitPreviousSibling ?: previousSibling)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user