Introduce parameter: Do not substitute references which don't resolve to parameters or receivers of the target function #KT-7965 Fixed
This commit is contained in:
@@ -57,6 +57,19 @@ public class JetParameterInfo(
|
||||
|
||||
defaultValueForCall!!.accept(
|
||||
object : JetTreeVisitorVoid() {
|
||||
private fun selfParameterOrNull(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
|
||||
return if (parameter is ValueParameterDescriptor &&
|
||||
parameter.getContainingDeclaration() == functionDescriptor) parameter else null
|
||||
}
|
||||
|
||||
private fun selfReceiverOrNull(receiver: ThisReceiver?): DeclarationDescriptor? {
|
||||
return when (receiver) {
|
||||
functionDescriptor.getExtensionReceiverParameter()?.getValue(),
|
||||
functionDescriptor.getDispatchReceiverParameter()?.getValue()-> receiver?.getDeclarationDescriptor()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRelevantDescriptor(
|
||||
expression: JetSimpleNameExpression,
|
||||
ref: JetReference
|
||||
@@ -64,18 +77,24 @@ public class JetParameterInfo(
|
||||
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
||||
if (descriptor is ValueParameterDescriptor) return descriptor
|
||||
if (descriptor is ValueParameterDescriptor) return selfParameterOrNull(descriptor)
|
||||
|
||||
if (descriptor is PropertyDescriptor && functionDescriptor is ConstructorDescriptor) {
|
||||
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? JetParameter
|
||||
return parameter?.let { context[BindingContext.VALUE_PARAMETER, it] }
|
||||
return parameter?.let { selfParameterOrNull(context[BindingContext.VALUE_PARAMETER, it]) }
|
||||
}
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(context) ?: return null
|
||||
(resolvedCall.getResultingDescriptor() as? ReceiverParameterDescriptor)?.let { return it }
|
||||
(resolvedCall.getResultingDescriptor() as? ReceiverParameterDescriptor)?.let {
|
||||
return when (it) {
|
||||
functionDescriptor.getDispatchReceiverParameter(),
|
||||
functionDescriptor.getExtensionReceiverParameter() -> it
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
(resolvedCall.getExtensionReceiver() as? ThisReceiver)?.let { return it.getDeclarationDescriptor() }
|
||||
(resolvedCall.getDispatchReceiver() as? ThisReceiver)?.let { return it.getDeclarationDescriptor() }
|
||||
selfReceiverOrNull(resolvedCall.getExtensionReceiver() as? ThisReceiver)?.let { return it }
|
||||
selfReceiverOrNull(resolvedCall.getDispatchReceiver() as? ThisReceiver)?.let { return it }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
+5
-1
@@ -120,7 +120,11 @@ fun IntroduceParameterDescriptor.performRefactoring() {
|
||||
return originalDescriptor.modify { methodDescriptor ->
|
||||
if (!withDefaultValue) {
|
||||
val parameters = callable.getValueParameters()
|
||||
parametersToRemove.map { parameters.indexOf(it) }.sortDescending().forEach { methodDescriptor.removeParameter(it) }
|
||||
val withReceiver = methodDescriptor.receiver != null
|
||||
parametersToRemove
|
||||
.map { parameters.indexOf(it) + if (withReceiver) 1 else 0 }
|
||||
.sortDescending()
|
||||
.forEach { methodDescriptor.removeParameter(it) }
|
||||
}
|
||||
|
||||
val parameterInfo = JetParameterInfo(functionDescriptor = callableDescriptor,
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun a() {
|
||||
1.b(2)
|
||||
}
|
||||
|
||||
fun Int.foo(f: Int.(Int) -> Int) = this
|
||||
|
||||
fun Int.b(n: Int) = <selection>n.foo { it + this + n + this@b }</selection> + 1
|
||||
@@ -0,0 +1,9 @@
|
||||
// WITH_RUNTIME
|
||||
// WITH_DEFAULT_VALUE: false
|
||||
fun a() {
|
||||
1.b(2.foo { it + this + 2 + 1 })
|
||||
}
|
||||
|
||||
fun Int.foo(f: Int.(Int) -> Int) = this
|
||||
|
||||
fun Int.b(i: Int) = i + 1
|
||||
+6
@@ -2401,6 +2401,12 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("foreignParameterRef.kt")
|
||||
public void testForeignParameterRef() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/foreignParameterRef.kt");
|
||||
doIntroduceSimpleParameterTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("fun.kt")
|
||||
public void testFun() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/introduceParameter/fun.kt");
|
||||
|
||||
Reference in New Issue
Block a user