diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt index ddbd637d324..0acb1589b3f 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightPsi.kt @@ -18,9 +18,11 @@ import org.jetbrains.kotlin.asJava.builder.LightClassData import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration import org.jetbrains.kotlin.asJava.elements.KtLightField import org.jetbrains.kotlin.asJava.elements.KtLightMethod +import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.codegen.JvmCodegenUtil +import org.jetbrains.kotlin.codegen.kotlinType import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotated @@ -33,6 +35,7 @@ import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.containingClass import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.DelegationResolver import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME @@ -293,6 +296,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor } addMethodsFromDataClass(result) + addDelegatesToInterfaceMethods(result) result } @@ -332,6 +336,28 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor }.generate() } + private fun addDelegatesToInterfaceMethods(result: MutableList) { + classOrObject.superTypeListEntries.filterIsInstance().forEach { + addDelegatesToInterfaceMethods(it, result) + } + } + + private fun addDelegatesToInterfaceMethods(superTypeEntry: KtDelegatedSuperTypeEntry, result: MutableList) { + val classDescriptor = classOrObject.resolve() as? ClassDescriptor ?: return + val typeReference = superTypeEntry.typeReference ?: return + val bindingContext = typeReference.analyze() + + val superClassDescriptor = CodegenUtil.getSuperClassBySuperTypeListEntry(superTypeEntry, bindingContext) ?: return + val delegationType = superTypeEntry.delegateExpression.kotlinType(bindingContext) ?: return + + for (delegate in DelegationResolver.getDelegates(classDescriptor, superClassDescriptor, delegationType).keys) { + when (delegate) { + is PropertyDescriptor -> delegate.accessors.mapTo(result, this::createGeneratedMethodFromDescriptor) + is FunctionDescriptor -> result.add(createGeneratedMethodFromDescriptor(delegate)) + } + } + } + private fun createConstructors(): List { val result = arrayListOf() val constructors = classOrObject.allConstructors diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt index f390b23d1a1..06c19236875 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightUtils.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtTypeParameter import org.jetbrains.kotlin.psi.KtTypeParameterListOwner import org.jetbrains.kotlin.resolve.BindingContext @@ -130,7 +131,7 @@ internal fun KtDeclaration.getKotlinType(): KotlinType? { } internal fun KtDeclaration.resolve() = LightClassGenerationSupport.getInstance(project).resolveToDescriptor(this) -internal fun KtDeclaration.analyze() = LightClassGenerationSupport.getInstance(project).analyze(this) +internal fun KtElement.analyze() = LightClassGenerationSupport.getInstance(project).analyze(this) // copy-pasted from kotlinInternalUastUtils.kt and post-processed internal fun KotlinType.asPsiType( @@ -233,7 +234,7 @@ fun KtUltraLightClass.createGeneratedMethodFromDescriptor( private fun KtUltraLightClass.lightMethod( descriptor: FunctionDescriptor ): LightMethodBuilder { - val name = descriptor.name.asString() + val name = typeMapper(support).mapFunctionName(descriptor, OwnerKind.IMPLEMENTATION) val accessFlags: Int by lazyPub { val asmFlags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, support.deprecationResolver) diff --git a/compiler/testData/asJava/ultraLightClasses/delegatingToInterfaces.kt b/compiler/testData/asJava/ultraLightClasses/delegatingToInterfaces.kt index d01d281d2bf..468595731e8 100644 --- a/compiler/testData/asJava/ultraLightClasses/delegatingToInterfaces.kt +++ b/compiler/testData/asJava/ultraLightClasses/delegatingToInterfaces.kt @@ -2,6 +2,11 @@ interface Base { fun printMessage() fun printMessageLine() + + val x: Int + var y: Int + + fun String.foo(y: Any?): Int } class BaseImpl(val x: Int) : Base { @@ -9,7 +14,6 @@ class BaseImpl(val x: Int) : Base { override fun printMessageLine() { println(x) } } -/** should load cls */ class Derived(b: Base) : Base by b { override fun printMessage() { print("abc") } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 4b75ef963cc..1f585335e80 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -122,8 +122,6 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG if (declaration is KtClassOrObject) { - declaration.superTypeListEntries.find { it is KtDelegatedSuperTypeEntry }?.let { return it } - declaration.primaryConstructor?.let { findTooComplexDeclaration(it) }?.let { return it } for (d in declaration.declarations) {