Generate IrTypeParameter and IrValueParameter declarations

This commit is contained in:
Dmitry Petrov
2017-03-15 17:47:46 +03:00
parent 03b664febd
commit 8cea27b5bb
149 changed files with 2251 additions and 331 deletions
@@ -16,16 +16,20 @@
package org.jetbrains.kotlin.psi2ir
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.name.Name
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.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
@@ -75,4 +79,7 @@ fun MemberScope.findSingleFunction(name: Name): FunctionDescriptor =
getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).single()
fun KotlinBuiltIns.findSingleFunction(name: Name): FunctionDescriptor =
builtInsPackageScope.findSingleFunction(name)
builtInsPackageScope.findSingleFunction(name)
val PsiElement?.startOffsetOrUndefined get() = this?.startOffset ?: UNDEFINED_OFFSET
val PsiElement?.endOffsetOrUndefined get() = this?.endOffset ?: UNDEFINED_OFFSET
@@ -36,20 +36,6 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
override val scope = Scope(scopeOwner)
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
fun generateDefaultParameters(ktFunction: KtFunction, irFunction: IrFunctionBase) {
generateDefaultParameters(ktFunction.valueParameterList ?: return, irFunction)
}
fun generateDefaultParameters(ktParameterList: KtParameterList, irFunction: IrFunctionBase) {
val statementGenerator = createStatementGenerator()
for (ktParameter in ktParameterList.parameters) {
val ktDefaultValue = ktParameter.defaultValue ?: continue
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter) as? ValueParameterDescriptor ?: continue
val irDefaultValue = statementGenerator.generateExpression(ktDefaultValue)
irFunction.putDefault(valueParameter, IrExpressionBodyImpl(irDefaultValue))
}
}
fun generateFunctionBody(ktBody: KtExpression): IrBody {
val statementGenerator = createStatementGenerator()
@@ -64,8 +50,8 @@ class BodyGenerator(val scopeOwner: DeclarationDescriptor, override val context:
return irBlockBody
}
fun generatePropertyInitializerBody(ktInitializer: KtExpression): IrExpressionBody =
IrExpressionBodyImpl(createStatementGenerator().generateExpression(ktInitializer))
fun generateExpressionBody(ktExpression: KtExpression): IrExpressionBody =
IrExpressionBodyImpl(createStatementGenerator().generateExpression(ktExpression))
fun generateLambdaBody(ktFun: KtFunctionLiteral): IrBody {
val statementGenerator = createStatementGenerator()
@@ -18,9 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
@@ -37,17 +35,16 @@ import org.jetbrains.kotlin.renderer.OverrideRenderingPolicy
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
import java.lang.AssertionError
import java.util.*
class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator {
override val context: GeneratorContext get() = declarationGenerator.context
class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
fun generateClass(ktClassOrObject: KtClassOrObject): IrClass {
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
val irClass = IrClassImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, IrDeclarationOrigin.DEFINED, descriptor)
declarationGenerator.generateTypeParameterDeclarations(irClass, descriptor.declaredTypeParameters)
generatePrimaryConstructor(irClass, ktClassOrObject)
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
@@ -117,7 +114,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
val irDelegate = IrFieldImpl(ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, IrDeclarationOrigin.DELEGATE,
delegateDescriptor)
val bodyGenerator = BodyGenerator(irClass.descriptor, context)
irDelegate.initializer = bodyGenerator.generatePropertyInitializerBody(ktDelegateExpression)
irDelegate.initializer = bodyGenerator.generateExpressionBody(ktDelegateExpression)
irClass.addMember(irDelegate)
for (delegatedMember in delegatedMembers) {
@@ -128,7 +125,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
}
}
private fun generateDelegatedMember(irClass: IrClassImpl, irDelegate: IrFieldImpl,
private fun generateDelegatedMember(irClass: IrClass, irDelegate: IrField,
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor) {
when (delegatedMember) {
is FunctionDescriptor ->
@@ -139,33 +136,36 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
}
private fun generateDelegatedProperty(irClass: IrClassImpl, irDelegate: IrFieldImpl,
delegated: PropertyDescriptor, overridden: PropertyDescriptor) {
private fun generateDelegatedProperty(irClass: IrClass, irDelegate: IrField, delegated: PropertyDescriptor, overridden: PropertyDescriptor) {
irClass.addMember(generateDelegatedProperty(irDelegate, delegated, overridden))
}
private fun generateDelegatedProperty(irDelegate: IrField, delegated: PropertyDescriptor, overridden: PropertyDescriptor): IrPropertyImpl {
val startOffset = irDelegate.startOffset
val endOffset = irDelegate.endOffset
val irProperty = IrPropertyImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, false, delegated)
val irGetter = IrFunctionImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.getter!!)
irGetter.body = generateDelegateFunctionBody(irDelegate, delegated.getter!!, overridden.getter!!)
irProperty.getter = irGetter
irProperty.getter = generateDelegatedFunction(irDelegate, delegated.getter!!, overridden.getter!!)
if (delegated.isVar) {
val irSetter = IrFunctionImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated.setter!!)
irSetter.body = generateDelegateFunctionBody(irDelegate, delegated.setter!!, overridden.setter!!)
irProperty.setter = irSetter
irProperty.setter = generateDelegatedFunction(irDelegate, delegated.setter!!, overridden.setter!!)
}
irClass.addMember(irProperty)
return irProperty
}
private fun generateDelegatedFunction(irClass: IrClassImpl, irDelegate: IrFieldImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor) {
private fun generateDelegatedFunction(irClass: IrClass, irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor) {
irClass.addMember(generateDelegatedFunction(irDelegate, delegated, overridden))
}
private fun generateDelegatedFunction(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrFunction {
val irFunction = IrFunctionImpl(irDelegate.startOffset, irDelegate.endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, delegated)
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden)
irClass.addMember(irFunction)
return irFunction
}
private fun generateDelegateFunctionBody(irDelegate: IrFieldImpl, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
val startOffset = irDelegate.startOffset
val endOffset = irDelegate.endOffset
val dispatchReceiver = delegated.dispatchReceiverParameter ?:
@@ -195,7 +195,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
}
private fun generateAdditionalMembersForDataClass(irClass: IrClassImpl, ktClassOrObject: KtClassOrObject) {
DataClassMembersGenerator(ktClassOrObject, context, irClass).generate()
DataClassMembersGenerator(declarationGenerator).generate(ktClassOrObject, irClass)
}
private fun generateAdditionalMembersForEnumClass(irClass: IrClassImpl) {
@@ -208,14 +208,7 @@ class ClassGenerator(val declarationGenerator: DeclarationGenerator) : Generator
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return
val irPrimaryConstructor = IrConstructorImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, IrDeclarationOrigin.DEFINED,
primaryConstructorDescriptor)
val bodyGenerator = BodyGenerator(primaryConstructorDescriptor, context)
ktClassOrObject.primaryConstructor?.valueParameterList?.let { ktValueParameterList ->
bodyGenerator.generateDefaultParameters(ktValueParameterList, irPrimaryConstructor)
}
irPrimaryConstructor.body = bodyGenerator.generatePrimaryConstructorBody(ktClassOrObject)
val irPrimaryConstructor = FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
irClass.addMember(irPrimaryConstructor)
}
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.common.DataClassMethodGenerator
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
@@ -39,119 +40,129 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import java.lang.AssertionError
class DataClassMembersGenerator(
ktClassOrObject: KtClassOrObject,
override val context: GeneratorContext,
val irClass: IrClassImpl
) : Generator, DataClassMethodGenerator(ktClassOrObject, context.bindingContext) {
private inline fun buildMember(
function: FunctionDescriptor,
psiElement: PsiElement? = null,
body: IrMemberFunctionBuilder.(IrFunction) -> Unit
) {
IrMemberFunctionBuilder(
context, irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER,
psiElement?.startOffset ?: UNDEFINED_OFFSET, psiElement?.endOffset ?: UNDEFINED_OFFSET
).addToClass(body)
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator), Generator{
fun generate(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
MyDataClassMethodGenerator(ktClassOrObject, irClass).generate()
}
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter) ?:
throw AssertionError("No definition for data class constructor parameter $parameter")
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
buildMember(function, ktParameter) {
+irReturn(irGet(irThis(), property))
}
}
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
throw AssertionError("Data class should have a primary constructor: $classDescriptor")
buildMember(function) {
function.valueParameters.forEach { parameter ->
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
putDefault(parameter, irGet(irThis(), property))
private inner class MyDataClassMethodGenerator(
ktClassOrObject: KtClassOrObject,
val irClass: IrClass
) : DataClassMethodGenerator(ktClassOrObject, declarationGenerator.context.bindingContext) {
private inline fun buildMember(
function: FunctionDescriptor,
psiElement: PsiElement? = null,
body: IrMemberFunctionBuilder.(IrFunction) -> Unit
) {
IrMemberFunctionBuilder(
context, irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER,
psiElement?.startOffset ?: UNDEFINED_OFFSET, psiElement?.endOffset ?: UNDEFINED_OFFSET
).addToClass { irFunction ->
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
body(irFunction)
}
+irReturn(irCall(dataClassConstructor).mapValueParameters { irGet(function.valueParameters[it.index]) })
}
}
override fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType))
val otherWithCast = defineTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
for (property in properties) {
+irIfThenReturnFalse(
irNotEquals(irGet(irThis(), property),
irGet(irGet(otherWithCast), property)))
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter) ?:
throw AssertionError("No definition for data class constructor parameter $parameter")
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
buildMember(function, ktParameter) {
+irReturn(irGet(irThis(), property))
}
+irReturnTrue()
}
}
private val INT = context.builtIns.int
private val INT_TYPE = context.builtIns.intType
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
throw AssertionError("Data class should have a primary constructor: $classDescriptor")
private val IMUL = INT.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) }
private val IADD = INT.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) }
private fun getHashCodeFunction(type: KotlinType): CallableDescriptor {
val typeConstructorDescriptor = type.constructor.declarationDescriptor
when (typeConstructorDescriptor) {
is ClassDescriptor ->
return typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
is TypeParameterDescriptor ->
return getHashCodeFunction(context.builtIns.anyType) // TODO
else ->
throw AssertionError("Unexpected type: $type")
}
}
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
val result = defineTemporaryVar(irInt(0), "result")
var first = true
for (property in properties) {
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
val irNewValue =
if (first) hashCodeOfProperty
else irCallOp(IADD, irCallOp(IMUL, irGet(result), irInt(31)), hashCodeOfProperty)
+irSetVar(result, irNewValue)
first = false
buildMember(function) {
function.valueParameters.forEach { parameter ->
val property = getOrFail(BindingContext.VALUE_PARAMETER_AS_PROPERTY, parameter)
putDefault(parameter, irGet(irThis(), property))
}
+irReturn(irCall(dataClassConstructor).mapValueParameters { irGet(function.valueParameters[it.index]) })
}
+irReturn(irGet(result))
}
}
private fun IrMemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
when {
property.type.containsNull() ->
irLet(irGet(receiver, property)) { variable ->
irIfNull(context.builtIns.intType, irGet(variable), irInt(0), getHashCodeOf(irGet(variable)))
}
override fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType))
val otherWithCast = defineTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
for (property in properties) {
+irIfThenReturnFalse(
irNotEquals(irGet(irThis(), property),
irGet(irGet(otherWithCast), property)))
}
+irReturnTrue()
}
}
private val INT = context.builtIns.int
private val INT_TYPE = context.builtIns.intType
private val IMUL = INT.findFirstFunction("times") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) }
private val IADD = INT.findFirstFunction("plus") { KotlinTypeChecker.DEFAULT.equalTypes(it.valueParameters[0].type, INT_TYPE) }
private fun getHashCodeFunction(type: KotlinType): CallableDescriptor {
val typeConstructorDescriptor = type.constructor.declarationDescriptor
when (typeConstructorDescriptor) {
is ClassDescriptor ->
return typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
is TypeParameterDescriptor ->
return getHashCodeFunction(context.builtIns.anyType) // TODO
else ->
getHashCodeOf(irGet(receiver, property))
throw AssertionError("Unexpected type: $type")
}
}
private fun IrMemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression =
irCall(getHashCodeFunction(irValue.type)).apply { dispatchReceiver = irValue }
override fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
val irConcat = irConcat()
irConcat.addArgument(irString(classDescriptor.name.asString() + "("))
var first = true
for (property in properties) {
if (!first) irConcat.addArgument(irString(", "))
irConcat.addArgument(irString(property.name.asString() + "="))
irConcat.addArgument(irGet(irThis(), property))
first = false
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
val result = defineTemporaryVar(irInt(0), "result")
var first = true
for (property in properties) {
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
val irNewValue =
if (first) hashCodeOfProperty
else irCallOp(IADD, irCallOp(IMUL, irGet(result), irInt(31)), hashCodeOfProperty)
+irSetVar(result, irNewValue)
first = false
}
+irReturn(irGet(result))
}
}
private fun IrMemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
when {
property.type.containsNull() ->
irLet(irGet(receiver, property)) { variable ->
irIfNull(context.builtIns.intType, irGet(variable), irInt(0), getHashCodeOf(irGet(variable)))
}
else ->
getHashCodeOf(irGet(receiver, property))
}
private fun IrMemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression =
irCall(getHashCodeFunction(irValue.type)).apply { dispatchReceiver = irValue }
override fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
buildMember(function) {
val irConcat = irConcat()
irConcat.addArgument(irString(classDescriptor.name.asString() + "("))
var first = true
for (property in properties) {
if (!first) irConcat.addArgument(irString(", "))
irConcat.addArgument(irString(property.name.asString() + "="))
irConcat.addArgument(irGet(irThis(), property))
first = false
}
irConcat.addArgument(irString(")"))
+irReturn(irConcat)
}
irConcat.addArgument(irString(")"))
+irReturn(irConcat)
}
}
}
@@ -17,23 +17,27 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.declarations.impl.IrAnonymousInitializerImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrErrorDeclarationImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
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
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
class DeclarationGenerator(override val context: GeneratorContext) : Generator {
fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration =
when (ktDeclaration) {
is KtNamedFunction ->
generateFunctionDeclaration(ktDeclaration)
FunctionGenerator(this).generateFunctionDeclaration(ktDeclaration)
is KtProperty ->
PropertyGenerator(this).generatePropertyDeclaration(ktDeclaration)
is KtClassOrObject ->
@@ -52,7 +56,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
is KtAnonymousInitializer ->
generateAnonymousInitializerDeclaration(ktDeclaration, classDescriptor)
is KtSecondaryConstructor ->
generateSecondaryConstructor(ktDeclaration)
FunctionGenerator(this).generateSecondaryConstructor(ktDeclaration)
is KtEnumEntry ->
generateEnumEntryDeclaration(ktDeclaration)
else ->
@@ -76,44 +80,28 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
return irAnonymousInitializer
}
fun generateFunctionDeclaration(ktFunction: KtNamedFunction): IrFunction {
val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktFunction)
val irFunction = IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset, IrDeclarationOrigin.DEFINED, functionDescriptor)
val bodyGenerator = createBodyGenerator(functionDescriptor)
bodyGenerator.generateDefaultParameters(ktFunction, irFunction)
irFunction.body = ktFunction.bodyExpression?.let { bodyGenerator.generateFunctionBody(it) }
return irFunction
}
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor): IrFunction {
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext)) {
return generateSecondaryConstructorWithNestedInitializers(ktConstructor)
fun generateTypeParameterDeclarations(
irTypeParametersOwner: IrTypeParametersContainer,
from: List<TypeParameterDescriptor>
) {
from.mapTo(irTypeParametersOwner.typeParameters) { typeParameterDescriptor ->
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
val startOffset = ktTypeParameterDeclaration?.startOffset ?: UNDEFINED_OFFSET
val endOffset = ktTypeParameterDeclaration?.endOffset ?: UNDEFINED_OFFSET
IrTypeParameterImpl(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
}
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor)
val bodyGenerator = createBodyGenerator(constructorDescriptor)
bodyGenerator.generateDefaultParameters(ktConstructor, irConstructor)
irConstructor.body = bodyGenerator.generateSecondaryConstructorBody(ktConstructor)
return irConstructor
}
private fun generateSecondaryConstructorWithNestedInitializers(ktConstructor: KtSecondaryConstructor): IrFunction {
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor)
val bodyGenerator = createBodyGenerator(constructorDescriptor)
bodyGenerator.generateDefaultParameters(ktConstructor, irConstructor)
irConstructor.body = createBodyGenerator(constructorDescriptor).generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor)
return irConstructor
}
fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
createBodyGenerator(scopeOwner).generateFunctionBody(ktBody)
fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrExpressionBody =
createBodyGenerator(scopeOwner).generatePropertyInitializerBody(ktBody)
createBodyGenerator(scopeOwner).generateExpressionBody(ktBody)
}
private fun createBodyGenerator(descriptor: CallableDescriptor) =
BodyGenerator(descriptor, context)
abstract class DeclarationGeneratorExtension(val declarationGenerator: DeclarationGenerator) : Generator {
override val context: GeneratorContext get() = declarationGenerator.context
}
}
fun Generator.createBodyGenerator(scopeOwnerDescriptor: CallableDescriptor) =
BodyGenerator(scopeOwnerDescriptor, context)
@@ -36,8 +36,9 @@ import org.jetbrains.kotlin.psi2ir.intermediate.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
constructor(context: GeneratorContext) : this(DeclarationGenerator(context))
class DelegatedPropertyGenerator(override val context: GeneratorContext) : Generator {
fun generateDelegatedProperty(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
@@ -55,30 +56,40 @@ class DelegatedPropertyGenerator(override val context: GeneratorContext) : Gener
val delegateReceiverValue = createBackingFieldValueForDelegate(delegateDescriptor, ktDelegate)
val getterDescriptor = propertyDescriptor.getter!!
irProperty.getter = IrFunctionImpl(
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
getterDescriptor,
generateDelegatedPropertyGetterBody(
ktDelegate, getterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
)
)
irProperty.getter = generateDelegatedPropertyAccessorExceptBody(ktProperty, ktDelegate, getterDescriptor).also { irGetter ->
irGetter.body = generateDelegatedPropertyGetterBody(
ktDelegate, getterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
)
}
if (propertyDescriptor.isVar) {
val setterDescriptor = propertyDescriptor.setter!!
irProperty.setter = IrFunctionImpl(
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
setterDescriptor,
generateDelegatedPropertySetterBody(
ktDelegate, setterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
)
)
irProperty.setter = generateDelegatedPropertyAccessorExceptBody(ktProperty, ktDelegate, setterDescriptor).also { irSetter ->
irSetter.body = generateDelegatedPropertySetterBody(
ktDelegate, setterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, kPropertyType, propertyDescriptor)
)
}
}
return irProperty
}
private fun generateDelegatedPropertyAccessorExceptBody(
ktProperty: KtProperty,
ktDelegate: KtPropertyDelegate,
accessorDescriptor: PropertyAccessorDescriptor
): IrFunction =
IrFunctionImpl(
ktDelegate.startOffset, ktDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
accessorDescriptor
).also { irGetter ->
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irGetter, ktProperty, null)
}
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter)
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, receivers.map{ it.type }, propertyDescriptor.type, propertyDescriptor.isVar)
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.addMember
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSyntheticBodyImpl
import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind
@@ -39,7 +40,10 @@ class EnumClassMembersGenerator(override val context: GeneratorContext) : Genera
irClass.addMember(
IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
valuesFunction, IrSyntheticBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrSyntheticBodyKind.ENUM_VALUES)))
valuesFunction,
IrSyntheticBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrSyntheticBodyKind.ENUM_VALUES)
)
)
}
private fun generateValueOf(irClass: IrClassImpl) {
@@ -51,6 +55,9 @@ class EnumClassMembersGenerator(override val context: GeneratorContext) : Genera
irClass.addMember(
IrFunctionImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
valueOfFunction, IrSyntheticBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrSyntheticBodyKind.ENUM_VALUEOF)))
valueOfFunction,
IrSyntheticBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrSyntheticBodyKind.ENUM_VALUEOF)
)
)
}
}
@@ -0,0 +1,161 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined
import org.jetbrains.kotlin.psi2ir.isConstructorDelegatingToSuper
import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
class FunctionGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
constructor(context: GeneratorContext) : this(DeclarationGenerator(context))
fun generateFunctionDeclaration(ktFunction: KtNamedFunction): IrFunction {
val functionDescriptor = getOrFail(BindingContext.FUNCTION, ktFunction)
val irFunction = IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset, IrDeclarationOrigin.DEFINED, functionDescriptor)
generateFunctionParameterDeclarations(irFunction, ktFunction, ktFunction.receiverTypeReference)
irFunction.body = ktFunction.bodyExpression?.let { createBodyGenerator(functionDescriptor).generateFunctionBody(it) }
return irFunction
}
fun generateLambdaFunctionDeclaration(ktFunction: KtFunctionLiteral): IrFunction {
val lambdaDescriptor = getOrFail(BindingContext.FUNCTION, ktFunction)
val irLambdaFunction = IrFunctionImpl(ktFunction.startOffset, ktFunction.endOffset, IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA, lambdaDescriptor)
generateFunctionParameterDeclarations(irLambdaFunction, ktFunction, null)
irLambdaFunction.body = createBodyGenerator(lambdaDescriptor).generateLambdaBody(ktFunction)
return irLambdaFunction
}
fun generateFunctionParameterDeclarations(
irFunction: IrFunction,
ktParameterOwner: KtElement,
ktReceiverParameterElement: KtElement?
) {
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
generateValueParameterDeclarations(irFunction, ktParameterOwner, ktReceiverParameterElement)
}
fun generatePrimaryConstructor(
primaryConstructorDescriptor: ClassConstructorDescriptor,
ktClassOrObject: KtClassOrObject
): IrConstructor {
val irPrimaryConstructor = IrConstructorImpl(
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
IrDeclarationOrigin.DEFINED,
primaryConstructorDescriptor
)
generateFunctionParameterDeclarations(
irPrimaryConstructor,
ktClassOrObject.primaryConstructor ?: ktClassOrObject,
null
)
irPrimaryConstructor.body = BodyGenerator(primaryConstructorDescriptor, context).generatePrimaryConstructorBody(ktClassOrObject)
return irPrimaryConstructor
}
fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
generateValueParameterDeclarations(irFunction, null, null)
}
private fun generateValueParameterDeclarations(
irFunction: IrFunction,
ktParameterOwner: KtElement?,
ktReceiverParameterElement: KtElement?
) {
val functionDescriptor = irFunction.descriptor
irFunction.dispatchReceiverParameter = functionDescriptor.dispatchReceiverParameter?.let {
generateReceiverParameterDeclaration(it, ktParameterOwner)
}
irFunction.extensionReceiverParameter = functionDescriptor.extensionReceiverParameter?.let {
generateReceiverParameterDeclaration(it, ktReceiverParameterElement ?: ktParameterOwner)
}
val bodyGenerator = createBodyGenerator(functionDescriptor)
functionDescriptor.valueParameters.mapTo(irFunction.valueParameters) { valueParameterDescriptor ->
val ktParameter = DescriptorToSourceUtils.getSourceFromDescriptor(valueParameterDescriptor) as? KtParameter
generateValueParameterDeclaration(valueParameterDescriptor, ktParameter, bodyGenerator)
}
}
private fun generateValueParameterDeclaration(
valueParameterDescriptor: ValueParameterDescriptor,
ktParameter: KtParameter?,
bodyGenerator: BodyGenerator
): IrValueParameter =
IrValueParameterImpl(
ktParameter.startOffsetOrUndefined,
ktParameter.endOffsetOrUndefined,
IrDeclarationOrigin.DEFINED,
valueParameterDescriptor,
ktParameter?.defaultValue?.let {
bodyGenerator.generateExpressionBody(it)
}
)
private fun generateReceiverParameterDeclaration(
receiverParameterDescriptor: ReceiverParameterDescriptor,
ktElement: KtElement?
): IrValueParameter =
IrValueParameterImpl(
ktElement.startOffsetOrUndefined,
ktElement.endOffsetOrUndefined,
IrDeclarationOrigin.DEFINED,
receiverParameterDescriptor
)
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor): IrFunction {
val constructorDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
val irConstructor = IrConstructorImpl(ktConstructor.startOffset, ktConstructor.endOffset, IrDeclarationOrigin.DEFINED,
constructorDescriptor)
generateFunctionParameterDeclarations(irConstructor, ktConstructor, null)
irConstructor.body = createBodyGenerator(constructorDescriptor).run {
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext))
generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor)
else
generateSecondaryConstructorBody(ktConstructor)
}
return irConstructor
}
}
@@ -17,36 +17,29 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.BindingContext
class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
val ktFun = ktLambda.functionLiteral
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda)
val lambdaDescriptor = getOrFail(BindingContext.FUNCTION, ktFun)
val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun)
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
val irFun = IrFunctionImpl(ktFun.startOffset, ktFun.endOffset, IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA, lambdaDescriptor)
irFun.body = BodyGenerator(lambdaDescriptor, statementGenerator.context).generateLambdaBody(ktFun)
irBlock.statements.add(irFun)
irBlock.statements.add(irLambdaFunction)
irBlock.statements.add(
IrCallableReferenceImpl(
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
lambdaDescriptor, null, IrStatementOrigin.LAMBDA
irLambdaFunction.descriptor, null, IrStatementOrigin.LAMBDA
)
)
return irBlock
}
@@ -73,6 +66,5 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
}
private fun generateFunctionDeclaration(ktFun: KtNamedFunction): IrFunction =
DeclarationGenerator(context).generateFunctionDeclaration(ktFun)
FunctionGenerator(context).generateFunctionDeclaration(ktFun)
}
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.PropertyGetterDescriptor
import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -37,11 +34,11 @@ import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyDelegate
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined
import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
import org.jetbrains.kotlin.resolve.BindingContext
class PropertyGenerator(val declarationGenerator: DeclarationGenerator) : Generator {
override val context: GeneratorContext get() = declarationGenerator.context
class PropertyGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
fun generatePropertyDeclaration(ktProperty: KtProperty): IrProperty {
val propertyDescriptor = getPropertyDescriptor(ktProperty)
val ktDelegate = ktProperty.delegate
@@ -65,25 +62,32 @@ class PropertyGenerator(val declarationGenerator: DeclarationGenerator) : Genera
val getter = propertyDescriptor.getter ?:
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
val irGetter = IrFunctionImpl(ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR, getter)
irProperty.getter = irGetter
irGetter.body = generateDefaultGetterBody(ktParameter, getter)
irProperty.getter = generateDefaultAccessor(getter, ktParameter, isGetter = true)
if (propertyDescriptor.isVar) {
val setter = propertyDescriptor.setter ?:
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
val irSetter = IrFunctionImpl(ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR, setter)
irSetter.body = generateDefaultSetterBody(ktParameter, setter)
irProperty.setter = irSetter
irProperty.setter = generateDefaultAccessor(setter, ktParameter, isGetter = false)
}
return irProperty
}
fun generateDefaultAccessor(descriptor: PropertyAccessorDescriptor, ktElement: KtElement, isGetter: Boolean): IrFunction {
val irAccessor = IrFunctionImpl(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR, descriptor)
val accessorDescriptor = irAccessor.descriptor
declarationGenerator.generateTypeParameterDeclarations(irAccessor, accessorDescriptor.typeParameters)
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
irAccessor.body =
if (isGetter) generateDefaultGetterBody(ktElement, descriptor as PropertyGetterDescriptor)
else generateDefaultSetterBody(ktElement, descriptor as PropertySetterDescriptor)
return irAccessor
}
private fun generateDelegatedProperty(ktProperty: KtProperty, ktDelegate: KtPropertyDelegate, propertyDescriptor: PropertyDescriptor): IrProperty {
val ktDelegateExpression = ktDelegate.expression!!
val irDelegateInitializer = declarationGenerator.generateInitializerBody(propertyDescriptor, ktDelegateExpression)
return DelegatedPropertyGenerator(context).generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor, irDelegateInitializer)
return DelegatedPropertyGenerator(declarationGenerator).generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor, irDelegateInitializer)
}
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty {
@@ -114,6 +118,7 @@ class PropertyGenerator(val declarationGenerator: DeclarationGenerator) : Genera
val irGetter = ktGetter?.let {
IrFunctionImpl(it.startOffset, it.endOffset, IrDeclarationOrigin.DEFINED, getter)
} ?: IrFunctionImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR, getter)
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irGetter, ktProperty, ktProperty.receiverTypeReference)
irGetter.body = ktGetter?.bodyExpression?.let {
declarationGenerator.generateFunctionBody(getter, it )
@@ -131,6 +136,7 @@ class PropertyGenerator(val declarationGenerator: DeclarationGenerator) : Genera
val irSetter = ktSetter?.let {
IrFunctionImpl(it.startOffset, it.endOffset, IrDeclarationOrigin.DEFINED, setter)
} ?: IrFunctionImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR, setter)
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irSetter, ktProperty, ktProperty.receiverTypeReference)
irSetter.body = ktSetter?.bodyExpression?.let {
declarationGenerator.generateFunctionBody(setter, it )
@@ -19,15 +19,17 @@ package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.putDefault
import org.jetbrains.kotlin.ir.expressions.IrExpression
class IrMemberFunctionBuilder(
context: IrGeneratorContext,
val irClass: IrClassImpl,
val irClass: IrClass,
val function: FunctionDescriptor,
val origin: IrDeclarationOrigin,
startOffset: Int = UNDEFINED_OFFSET,
@@ -35,11 +37,12 @@ class IrMemberFunctionBuilder(
) : IrBlockBodyBuilder(context, Scope(function), startOffset, endOffset) {
lateinit var irFunction: IrFunction
inline fun addToClass(body: IrMemberFunctionBuilder.(IrFunction) -> Unit) {
inline fun addToClass(body: IrMemberFunctionBuilder.(IrFunction) -> Unit): IrFunction {
irFunction = IrFunctionImpl(startOffset, endOffset, origin, function)
body(irFunction)
irFunction.body = doBuild()
irClass.addMember(irFunction)
irClass.declarations.add(irFunction)
return irFunction
}
fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
@@ -18,13 +18,19 @@ package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.ClassDescriptor
interface IrClass : IrDeclaration, IrDeclarationContainer {
interface IrClass : IrDeclaration, IrDeclarationContainer, IrTypeParametersContainer {
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.CLASS
override val descriptor: ClassDescriptor
}
val typeParameters: MutableList<IrTypeParameter>
fun IrClass.addMember(member: IrDeclaration) {
declarations.add(member)
}
fun IrClass.addAll(members: List<IrDeclaration>) {
declarations.addAll(members)
}
fun IrClass.getInstanceInitializerMembers() =
@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.ir.util.transformFlat
interface IrDeclarationContainer {
val declarations: MutableList<IrDeclaration>
}
@@ -21,19 +21,32 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
interface IrFunction : IrDeclaration {
interface IrFunction : IrDeclaration, IrTypeParametersContainer {
override val descriptor: FunctionDescriptor
val typeParameters: MutableList<IrTypeParameter>
var dispatchReceiverParameter: IrValueParameter?
var extensionReceiverParameter: IrValueParameter?
val valueParameters: MutableList<IrValueParameter>
var body: IrBody?
override val declarationKind: IrDeclarationKind
get() = IrDeclarationKind.FUNCTION
fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody)
fun getDefault(parameter: ValueParameterDescriptor): IrExpressionBody?
}
fun IrFunction.getIrValueParameter(parameter: ValueParameterDescriptor): IrValueParameter =
valueParameters.getOrElse(parameter.index) {
throw AssertionError("No IrValueParameter for $parameter")
}.also { found ->
assert(found.descriptor == parameter) {
"Parameter indices mismatch at $descriptor: $parameter != ${found.descriptor}"
}
}
fun IrFunction.getDefault(parameter: ValueParameterDescriptor): IrExpressionBody? =
getIrValueParameter(parameter).defaultValue
fun IrFunction.putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody) {
getIrValueParameter(parameter).defaultValue = expressionBody
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.ir.declarations
interface IrTypeParametersContainer {
val typeParameters: MutableList<IrTypeParameter>
}
@@ -41,14 +41,6 @@ class IrClassImpl(
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
fun addMember(member: IrDeclaration) {
declarations.add(member)
}
fun addAll(members: List<IrDeclaration>) {
declarations.addAll(members)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitClass(this, data)
@@ -35,30 +35,27 @@ abstract class IrFunctionBase(
) : IrDeclarationBase(startOffset, endOffset, origin), IrFunction {
override val typeParameters: MutableList<IrTypeParameter> = SmartList()
override var dispatchReceiverParameter: IrValueParameter? = null
override var extensionReceiverParameter: IrValueParameter? = null
override val valueParameters: MutableList<IrValueParameter> = ArrayList()
final override var body: IrBody? = null
private fun getIrValueParameter(parameter: ValueParameterDescriptor): IrValueParameter =
valueParameters.getOrElse(parameter.index) {
throw AssertionError("No IrValueParameter for $parameter")
}
override fun getDefault(parameter: ValueParameterDescriptor): IrExpressionBody? =
getIrValueParameter(parameter).defaultValue
override fun putDefault(parameter: ValueParameterDescriptor, expressionBody: IrExpressionBody) {
getIrValueParameter(parameter).defaultValue = expressionBody
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
typeParameters.forEach { it.accept(visitor, data) }
dispatchReceiverParameter?.accept(visitor, data)
extensionReceiverParameter?.accept(visitor, data)
valueParameters.forEach { it.accept(visitor, data) }
body?.accept(visitor, data)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters.transform { it.transform(transformer, data) }
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
valueParameters.transform { it.transform(transformer, data) }
body = body?.transform(transformer, data)
@@ -36,7 +36,7 @@ class IrValueParameterImpl(
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ParameterDescriptor,
defaultValue: IrExpressionBody
defaultValue: IrExpressionBody?
) : this(startOffset, endOffset, origin, descriptor) {
this.defaultValue = defaultValue
}
@@ -85,7 +85,9 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapDeclarationOrigin(declaration.origin),
mapClassDeclaration(declaration.descriptor),
declaration.declarations.map { it.transform(this, null) as IrDeclaration }
)
).apply {
transformTypeParameters(declaration, descriptor.declaredTypeParameters)
}
override fun visitTypeAlias(declaration: IrTypeAlias): IrTypeAlias =
IrTypeAliasImpl(
@@ -100,7 +102,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapDeclarationOrigin(declaration.origin),
mapFunctionDeclaration(declaration.descriptor),
declaration.body?.transform(this, null)
).transformDefaults(declaration)
).transformParameters(declaration)
override fun visitConstructor(declaration: IrConstructor): IrConstructor =
IrConstructorImpl(
@@ -108,17 +110,59 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
mapDeclarationOrigin(declaration.origin),
mapConstructorDeclaration(declaration.descriptor),
declaration.body!!.transform(this, null)
).transformDefaults(declaration)
).transformParameters(declaration)
private fun <T : IrFunction> T.transformDefaults(original: T): T {
for (originalValueParameter in original.descriptor.valueParameters) {
val valueParameter = descriptor.valueParameters[originalValueParameter.index]
original.getDefault(originalValueParameter)?.let { irDefaultParameterValue ->
putDefault(valueParameter, irDefaultParameterValue.transform(this@DeepCopyIrTree, null))
private fun <T : IrTypeParametersContainer> T.transformTypeParameters(original: T, myTypeParameters: List<TypeParameterDescriptor>): T =
apply {
original.typeParameters.mapTo(typeParameters) { originalTypeParameter ->
copyTypeParameter(originalTypeParameter, myTypeParameters[originalTypeParameter.descriptor.index])
}
}
}
return this
}
private fun <T : IrFunction> T.transformParameters(original: T): T =
apply {
transformTypeParameters(original, descriptor.typeParameters)
transformValueParameters(original)
}
private fun <T : IrFunction> T.transformValueParameters(original: T) =
apply {
dispatchReceiverParameter = original.dispatchReceiverParameter?.let {
copyValueParameter(it, descriptor.dispatchReceiverParameter ?: throw AssertionError("No dispatch receiver in $descriptor"))
}
extensionReceiverParameter = original.extensionReceiverParameter?.let {
copyValueParameter(it, descriptor.extensionReceiverParameter ?: throw AssertionError("No extension receiver in $descriptor"))
}
original.valueParameters.mapIndexedTo(valueParameters) { i, originalValueParameter ->
copyValueParameter(originalValueParameter, descriptor.valueParameters[i])
}
}
private fun copyTypeParameter(
originalTypeParameter: IrTypeParameter,
newTypeParameterDescriptor: TypeParameterDescriptor
): IrTypeParameterImpl =
IrTypeParameterImpl(
originalTypeParameter.startOffset, originalTypeParameter.endOffset,
mapDeclarationOrigin(originalTypeParameter.origin),
newTypeParameterDescriptor
)
private fun copyValueParameter(
originalValueParameter: IrValueParameter,
newParameterDescriptor: ParameterDescriptor
): IrValueParameterImpl =
IrValueParameterImpl(
originalValueParameter.startOffset, originalValueParameter.endOffset,
mapDeclarationOrigin(originalValueParameter.origin),
newParameterDescriptor,
originalValueParameter.defaultValue?.transform(this@DeepCopyIrTree, null)
)
// TODO visitTypeParameter
// TODO visitValueParameter
override fun visitProperty(declaration: IrProperty): IrProperty =
IrPropertyImpl(
@@ -71,6 +71,8 @@ class DumpIrTreeVisitor(out: Appendable): IrElementVisitor<Unit, String> {
override fun visitFunction(declaration: IrFunction, data: String) {
declaration.dumpLabeledElementWith(data) {
declaration.typeParameters.dumpElements()
declaration.dispatchReceiverParameter?.accept(this, "\$this")
declaration.extensionReceiverParameter?.accept(this, "\$receiver")
declaration.valueParameters.dumpElements()
declaration.body?.accept(this, "")
}
@@ -16,11 +16,13 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.util.RenderIrElementVisitor.Companion.ref
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.renderer.ClassifierNamePolicy
import org.jetbrains.kotlin.renderer.DescriptorRenderer
@@ -209,14 +211,17 @@ class RenderIrElementVisitor : IrElementVisitor<String, Nothing?> {
internal fun IrDeclaration.name(): String =
descriptor.name.toString()
internal fun IrDeclaration.renderDeclared(): String =
DECLARATION_RENDERER.render(this.descriptor)
internal fun DeclarationDescriptor.ref(): String =
if (this is ReceiverParameterDescriptor)
"<receiver: ${containingDeclaration.ref()}>"
internal fun DescriptorRenderer.renderDescriptor(descriptor: DeclarationDescriptor): String =
if (descriptor is ReceiverParameterDescriptor)
"<receiver: ${descriptor.containingDeclaration.ref()}>"
else
REFERENCE_RENDERER.render(this)
render(descriptor)
internal fun IrDeclaration.renderDeclared(): String =
DECLARATION_RENDERER.renderDescriptor(this.descriptor)
internal fun DeclarationDescriptor.ref(): String =
REFERENCE_RENDERER.renderDescriptor(this)
internal fun KotlinType.render(): String =
DECLARATION_RENDERER.renderType(this)