From dcfefb0847227fe65d24742c88c2d14f8ea0791c Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 26 Mar 2015 16:40:49 +0300 Subject: [PATCH] Extract Function: Do not extract extension function reference as parameter --- .../extractableAnalysisUtil.kt | 23 +++++++++++++++---- .../parameters/misc/extensionLambda.kt | 18 +++++++++++++++ .../parameters/misc/extensionLambda.kt.after | 22 ++++++++++++++++++ .../introduce/JetExtractionTestGenerated.java | 6 +++++ 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt create mode 100644 idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt index 5bede079bf0..267d214ff20 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt @@ -598,6 +598,11 @@ private fun ExtractionData.inferParametersInfo( val hasThisReceiver = thisDescriptor != null val thisExpr = ref.getParent() as? JetThisExpression + if (hasThisReceiver + && DescriptorToSourceUtilsIde.getAllDeclarations(project, thisDescriptor!!).all { it.isInsideOf(originalElements) }) { + continue + } + val referencedClassDescriptor: ClassDescriptor? = (thisDescriptor ?: originalDescriptor).let { when (it) { is ClassDescriptor -> @@ -638,9 +643,6 @@ private fun ExtractionData.inferParametersInfo( ?: DEFAULT_PARAMETER_TYPE } - val parameterTypePredicate = - and(pseudocode.getElementValuesRecursively(originalRef).map { getExpectedTypePredicate(it, bindingContext) }) - val parameter = extractedDescriptorToParameter.getOrPut(descriptorToExtract) { val argumentText = if (hasThisReceiver && extractThis) { @@ -661,7 +663,20 @@ private fun ExtractionData.inferParametersInfo( info.originalRefToParameter[originalRef] = parameter parameter.addDefaultType(parameterType) - parameter.addTypePredicate(parameterTypePredicate) + + if (extractThis && thisExpr == null) { + val callElement = resolvedCall!!.getCall().getCallElement() + val instruction = pseudocode.getElementValue(callElement)?.createdAt as? InstructionWithReceivers + val receiverValue = instruction?.receiverValues?.entrySet()?.singleOrNull { it.getValue() == receiverToExtract }?.getKey() + if (receiverValue != null) { + parameter.addTypePredicate(getExpectedTypePredicate(receiverValue, bindingContext)) + } + } + else { + pseudocode.getElementValuesRecursively(originalRef).forEach { + parameter.addTypePredicate(getExpectedTypePredicate(it, bindingContext)) + } + } info.replacementMap[refInfo.offsetInBody] = if (hasThisReceiver && extractThis) AddPrefixReplacement(parameter) else RenameReplacement(parameter) diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt b/idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt new file mode 100644 index 00000000000..f399cf51c51 --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt @@ -0,0 +1,18 @@ +// PARAM_DESCRIPTOR: local final fun Builder.(): kotlin.Unit defined in test. +// PARAM_TYPES: Builder + +class Builder() + +fun Builder.build(b: Builder.() -> Unit) { +} + +fun Builder.test(b: Builder, param: Int) { + build { + build { + build { + build { + } + } + } + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt.after b/idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt.after new file mode 100644 index 00000000000..7fb61772d9a --- /dev/null +++ b/idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt.after @@ -0,0 +1,22 @@ +// PARAM_DESCRIPTOR: local final fun Builder.(): kotlin.Unit defined in test. +// PARAM_TYPES: Builder + +class Builder() + +fun Builder.build(b: Builder.() -> Unit) { +} + +fun Builder.test(b: Builder, param: Int) { + build { + build { + __dummyTestFun__() + } + } +} + +private fun Builder.__dummyTestFun__() { + build { + build { + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java index f86418aba77..ff2e4b0e0e4 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/JetExtractionTestGenerated.java @@ -1726,6 +1726,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest { doExtractFunctionTest(fileName); } + @TestMetadata("extensionLambda.kt") + public void testExtensionLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/extensionLambda.kt"); + doExtractFunctionTest(fileName); + } + @TestMetadata("extensionLambdaAsParameter.kt") public void testExtensionLambdaAsParameter() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/extractFunction/parameters/misc/extensionLambdaAsParameter.kt");