Fixed other parameter references broken in new parameter values in conventional Change Signature
This commit is contained in:
+53
-73
@@ -40,86 +40,66 @@ class KotlinParameterInfo @JvmOverloads constructor(
|
|||||||
) : ParameterInfo {
|
) : ParameterInfo {
|
||||||
var currentTypeInfo: KotlinTypeInfo = originalTypeInfo
|
var currentTypeInfo: KotlinTypeInfo = originalTypeInfo
|
||||||
|
|
||||||
val defaultValueParameterReferences: Map<PsiReference, DeclarationDescriptor>
|
val defaultValueParameterReferences: Map<PsiReference, DeclarationDescriptor> by lazy { collectDefaultValueParameterReferences(defaultValueForCall) }
|
||||||
|
|
||||||
init {
|
private fun collectDefaultValueParameterReferences(defaultValueForCall: KtExpression?): Map<PsiReference, DeclarationDescriptor> {
|
||||||
val file = defaultValueForCall?.containingFile as? KtFile
|
val file = defaultValueForCall?.containingFile as? KtFile ?: return emptyMap()
|
||||||
defaultValueParameterReferences =
|
if (!file.isPhysical && file.analysisContext == null) return emptyMap()
|
||||||
if (defaultValueForCall != null && file != null && (file.isPhysical || file.analysisContext != null)) {
|
|
||||||
val project = file.project
|
|
||||||
val map = LinkedHashMap<PsiReference, DeclarationDescriptor>()
|
|
||||||
|
|
||||||
defaultValueForCall!!.accept(
|
val project = file.project
|
||||||
object : KtTreeVisitorVoid() {
|
val map = LinkedHashMap<PsiReference, DeclarationDescriptor>()
|
||||||
private fun selfParameterOrNull(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
|
|
||||||
return if (parameter is ValueParameterDescriptor &&
|
|
||||||
compareDescriptors(project, parameter.containingDeclaration, callableDescriptor)
|
|
||||||
) {
|
|
||||||
parameter
|
|
||||||
} else null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun selfReceiverOrNull(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
|
defaultValueForCall.accept(
|
||||||
if (compareDescriptors(
|
object : KtTreeVisitorVoid() {
|
||||||
project,
|
private fun selfParameterOrNull(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
|
||||||
receiverDescriptor,
|
return (parameter as? ValueParameterDescriptor)
|
||||||
callableDescriptor.extensionReceiverParameter?.containingDeclaration
|
?.takeIf { compareDescriptors(project, parameter.containingDeclaration, callableDescriptor) }
|
||||||
)
|
}
|
||||||
) {
|
|
||||||
return receiverDescriptor
|
|
||||||
}
|
|
||||||
if (compareDescriptors(
|
|
||||||
project,
|
|
||||||
receiverDescriptor,
|
|
||||||
callableDescriptor.dispatchReceiverParameter?.containingDeclaration
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return receiverDescriptor
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun selfReceiverOrNull(receiver: ImplicitReceiver?): DeclarationDescriptor? {
|
private fun selfReceiverOrNull(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
|
||||||
return selfReceiverOrNull(receiver?.declarationDescriptor)
|
if (compareDescriptors(project, receiverDescriptor, callableDescriptor.extensionReceiverParameter?.containingDeclaration)) {
|
||||||
}
|
return receiverDescriptor
|
||||||
|
|
||||||
private fun getRelevantDescriptor(
|
|
||||||
expression: KtSimpleNameExpression,
|
|
||||||
ref: KtReference
|
|
||||||
): DeclarationDescriptor? {
|
|
||||||
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
|
||||||
|
|
||||||
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
|
||||||
if (descriptor is ValueParameterDescriptor) return selfParameterOrNull(descriptor)
|
|
||||||
|
|
||||||
if (descriptor is PropertyDescriptor && callableDescriptor is ConstructorDescriptor) {
|
|
||||||
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? KtParameter
|
|
||||||
return parameter?.let { selfParameterOrNull(context[BindingContext.VALUE_PARAMETER, it]) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val resolvedCall = expression.getResolvedCall(context) ?: return null
|
|
||||||
(resolvedCall.resultingDescriptor as? ReceiverParameterDescriptor)?.let {
|
|
||||||
return if (selfReceiverOrNull(it.containingDeclaration) != null) it else null
|
|
||||||
}
|
|
||||||
|
|
||||||
selfReceiverOrNull(resolvedCall.extensionReceiver as? ImplicitReceiver)?.let { return it }
|
|
||||||
selfReceiverOrNull(resolvedCall.dispatchReceiver as? ImplicitReceiver)?.let { return it }
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
|
||||||
val ref = expression.mainReference
|
|
||||||
val descriptor = getRelevantDescriptor(expression, ref) ?: return
|
|
||||||
map[ref] = descriptor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
if (compareDescriptors(project, receiverDescriptor, callableDescriptor.dispatchReceiverParameter?.containingDeclaration)) {
|
||||||
|
return receiverDescriptor
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
map
|
private fun selfReceiverOrNull(receiver: ImplicitReceiver?): DeclarationDescriptor? {
|
||||||
} else {
|
return selfReceiverOrNull(receiver?.declarationDescriptor)
|
||||||
emptyMap()
|
}
|
||||||
|
|
||||||
|
private fun getRelevantDescriptor(expression: KtSimpleNameExpression, ref: KtReference): DeclarationDescriptor? {
|
||||||
|
val context = expression.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
|
||||||
|
val descriptor = ref.resolveToDescriptors(context).singleOrNull()
|
||||||
|
if (descriptor is ValueParameterDescriptor) return selfParameterOrNull(descriptor)
|
||||||
|
|
||||||
|
if (descriptor is PropertyDescriptor && callableDescriptor is ConstructorDescriptor) {
|
||||||
|
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor) as? KtParameter
|
||||||
|
return parameter?.let { selfParameterOrNull(context[BindingContext.VALUE_PARAMETER, it]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
val resolvedCall = expression.getResolvedCall(context) ?: return null
|
||||||
|
(resolvedCall.resultingDescriptor as? ReceiverParameterDescriptor)?.let {
|
||||||
|
return if (selfReceiverOrNull(it.containingDeclaration) != null) it else null
|
||||||
|
}
|
||||||
|
|
||||||
|
selfReceiverOrNull(resolvedCall.extensionReceiver as? ImplicitReceiver)?.let { return it }
|
||||||
|
selfReceiverOrNull(resolvedCall.dispatchReceiver as? ImplicitReceiver)?.let { return it }
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||||
|
val ref = expression.mainReference
|
||||||
|
val descriptor = getRelevantDescriptor(expression, ref) ?: return
|
||||||
|
map[ref] = descriptor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
return map
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getOldIndex(): Int = originalIndex
|
override fun getOldIndex(): Int = originalIndex
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun <caret>foo(p1: Int, p2: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(1, 1 * 1)
|
||||||
|
foo(2, 2 * 2)
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun <caret>foo(p1: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(1)
|
||||||
|
foo(2)
|
||||||
|
}
|
||||||
+9
@@ -1599,4 +1599,13 @@ class KotlinChangeSignatureTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
fun testRemoveLambdaParameter2() {
|
fun testRemoveLambdaParameter2() {
|
||||||
doTest { removeParameter(0) }
|
doTest { removeParameter(0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testNewParamValueRefsOtherParam() {
|
||||||
|
doTest {
|
||||||
|
val parameterInfo = KotlinParameterInfo(originalBaseFunctionDescriptor, -1, "p2", KotlinTypeInfo(false, BUILT_INS.intType))
|
||||||
|
val codeFragment = KtPsiFactory(project).createExpressionCodeFragment("p1 * p1", context)
|
||||||
|
parameterInfo.defaultValueForCall = codeFragment.getContentElement()!!
|
||||||
|
addParameter(parameterInfo)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user