Minor: DeclarationsGenerator can take care of secondary constructor delegating to 'super'.
This commit is contained in:
committed by
Dmitry Petrov
parent
a140d75016
commit
f83237498f
@@ -20,6 +20,10 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.psi2ir.generators.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -56,3 +60,10 @@ fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
fun KtSecondaryConstructor.isConstructorDelegatingToSuper(bindingContext: BindingContext): Boolean {
|
||||
val delegatingResolvedCall = getDelegationCall().getResolvedCall(bindingContext) ?: return false
|
||||
val constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, this) ?: return false
|
||||
val ownerClassDescriptor = constructorDescriptor.containingDeclaration
|
||||
val targetClassDescriptor = delegatingResolvedCall.resultingDescriptor.containingDeclaration
|
||||
return targetClassDescriptor != ownerClassDescriptor
|
||||
}
|
||||
|
||||
@@ -130,13 +130,13 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
|
||||
return irBlockBody
|
||||
}
|
||||
|
||||
fun generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor: KtSecondaryConstructor, ktClassOrObject: KtClassOrObject): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset)
|
||||
fun generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor: KtSecondaryConstructor): IrBody {
|
||||
val irBlockBody = IrBlockBodyImpl(ktConstructor.startOffset, ktConstructor.endOffset)
|
||||
|
||||
generateDelegatingConstructorCall(irBlockBody, ktConstructor)
|
||||
|
||||
irBlockBody.addStatement(IrNestedInitializersCallImpl(ktConstructor.startOffset, ktConstructor.endOffset,
|
||||
getOrFail(BindingContext.CLASS, ktClassOrObject)))
|
||||
val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration
|
||||
irBlockBody.addStatement(IrNestedInitializersCallImpl(ktConstructor.startOffset, ktConstructor.endOffset, classDescriptor))
|
||||
|
||||
ktConstructor.bodyExpression?.let { ktBody ->
|
||||
createStatementGenerator().generateBlockBodyStatements(irBlockBody, ktBody)
|
||||
|
||||
+11
-21
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetVariableImpl
|
||||
@@ -27,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.isConstructorDelegatingToSuper
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator {
|
||||
@@ -40,15 +40,21 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
|
||||
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
|
||||
|
||||
val shouldGenerateNestedInitializers = generateMembersDeclaredInClassBody(irClass, ktClassOrObject)
|
||||
generateMembersDeclaredInClassBody(irClass, ktClassOrObject)
|
||||
|
||||
if (shouldGenerateNestedInitializers) {
|
||||
if (shouldGenerateNestedInitializers(ktClassOrObject)) {
|
||||
irClass.nestedInitializers = BodyGenerator(descriptor, context).generateNestedInitializersBody(ktClassOrObject)
|
||||
}
|
||||
|
||||
return irClass
|
||||
}
|
||||
|
||||
private fun shouldGenerateNestedInitializers(ktClassOrObject: KtClassOrObject): Boolean {
|
||||
val ktClassBody = ktClassOrObject.getBody() ?: return false
|
||||
|
||||
return ktClassBody.declarations.any { it is KtSecondaryConstructor && it.isConstructorDelegatingToSuper(context.bindingContext) }
|
||||
}
|
||||
|
||||
private fun generatePrimaryConstructor(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject) {
|
||||
val primaryConstructorDescriptor = irClass.descriptor.unsubstitutedPrimaryConstructor ?: return
|
||||
|
||||
@@ -70,20 +76,12 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateMembersDeclaredInClassBody(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject): Boolean {
|
||||
var hasConstructorsWithNestedInitializersCall = false
|
||||
|
||||
private fun generateMembersDeclaredInClassBody(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject) {
|
||||
ktClassOrObject.getBody()?.let { ktClassBody ->
|
||||
for (ktDeclaration in ktClassBody.declarations) {
|
||||
if (ktDeclaration is KtAnonymousInitializer) continue
|
||||
|
||||
val irMember =
|
||||
if (ktDeclaration is KtSecondaryConstructor && isConstructorDelegatingToSuper(ktDeclaration, irClass.descriptor)) {
|
||||
hasConstructorsWithNestedInitializersCall = true
|
||||
declarationGenerator.generateSecondaryConstructorWithNestedInitializers(ktDeclaration, ktClassOrObject)
|
||||
}
|
||||
else
|
||||
declarationGenerator.generateMemberDeclaration(ktDeclaration)
|
||||
val irMember = declarationGenerator.generateMemberDeclaration(ktDeclaration)
|
||||
|
||||
irClass.addMember(irMember)
|
||||
if (irMember is IrProperty) {
|
||||
@@ -92,14 +90,6 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasConstructorsWithNestedInitializersCall
|
||||
}
|
||||
|
||||
private fun isConstructorDelegatingToSuper(ktConstructor: KtSecondaryConstructor, classOwner: ClassDescriptor): Boolean {
|
||||
val delegatingResolvedCall = getResolvedCall(ktConstructor.getDelegationCall())!!
|
||||
val calleeOwner = delegatingResolvedCall.resultingDescriptor.containingDeclaration as ClassDescriptor
|
||||
return calleeOwner != classOwner
|
||||
}
|
||||
|
||||
private fun generatePropertyForPrimaryConstructorParameter(ktParameter: KtParameter): IrDeclaration {
|
||||
|
||||
+6
-2
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.psi2ir.isConstructorDelegatingToSuper
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
@@ -59,6 +60,9 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor) : IrFunction {
|
||||
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext)) {
|
||||
return generateSecondaryConstructorWithNestedInitializers(ktConstructor)
|
||||
}
|
||||
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
||||
val body = createBodyGenerator(constructorDescriptor).generateSecondaryConstructorBody(ktConstructor)
|
||||
return IrFunctionImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
@@ -66,9 +70,9 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
|
||||
}
|
||||
|
||||
|
||||
fun generateSecondaryConstructorWithNestedInitializers(ktConstructor: KtSecondaryConstructor, ktClassOrObject: KtClassOrObject): IrDeclaration {
|
||||
private fun generateSecondaryConstructorWithNestedInitializers(ktConstructor: KtSecondaryConstructor): IrFunction {
|
||||
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor)
|
||||
val body = createBodyGenerator(constructorDescriptor).generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor, ktClassOrObject)
|
||||
val body = createBodyGenerator(constructorDescriptor).generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor)
|
||||
return IrFunctionImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED,
|
||||
constructorDescriptor, body)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user