diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInsight/unwrap/KotlinUnwrapRemoveBase.java b/idea/src/org/jetbrains/kotlin/idea/codeInsight/unwrap/KotlinUnwrapRemoveBase.java index f8420f28b1b..f673c62231c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInsight/unwrap/KotlinUnwrapRemoveBase.java +++ b/idea/src/org/jetbrains/kotlin/idea/codeInsight/unwrap/KotlinUnwrapRemoveBase.java @@ -22,7 +22,7 @@ import com.intellij.psi.PsiWhiteSpace; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.KotlinBundle; -import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtil2Kt; +import org.jetbrains.kotlin.idea.refactoring.ElementSelectionUtilsKt; import org.jetbrains.kotlin.psi.KtBlockExpression; import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.psi.KtExpression; @@ -44,7 +44,7 @@ public abstract class KotlinUnwrapRemoveBase extends AbstractUnwrapper$s" else s - -fun formatClassDescriptor(classDescriptor: DeclarationDescriptor) = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(classDescriptor) - -fun formatPsiClass( - psiClass: PsiClass, - markAsJava: Boolean, - inCode: Boolean -): String { - var description: String - - val kind = if (psiClass.isInterface) "interface " else "class " - description = kind + PsiFormatUtil.formatClass( - psiClass, - PsiFormatUtilBase.SHOW_CONTAINING_CLASS or PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE - ) - description = wrapOrSkip(description, inCode) - - return if (markAsJava) "[Java] $description" else description -} - -fun checkSuperMethods( - declaration: KtDeclaration, - ignore: Collection?, - actionStringKey: String -): List { - val declarationDescriptor = declaration.resolveToDescriptor() as CallableDescriptor - - if (declarationDescriptor is LocalVariableDescriptor) return listOf(declaration) - - val project = declaration.project - val overriddenElementsToDescriptor = HashMap() - for (overriddenDescriptor in DescriptorUtils.getAllOverriddenDescriptors(declarationDescriptor)) { - val overriddenDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, overriddenDescriptor) ?: continue - if (overriddenDeclaration is KtNamedFunction || overriddenDeclaration is KtProperty || overriddenDeclaration is PsiMethod) { - overriddenElementsToDescriptor[overriddenDeclaration] = overriddenDescriptor - } - } - if (ignore != null) { - overriddenElementsToDescriptor.keys.removeAll(ignore) - } - - if (overriddenElementsToDescriptor.isEmpty()) return listOf(declaration) - - return askUserForMethodsToSearch(declaration, declarationDescriptor, overriddenElementsToDescriptor, actionStringKey) -} - -private fun askUserForMethodsToSearch( - declaration: KtDeclaration, - declarationDescriptor: CallableDescriptor, - overriddenElementsToDescriptor: Map, - actionStringKey: String -): List { - if (ApplicationManager.getApplication().isUnitTestMode) return overriddenElementsToDescriptor.keys.toList() - - val superClassDescriptions = getClassDescriptions(overriddenElementsToDescriptor) - - val message = KotlinBundle.message( - "x.overrides.y.in.class.list", - DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(declarationDescriptor), - "\n${superClassDescriptions.joinToString(separator = "")}", - KotlinBundle.message(actionStringKey) - ) - - val exitCode = Messages.showYesNoCancelDialog(declaration.project, message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()) - when (exitCode) { - Messages.YES -> return overriddenElementsToDescriptor.keys.toList() - Messages.NO -> return listOf(declaration) - else -> return emptyList() - } -} - -private fun getClassDescriptions(overriddenElementsToDescriptor: Map): List { - return overriddenElementsToDescriptor.entries.map { entry -> - val (element, descriptor) = entry - val description = when (element) { - is KtNamedFunction, is KtProperty -> formatClassDescriptor(descriptor.containingDeclaration) - is PsiMethod -> { - val psiClass = element.containingClass ?: error("Invalid element: ${element.getText()}") - formatPsiClass(psiClass, true, false) - } - else -> error("Unexpected element: ${element.getElementTextWithContext()}") - } - " $description\n" - } -} - -fun formatClass(classDescriptor: DeclarationDescriptor, inCode: Boolean): String { - val element = DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor) - return if (element is PsiClass) { - formatPsiClass(element, false, inCode) - } - else { - wrapOrSkip(formatClassDescriptor(classDescriptor), inCode) - } -} - -fun formatFunction(functionDescriptor: DeclarationDescriptor, inCode: Boolean): String { - val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) - return if (element is PsiMethod) { - formatPsiMethod(element, false, inCode) - } - else { - wrapOrSkip(formatFunctionDescriptor(functionDescriptor), inCode) - } -} - -private fun formatFunctionDescriptor(functionDescriptor: DeclarationDescriptor) = DescriptorRenderer.COMPACT.render(functionDescriptor) - -fun formatPsiMethod( - psiMethod: PsiMethod, - showContainingClass: Boolean, - inCode: Boolean -): String { - var options = PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE - if (showContainingClass) { - //noinspection ConstantConditions - options = options or PsiFormatUtilBase.SHOW_CONTAINING_CLASS - } - - var description = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, options, PsiFormatUtilBase.SHOW_TYPE) - description = wrapOrSkip(description, inCode) - - return "[Java] $description" -} - -fun formatJavaOrLightMethod(method: PsiMethod): String { - val originalDeclaration = method.unwrapped - return if (originalDeclaration is KtDeclaration) { - formatFunctionDescriptor(originalDeclaration.resolveToDescriptor()) - } - else { - formatPsiMethod(method, false, false) - } -} - -fun formatClass(classOrObject: KtClassOrObject) = formatClassDescriptor(classOrObject.resolveToDescriptor() as ClassDescriptor) - -fun checkParametersInMethodHierarchy(parameter: PsiParameter): Collection? { - val method = parameter.declarationScope as PsiMethod - - val parametersToDelete = collectParametersHierarchy(method, parameter) - if (parametersToDelete.size <= 1 || ApplicationManager.getApplication().isUnitTestMode) return parametersToDelete - - val message = KotlinBundle.message("delete.param.in.method.hierarchy", formatJavaOrLightMethod(method)) - val exitCode = Messages.showOkCancelDialog(parameter.project, message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()) - return if (exitCode == Messages.OK) parametersToDelete else null -} - -// TODO: generalize breadth-first search -private fun collectParametersHierarchy(method: PsiMethod, parameter: PsiParameter): Set { - val queue = ArrayDeque() - val visited = HashSet() - val parametersToDelete = HashSet() - - queue.add(method) - while (!queue.isEmpty()) { - val currentMethod = queue.poll() - - visited += currentMethod - addParameter(currentMethod, parametersToDelete, parameter) - - currentMethod.findSuperMethods(true) - .filter { it !in visited } - .forEach { queue.offer(it) } - OverridingMethodsSearch.search(currentMethod) - .filter { it !in visited } - .forEach { queue.offer(it) } - } - return parametersToDelete -} - -private fun addParameter(method: PsiMethod, result: MutableSet, parameter: PsiParameter) { - val parameterIndex = parameter.unwrapped!!.parameterIndex() - - if (method is KtLightMethod) { - val declaration = method.kotlinOrigin - if (declaration is KtFunction) { - result.add(declaration.valueParameters[parameterIndex]) - } - } - else { - result.add(method.parameterList.parameters[parameterIndex]) - } -} - @Throws(IntroduceRefactoringException::class) fun selectElement( editor: Editor, diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt index e873212564b..8d2990b481c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.refactoring import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils import com.intellij.codeInsight.unwrap.RangeSplitter import com.intellij.codeInsight.unwrap.UnwrapHandler +import com.intellij.ide.IdeBundle import com.intellij.ide.util.PsiElementListCellRenderer import com.intellij.lang.injection.InjectedLanguageManager import com.intellij.lang.java.JavaLanguage @@ -36,6 +37,7 @@ import com.intellij.openapi.options.ConfigurationException import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project import com.intellij.openapi.roots.JavaProjectRootsUtil +import com.intellij.openapi.ui.Messages import com.intellij.openapi.ui.popup.JBPopup import com.intellij.openapi.ui.popup.JBPopupAdapter import com.intellij.openapi.ui.popup.LightweightWindowEvent @@ -62,11 +64,14 @@ import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.toLightClass import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor +import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getJavaMemberDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.intentions.RemoveCurlyBracesFromTemplateIntention import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices @@ -84,6 +89,7 @@ import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.renderer.DescriptorRenderer import org.jetbrains.kotlin.resolve.AnalyzingUtils import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode @@ -795,3 +801,68 @@ val PsiFile.isInjectedFragment: Boolean val PsiElement.isInsideInjectedFragment: Boolean get() = containingFile.isInjectedFragment + +fun checkSuperMethods( + declaration: KtDeclaration, + ignore: Collection?, + actionStringKey: String +): List { + fun getClassDescriptions(overriddenElementsToDescriptor: Map): List { + return overriddenElementsToDescriptor.entries.map { entry -> + val (element, descriptor) = entry + val description = when (element) { + is KtNamedFunction, is KtProperty -> formatClassDescriptor(descriptor.containingDeclaration) + is PsiMethod -> { + val psiClass = element.containingClass ?: error("Invalid element: ${element.getText()}") + formatPsiClass(psiClass, true, false) + } + else -> error("Unexpected element: ${element.getElementTextWithContext()}") + } + " $description\n" + } + } + + fun askUserForMethodsToSearch( + declarationDescriptor: CallableDescriptor, + overriddenElementsToDescriptor: Map + ): List { + if (ApplicationManager.getApplication().isUnitTestMode) return overriddenElementsToDescriptor.keys.toList() + + val superClassDescriptions = getClassDescriptions(overriddenElementsToDescriptor) + + val message = KotlinBundle.message( + "x.overrides.y.in.class.list", + DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(declarationDescriptor), + "\n${superClassDescriptions.joinToString(separator = "")}", + KotlinBundle.message(actionStringKey) + ) + + val exitCode = Messages.showYesNoCancelDialog(declaration.project, message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()) + when (exitCode) { + Messages.YES -> return overriddenElementsToDescriptor.keys.toList() + Messages.NO -> return listOf(declaration) + else -> return emptyList() + } + } + + + val declarationDescriptor = declaration.resolveToDescriptor() as CallableDescriptor + + if (declarationDescriptor is LocalVariableDescriptor) return listOf(declaration) + + val project = declaration.project + val overriddenElementsToDescriptor = HashMap() + for (overriddenDescriptor in DescriptorUtils.getAllOverriddenDescriptors(declarationDescriptor)) { + val overriddenDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, overriddenDescriptor) ?: continue + if (overriddenDeclaration is KtNamedFunction || overriddenDeclaration is KtProperty || overriddenDeclaration is PsiMethod) { + overriddenElementsToDescriptor[overriddenDeclaration] = overriddenDescriptor + } + } + if (ignore != null) { + overriddenElementsToDescriptor.keys.removeAll(ignore) + } + + if (overriddenElementsToDescriptor.isEmpty()) return listOf(declaration) + + return askUserForMethodsToSearch(declarationDescriptor, overriddenElementsToDescriptor) +} diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/renderingUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/renderingUtils.kt new file mode 100644 index 00000000000..fde6f31ccef --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/renderingUtils.kt @@ -0,0 +1,104 @@ +/* + * 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 + +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiSubstitutor +import com.intellij.psi.util.PsiFormatUtil +import com.intellij.psi.util.PsiFormatUtilBase +import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor +import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.renderer.DescriptorRenderer +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils + +fun wrapOrSkip(s: String, inCode: Boolean) = if (inCode) "$s" else s + +fun formatClassDescriptor(classDescriptor: DeclarationDescriptor) = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.render(classDescriptor) + +fun formatPsiClass( + psiClass: PsiClass, + markAsJava: Boolean, + inCode: Boolean +): String { + var description: String + + val kind = if (psiClass.isInterface) "interface " else "class " + description = kind + PsiFormatUtil.formatClass( + psiClass, + PsiFormatUtilBase.SHOW_CONTAINING_CLASS or PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE + ) + description = wrapOrSkip(description, inCode) + + return if (markAsJava) "[Java] $description" else description +} + +fun formatClass(classDescriptor: DeclarationDescriptor, inCode: Boolean): String { + val element = DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor) + return if (element is PsiClass) { + formatPsiClass(element, false, inCode) + } + else { + wrapOrSkip(formatClassDescriptor(classDescriptor), inCode) + } +} + +fun formatFunction(functionDescriptor: DeclarationDescriptor, inCode: Boolean): String { + val element = DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) + return if (element is PsiMethod) { + formatPsiMethod(element, false, inCode) + } + else { + wrapOrSkip(formatFunctionDescriptor(functionDescriptor), inCode) + } +} + +private fun formatFunctionDescriptor(functionDescriptor: DeclarationDescriptor) = DescriptorRenderer.COMPACT.render(functionDescriptor) + +fun formatPsiMethod( + psiMethod: PsiMethod, + showContainingClass: Boolean, + inCode: Boolean +): String { + var options = PsiFormatUtilBase.SHOW_NAME or PsiFormatUtilBase.SHOW_PARAMETERS or PsiFormatUtilBase.SHOW_TYPE + if (showContainingClass) { + //noinspection ConstantConditions + options = options or PsiFormatUtilBase.SHOW_CONTAINING_CLASS + } + + var description = PsiFormatUtil.formatMethod(psiMethod, PsiSubstitutor.EMPTY, options, PsiFormatUtilBase.SHOW_TYPE) + description = wrapOrSkip(description, inCode) + + return "[Java] $description" +} + +fun formatJavaOrLightMethod(method: PsiMethod): String { + val originalDeclaration = method.unwrapped + return if (originalDeclaration is KtDeclaration) { + formatFunctionDescriptor(originalDeclaration.resolveToDescriptor()) + } + else { + formatPsiMethod(method, false, false) + } +} + +fun formatClass(classOrObject: KtClassOrObject) = formatClassDescriptor(classOrObject.resolveToDescriptor() as ClassDescriptor) \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinOverridingDialog.java b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinOverridingDialog.java index bca3ce44e24..88d7bdf8f14 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinOverridingDialog.java +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinOverridingDialog.java @@ -37,7 +37,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.idea.KotlinBundle; import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; -import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtil2Kt; +import org.jetbrains.kotlin.idea.refactoring.RenderingUtilsKt; import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.psi.KtNamedFunction; @@ -110,7 +110,7 @@ class KotlinOverridingDialog extends DialogWrapper { assert element instanceof PsiMethod : "Method accepts only kotlin functions/properties and java methods, but '" + element.getText() + "' was found"; - return KotlinRefactoringUtil2Kt.formatPsiMethod((PsiMethod) element, true, false); + return RenderingUtilsKt.formatPsiMethod((PsiMethod) element, true, false); } @Override diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt index 63a697e6d11..42d5eb56059 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/KotlinSafeDeleteProcessor.kt @@ -39,7 +39,6 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.deleteElementAndCleanParent -import org.jetbrains.kotlin.idea.refactoring.checkParametersInMethodHierarchy import org.jetbrains.kotlin.idea.refactoring.checkSuperMethods import org.jetbrains.kotlin.idea.refactoring.formatClass import org.jetbrains.kotlin.idea.refactoring.formatFunction diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/utils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/utils.kt index 3754829faa5..ca1bbc48b96 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/utils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/safeDelete/utils.kt @@ -16,13 +16,22 @@ package org.jetbrains.kotlin.idea.refactoring.safeDelete +import com.intellij.ide.IdeBundle +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.ui.Messages import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiMethod +import com.intellij.psi.PsiParameter import com.intellij.psi.search.searches.OverridingMethodsSearch +import org.jetbrains.kotlin.asJava.elements.KtLightMethod import org.jetbrains.kotlin.asJava.unwrapped +import org.jetbrains.kotlin.idea.KotlinBundle +import org.jetbrains.kotlin.idea.refactoring.formatJavaOrLightMethod import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.parameterIndex +import java.util.* fun PsiElement.canDeleteElement(): Boolean { if (this is KtObjectDeclaration && isObjectLiteral()) return false @@ -64,3 +73,51 @@ fun PsiMethod.cleanUpOverrides() { } } } + +fun checkParametersInMethodHierarchy(parameter: PsiParameter): Collection? { + val method = parameter.declarationScope as PsiMethod + + val parametersToDelete = collectParametersHierarchy(method, parameter) + if (parametersToDelete.size <= 1 || ApplicationManager.getApplication().isUnitTestMode) return parametersToDelete + + val message = KotlinBundle.message("delete.param.in.method.hierarchy", formatJavaOrLightMethod(method)) + val exitCode = Messages.showOkCancelDialog(parameter.project, message, IdeBundle.message("title.warning"), Messages.getQuestionIcon()) + return if (exitCode == Messages.OK) parametersToDelete else null +} + +// TODO: generalize breadth-first search +private fun collectParametersHierarchy(method: PsiMethod, parameter: PsiParameter): Set { + val queue = ArrayDeque() + val visited = HashSet() + val parametersToDelete = HashSet() + + queue.add(method) + while (!queue.isEmpty()) { + val currentMethod = queue.poll() + + visited += currentMethod + addParameter(currentMethod, parametersToDelete, parameter) + + currentMethod.findSuperMethods(true) + .filter { it !in visited } + .forEach { queue.offer(it) } + OverridingMethodsSearch.search(currentMethod) + .filter { it !in visited } + .forEach { queue.offer(it) } + } + return parametersToDelete +} + +private fun addParameter(method: PsiMethod, result: MutableSet, parameter: PsiParameter) { + val parameterIndex = parameter.unwrapped!!.parameterIndex() + + if (method is KtLightMethod) { + val declaration = method.kotlinOrigin + if (declaration is KtFunction) { + result.add(declaration.valueParameters[parameterIndex]) + } + } + else { + result.add(method.parameterList.parameters[parameterIndex]) + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/AbstractExpressionSelectionTest.java b/idea/tests/org/jetbrains/kotlin/idea/AbstractExpressionSelectionTest.java index 4e625be7805..492a330f68b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/AbstractExpressionSelectionTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/AbstractExpressionSelectionTest.java @@ -23,7 +23,7 @@ import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils; import org.jetbrains.kotlin.idea.refactoring.IntroduceRefactoringException; -import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtil2Kt; +import org.jetbrains.kotlin.idea.refactoring.ElementSelectionUtilsKt; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.test.KotlinTestUtils; @@ -36,7 +36,7 @@ public abstract class AbstractExpressionSelectionTest extends LightCodeInsightTe final String expectedExpression = KotlinTestUtils.getLastCommentInFile((KtFile) getFile()); try { - KotlinRefactoringUtil2Kt.selectElement( + ElementSelectionUtilsKt.selectElement( getEditor(), (KtFile) getFile(), Collections.singletonList(CodeInsightUtils.ElementKind.EXPRESSION), diff --git a/idea/tests/org/jetbrains/kotlin/idea/AbstractSmartSelectionTest.java b/idea/tests/org/jetbrains/kotlin/idea/AbstractSmartSelectionTest.java index 9a07a92f9fa..e8542896d56 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/AbstractSmartSelectionTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/AbstractSmartSelectionTest.java @@ -20,7 +20,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.testFramework.LightCodeInsightTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils; -import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringUtil2Kt; +import org.jetbrains.kotlin.idea.refactoring.ElementSelectionUtilsKt; import org.jetbrains.kotlin.psi.KtElement; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.test.KotlinTestUtils; @@ -34,12 +34,12 @@ public abstract class AbstractSmartSelectionTest extends LightCodeInsightTestCas configureByFile(path); String expectedResultText = KotlinTestUtils.getLastCommentInFile((KtFile) getFile()); - List elements = KotlinRefactoringUtil2Kt.getSmartSelectSuggestions( + List elements = ElementSelectionUtilsKt.getSmartSelectSuggestions( getFile(), getEditor().getCaretModel().getOffset(), CodeInsightUtils.ElementKind.EXPRESSION); List textualExpressions = new ArrayList(); for (KtElement element : elements) { - textualExpressions.add(KotlinRefactoringUtil2Kt.getExpressionShortText(element)); + textualExpressions.add(ElementSelectionUtilsKt.getExpressionShortText(element)); } assertEquals(expectedResultText, StringUtil.join(textualExpressions, "\n")); }