IR: refactor IrMemberAccessExpression internals

The idea is to keep the subclasses as simple as possible, to simplify
transition to auto-generated IR.

Co-authored-by: mcpiroman <mcpiroman@gmail.com>
This commit is contained in:
Alexander Udalov
2022-01-12 23:11:00 +01:00
parent 6f6bdd8aec
commit 785eb83822
17 changed files with 91 additions and 142 deletions
@@ -9,11 +9,8 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrCall(
typeArgumentsCount: Int,
valueArgumentsCount: Int,
) : IrFunctionAccessExpression(typeArgumentsCount, valueArgumentsCount) {
override abstract val symbol: IrSimpleFunctionSymbol
abstract class IrCall : IrFunctionAccessExpression() {
abstract override val symbol: IrSimpleFunctionSymbol
abstract val superQualifierSymbol: IrClassSymbol?
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -8,6 +8,6 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.name.Name
abstract class IrCallableReference<S : IrSymbol>(typeArgumentsCount: Int) : IrMemberAccessExpression<S>(typeArgumentsCount) {
abstract class IrCallableReference<S : IrSymbol> : IrMemberAccessExpression<S>() {
abstract val referencedName: Name
}
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrConstructorCall(
typeArgumentsCount: Int,
valueArgumentsCount: Int,
) : IrFunctionAccessExpression(typeArgumentsCount, valueArgumentsCount) {
abstract class IrConstructorCall : IrFunctionAccessExpression() {
abstract override val symbol: IrConstructorSymbol
abstract val constructorTypeArgumentsCount: Int
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrDelegatingConstructorCall(
typeArgumentsCount: Int,
valueArgumentsCount: Int,
) : IrFunctionAccessExpression(typeArgumentsCount, valueArgumentsCount) {
abstract class IrDelegatingConstructorCall : IrFunctionAccessExpression() {
abstract override val symbol: IrConstructorSymbol
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrEnumConstructorCall(
typeArgumentsCount: Int,
valueArgumentsCount: Int,
) : IrFunctionAccessExpression(typeArgumentsCount, valueArgumentsCount) {
abstract class IrEnumConstructorCall : IrFunctionAccessExpression() {
abstract override val symbol: IrConstructorSymbol
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
@@ -6,47 +6,7 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrFunctionAccessExpression(
typeArgumentsCount: Int,
valueArgumentsCount: Int,
) : IrMemberAccessExpression<IrFunctionSymbol>(typeArgumentsCount) {
private val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
final override val valueArgumentsCount: Int
get() = argumentsByParameterIndex.size
var contextReceiversCount: Int = 0
override fun getValueArgument(index: Int): IrExpression? {
if (index >= valueArgumentsCount) {
throwNoSuchArgumentSlotException("value", index, valueArgumentsCount)
}
return argumentsByParameterIndex[index]
}
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
if (index >= valueArgumentsCount) {
throwNoSuchArgumentSlotException("value", index, valueArgumentsCount)
}
argumentsByParameterIndex[index] = valueArgument
}
override fun removeValueArgument(index: Int) {
argumentsByParameterIndex[index] = null
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
super.acceptChildren(visitor, data)
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
super.transformChildren(transformer, data)
argumentsByParameterIndex.forEachIndexed { i, irExpression ->
argumentsByParameterIndex[i] = irExpression?.transform(transformer, data)
}
}
abstract class IrFunctionAccessExpression : IrMemberAccessExpression<IrFunctionSymbol>() {
abstract var contextReceiversCount: Int
}
@@ -6,7 +6,11 @@
package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrFunctionReference(typeArgumentsCount: Int) : IrCallableReference<IrFunctionSymbol>(typeArgumentsCount) {
abstract class IrFunctionReference : IrCallableReference<IrFunctionSymbol>() {
abstract val reflectionTarget: IrFunctionSymbol?
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFunctionReference(this, data)
}
@@ -10,14 +10,11 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrLocalDelegatedPropertyReference : IrCallableReference<IrLocalDelegatedPropertySymbol>(0) {
abstract class IrLocalDelegatedPropertyReference : IrCallableReference<IrLocalDelegatedPropertySymbol>() {
abstract val delegate: IrVariableSymbol
abstract val getter: IrSimpleFunctionSymbol
abstract val setter: IrSimpleFunctionSymbol?
override val valueArgumentsCount: Int
get() = 0
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitLocalDelegatedPropertyReference(this, data)
}
@@ -20,23 +20,34 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
abstract class IrMemberAccessExpression<S : IrSymbol>(typeArgumentsCount: Int) : IrDeclarationReference() {
abstract class IrMemberAccessExpression<S : IrSymbol> : IrDeclarationReference() {
var dispatchReceiver: IrExpression? = null
var extensionReceiver: IrExpression? = null
abstract override val symbol: S
abstract val origin: IrStatementOrigin?
abstract val valueArgumentsCount: Int
abstract fun getValueArgument(index: Int): IrExpression?
abstract fun putValueArgument(index: Int, valueArgument: IrExpression?)
abstract fun removeValueArgument(index: Int)
private val typeArgumentsByIndex = arrayOfNulls<IrType>(typeArgumentsCount)
protected abstract val typeArgumentsByIndex: Array<IrType?>
val typeArgumentsCount: Int get() = typeArgumentsByIndex.size
protected abstract val argumentsByParameterIndex: Array<IrExpression?>
open val valueArgumentsCount: Int get() = argumentsByParameterIndex.size
fun getValueArgument(index: Int): IrExpression? {
if (index >= valueArgumentsCount) {
throw AssertionError("$this: No such value argument slot: $index")
}
return argumentsByParameterIndex[index]
}
fun putValueArgument(index: Int, valueArgument: IrExpression?) {
if (index >= valueArgumentsCount) {
throw AssertionError("$this: No such value argument slot: $index")
}
argumentsByParameterIndex[index] = valueArgument
}
fun getTypeArgument(index: Int): IrType? {
if (index >= typeArgumentsCount) {
throwNoSuchArgumentSlotException("type", index, typeArgumentsCount)
@@ -54,11 +65,19 @@ abstract class IrMemberAccessExpression<S : IrSymbol>(typeArgumentsCount: Int) :
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
dispatchReceiver?.accept(visitor, data)
extensionReceiver?.accept(visitor, data)
if (valueArgumentsCount > 0) {
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
}
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
dispatchReceiver = dispatchReceiver?.transform(transformer, data)
extensionReceiver = extensionReceiver?.transform(transformer, data)
if (valueArgumentsCount > 0) {
argumentsByParameterIndex.forEachIndexed { i, irExpression ->
argumentsByParameterIndex[i] = irExpression?.transform(transformer, data)
}
}
}
}
@@ -108,10 +127,6 @@ fun IrMemberAccessExpression<*>.putValueArgument(valueParameterDescriptor: Value
putValueArgument(valueParameterDescriptor.index, valueArgument)
}
fun IrMemberAccessExpression<*>.removeValueArgument(valueParameterDescriptor: ValueParameterDescriptor) {
removeValueArgument(valueParameterDescriptor.index)
}
@ObsoleteDescriptorBasedAPI
inline fun <T : IrMemberAccessExpression<*>> T.mapTypeParameters(transform: (TypeParameterDescriptor) -> IrType) : T =
apply {
@@ -10,14 +10,11 @@ import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
abstract class IrPropertyReference(typeArgumentsCount: Int) : IrCallableReference<IrPropertySymbol>(typeArgumentsCount) {
abstract class IrPropertyReference : IrCallableReference<IrPropertySymbol>() {
abstract val field: IrFieldSymbol?
abstract val getter: IrSimpleFunctionSymbol?
abstract val setter: IrSimpleFunctionSymbol?
override val valueArgumentsCount: Int
get() = 0
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitPropertyReference(this, data)
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
@@ -35,7 +36,14 @@ class IrCallImpl(
valueArgumentsCount: Int,
override val origin: IrStatementOrigin? = null,
override val superQualifierSymbol: IrClassSymbol? = null
) : IrCall(typeArgumentsCount, valueArgumentsCount) {
) : IrCall() {
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
override var contextReceiversCount = 0
init {
if (symbol is IrConstructorSymbol) {
throw AssertionError("Should be IrConstructorCall: ${this.render()}")
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.types.IrType
@@ -22,7 +23,13 @@ class IrConstructorCallImpl(
override val constructorTypeArgumentsCount: Int,
valueArgumentsCount: Int,
override val origin: IrStatementOrigin? = null,
) : IrConstructorCall(typeArgumentsCount, valueArgumentsCount) {
) : IrConstructorCall() {
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
override var contextReceiversCount = 0
companion object {
@ObsoleteDescriptorBasedAPI
fun fromSymbolDescriptor(
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
@@ -30,11 +31,17 @@ class IrDelegatingConstructorCallImpl(
override var type: IrType,
override val symbol: IrConstructorSymbol,
typeArgumentsCount: Int,
valueArgumentsCount: Int
) : IrDelegatingConstructorCall(typeArgumentsCount, valueArgumentsCount) {
valueArgumentsCount: Int,
) : IrDelegatingConstructorCall() {
override val origin: IrStatementOrigin?
get() = null
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
override var contextReceiversCount = 0
companion object {
@ObsoleteDescriptorBasedAPI
fun fromSymbolDescriptor(
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.types.IrType
@@ -29,10 +30,16 @@ class IrEnumConstructorCallImpl(
override val symbol: IrConstructorSymbol,
typeArgumentsCount: Int,
valueArgumentsCount: Int
) : IrEnumConstructorCall(typeArgumentsCount, valueArgumentsCount) {
) : IrEnumConstructorCall() {
override val origin: IrStatementOrigin?
get() = null
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
override var contextReceiversCount = 0
companion object {
@ObsoleteDescriptorBasedAPI
fun fromSymbolDescriptor(
@@ -22,8 +22,6 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
class IrFunctionReferenceImpl(
@@ -32,47 +30,16 @@ class IrFunctionReferenceImpl(
override var type: IrType,
override val symbol: IrFunctionSymbol,
typeArgumentsCount: Int,
override val valueArgumentsCount: Int,
valueArgumentsCount: Int,
override val reflectionTarget: IrFunctionSymbol? = symbol,
override val origin: IrStatementOrigin? = null,
) : IrFunctionReference(typeArgumentsCount) {
) : IrFunctionReference() {
override val referencedName: Name
get() = symbol.owner.name
private val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
override fun getValueArgument(index: Int): IrExpression? {
if (index >= valueArgumentsCount) {
throw AssertionError("$this: No such value argument slot: $index")
}
return argumentsByParameterIndex[index]
}
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
if (index >= valueArgumentsCount) {
throw AssertionError("$this: No such value argument slot: $index")
}
argumentsByParameterIndex[index] = valueArgument
}
override fun removeValueArgument(index: Int) {
argumentsByParameterIndex[index] = null
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFunctionReference(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
super.acceptChildren(visitor, data)
argumentsByParameterIndex.forEach { it?.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
super.transformChildren(transformer, data)
argumentsByParameterIndex.forEachIndexed { i, irExpression ->
argumentsByParameterIndex[i] = irExpression?.transform(transformer, data)
}
}
override val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
companion object {
@ObsoleteDescriptorBasedAPI
@@ -35,18 +35,14 @@ class IrLocalDelegatedPropertyReferenceImpl(
override val setter: IrSimpleFunctionSymbol?,
override val origin: IrStatementOrigin? = null,
) : IrLocalDelegatedPropertyReference() {
override val typeArgumentsByIndex: Array<IrType?> = emptyArray()
override val argumentsByParameterIndex: Array<IrExpression?>
get() = throw UnsupportedOperationException("Property reference $symbol has no value arguments")
override val valueArgumentsCount: Int
get() = 0
override val referencedName: Name
get() = symbol.owner.name
private fun throwNoValueArguments(): Nothing =
throw UnsupportedOperationException("Property reference $symbol has no value arguments")
override fun getValueArgument(index: Int): IrExpression? = throwNoValueArguments()
override fun putValueArgument(index: Int, valueArgument: IrExpression?): Unit = throwNoValueArguments()
override fun removeValueArgument(index: Int): Unit = throwNoValueArguments()
}
@@ -35,19 +35,15 @@ class IrPropertyReferenceImpl(
override val getter: IrSimpleFunctionSymbol?,
override val setter: IrSimpleFunctionSymbol?,
override val origin: IrStatementOrigin? = null,
) : IrPropertyReference(typeArgumentsCount) {
) : IrPropertyReference() {
override val typeArgumentsByIndex: Array<IrType?> = arrayOfNulls(typeArgumentsCount)
override val argumentsByParameterIndex: Array<IrExpression?>
get() = throw UnsupportedOperationException("Property reference $symbol has no value arguments")
override val valueArgumentsCount: Int
get() = 0
override val referencedName: Name
get() = symbol.owner.name
private fun throwNoValueArguments(): Nothing =
throw UnsupportedOperationException("Property reference $symbol has no value arguments")
override fun getValueArgument(index: Int): IrExpression? = throwNoValueArguments()
override fun putValueArgument(index: Int, valueArgument: IrExpression?): Unit = throwNoValueArguments()
override fun removeValueArgument(index: Int): Unit = throwNoValueArguments()
}