JVM IR: lookup symbols by name in ProgressionHandlers in known classes only
Alternatively, we could improve the lookup utilities and their usages to always find the exact override of a symbol from Collection/Iterable/CharSequence/etc, but since we need to load the original symbol anyway in cases when the loop subject's type is a type parameter, we might as well simplify everything and always reference the original symbol. Also improve exception message and removed unused declarations in IrBackendUtils.kt.
This commit is contained in:
@@ -73,6 +73,7 @@ open class BuiltinSymbolsBase(protected val builtIns: KotlinBuiltIns, private va
|
||||
val iterator = getClass(Name.identifier("Iterator"), "kotlin", "collections")
|
||||
|
||||
val charSequence = getClass(Name.identifier("CharSequence"), "kotlin")
|
||||
val string = getClass(Name.identifier("String"), "kotlin")
|
||||
|
||||
val primitiveIteratorsByType = PrimitiveType.values().associate { type ->
|
||||
val iteratorClass = getClass(Name.identifier(type.typeName.asString() + "Iterator"), "kotlin", "collections")
|
||||
|
||||
+1
@@ -272,6 +272,7 @@ internal abstract class HeaderInfoBuilder(context: CommonBackendContext, private
|
||||
|
||||
private val progressionHandlers = listOf(
|
||||
CollectionIndicesHandler(context),
|
||||
ArrayIndicesHandler(context),
|
||||
CharSequenceIndicesHandler(context),
|
||||
UntilHandler(context, progressionElementTypes),
|
||||
DownToHandler(context, progressionElementTypes),
|
||||
|
||||
+28
-29
@@ -512,16 +512,25 @@ internal abstract class IndicesHandler(protected val context: CommonBackendConte
|
||||
internal class CollectionIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) {
|
||||
|
||||
override val matcher = SimpleCalleeMatcher {
|
||||
extensionReceiver { it != null && it.type.run { isArray() || isPrimitiveArray() || isCollection() } }
|
||||
extensionReceiver { it?.type?.isCollection() == true }
|
||||
fqName { it == FqName("kotlin.collections.<get-indices>") }
|
||||
parameterCount { it == 0 }
|
||||
}
|
||||
|
||||
// The lowering operates on subtypes of Collection. Therefore, the IrType could be
|
||||
// a type parameter bounded by Collection. When that is the case, we cannot get
|
||||
// the class from the type and instead uses the Collection getter.
|
||||
override val IrType.sizePropertyGetter
|
||||
get() = getClass()?.getPropertyGetter("size")?.owner ?: context.ir.symbols.collection.getPropertyGetter("size")!!.owner
|
||||
override val IrType.sizePropertyGetter: IrSimpleFunction
|
||||
get() = context.ir.symbols.collection.getPropertyGetter("size")!!.owner
|
||||
}
|
||||
|
||||
internal class ArrayIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) {
|
||||
|
||||
override val matcher = SimpleCalleeMatcher {
|
||||
extensionReceiver { it != null && it.type.run { isArray() || isPrimitiveArray() } }
|
||||
fqName { it == FqName("kotlin.collections.<get-indices>") }
|
||||
parameterCount { it == 0 }
|
||||
}
|
||||
|
||||
override val IrType.sizePropertyGetter: IrSimpleFunction
|
||||
get() = getClass()!!.getPropertyGetter("size")!!.owner
|
||||
}
|
||||
|
||||
internal class CharSequenceIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) {
|
||||
@@ -532,11 +541,8 @@ internal class CharSequenceIndicesHandler(context: CommonBackendContext) : Indic
|
||||
parameterCount { it == 0 }
|
||||
}
|
||||
|
||||
// The lowering operates on subtypes of CharSequence. Therefore, the IrType could be
|
||||
// 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()?.getPropertyGetter("length")?.owner ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
|
||||
override val IrType.sizePropertyGetter: IrSimpleFunction
|
||||
get() = context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
|
||||
}
|
||||
|
||||
/** Builds a [HeaderInfo] for calls to reverse an iterable. */
|
||||
@@ -673,18 +679,11 @@ internal open class CharSequenceIterationHandler(context: CommonBackendContext,
|
||||
parameterCount { it == 0 }
|
||||
}
|
||||
|
||||
// The lowering operates on subtypes of CharSequence. Therefore, the IrType could be
|
||||
// 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()?.getPropertyGetter("length")?.owner ?: context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
|
||||
override val IrType.sizePropertyGetter: IrSimpleFunction
|
||||
get() = context.ir.symbols.charSequence.getPropertyGetter("length")!!.owner
|
||||
|
||||
override val IrType.getFunction
|
||||
get() = getClass()?.functions?.single {
|
||||
it.name == OperatorNameConventions.GET &&
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters[0].type.isInt()
|
||||
} ?: context.ir.symbols.charSequence.getSimpleFunction(OperatorNameConventions.GET.asString())!!.owner
|
||||
override val IrType.getFunction: IrSimpleFunction
|
||||
get() = context.ir.symbols.charSequence.getSimpleFunction(OperatorNameConventions.GET.asString())!!.owner
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -694,6 +693,12 @@ internal open class CharSequenceIterationHandler(context: CommonBackendContext,
|
||||
*/
|
||||
internal class StringIterationHandler(context: CommonBackendContext) : CharSequenceIterationHandler(context, canCacheLast = true) {
|
||||
override fun matchIterable(expression: IrExpression) = expression.type.isString()
|
||||
|
||||
override val IrType.sizePropertyGetter: IrSimpleFunction
|
||||
get() = context.ir.symbols.string.getPropertyGetter("length")!!.owner
|
||||
|
||||
override val IrType.getFunction: IrSimpleFunction
|
||||
get() = context.ir.symbols.string.getSimpleFunction(OperatorNameConventions.GET.asString())!!.owner
|
||||
}
|
||||
|
||||
/** Builds a [HeaderInfo] for calls to `withIndex()`. */
|
||||
@@ -740,13 +745,7 @@ internal open class DefaultIterableHandler(private val context: CommonBackendCon
|
||||
|
||||
override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? =
|
||||
with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) {
|
||||
// The lowering operates on subtypes of Iterable. Therefore, the IrType could be
|
||||
// a type parameter bounded by Iterable. When that is the case, we cannot get
|
||||
// the class from the type and instead uses the Iterable.iterator() function.
|
||||
val iteratorFun = expression.type.getClass()?.functions?.single {
|
||||
it.name == OperatorNameConventions.ITERATOR &&
|
||||
it.valueParameters.isEmpty()
|
||||
} ?: iterableClassSymbol.getSimpleFunction(OperatorNameConventions.ITERATOR.asString())!!.owner
|
||||
val iteratorFun = iterableClassSymbol.getSimpleFunction(OperatorNameConventions.ITERATOR.asString())!!.owner
|
||||
IterableHeaderInfo(
|
||||
scope.createTmpVariable(irCall(iteratorFun).apply { dispatchReceiver = expression }, nameHint = "iterator")
|
||||
)
|
||||
|
||||
@@ -16,18 +16,24 @@
|
||||
|
||||
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
|
||||
|
||||
fun IrClass.getPropertyDeclaration(name: String) =
|
||||
declarations.filterIsInstance<IrProperty>().atMostOne { it.name.asString() == name }
|
||||
private fun IrClass.getPropertyDeclaration(name: String): IrProperty? {
|
||||
val properties = declarations.filterIsInstance<IrProperty>().filter { it.name.asString() == name }
|
||||
if (properties.size > 1) {
|
||||
error(
|
||||
"More than one property with name $name in class $fqNameWhenAvailable:\n" +
|
||||
properties.joinToString("\n", transform = IrProperty::render)
|
||||
)
|
||||
}
|
||||
return properties.firstOrNull()
|
||||
}
|
||||
|
||||
fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
|
||||
private fun IrClass.getSimpleFunction(name: String): IrSimpleFunctionSymbol? =
|
||||
findDeclaration<IrSimpleFunction> { it.name.asString() == name }?.symbol
|
||||
|
||||
fun IrClass.getPropertyGetter(name: String): IrSimpleFunctionSymbol? =
|
||||
@@ -38,11 +44,6 @@ fun IrClass.getPropertySetter(name: String): IrSimpleFunctionSymbol? =
|
||||
getPropertyDeclaration(name)?.setter?.symbol
|
||||
?: getSimpleFunction("<set-$name>").also { assert(it?.owner?.correspondingPropertySymbol?.owner?.name?.asString() == name) }
|
||||
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user