Simplify interpretation for java methods with names other in kotlin
This commit is contained in:
+3
-1
@@ -246,7 +246,9 @@ fun getTypeArguments(
|
||||
container: IrTypeParametersContainer, expression: IrFunctionAccessExpression, mapper: (TypeParameterDescriptor) -> State
|
||||
): List<Variable> {
|
||||
return container.typeParameters.mapIndexed { index, typeParameter ->
|
||||
val argumentState = expression.getTypeArgument(index)?.classOrNull?.owner?.let { Common(it) } ?: mapper(typeParameter.descriptor)
|
||||
val typeArgument = expression.getTypeArgument(index)!!
|
||||
val argumentState = typeArgument.classOrNull?.owner?.let { Common(it) }
|
||||
?: mapper(typeArgument.classifierOrFail.descriptor as TypeParameterDescriptor)
|
||||
Variable(typeParameter.descriptor, argumentState)
|
||||
}
|
||||
}
|
||||
|
||||
+33
-9
@@ -12,8 +12,10 @@ import org.jetbrains.kotlin.backend.common.interpreter.getPrimitiveClass
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.hasAnnotation
|
||||
import org.jetbrains.kotlin.backend.common.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
@@ -21,7 +23,13 @@ import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isTypeParameter
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithDifferentJvmName
|
||||
import org.jetbrains.kotlin.load.java.BuiltinSpecialProperties
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.firstOverridden
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeAsSequence
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||
import java.lang.invoke.MethodHandle
|
||||
import java.lang.invoke.MethodHandles
|
||||
import java.lang.invoke.MethodType
|
||||
@@ -36,17 +44,14 @@ class Wrapper private constructor(
|
||||
constructor(value: Any, irClass: IrClass) : this(value, irClass, null)
|
||||
|
||||
fun getMethod(irFunction: IrFunction): MethodHandle? {
|
||||
if (irFunction.getEvaluateIntrinsicValue()?.isEmpty() == true) return null // this method will handle IntrinsicEvaluator
|
||||
// if function is actually a getter, then use "get${property.name.capitalize()}" as method name
|
||||
val propertyName = (irFunction as? IrFunctionImpl)?.correspondingPropertySymbol?.owner?.name?.asString()
|
||||
val propertyExplicitCall = propertyName?.takeIf { receiverClass.methods.map { it.name }.contains(it) }
|
||||
val propertyGetCall = "get${propertyName?.capitalize()}".takeIf { receiverClass.methods.map { it.name }.contains(it) }
|
||||
|
||||
// intrinsicName is used to get correct java method
|
||||
// for example: - method 'get' in kotlin StringBuilder is actually 'charAt' in java StringBuilder
|
||||
val intrinsicName = irFunction.getEvaluateIntrinsicValue()
|
||||
if (intrinsicName?.isEmpty() == true) return null
|
||||
val methodName = intrinsicName ?: propertyExplicitCall ?: propertyGetCall ?: irFunction.name.toString()
|
||||
val propertyName = (irFunction as? IrSimpleFunction)?.correspondingPropertySymbol?.owner?.name?.asString()
|
||||
val propertyCall = listOfNotNull(propertyName, "get${propertyName?.capitalize()}")
|
||||
.firstOrNull { receiverClass.methods.any { method -> method.name == it } }
|
||||
|
||||
val intrinsicName = getJavaOriginalName(irFunction)
|
||||
val methodName = intrinsicName ?: propertyCall ?: irFunction.name.toString()
|
||||
val methodType = irFunction.getMethodType()
|
||||
return MethodHandles.lookup().findVirtual(receiverClass, methodName, methodType)
|
||||
}
|
||||
@@ -55,6 +60,25 @@ class Wrapper private constructor(
|
||||
throw UnsupportedOperationException("Method setState is not supported in Wrapper class")
|
||||
}
|
||||
|
||||
// this method is used to get correct java method name
|
||||
// for example: - method 'get' in kotlin StringBuilder is actually 'charAt' in java StringBuilder
|
||||
// - method 'keys' in kotlin Map is actually 'keySet' in java
|
||||
private fun getJavaOriginalName(irFunction: IrFunction): String? {
|
||||
return when {
|
||||
(irFunction as? IrSimpleFunction)?.correspondingPropertySymbol != null -> {
|
||||
val property = irFunction.descriptor.firstOverridden {
|
||||
BuiltinSpecialProperties.hasBuiltinSpecialPropertyFqName(it.propertyIfAccessor)
|
||||
}
|
||||
property?.let { BuiltinSpecialProperties.PROPERTY_FQ_NAME_TO_JVM_GETTER_NAME_MAP[it.propertyIfAccessor.fqNameSafe]?.asString() }
|
||||
}
|
||||
irFunction.descriptor is SimpleFunctionDescriptor -> {
|
||||
val last = irFunction.descriptor.overriddenTreeAsSequence(true).last()
|
||||
BuiltinMethodsWithDifferentJvmName.getJvmName(last as SimpleFunctionDescriptor)?.asString()
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val companionObjectValue = mapOf<String, Any>("kotlin.text.Regex\$Companion" to Regex.Companion)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user