Support delegating to interfaces in ultra-light classes
This commit is contained in:
@@ -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<KtLightMethod>) {
|
||||
classOrObject.superTypeListEntries.filterIsInstance<KtDelegatedSuperTypeEntry>().forEach {
|
||||
addDelegatesToInterfaceMethods(it, result)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addDelegatesToInterfaceMethods(superTypeEntry: KtDelegatedSuperTypeEntry, result: MutableList<KtLightMethod>) {
|
||||
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<KtLightMethod> {
|
||||
val result = arrayListOf<KtLightMethod>()
|
||||
val constructors = classOrObject.allConstructors
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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") }
|
||||
}
|
||||
|
||||
-2
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user