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.KtLightDeclaration
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
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.backend.common.DataClassMethodGenerator
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||||
|
import org.jetbrains.kotlin.codegen.kotlinType
|
||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
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.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
|
import org.jetbrains.kotlin.resolve.DelegationResolver
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
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)
|
addMethodsFromDataClass(result)
|
||||||
|
addDelegatesToInterfaceMethods(result)
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@@ -332,6 +336,28 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
|||||||
}.generate()
|
}.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> {
|
private fun createConstructors(): List<KtLightMethod> {
|
||||||
val result = arrayListOf<KtLightMethod>()
|
val result = arrayListOf<KtLightMethod>()
|
||||||
val constructors = classOrObject.allConstructors
|
val constructors = classOrObject.allConstructors
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.config.JvmTarget
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtTypeParameter
|
import org.jetbrains.kotlin.psi.KtTypeParameter
|
||||||
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
import org.jetbrains.kotlin.psi.KtTypeParameterListOwner
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
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.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
|
// copy-pasted from kotlinInternalUastUtils.kt and post-processed
|
||||||
internal fun KotlinType.asPsiType(
|
internal fun KotlinType.asPsiType(
|
||||||
@@ -233,7 +234,7 @@ fun KtUltraLightClass.createGeneratedMethodFromDescriptor(
|
|||||||
private fun KtUltraLightClass.lightMethod(
|
private fun KtUltraLightClass.lightMethod(
|
||||||
descriptor: FunctionDescriptor
|
descriptor: FunctionDescriptor
|
||||||
): LightMethodBuilder {
|
): LightMethodBuilder {
|
||||||
val name = descriptor.name.asString()
|
val name = typeMapper(support).mapFunctionName(descriptor, OwnerKind.IMPLEMENTATION)
|
||||||
|
|
||||||
val accessFlags: Int by lazyPub {
|
val accessFlags: Int by lazyPub {
|
||||||
val asmFlags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, support.deprecationResolver)
|
val asmFlags = AsmUtil.getMethodAsmFlags(descriptor, OwnerKind.IMPLEMENTATION, support.deprecationResolver)
|
||||||
|
|||||||
@@ -2,6 +2,11 @@
|
|||||||
interface Base {
|
interface Base {
|
||||||
fun printMessage()
|
fun printMessage()
|
||||||
fun printMessageLine()
|
fun printMessageLine()
|
||||||
|
|
||||||
|
val x: Int
|
||||||
|
var y: Int
|
||||||
|
|
||||||
|
fun String.foo(y: Any?): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseImpl(val x: Int) : Base {
|
class BaseImpl(val x: Int) : Base {
|
||||||
@@ -9,7 +14,6 @@ class BaseImpl(val x: Int) : Base {
|
|||||||
override fun printMessageLine() { println(x) }
|
override fun printMessageLine() { println(x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** should load cls */
|
|
||||||
class Derived(b: Base) : Base by b {
|
class Derived(b: Base) : Base by b {
|
||||||
override fun printMessage() { print("abc") }
|
override fun printMessage() { print("abc") }
|
||||||
}
|
}
|
||||||
|
|||||||
-2
@@ -122,8 +122,6 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
|||||||
|
|
||||||
|
|
||||||
if (declaration is KtClassOrObject) {
|
if (declaration is KtClassOrObject) {
|
||||||
declaration.superTypeListEntries.find { it is KtDelegatedSuperTypeEntry }?.let { return it }
|
|
||||||
|
|
||||||
declaration.primaryConstructor?.let { findTooComplexDeclaration(it) }?.let { return it }
|
declaration.primaryConstructor?.let { findTooComplexDeclaration(it) }?.let { return it }
|
||||||
|
|
||||||
for (d in declaration.declarations) {
|
for (d in declaration.declarations) {
|
||||||
|
|||||||
Reference in New Issue
Block a user