Use SymbolTable to create symbols for declarations

Introduce hierarchical sub-tables (for variables, type parameters, and value parameters).
First version passing all tests.
This commit is contained in:
Dmitry Petrov
2017-03-22 16:33:08 +03:00
parent 209864e6a3
commit 0595e93952
55 changed files with 595 additions and 410 deletions
@@ -46,39 +46,38 @@ fun StatementGenerator.generateReceiverOrNull(ktDefaultElement: KtElement, recei
fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: ReceiverValue): IntermediateValue =
generateReceiver(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver)
fun StatementGenerator.generateReceiver(startOffset: Int, endOffset: Int, receiver: ReceiverValue): IntermediateValue {
if (receiver is TransientReceiver) {
return TransientReceiverValue(receiver.type)
}
fun StatementGenerator.generateReceiver(startOffset: Int, endOffset: Int, receiver: ReceiverValue): IntermediateValue =
if (receiver is TransientReceiver)
TransientReceiverValue(receiver.type)
else generateDelegatedValue(receiver.type) {
val receiverExpression = when (receiver) {
is ImplicitClassReceiver -> {
val receiverClassDescriptor = receiver.classDescriptor
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
generateSingletonReference(receiverClassDescriptor, startOffset, endOffset, receiver.type)
else
IrGetValueImpl(startOffset, endOffset, receiverClassDescriptor.thisAsReceiverParameter)
}
is ThisClassReceiver ->
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
is SuperCallReceiverValue ->
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
is ExpressionReceiver ->
generateExpression(receiver.expression)
is ClassValueReceiver ->
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
receiver.classQualifier.descriptor as ClassDescriptor)
is ExtensionReceiver ->
IrGetValueImpl(startOffset, startOffset, receiver.declarationDescriptor.extensionReceiverParameter!!)
else ->
TODO("Receiver: ${receiver::class.java.simpleName}")
}
val receiverExpression = when (receiver) {
is ImplicitClassReceiver -> {
val receiverClassDescriptor = receiver.classDescriptor
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
generateSingletonReference(receiverClassDescriptor, startOffset, endOffset, receiver.type)
if (receiverExpression is IrExpressionWithCopy)
RematerializableValue(receiverExpression)
else
IrGetValueImpl(startOffset, endOffset, receiverClassDescriptor.thisAsReceiverParameter)
OnceExpressionValue(receiverExpression)
}
is ThisClassReceiver ->
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
is SuperCallReceiverValue ->
generateThisOrSuperReceiver(receiver, receiver.thisType.constructor.declarationDescriptor as ClassDescriptor)
is ExpressionReceiver ->
generateExpression(receiver.expression)
is ClassValueReceiver ->
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
receiver.classQualifier.descriptor as ClassDescriptor)
is ExtensionReceiver ->
IrGetValueImpl(startOffset, startOffset, receiver.declarationDescriptor.extensionReceiverParameter!!)
else ->
TODO("Receiver: ${receiver::class.java.simpleName}")
}
return if (receiverExpression is IrExpressionWithCopy)
RematerializableValue(receiverExpression)
else
OnceExpressionValue(receiverExpression)
}
fun generateSingletonReference(descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, type: KotlinType): IrDeclarationReference =
when {
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionBase
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.*
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
@@ -42,29 +42,32 @@ import java.util.*
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)
return context.symbolTable.declareClass(
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
IrDeclarationOrigin.DEFINED,
descriptor
).buildWithScope { irClass ->
declarationGenerator.generateTypeParameterDeclarations(irClass, descriptor.declaredTypeParameters)
generatePrimaryConstructor(irClass, ktClassOrObject)
generatePrimaryConstructor(irClass, ktClassOrObject)
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
generatePropertiesDeclaredInPrimaryConstructor(irClass, ktClassOrObject)
generateMembersDeclaredInSupertypeList(irClass, ktClassOrObject)
generateMembersDeclaredInSupertypeList(irClass, ktClassOrObject)
generateMembersDeclaredInClassBody(irClass, ktClassOrObject)
generateMembersDeclaredInClassBody(irClass, ktClassOrObject)
generateFakeOverrideMemberDeclarations(irClass)
generateFakeOverrideMemberDeclarations(irClass)
if (descriptor.isData) {
generateAdditionalMembersForDataClass(irClass, ktClassOrObject)
if (descriptor.isData) {
generateAdditionalMembersForDataClass(irClass, ktClassOrObject)
}
if (descriptor.kind == ClassKind.ENUM_CLASS) {
generateAdditionalMembersForEnumClass(irClass)
}
}
if (descriptor.kind == ClassKind.ENUM_CLASS) {
generateAdditionalMembersForEnumClass(irClass)
}
return irClass
}
private fun generateFakeOverrideMemberDeclarations(irClass: IrClass) {
@@ -130,16 +133,18 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val superClass = superTypeConstructorDescriptor as? ClassDescriptor ?:
throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
val irDelegate = IrFieldImpl(ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, IrDeclarationOrigin.DELEGATE,
delegateDescriptor)
val bodyGenerator = BodyGenerator(irClass.descriptor, context)
irDelegate.initializer = bodyGenerator.generateExpressionBody(ktDelegateExpression)
irClass.addMember(irDelegate)
val irDelegateField = context.symbolTable.declareField(
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
IrDeclarationOrigin.DELEGATE,
delegateDescriptor,
createBodyGenerator(irClass.descriptor).generateExpressionBody(ktDelegateExpression)
)
irClass.addMember(irDelegateField)
for (delegatedMember in delegatedMembers) {
val overriddenMember = delegatedMember.overriddenDescriptors.find { it.containingDeclaration.original == superClass.original }
if (overriddenMember != null) {
generateDelegatedMember(irClass, irDelegate, delegatedMember, overriddenMember)
generateDelegatedMember(irClass, irDelegateField, delegatedMember, overriddenMember)
}
}
}
@@ -177,12 +182,15 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
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)
return irFunction
}
private fun generateDelegatedFunction(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrFunction =
context.symbolTable.declareSimpleFunction(
irDelegate.startOffset, irDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_MEMBER,
delegated
).buildWithScope { irFunction ->
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden)
}
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor): IrBlockBodyImpl {
val startOffset = irDelegate.startOffset
@@ -252,16 +260,20 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
fun generateEnumEntry(ktEnumEntry: KtEnumEntry): IrEnumEntry {
val enumEntryDescriptor = getOrFail(BindingContext.CLASS, ktEnumEntry)
val irEnumEntry = IrEnumEntryImpl(ktEnumEntry.startOffset, ktEnumEntry.endOffset, IrDeclarationOrigin.DEFINED, enumEntryDescriptor)
return context.symbolTable.declareEnumEntry(
ktEnumEntry.startOffset,
ktEnumEntry.endOffset,
IrDeclarationOrigin.DEFINED,
enumEntryDescriptor
).buildWithScope { irEnumEntry ->
irEnumEntry.initializerExpression =
BodyGenerator(enumEntryDescriptor.containingDeclaration, context)
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
irEnumEntry.initializerExpression =
BodyGenerator(enumEntryDescriptor.containingDeclaration, context)
.generateEnumEntryInitializer(ktEnumEntry, enumEntryDescriptor)
if (ktEnumEntry.declarations.isNotEmpty()) {
irEnumEntry.correspondingClass = generateClass(ktEnumEntry)
if (ktEnumEntry.declarations.isNotEmpty()) {
irEnumEntry.correspondingClass = generateClass(ktEnumEntry)
}
}
return irEnumEntry
}
}
@@ -19,10 +19,12 @@ package org.jetbrains.kotlin.psi2ir.generators
import com.intellij.psi.PsiElement
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.putDefault
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -44,6 +46,30 @@ class DataClassMembersGenerator(
MyDataClassMethodGenerator(ktClassOrObject, irClass).generate()
}
private inner class MemberFunctionBuilder(
val irClass: IrClass,
val function: FunctionDescriptor,
val origin: IrDeclarationOrigin,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET
) : IrBlockBodyBuilder(context, Scope(function), startOffset, endOffset) {
lateinit var irFunction: IrFunction
inline fun addToClass(body: MemberFunctionBuilder.(IrFunction) -> Unit): IrFunction {
irFunction = this@DataClassMembersGenerator.context.symbolTable
.declareSimpleFunction(startOffset, endOffset, origin, function)
body(irFunction)
irFunction.body = doBuild()
irClass.declarations.add(irFunction)
return irFunction
}
fun putDefault(parameter: ValueParameterDescriptor, value: IrExpression) {
irFunction.putDefault(parameter, irExprBody(value))
}
}
private inner class MyDataClassMethodGenerator(
ktClassOrObject: KtClassOrObject,
val irClass: IrClass
@@ -51,14 +77,16 @@ class DataClassMembersGenerator(
private inline fun buildMember(
function: FunctionDescriptor,
psiElement: PsiElement? = null,
body: IrMemberFunctionBuilder.(IrFunction) -> Unit
body: MemberFunctionBuilder.(IrFunction) -> Unit
) {
IrMemberFunctionBuilder(
context, irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER,
MemberFunctionBuilder(
irClass, function, IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER,
psiElement.startOffsetOrUndefined, psiElement.endOffsetOrUndefined
).addToClass { irFunction ->
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
body(irFunction)
irFunction.buildWithScope {
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irFunction)
body(irFunction)
}
}
}
@@ -134,7 +162,7 @@ class DataClassMembersGenerator(
}
}
private fun IrMemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
private fun MemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression =
when {
property.type.containsNull() ->
irLet(irGet(receiver, property)) { variable ->
@@ -144,7 +172,7 @@ class DataClassMembersGenerator(
getHashCodeOf(irGet(receiver, property))
}
private fun IrMemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression =
private fun MemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression =
irCall(getHashCodeFunction(irValue.type)).apply { dispatchReceiver = irValue }
override fun generateToStringMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
@@ -17,10 +17,10 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
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.expressions.IrBody
import org.jetbrains.kotlin.ir.declarations.impl.IrErrorDeclarationImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -70,12 +70,13 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
IrTypeAliasImpl(ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration))
fun generateAnonymousInitializerDeclaration(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration {
val irAnonymousInitializer = IrAnonymousInitializerImpl(ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset,
IrDeclarationOrigin.DEFINED, classDescriptor)
irAnonymousInitializer.body = BodyGenerator(classDescriptor, context).generateAnonymousInitializerBody(ktAnonymousInitializer)
return irAnonymousInitializer
}
fun generateAnonymousInitializerDeclaration(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration =
context.symbolTable.declareAnonymousInitializer(
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
).apply {
body = createBodyGenerator(classDescriptor).generateAnonymousInitializerBody(ktAnonymousInitializer)
}
fun generateTypeParameterDeclarations(
irTypeParametersOwner: IrTypeParametersContainer,
@@ -85,13 +86,10 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
val ktTypeParameterDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(typeParameterDescriptor)
val startOffset = ktTypeParameterDeclaration.startOffsetOrUndefined
val endOffset = ktTypeParameterDeclaration.endOffsetOrUndefined
IrTypeParameterImpl(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
context.symbolTable.declareTypeParameter(startOffset, endOffset, IrDeclarationOrigin.DEFINED, typeParameterDescriptor)
}
}
fun generateFunctionBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrBody =
createBodyGenerator(scopeOwner).generateFunctionBody(ktBody)
fun generateInitializerBody(scopeOwner: CallableDescriptor, ktBody: KtExpression): IrExpressionBody =
createBodyGenerator(scopeOwner).generateExpressionBody(ktBody)
@@ -121,7 +119,7 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
)
private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement?): IrFunction =
IrFunctionImpl(
context.symbolTable.declareSimpleFunction(
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
IrDeclarationOrigin.FAKE_OVERRIDE,
functionDescriptor
@@ -130,7 +128,14 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
abstract class DeclarationGeneratorExtension(val declarationGenerator: DeclarationGenerator) : Generator {
override val context: GeneratorContext get() = declarationGenerator.context
inline fun <T : IrDeclaration> T.buildWithScope(builder: (T) -> Unit): T =
also { irDeclaration ->
context.symbolTable.withScope(irDeclaration.descriptor) {
builder(irDeclaration)
}
}
}
fun Generator.createBodyGenerator(scopeOwnerDescriptor: CallableDescriptor) =
fun Generator.createBodyGenerator(scopeOwnerDescriptor: DeclarationDescriptor) =
BodyGenerator(scopeOwnerDescriptor, context)
@@ -21,8 +21,12 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.descriptors.*
import org.jetbrains.kotlin.ir.declarations.impl.IrLocalDelegatedPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrLocalDelegatedPropertyDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
@@ -81,11 +85,11 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
ktDelegate: KtPropertyDelegate,
accessorDescriptor: PropertyAccessorDescriptor
): IrFunction =
IrFunctionImpl(
context.symbolTable.declareSimpleFunction(
ktDelegate.startOffset, ktDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
accessorDescriptor
).also { irGetter ->
).buildWithScope { irGetter ->
FunctionGenerator(declarationGenerator).generateFunctionParameterDeclarations(irGetter, ktProperty, null)
}
@@ -100,13 +104,13 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
kPropertyType: KotlinType,
irDelegateInitializer: IrExpressionBody,
ktDelegate: KtPropertyDelegate
): IrFieldImpl {
): IrField {
val irActualDelegateInitializer = generateInitializerBodyForPropertyDelegate(propertyDescriptor, kPropertyType, irDelegateInitializer, ktDelegate)
val delegateType = irActualDelegateInitializer.expression.type
val delegateDescriptor = createPropertyDelegateDescriptor(propertyDescriptor, delegateType, kPropertyType)
return IrFieldImpl(
return context.symbolTable.declareField(
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
delegateDescriptor, irActualDelegateInitializer
)
@@ -158,10 +162,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
val delegateDescriptor = createLocalPropertyDelegatedDescriptor(variableDescriptor, delegateType, kPropertyType)
val irDelegate = IrVariableImpl(
val irDelegate = context.symbolTable.declareVariable(
ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATE,
delegateDescriptor,
irActualDelegateInitializer
delegateDescriptor, irActualDelegateInitializer
)
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
@@ -174,7 +177,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
getterDescriptor, ktDelegate,
generateDelegatedPropertyGetterBody(
ktDelegate, getterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)))
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)
)
)
if (variableDescriptor.isVar) {
val setterDescriptor = variableDescriptor.setter!!
@@ -182,8 +187,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
setterDescriptor, ktDelegate,
generateDelegatedPropertySetterBody(
ktDelegate, setterDescriptor, delegateReceiverValue,
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)))
createCallableReference(ktDelegate, delegateDescriptor.kPropertyType, delegateDescriptor.correspondingLocalProperty)
)
)
}
return irLocalDelegatedProperty
@@ -192,9 +198,14 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
private fun createVariableValueForDelegate(delegateDescriptor: IrLocalDelegatedPropertyDelegateDescriptor, ktDelegate: KtPropertyDelegate) =
VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, delegateDescriptor)
private fun createLocalPropertyAccessor(getterDescriptor: VariableAccessorDescriptor, ktDelegate: KtPropertyDelegate, body: IrBody) =
IrFunctionImpl(ktDelegate.startOffset, ktDelegate.endOffset, IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
getterDescriptor, body)
private fun createLocalPropertyAccessor(getterDescriptor: VariableAccessorDescriptor, ktDelegate: KtPropertyDelegate, irBody: IrBody) =
context.symbolTable.declareSimpleFunction(
ktDelegate.startOffset, ktDelegate.endOffset,
IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR,
getterDescriptor
).apply {
body = irBody
}
private fun createLocalPropertyDelegatedDescriptor(
variableDescriptor: VariableDescriptorWithAccessors,
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrClass
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.IrSyntheticBodyKind
import org.jetbrains.kotlin.ir.expressions.impl.IrSyntheticBodyImpl
import org.jetbrains.kotlin.psi2ir.findFirstFunction
@@ -39,10 +38,13 @@ 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)
)
context.symbolTable.declareSimpleFunction(
irClass.startOffset, irClass.endOffset,
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
valuesFunction
).apply {
body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUES)
}
)
}
@@ -54,10 +56,13 @@ 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)
)
context.symbolTable.declareSimpleFunction(
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER,
valueOfFunction
).apply {
body = IrSyntheticBodyImpl(irClass.startOffset, irClass.endOffset, IrSyntheticBodyKind.ENUM_VALUEOF)
}
)
}
}
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorCallExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -16,17 +16,12 @@
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.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -39,21 +34,40 @@ 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 generateFunctionDeclaration(ktFunction: KtNamedFunction): IrFunction =
declareSimpleFunction(
ktFunction,
ktFunction.receiverTypeReference,
IrDeclarationOrigin.DEFINED,
getOrFail(BindingContext.FUNCTION, ktFunction)
) {
ktFunction.bodyExpression?.let { generateFunctionBody(it) }
}
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 generateLambdaFunctionDeclaration(ktFunction: KtFunctionLiteral): IrFunction =
declareSimpleFunction(
ktFunction,
null,
IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA,
getOrFail(BindingContext.FUNCTION, ktFunction)
) {
generateLambdaBody(ktFunction)
}
private inline fun declareSimpleFunction(
ktFunction: KtFunction,
ktReceiver: KtElement?,
origin: IrDeclarationOrigin,
descriptor: FunctionDescriptor,
generateBody: BodyGenerator.() -> IrBody?
): IrSimpleFunction =
context.symbolTable.declareSimpleFunction(
ktFunction.startOffset, ktFunction.endOffset, origin, descriptor
).buildWithScope { irFunction ->
generateFunctionParameterDeclarations(irFunction, ktFunction, ktReceiver)
irFunction.body = createBodyGenerator(descriptor).generateBody()
}
fun generateFunctionParameterDeclarations(
irFunction: IrFunction,
@@ -64,33 +78,126 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
generateValueParameterDeclarations(irFunction, ktParameterOwner, ktReceiverParameterElement)
}
fun generatePropertyAccessor(
descriptor: PropertyAccessorDescriptor,
ktProperty: KtProperty,
ktAccessor: KtPropertyAccessor?
): IrSimpleFunction =
context.symbolTable.declareSimpleFunction(
ktAccessor?.startOffset ?: ktProperty.startOffset,
ktAccessor?.endOffset ?: ktProperty.endOffset,
if (ktAccessor != null) IrDeclarationOrigin.DEFINED else IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
descriptor
).buildWithScope { irAccessor ->
generateFunctionParameterDeclarations(irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference)
val ktBodyExpression = ktAccessor?.bodyExpression
irAccessor.body =
if (ktBodyExpression != null)
createBodyGenerator(descriptor).generateFunctionBody(ktBodyExpression)
else
generateDefaultAccessorBody(ktProperty, descriptor)
}
fun generateDefaultAccessorForPrimaryConstructorParameter(
descriptor: PropertyAccessorDescriptor,
ktParameter: KtParameter,
isGetter: Boolean
): IrFunction =
context.symbolTable.declareSimpleFunction(
ktParameter.startOffsetOrUndefined,
ktParameter.endOffsetOrUndefined,
IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR,
descriptor
).buildWithScope { irAccessor ->
val accessorDescriptor = irAccessor.descriptor
declarationGenerator.generateTypeParameterDeclarations(irAccessor, accessorDescriptor.typeParameters)
FunctionGenerator(declarationGenerator).generateSyntheticFunctionParameterDeclarations(irAccessor)
irAccessor.body =
if (isGetter) generateDefaultGetterBody(ktParameter, descriptor as PropertyGetterDescriptor)
else generateDefaultSetterBody(ktParameter, descriptor as PropertySetterDescriptor)
}
private fun generateDefaultAccessorBody(ktProperty: KtElement, accessor: PropertyAccessorDescriptor) =
when (accessor) {
is PropertyGetterDescriptor -> generateDefaultGetterBody(ktProperty, accessor)
is PropertySetterDescriptor -> generateDefaultSetterBody(ktProperty, accessor)
else -> throw AssertionError("Should be getter or setter: $accessor")
}
private fun generateDefaultGetterBody(ktProperty: KtElement, getter: PropertyGetterDescriptor): IrBlockBody {
val property = getter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
irBody.statements.add(IrReturnImpl(ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType, getter,
IrGetFieldImpl(ktProperty.startOffset, ktProperty.endOffset, property, receiver)))
return irBody
}
private fun generateDefaultSetterBody(ktProperty: KtElement, setter: PropertySetterDescriptor): IrBlockBody {
val property = setter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
val setterParameter = setter.valueParameters.single()
irBody.statements.add(IrSetFieldImpl(ktProperty.startOffset, ktProperty.endOffset, property, receiver,
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)))
return irBody
}
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
val containingDeclaration = property.containingDeclaration
val receiver = when (containingDeclaration) {
is ClassDescriptor ->
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, containingDeclaration.thisAsReceiverParameter)
else -> null
}
return receiver
}
fun generatePrimaryConstructor(
primaryConstructorDescriptor: ClassConstructorDescriptor,
ktClassOrObject: KtClassOrObject
): IrConstructor {
val irPrimaryConstructor = IrConstructorImpl(
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
IrDeclarationOrigin.DEFINED,
primaryConstructorDescriptor
)
): IrConstructor =
declareConstructor(ktClassOrObject, ktClassOrObject.primaryConstructor ?: ktClassOrObject, primaryConstructorDescriptor) {
generatePrimaryConstructorBody(ktClassOrObject)
}
generateFunctionParameterDeclarations(
irPrimaryConstructor,
ktClassOrObject.primaryConstructor ?: ktClassOrObject,
null
)
fun generateSecondaryConstructor(ktConstructor: KtSecondaryConstructor): IrConstructor =
declareConstructor(
ktConstructor, ktConstructor,
getOrFail(BindingContext.CONSTRUCTOR, ktConstructor) as ClassConstructorDescriptor
) {
if (ktConstructor.isConstructorDelegatingToSuper(context.bindingContext))
generateSecondaryConstructorBodyWithNestedInitializers(ktConstructor)
else
generateSecondaryConstructorBody(ktConstructor)
}
irPrimaryConstructor.body = BodyGenerator(primaryConstructorDescriptor, context).generatePrimaryConstructorBody(ktClassOrObject)
return irPrimaryConstructor
}
private inline fun declareConstructor(
ktConstructorElement: KtElement,
ktParametersElement: KtElement,
constructorDescriptor: ClassConstructorDescriptor,
generateBody: BodyGenerator.() -> IrBody
): IrConstructor =
context.symbolTable.declareConstructor(
ktConstructorElement.startOffset, ktConstructorElement.endOffset, IrDeclarationOrigin.DEFINED, constructorDescriptor
).buildWithScope { irConstructor ->
generateFunctionParameterDeclarations(irConstructor, ktParametersElement, null)
irConstructor.body = createBodyGenerator(constructorDescriptor).generateBody()
}
fun generateSyntheticFunctionParameterDeclarations(irFunction: IrFunction) {
declarationGenerator.generateTypeParameterDeclarations(irFunction, irFunction.descriptor.typeParameters)
generateValueParameterDeclarations(irFunction, null, null)
}
private fun generateValueParameterDeclarations(
fun generateValueParameterDeclarations(
irFunction: IrFunction,
ktParameterOwner: KtElement?,
ktReceiverParameterElement: KtElement?
@@ -117,45 +224,26 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
ktParameter: KtParameter?,
bodyGenerator: BodyGenerator
): IrValueParameter =
IrValueParameterImpl(
context.symbolTable.declareValueParameter(
ktParameter.startOffsetOrUndefined,
ktParameter.endOffsetOrUndefined,
IrDeclarationOrigin.DEFINED,
valueParameterDescriptor,
ktParameter?.defaultValue?.let {
bodyGenerator.generateExpressionBody(it)
}
)
valueParameterDescriptor
).also {
it.defaultValue = ktParameter?.defaultValue?.let {
bodyGenerator.generateExpressionBody(it)
}
}
private fun generateReceiverParameterDeclaration(
receiverParameterDescriptor: ReceiverParameterDescriptor,
ktElement: KtElement?
): IrValueParameter =
IrValueParameterImpl(
context.symbolTable.declareValueParameter(
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,7 +17,6 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -33,7 +32,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.slicedMap.ReadOnlySlice
import java.lang.AssertionError
import java.lang.RuntimeException
@@ -73,4 +71,6 @@ inline fun GeneratorWithScope.irBlock(ktElement: KtElement?,
this.irBlock(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, origin, resultType, body)
inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit) : IrBlockBody =
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
@@ -17,9 +17,9 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -17,8 +17,9 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -167,14 +168,14 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
nextCall.setExplicitReceiverValue(iteratorValue)
val irNextCall = callGenerator.generateCall(ktLoopRange, nextCall, IrStatementOrigin.FOR_LOOP_NEXT)
val irLoopParameter =
if (ktLoopParameter != null && ktLoopDestructuringDeclaration == null) {
val loopParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktLoopParameter)
IrVariableImpl(ktLoopParameter.startOffset, ktLoopParameter.endOffset, IrDeclarationOrigin.DEFINED,
loopParameterDescriptor, irNextCall)
}
else {
if (ktLoopParameter != null && ktLoopDestructuringDeclaration == null)
context.symbolTable.declareVariable(
ktLoopParameter.startOffset, ktLoopParameter.endOffset, IrDeclarationOrigin.DEFINED,
getOrFail(BindingContext.VALUE_PARAMETER, ktLoopParameter),
irNextCall
)
else
scope.createTemporaryVariable(irNextCall, "loop_parameter")
}
irInnerBody.statements.add(irLoopParameter)
if (ktLoopDestructuringDeclaration != null) {
@@ -16,7 +16,8 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.psi.KtFile
@@ -19,7 +19,9 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.impl.IrBinaryPrimitiveImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrUnaryPrimitiveImpl
@@ -16,26 +16,19 @@
package org.jetbrains.kotlin.psi2ir.generators
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
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtParameter
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(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
@@ -52,37 +45,43 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
val valueParameterDescriptor = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter)
val irProperty = IrPropertyImpl(ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.DEFINED, false, propertyDescriptor)
return IrPropertyImpl(
ktParameter.startOffset, ktParameter.endOffset,
IrDeclarationOrigin.DEFINED, false,
propertyDescriptor
).also { irProperty ->
irProperty.backingField =
generatePropertyBackingField(ktParameter, propertyDescriptor) {
IrExpressionBodyImpl(IrGetValueImpl(
ktParameter.startOffset, ktParameter.endOffset,
valueParameterDescriptor, IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
))
}
val irField = IrFieldImpl(ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, propertyDescriptor)
val irGetParameter = IrGetValueImpl(ktParameter.startOffset, ktParameter.endOffset,
valueParameterDescriptor, IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER)
irField.initializer = IrExpressionBodyImpl(irGetParameter)
irProperty.backingField = irField
val getter = propertyDescriptor.getter ?:
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
irProperty.getter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter, isGetter = true)
val getter = propertyDescriptor.getter ?:
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
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")
irProperty.setter = generateDefaultAccessor(setter, ktParameter, isGetter = false)
if (propertyDescriptor.isVar) {
val setter = propertyDescriptor.setter ?:
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
irProperty.setter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(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 inline fun generatePropertyBackingField(
ktPropertyElement: KtElement,
propertyDescriptor: PropertyDescriptor,
generateInitializer: () -> IrExpressionBody?
) : IrField =
context.symbolTable.declareField(
ktPropertyElement.startOffset, ktPropertyElement.endOffset,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
propertyDescriptor,
generateInitializer()
)
private fun generateDelegatedProperty(ktProperty: KtProperty, ktDelegate: KtPropertyDelegate, propertyDescriptor: PropertyDescriptor): IrProperty {
val ktDelegateExpression = ktDelegate.expression!!
@@ -90,94 +89,37 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
return DelegatedPropertyGenerator(declarationGenerator).generateDelegatedProperty(ktProperty, ktDelegate, propertyDescriptor, irDelegateInitializer)
}
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty {
val irProperty = IrPropertyImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, false, propertyDescriptor)
private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty =
IrPropertyImpl(
ktProperty.startOffset, ktProperty.endOffset,
IrDeclarationOrigin.DEFINED, false,
propertyDescriptor
).apply {
backingField =
if (propertyDescriptor.hasBackingField())
generatePropertyBackingField(ktProperty, propertyDescriptor) {
ktProperty.initializer?.let { declarationGenerator.generateInitializerBody(propertyDescriptor, it) }
}
else
null
val irField = if (propertyDescriptor.hasBackingField()) {
IrFieldImpl(ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, propertyDescriptor,
ktProperty.initializer?.let { declarationGenerator.generateInitializerBody(propertyDescriptor, it) })
}
else null
irProperty.backingField = irField
getter = generateGetterIfRequired(ktProperty, propertyDescriptor)
irProperty.getter = generateGetterIfRequired(ktProperty, propertyDescriptor)
irProperty.setter = generateSetterIfRequired(ktProperty, propertyDescriptor)
return irProperty
}
setter = generateSetterIfRequired(ktProperty, propertyDescriptor)
}
private fun PropertyDescriptor.hasBackingField(): Boolean =
get(BindingContext.BACKING_FIELD_REQUIRED, this) ?: false
private fun generateGetterIfRequired(ktProperty: KtProperty, property: PropertyDescriptor): IrFunction? {
val getter = property.getter ?: return null
val ktGetter = ktProperty.getter
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 )
} ?: generateDefaultGetterBody(ktProperty, getter)
return irGetter
return FunctionGenerator(declarationGenerator).generatePropertyAccessor(getter, ktProperty, ktProperty.getter)
}
private fun generateSetterIfRequired(ktProperty: KtProperty, property: PropertyDescriptor): IrFunction? {
if (!property.isVar) return null
val setter = property.setter ?: return null
val ktSetter = ktProperty.setter
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 )
} ?: generateDefaultSetterBody(ktProperty, setter)
return irSetter
}
private fun generateDefaultGetterBody(ktProperty: KtElement, getter: PropertyGetterDescriptor): IrBlockBody {
val property = getter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
irBody.statements.add(IrReturnImpl(ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType, getter,
IrGetFieldImpl(ktProperty.startOffset, ktProperty.endOffset, property, receiver)))
return irBody
}
private fun generateDefaultSetterBody(ktProperty: KtElement, setter: PropertySetterDescriptor): IrBlockBody {
val property = setter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
val setterParameter = setter.valueParameters.single()
irBody.statements.add(IrSetFieldImpl(ktProperty.startOffset, ktProperty.endOffset, property, receiver,
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)))
return irBody
}
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
val containingDeclaration = property.containingDeclaration
val receiver =
if (containingDeclaration is ClassDescriptor)
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, containingDeclaration.thisAsReceiverParameter)
else
null
return receiver
return FunctionGenerator(declarationGenerator).generatePropertyAccessor(setter, ktProperty, ktProperty.setter)
}
private fun getPropertyDescriptor(ktProperty: KtProperty): PropertyDescriptor {
@@ -17,9 +17,9 @@
package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrCallableReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetClassImpl
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.assertCast
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.*
@@ -78,9 +77,10 @@ class StatementGenerator(
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors)
}
val irLocalVariable = IrVariableImpl(property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED, variableDescriptor)
irLocalVariable.initializer = property.initializer?.genExpr()
return irLocalVariable
return context.symbolTable.declareVariable(
property.startOffset, property.endOffset, IrDeclarationOrigin.DEFINED,
variableDescriptor, property.initializer?.genExpr()
)
}
private fun generateLocalDelegatedProperty(
@@ -119,8 +119,10 @@ class StatementGenerator(
val irComponentCall = callGenerator.generateCall(ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall,
IrStatementOrigin.COMPONENT_N.withIndex(index + 1))
val irComponentVar = IrVariableImpl(ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
componentVariable, irComponentCall)
val irComponentVar = context.symbolTable.declareVariable(
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
componentVariable, irComponentCall
)
irBlock.statements.add(irComponentVar)
}
}
@@ -20,52 +20,132 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.symbols.impl.*
class SymbolTable {
private class SpecializedSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
val descriptorToSymbol = linkedMapOf<D, S>()
private abstract class SymbolTableBase<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>> {
val unboundSymbols = linkedSetOf<S>()
protected abstract fun get(d: D): S?
protected abstract fun set(d: D, s: S)
fun markAsUnbound(s: S) {
assert(unboundSymbols.add(s)) {
"Symbol for ${s.descriptor} was already referenced"
}
}
fun markAsBound(s: S) {
unboundSymbols.remove(s)
}
inline fun declare(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
val symbol = declared(d, createSymbol)
val symbol = getOrCreateSymbol(d, createSymbol)
val owner = createOwner(symbol)
symbol.bind(owner)
return owner
}
inline fun declared(d: D, createSymbol: () -> S): S {
val existing = descriptorToSymbol[d]
inline fun getOrCreateSymbol(d: D, createSymbol: () -> S): S {
val existing = get(d)
return if (existing == null) {
val new = createSymbol()
descriptorToSymbol[d] = new
set(d, new)
new
}
else {
assert(unboundSymbols.remove(existing)) {
"Symbol for $d is already bound"
}
markAsBound(existing)
existing
}
}
inline fun referenced(d: D, createSymbol: () -> S): S =
descriptorToSymbol.getOrPut(d) {
createSymbol().also {
unboundSymbols.add(it)
}
}
inline fun referenced(d: D, createSymbol: () -> S): S {
val s = get(d)
if (s == null) {
val new = createSymbol().also { markAsUnbound(it) }
return new
}
return s
}
}
private val classSymbolTable = SpecializedSymbolTable<ClassDescriptor, IrClass, IrClassSymbol>()
private val constructorSymbolTable = SpecializedSymbolTable<ClassConstructorDescriptor, IrConstructor, IrConstructorSymbol>()
private val enumEntrySymbolTable = SpecializedSymbolTable<ClassDescriptor, IrEnumEntry, IrEnumEntrySymbol>()
private val fieldSymbolTable = SpecializedSymbolTable<PropertyDescriptor, IrField, IrFieldSymbol>()
private val simpleFunctionSymbolTable = SpecializedSymbolTable<FunctionDescriptor, IrSimpleFunction, IrSimpleFunctionSymbol>()
private val typeParameterSymbolTable = SpecializedSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
private val valueParameterSymbolTable = SpecializedSymbolTable<ParameterDescriptor, IrValueParameter, IrValueParameterSymbol>()
private val variableSymbolTable = SpecializedSymbolTable<VariableDescriptor, IrVariable, IrVariableSymbol>()
private class FlatSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>>
: SymbolTableBase<D, B, S>()
{
val descriptorToSymbol = linkedMapOf<D, S>()
override fun get(d: D): S? = descriptorToSymbol[d]
override fun set(d: D, s: S) {
descriptorToSymbol[d] = s
}
}
private class ScopedSymbolTable<D : DeclarationDescriptor, B : IrSymbolOwner, S : IrBindableSymbol<D, B>>
: SymbolTableBase<D, B, S>()
{
inner class Scope(val owner: DeclarationDescriptor, val parent: Scope?) {
private val descriptorToSymbol = linkedMapOf<D, S>()
operator fun get(d: D): S? =
descriptorToSymbol[d] ?: parent?.get(d)
fun getLocal(d: D) = descriptorToSymbol[d]
operator fun set(d: D, s: S) {
descriptorToSymbol[d] = s
}
}
private var currentScope: Scope? = null
override fun get(d: D): S? {
val scope = currentScope ?: throw AssertionError("No active scope")
return scope[d]
}
override fun set(d: D, s: S) {
val scope = currentScope ?: throw AssertionError("No active scope")
scope[d] = s
}
inline fun declareLocal(d: D, createSymbol: () -> S, createOwner: (S) -> B): B {
val scope = currentScope ?: throw AssertionError("No active scope")
val symbol = scope.getLocal(d) ?: createSymbol().also { scope[d] = it }
val owner = createOwner(symbol)
symbol.bind(owner)
return owner
}
fun enterScope(owner: DeclarationDescriptor) {
currentScope = Scope(owner, currentScope)
}
fun leaveScope(owner: DeclarationDescriptor) {
currentScope?.owner.let {
assert(it == owner) { "Unexpected leaveScope: owner=$owner, currentScope.owner=$it" }
}
currentScope = currentScope?.parent
if (currentScope != null && unboundSymbols.isNotEmpty()) {
throw AssertionError("")
}
}
}
private val classSymbolTable = FlatSymbolTable<ClassDescriptor, IrClass, IrClassSymbol>()
private val constructorSymbolTable = FlatSymbolTable<ClassConstructorDescriptor, IrConstructor, IrConstructorSymbol>()
private val enumEntrySymbolTable = FlatSymbolTable<ClassDescriptor, IrEnumEntry, IrEnumEntrySymbol>()
private val fieldSymbolTable = FlatSymbolTable<PropertyDescriptor, IrField, IrFieldSymbol>()
private val simpleFunctionSymbolTable = FlatSymbolTable<FunctionDescriptor, IrSimpleFunction, IrSimpleFunctionSymbol>()
private val typeParameterSymbolTable = ScopedSymbolTable<TypeParameterDescriptor, IrTypeParameter, IrTypeParameterSymbol>()
private val valueParameterSymbolTable = ScopedSymbolTable<ParameterDescriptor, IrValueParameter, IrValueParameterSymbol>()
private val variableSymbolTable = ScopedSymbolTable<VariableDescriptor, IrVariable, IrVariableSymbol>()
private val scopedSymbolTables = listOf(typeParameterSymbolTable, valueParameterSymbolTable, variableSymbolTable)
fun declareFile(fileEntry: SourceManager.FileEntry, packageFragmentDescriptor: PackageFragmentDescriptor): IrFile =
IrFileImpl(
@@ -123,6 +203,10 @@ class SymbolTable {
{ IrFieldImpl(startOffset, endOffset, origin, descriptor, it) }
)
fun declareField(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: PropertyDescriptor,
irInitializer: IrExpressionBody?) : IrField =
declareField(startOffset, endOffset, origin, descriptor).apply { initializer = irInitializer }
fun referenceField(descriptor: PropertyDescriptor) =
fieldSymbolTable.referenced(descriptor) { IrFieldSymbolImpl(descriptor) }
@@ -141,7 +225,7 @@ class SymbolTable {
val unboundSimpleFunctions: Set<IrSimpleFunctionSymbol> get() = simpleFunctionSymbolTable.unboundSymbols
fun declareTypeParameter(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: TypeParameterDescriptor) : IrTypeParameter =
typeParameterSymbolTable.declare(
typeParameterSymbolTable.declareLocal(
descriptor,
{ IrTypeParameterSymbolImpl(descriptor) },
{ IrTypeParameterImpl(startOffset, endOffset, origin, descriptor, it) }
@@ -153,7 +237,7 @@ class SymbolTable {
val unboundTypeParameters: Set<IrTypeParameterSymbol> get() = typeParameterSymbolTable.unboundSymbols
fun declareValueParameter(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: ParameterDescriptor): IrValueParameter =
valueParameterSymbolTable.declare(
valueParameterSymbolTable.declareLocal(
descriptor,
{ IrValueParameterSymbolImpl(descriptor) },
{ IrValueParameterImpl(startOffset, endOffset, origin, descriptor, it) }
@@ -165,14 +249,36 @@ class SymbolTable {
val unboundValueParameters: Set<IrValueParameterSymbol> get() = valueParameterSymbolTable.unboundSymbols
fun declareVariable(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor): IrVariable =
variableSymbolTable.declare(
variableSymbolTable.declareLocal(
descriptor,
{ IrVariableSymbolImpl(descriptor) },
{ IrVariableImpl(startOffset, endOffset, origin, descriptor, it) }
)
fun declareVariable(startOffset: Int, endOffset: Int, origin: IrDeclarationOrigin, descriptor: VariableDescriptor,
irInitializerExpression: IrExpression?
): IrVariable =
declareVariable(startOffset, endOffset, origin, descriptor).apply {
initializer = irInitializerExpression
}
fun referenceVariable(descriptor: VariableDescriptor) =
variableSymbolTable.referenced(descriptor) { IrVariableSymbolImpl(descriptor) }
val unboundVariables: Set<IrVariableSymbol> get() = variableSymbolTable.unboundSymbols
fun enterScope(owner: DeclarationDescriptor) {
scopedSymbolTables.forEach { it.enterScope(owner) }
}
fun leaveScope(owner: DeclarationDescriptor) {
scopedSymbolTables.forEach { it.leaveScope(owner) }
}
}
inline fun <T> SymbolTable.withScope(owner: DeclarationDescriptor, block: () -> T): T {
enterScope(owner)
val result = block()
leaveScope(owner)
return result
}
@@ -16,9 +16,11 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.inlineStatement
import org.jetbrains.kotlin.ir.expressions.isAssignmentOperatorWithResult
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
import org.jetbrains.kotlin.types.KotlinType
import java.lang.AssertionError
@@ -17,7 +17,8 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.types.KotlinType
@@ -17,9 +17,9 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.types.KotlinType
class DelegatedLocalPropertyLValue(
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
import org.jetbrains.kotlin.psi2ir.intermediate.CallBuilder
import org.jetbrains.kotlin.types.KotlinType
class OnceCallValue(
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
import org.jetbrains.kotlin.types.KotlinType
abstract class ExpressionValue(override val type: KotlinType) : IntermediateValue
@@ -28,6 +27,12 @@ inline fun generateExpressionValue(type: KotlinType, crossinline generate: () ->
override fun load(): IrExpression = generate()
}
inline fun generateDelegatedValue(type: KotlinType, crossinline generateValue: () -> IntermediateValue) =
object : ExpressionValue(type) {
val lazyDelegate by lazy { generateValue() }
override fun load(): IrExpression = lazyDelegate.load()
}
class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentReceiver {
private var instantiated = false
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
@@ -18,10 +18,10 @@ package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.builders.constNull
import org.jetbrains.kotlin.ir.builders.equalsNull
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl
import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.makeNullable
@@ -20,7 +20,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext
import org.jetbrains.kotlin.types.KotlinType
@@ -20,7 +20,10 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.types.KotlinType
@@ -19,7 +19,10 @@ package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.types.KotlinType
@@ -17,8 +17,9 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrWhen
import org.jetbrains.kotlin.ir.expressions.impl.*
fun primitiveOp1(startOffset: Int, endOffset: Int, primitiveOpDescriptor: CallableDescriptor, origin: IrStatementOrigin,
@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
inline fun <reified T> Scope.assertCastOwner() =
scopeOwner as? T ?:
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.ir.declarations
import org.jetbrains.kotlin.descriptors.VariableAccessorDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
interface IrLocalDelegatedProperty : IrDeclaration {
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import java.lang.UnsupportedOperationException
interface IrModuleFragment : IrElement {
val descriptor: ModuleDescriptor
@@ -16,13 +16,11 @@
package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.ir.declarations.impl
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -48,15 +46,6 @@ class IrValueParameterImpl(
this.defaultValue = defaultValue
}
constructor(
startOffset: Int,
endOffset: Int,
origin: IrDeclarationOrigin,
descriptor: ParameterDescriptor,
defaultValue: IrExpression
) : this(startOffset, endOffset, origin, descriptor, IrExpressionBodyImpl(defaultValue))
override var defaultValue: IrExpressionBody? = null
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -16,7 +16,8 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrBreakContinue
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.expressions.impl.IrTerminalExpressionBase
import org.jetbrains.kotlin.types.KotlinType
abstract class IrBreakContinueBase(
@@ -21,9 +21,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.ir.expressions.IrClassReference
import org.jetbrains.kotlin.ir.expressions.impl.IrTerminalDeclarationReferenceBase
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrTerminalExpressionBase
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.expressions.IrErrorExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
import org.jetbrains.kotlin.ir.expressions.impl.IrTerminalExpressionBase
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -18,9 +18,8 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFieldAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.types.KotlinType
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetField
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.expressions.IrBranch
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.utils.SmartList
class IrIfThenElseImpl(
@@ -16,11 +16,9 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
import org.jetbrains.kotlin.types.KotlinType
abstract class IrLoopBase(
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -18,11 +18,9 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrSetField
import org.jetbrains.kotlin.ir.expressions.impl.IrFieldExpressionBase
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.typeUtil.builtIns
@@ -17,11 +17,9 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrSetVariable
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrSpreadElement
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -16,11 +16,9 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.*
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -18,7 +18,10 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.SourceManager
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
@@ -16,13 +16,11 @@
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
@@ -78,7 +78,7 @@ FILE /safeCallWithIncrementDecrement.kt
BLOCK_BODY
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
BLOCK type=kotlin.Int origin=POSTFIX_INCR
VAR IR_TEMPORARY_VARIABLE val tmp3_array: kotlin.Int?
VAR IR_TEMPORARY_VARIABLE val tmp1_array: kotlin.Int?
BLOCK type=kotlin.Int? origin=SAFE_CALL
VAR IR_TEMPORARY_VARIABLE val tmp0_safe_receiver: test.C?
GET_VAR 'value-parameter nc: C?' type=test.C? origin=null
@@ -92,15 +92,15 @@ FILE /safeCallWithIncrementDecrement.kt
if: CONST Boolean type=kotlin.Boolean value='true'
then: CALL '<get-p>() on C?: Int' type=kotlin.Int origin=GET_PROPERTY
$receiver: GET_VAR 'tmp0_safe_receiver: C?' type=test.C? origin=null
VAR IR_TEMPORARY_VARIABLE val tmp4_index0: kotlin.Int
VAR IR_TEMPORARY_VARIABLE val tmp2_index0: kotlin.Int
CONST Int type=kotlin.Int value='0'
VAR IR_TEMPORARY_VARIABLE val tmp5: kotlin.Int
VAR IR_TEMPORARY_VARIABLE val tmp3: kotlin.Int
CALL 'get(Int) on Int?: Int' type=kotlin.Int origin=POSTFIX_INCR
$receiver: GET_VAR 'tmp3_array: Int?' type=kotlin.Int? origin=null
index: GET_VAR 'tmp4_index0: Int' type=kotlin.Int origin=null
$receiver: GET_VAR 'tmp1_array: Int?' type=kotlin.Int? origin=null
index: GET_VAR 'tmp2_index0: Int' type=kotlin.Int origin=null
CALL 'set(Int, Int) on Int?: Unit' type=kotlin.Unit origin=POSTFIX_INCR
$receiver: GET_VAR 'tmp3_array: Int?' type=kotlin.Int? origin=null
index: GET_VAR 'tmp4_index0: Int' type=kotlin.Int origin=null
$receiver: GET_VAR 'tmp1_array: Int?' type=kotlin.Int? origin=null
index: GET_VAR 'tmp2_index0: Int' type=kotlin.Int origin=null
value: CALL 'inc(): Int' type=kotlin.Int origin=POSTFIX_INCR
$this: GET_VAR 'tmp5: Int' type=kotlin.Int origin=null
GET_VAR 'tmp5: Int' type=kotlin.Int origin=null
$this: GET_VAR 'tmp3: Int' type=kotlin.Int origin=null
GET_VAR 'tmp3: Int' type=kotlin.Int origin=null