diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/searchHelpers.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/searchHelpers.kt index 795b620ab04..09e6a359996 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/searchHelpers.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/searchHelpers.kt @@ -19,12 +19,18 @@ package org.jetbrains.kotlin.idea.search.usagesSearch import com.intellij.psi.PsiNamedElement import org.jetbrains.kotlin.asJava.LightClassUtil import org.jetbrains.kotlin.asJava.LightClassUtil.PropertyAccessorsPsiMethods +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ConstructorDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver import java.util.* fun PsiNamedElement.getAccessorNames(readable: Boolean = true, writable: Boolean = true): List { @@ -61,16 +67,23 @@ fun PsiNamedElement.getClassNameForCompanionObject(): String? { } fun KtParameter.dataClassComponentFunction(): FunctionDescriptor? { - if (!hasValOrVar()) return null - - // Forcing full resolve of owner class: otherwise DATA_CLASS_COMPONENT_FUNCTION won't be calculated. - // This is a hack, but better solution would need refactoring of data class component function resolution: they need to be resolved - // when resolving corresponding property. - LightClassUtil.getLightClassPropertyMethods(this) + if (!isDataClassProperty()) return null val context = this.analyze() val paramDescriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, this] as? ValueParameterDescriptor + + val constructor = paramDescriptor?.containingDeclaration as? ConstructorDescriptor ?: return null + val index = constructor.valueParameters.indexOf(paramDescriptor) + val correspondingComponentName = DataClassDescriptorResolver.createComponentName(index + 1) + + val dataClass = constructor.containingDeclaration as? ClassDescriptor ?: return null + dataClass.unsubstitutedMemberScope.getContributedFunctions(correspondingComponentName, NoLookupLocation.FROM_IDE) + return context[BindingContext.DATA_CLASS_COMPONENT_FUNCTION, paramDescriptor] } +fun KtParameter.isDataClassProperty(): Boolean { + if (!hasValOrVar()) return false + return this.containingClassOrObject?.hasModifier(KtTokens.DATA_KEYWORD) ?: false +}