Use getPropertyGetter() in ForLoopsLowering to retrieve property

getters instead of directly retrieving the property first.

When the IR backend is used to compile the standard library, the
progression classes (in sources) are lowered, and therefore do not have
properties anymore (only fields and functions).
This commit is contained in:
Mark Punzalan
2019-09-30 12:48:39 -07:00
committed by max-kammerer
parent a19c5f944e
commit a01c53fb74
2 changed files with 33 additions and 34 deletions
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher
import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher
import org.jetbrains.kotlin.backend.common.lower.matchers.singleArgumentExtension
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrCall
@@ -143,11 +142,11 @@ internal class UntilHandler(private val context: CommonBackendContext, private v
val last = untilArgExpression.decrement()
val (minValueAsLong, minValueIrConst) =
when (data) {
ProgressionType.INT_PROGRESSION -> Pair(Int.MIN_VALUE.toLong(), irInt(Int.MIN_VALUE))
ProgressionType.CHAR_PROGRESSION -> Pair(Char.MIN_VALUE.toLong(), irChar(Char.MIN_VALUE))
ProgressionType.LONG_PROGRESSION -> Pair(Long.MIN_VALUE, irLong(Long.MIN_VALUE))
}
when (data) {
ProgressionType.INT_PROGRESSION -> Pair(Int.MIN_VALUE.toLong(), irInt(Int.MIN_VALUE))
ProgressionType.CHAR_PROGRESSION -> Pair(Char.MIN_VALUE.toLong(), irChar(Char.MIN_VALUE))
ProgressionType.LONG_PROGRESSION -> Pair(Long.MIN_VALUE, irLong(Long.MIN_VALUE))
}
val additionalNotEmptyCondition = untilArg.constLongValue.let {
when {
it == null && isAdditionalNotEmptyConditionNeeded(receiverValue.type, untilArg.type) ->
@@ -251,13 +250,13 @@ internal class CollectionIndicesHandler(context: CommonBackendContext) : Indices
}
override val IrType.sizePropertyGetter
get() = getClass()!!.properties.first { it.name.asString() == "size" }.getter!!
get() = getClass()!!.getPropertyGetter("size")!!.owner
}
internal class CharSequenceIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) {
override val matcher = SimpleCalleeMatcher {
extensionReceiver { it != null && it.type.run { isSubtypeOfClass(context.ir.symbols.charSequence)} }
extensionReceiver { it != null && it.type.run { isSubtypeOfClass(context.ir.symbols.charSequence) } }
fqName { it == FqName("kotlin.text.<get-indices>") }
parameterCount { it == 0 }
}
@@ -266,9 +265,7 @@ internal class CharSequenceIndicesHandler(context: CommonBackendContext) : Indic
// a type parameter bounded by CharSequence. When that is the case, we cannot get
// the class from the type and instead uses the CharSequence getter.
override val IrType.sizePropertyGetter
get() = getClass()?.properties?.first { it.name.asString() == "length" }?.let {
it.getter!!
} ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
get() = getClass()?.getPropertyGetter("length")?.owner ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
}
/** Builds a [HeaderInfo] for calls to reverse an iterable. */
@@ -306,16 +303,13 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte
// Directly use the `first/last/step` properties of the progression.
val progression = scope.createTemporaryVariable(expression, nameHint = "progression")
val progressionClass = progression.type.getClass()!!
val firstProperty = progressionClass.properties.first { it.name.asString() == "first" }
val first = irCall(firstProperty.getter!!).apply {
val first = irCall(progressionClass.symbol.getPropertyGetter("first")!!).apply {
dispatchReceiver = irGet(progression)
}
val lastProperty = progressionClass.properties.first { it.name.asString() == "last" }
val last = irCall(lastProperty.getter!!).apply {
val last = irCall(progressionClass.symbol.getPropertyGetter("last")!!).apply {
dispatchReceiver = irGet(progression)
}
val stepProperty = progressionClass.properties.first { it.name.asString() == "step" }
val step = irCall(stepProperty.getter!!).apply {
val step = irCall(progressionClass.symbol.getPropertyGetter("step")!!).apply {
dispatchReceiver = irGet(progression)
}
@@ -380,7 +374,7 @@ internal class ArrayIterationHandler(context: CommonBackendContext) : IndexedGet
override fun match(expression: IrExpression) = expression.type.run { isArray() || isPrimitiveArray() }
override val IrType.sizePropertyGetter
get() = getClass()!!.properties.first { it.name.asString() == "size" }.getter!!
get() = getClass()!!.getPropertyGetter("size")!!.owner
override val IrType.getFunction
get() = getClass()!!.functions.first { it.name.asString() == "get" }
@@ -391,7 +385,7 @@ internal class StringIterationHandler(context: CommonBackendContext) : IndexedGe
override fun match(expression: IrExpression) = expression.type.isString()
override val IrType.sizePropertyGetter
get() = getClass()!!.properties.first { it.name.asString() == "length" }.getter!!
get() = getClass()!!.getPropertyGetter("length")!!.owner
override val IrType.getFunction
get() = getClass()!!.functions.first { it.name.asString() == "get" }
@@ -410,9 +404,7 @@ internal class CharSequenceIterationHandler(context: CommonBackendContext) : Ind
// a type parameter bounded by CharSequence. When that is the case, we cannot get
// the class from the type and instead uses the CharSequence getter and function.
override val IrType.sizePropertyGetter
get() = getClass()?.properties?.first { it.name.asString() == "length" }?.let {
it.getter!!
} ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
get() = getClass()?.getPropertyGetter("length")?.owner ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
override val IrType.getFunction
get() = getClass()?.functions?.first { it.name.asString() == "get" }
@@ -17,25 +17,32 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.name.Name
fun IrClassSymbol.getPropertyDeclaration(name: String) =
this.owner.declarations.filterIsInstance<IrProperty>()
.atMostOne { it.descriptor.name == Name.identifier(name) }
fun IrClass.getPropertyDeclaration(name: String) =
declarations.filterIsInstance<IrProperty>().atMostOne { it.name.asString() == name }
fun IrClassSymbol.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
owner.findDeclaration<IrSimpleFunction> { it.name.asString() == name }?.symbol
fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
findDeclaration<IrSimpleFunction> { it.name.asString() == name }?.symbol
fun IrClassSymbol.getPropertyGetter(name: String): IrSimpleFunctionSymbol? =
this.getPropertyDeclaration(name)?.getter?.symbol ?: this.getSimpleFunction("<get-$name>")
fun IrClass.getPropertyGetter(name: String): IrSimpleFunctionSymbol? =
getPropertyDeclaration(name)?.getter?.symbol
?: getSimpleFunction("<get-$name>").also { assert(it?.owner?.correspondingPropertySymbol?.owner?.name?.asString() == name) }
fun IrClassSymbol.getPropertySetter(name: String): IrSimpleFunctionSymbol? =
this.getPropertyDeclaration(name)?.setter?.symbol ?: this.getSimpleFunction("<set-$name>")
fun IrClass.getPropertySetter(name: String): IrSimpleFunctionSymbol? =
getPropertyDeclaration(name)?.setter?.symbol
?: getSimpleFunction("<set-$name>").also { assert(it?.owner?.correspondingPropertySymbol?.owner?.name?.asString() == name) }
fun IrClassSymbol.getPropertyField(name: String): IrFieldSymbol? =
this.getPropertyDeclaration(name)?.backingField?.symbol
fun IrClass.getPropertyField(name: String): IrFieldSymbol? =
getPropertyDeclaration(name)?.backingField?.symbol
fun IrClassSymbol.getPropertyDeclaration(name: String) = owner.getPropertyDeclaration(name)
fun IrClassSymbol.getSimpleFunction(name: String): IrSimpleFunctionSymbol? = owner.getSimpleFunction(name)
fun IrClassSymbol.getPropertyGetter(name: String): IrSimpleFunctionSymbol? = owner.getPropertyGetter(name)
fun IrClassSymbol.getPropertySetter(name: String): IrSimpleFunctionSymbol? = owner.getPropertySetter(name)
fun IrClassSymbol.getPropertyField(name: String): IrFieldSymbol? = owner.getPropertyField(name)