Code refactoring

This commit is contained in:
Valentin Kipyatkov
2020-03-26 15:32:36 +02:00
parent e49ca20d17
commit 4f19dd5fe1
@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.resolve.calls.components.isVararg
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.isError
import java.util.*
class KotlinParameterInfo @JvmOverloads constructor(
val callableDescriptor: CallableDescriptor,
@@ -47,66 +46,7 @@ class KotlinParameterInfo @JvmOverloads constructor(
private fun collectDefaultValueParameterReferences(defaultValueForCall: KtExpression?): Map<PsiReference, DeclarationDescriptor> {
val file = defaultValueForCall?.containingFile as? KtFile ?: return emptyMap()
if (!file.isPhysical && file.analysisContext == null) return emptyMap()
val project = file.project
val map = LinkedHashMap<PsiReference, DeclarationDescriptor>()
defaultValueForCall.accept(
object : KtTreeVisitorVoid() {
private fun compareDescriptors(currentDescriptor: DeclarationDescriptor?, originalDescriptor: DeclarationDescriptor?): Boolean {
return compareDescriptors(project, currentDescriptor, originalDescriptor)
}
private fun takeIfParameterOfSelf(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
return (parameter as? ValueParameterDescriptor)
?.takeIf { compareDescriptors(it.containingDeclaration, callableDescriptor) }
}
private fun takeIfReceiverOfSelf(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
return receiverDescriptor?.takeIf {
compareDescriptors(it, callableDescriptor.extensionReceiverParameter?.containingDeclaration)
|| compareDescriptors(it, callableDescriptor.dispatchReceiverParameter?.containingDeclaration)
}
}
private fun takeIfReceiverOfSelf(receiver: ImplicitReceiver?): DeclarationDescriptor? {
return takeIfReceiverOfSelf(receiver?.declarationDescriptor)
}
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 takeIfParameterOfSelf(descriptor)
}
if (descriptor is PropertyDescriptor && callableDescriptor is ConstructorDescriptor) {
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor)
if (parameter is KtParameter) {
return takeIfParameterOfSelf(context[BindingContext.VALUE_PARAMETER, parameter])
}
}
val resolvedCall = expression.getResolvedCall(context) ?: return null
(resolvedCall.resultingDescriptor as? ReceiverParameterDescriptor)?.let {
return if (takeIfReceiverOfSelf(it.containingDeclaration) != null) it else null
}
takeIfReceiverOfSelf(resolvedCall.extensionReceiver as? ImplicitReceiver)?.let { return it }
takeIfReceiverOfSelf(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
return CollectParameterRefsVisitor(callableDescriptor, defaultValueForCall).run()
}
override fun getOldIndex(): Int = originalIndex
@@ -234,4 +174,68 @@ class KotlinParameterInfo @JvmOverloads constructor(
return newParameter
}
private class CollectParameterRefsVisitor(
private val callableDescriptor: CallableDescriptor,
private val expressionToProcess: KtExpression
) : KtTreeVisitorVoid() {
private val refs = LinkedHashMap<PsiReference, DeclarationDescriptor>()
private val bindingContext = expressionToProcess.analyze(BodyResolveMode.PARTIAL)
private val project = expressionToProcess.project
fun run(): Map<PsiReference, DeclarationDescriptor> {
expressionToProcess.accept(this)
return refs
}
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
val ref = expression.mainReference
val descriptor = targetToCollect(expression, ref) ?: return
refs[ref] = descriptor
}
private fun targetToCollect(expression: KtSimpleNameExpression, ref: KtReference): DeclarationDescriptor? {
val descriptor = ref.resolveToDescriptors(bindingContext).singleOrNull()
if (descriptor is ValueParameterDescriptor) {
return takeIfOurParameter(descriptor)
}
if (descriptor is PropertyDescriptor && callableDescriptor is ConstructorDescriptor) {
val parameter = DescriptorToSourceUtils.getSourceFromDescriptor(descriptor)
if (parameter is KtParameter) {
return takeIfOurParameter(bindingContext[BindingContext.VALUE_PARAMETER, parameter])
}
}
val resolvedCall = expression.getResolvedCall(bindingContext) ?: return null
(resolvedCall.resultingDescriptor as? ReceiverParameterDescriptor)?.let {
return if (takeIfOurReceiver(it.containingDeclaration) != null) it else null
}
takeIfOurReceiver(resolvedCall.extensionReceiver as? ImplicitReceiver)?.let { return it }
takeIfOurReceiver(resolvedCall.dispatchReceiver as? ImplicitReceiver)?.let { return it }
return null
}
private fun compareDescriptors(currentDescriptor: DeclarationDescriptor?, originalDescriptor: DeclarationDescriptor?): Boolean {
return compareDescriptors(project, currentDescriptor, originalDescriptor)
}
private fun takeIfOurParameter(parameter: DeclarationDescriptor?): ValueParameterDescriptor? {
return (parameter as? ValueParameterDescriptor)
?.takeIf { compareDescriptors(it.containingDeclaration, callableDescriptor) }
}
private fun takeIfOurReceiver(receiverDescriptor: DeclarationDescriptor?): DeclarationDescriptor? {
return receiverDescriptor?.takeIf {
compareDescriptors(it, callableDescriptor.extensionReceiverParameter?.containingDeclaration)
|| compareDescriptors(it, callableDescriptor.dispatchReceiverParameter?.containingDeclaration)
}
}
private fun takeIfOurReceiver(receiver: ImplicitReceiver?): DeclarationDescriptor? {
return takeIfOurReceiver(receiver?.declarationDescriptor)
}
}
}