Introduce new property fqName to make it easier to take element's name
This commit is contained in:
committed by
TeamCityServer
parent
fe74dd2689
commit
524189132b
+1
-2
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.ir.types.isUnsignedType
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import java.lang.invoke.MethodHandle
|
import java.lang.invoke.MethodHandle
|
||||||
|
|
||||||
internal interface CallInterceptor {
|
internal interface CallInterceptor {
|
||||||
@@ -79,7 +78,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
|||||||
val irConstructor = constructorCall.symbol.owner
|
val irConstructor = constructorCall.symbol.owner
|
||||||
val irClass = irConstructor.parentAsClass
|
val irClass = irConstructor.parentAsClass
|
||||||
when {
|
when {
|
||||||
Wrapper.mustBeHandledWithWrapper(irClass) || irClass.fqNameWhenAvailable!!.startsWith(Name.identifier("java")) -> {
|
Wrapper.mustBeHandledWithWrapper(irClass) || irClass.fqName.startsWith("java") -> {
|
||||||
Wrapper.getConstructorMethod(irConstructor).invokeMethod(irConstructor, args)
|
Wrapper.getConstructorMethod(irConstructor).invokeMethod(irConstructor, args)
|
||||||
when {
|
when {
|
||||||
irClass.isSubclassOfThrowable() -> (receiver as ExceptionState).copyFieldsFrom(callStack.popState() as Wrapper)
|
irClass.isSubclassOfThrowable() -> (receiver as ExceptionState).copyFieldsFrom(callStack.popState() as Wrapper)
|
||||||
|
|||||||
+1
-1
@@ -88,7 +88,7 @@ private fun unfoldFunction(function: IrSimpleFunction, environment: IrInterprete
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack) {
|
private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack) {
|
||||||
when (constructor.fqNameWhenAvailable?.asString()) {
|
when (constructor.fqName) {
|
||||||
"kotlin.Enum.<init>", "kotlin.Throwable.<init>" -> {
|
"kotlin.Enum.<init>", "kotlin.Throwable.<init>" -> {
|
||||||
val irClass = constructor.parentAsClass
|
val irClass = constructor.parentAsClass
|
||||||
val receiverSymbol = irClass.thisReceiver!!.symbol
|
val receiverSymbol = irClass.thisReceiver!!.symbol
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
|
|
||||||
state.checkNullability(valueParameter.type, environment) {
|
state.checkNullability(valueParameter.type, environment) {
|
||||||
if (isReceiver()) return@checkNullability NullPointerException()
|
if (isReceiver()) return@checkNullability NullPointerException()
|
||||||
val method = irFunction.getCapitalizedFileName() + "." + irFunction.fqNameWhenAvailable
|
val method = irFunction.getCapitalizedFileName() + "." + irFunction.fqName
|
||||||
val parameter = valueParameter.name
|
val parameter = valueParameter.name
|
||||||
IllegalArgumentException("Parameter specified as non-null is null: method $method, parameter $parameter")
|
IllegalArgumentException("Parameter specified as non-null is null: method $method, parameter $parameter")
|
||||||
} ?: return
|
} ?: return
|
||||||
@@ -414,7 +414,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
val enumClass = enumEntry.symbol.owner.parentAsClass
|
val enumClass = enumEntry.symbol.owner.parentAsClass
|
||||||
val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>()
|
val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>()
|
||||||
val enumInitializer = enumEntry.initializerExpression?.expression
|
val enumInitializer = enumEntry.initializerExpression?.expression
|
||||||
?: throw InterpreterError("Initializer at enum entry ${enumEntry.fqNameWhenAvailable} is null")
|
?: throw InterpreterError("Initializer at enum entry ${enumEntry.fqName} is null")
|
||||||
val enumConstructorCall = enumInitializer as? IrEnumConstructorCall
|
val enumConstructorCall = enumInitializer as? IrEnumConstructorCall
|
||||||
?: (enumInitializer as IrBlock).statements.filterIsInstance<IrEnumConstructorCall>().single()
|
?: (enumInitializer as IrBlock).statements.filterIsInstance<IrEnumConstructorCall>().single()
|
||||||
val enumSuperCall = enumConstructorCall.getSuperEnumCall()
|
val enumSuperCall = enumConstructorCall.getSuperEnumCall()
|
||||||
@@ -460,7 +460,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
|||||||
// this first check is performed inside `isSubtypeOf` but repeated here to create separate exception
|
// this first check is performed inside `isSubtypeOf` but repeated here to create separate exception
|
||||||
state.isNull() && !typeOperand.isNullable() -> NullPointerException().handleUserException(environment)
|
state.isNull() && !typeOperand.isNullable() -> NullPointerException().handleUserException(environment)
|
||||||
!isErased && !state.isSubtypeOf(typeOperand) -> {
|
!isErased && !state.isSubtypeOf(typeOperand) -> {
|
||||||
val castedClassName = state.irClass.fqNameWhenAvailable
|
val castedClassName = state.irClass.fqName
|
||||||
ClassCastException("$castedClassName cannot be cast to ${typeOperand.render()}").handleUserException(environment)
|
ClassCastException("$castedClassName cannot be cast to ${typeOperand.render()}").handleUserException(environment)
|
||||||
}
|
}
|
||||||
else -> callStack.pushState(state)
|
else -> callStack.pushState(state)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
@@ -23,7 +24,6 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
@@ -32,6 +32,12 @@ val compileTimeAnnotation = FqName("kotlin.CompileTimeCalculation")
|
|||||||
val evaluateIntrinsicAnnotation = FqName("kotlin.EvaluateIntrinsic")
|
val evaluateIntrinsicAnnotation = FqName("kotlin.EvaluateIntrinsic")
|
||||||
val contractsDslAnnotation = FqName("kotlin.internal.ContractsDsl")
|
val contractsDslAnnotation = FqName("kotlin.internal.ContractsDsl")
|
||||||
|
|
||||||
|
internal val IrElement.fqName: String
|
||||||
|
get() = when (this) {
|
||||||
|
is IrExpression -> (this as? IrSymbolOwner)?.symbol?.owner?.fqName ?: ""
|
||||||
|
else -> (this as? IrDeclarationWithName)?.fqNameWhenAvailable?.asString() ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
internal fun IrFunction.getDispatchReceiver(): IrValueParameterSymbol? = this.dispatchReceiverParameter?.symbol
|
internal fun IrFunction.getDispatchReceiver(): IrValueParameterSymbol? = this.dispatchReceiverParameter?.symbol
|
||||||
|
|
||||||
internal fun IrFunction.getExtensionReceiver(): IrValueParameterSymbol? = this.extensionReceiverParameter?.symbol
|
internal fun IrFunction.getExtensionReceiver(): IrValueParameterSymbol? = this.extensionReceiverParameter?.symbol
|
||||||
@@ -75,7 +81,7 @@ fun IrAnnotationContainer.getAnnotation(annotation: FqName): IrConstructorCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrAnnotationContainer.getEvaluateIntrinsicValue(): String? {
|
internal fun IrAnnotationContainer.getEvaluateIntrinsicValue(): String? {
|
||||||
if (this is IrClass && this.fqNameWhenAvailable?.startsWith(Name.identifier("java")) == true) return this.fqNameWhenAvailable?.asString()
|
if (this is IrClass && this.fqName.startsWith("java")) return this.fqName
|
||||||
if (!this.hasAnnotation(evaluateIntrinsicAnnotation)) return null
|
if (!this.hasAnnotation(evaluateIntrinsicAnnotation)) return null
|
||||||
return (this.getAnnotation(evaluateIntrinsicAnnotation).getValueArgument(0) as IrConst<*>).value.toString()
|
return (this.getAnnotation(evaluateIntrinsicAnnotation).getValueArgument(0) as IrConst<*>).value.toString()
|
||||||
}
|
}
|
||||||
@@ -129,10 +135,10 @@ fun IrFunctionAccessExpression.getVarargType(index: Int): IrType? {
|
|||||||
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
||||||
|
|
||||||
internal fun IrType.isUnsigned() = this.getUnsignedType() != null
|
internal fun IrType.isUnsigned() = this.getUnsignedType() != null
|
||||||
internal fun IrType.isFunction() = this.getClass()?.fqNameWhenAvailable?.asString()?.startsWith("kotlin.Function") ?: false
|
internal fun IrType.isFunction() = this.getClass()?.fqName?.startsWith("kotlin.Function") ?: false
|
||||||
internal fun IrType.isKFunction() = this.getClass()?.fqNameWhenAvailable?.asString()?.startsWith("kotlin.reflect.KFunction") ?: false
|
internal fun IrType.isKFunction() = this.getClass()?.fqName?.startsWith("kotlin.reflect.KFunction") ?: false
|
||||||
internal fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol
|
internal fun IrType.isTypeParameter() = classifierOrNull is IrTypeParameterSymbol
|
||||||
internal fun IrType.isThrowable() = this.getClass()?.fqNameWhenAvailable?.asString() == "kotlin.Throwable"
|
internal fun IrType.isThrowable() = this.getClass()?.fqName == "kotlin.Throwable"
|
||||||
internal fun IrClass.isSubclassOfThrowable(): Boolean {
|
internal fun IrClass.isSubclassOfThrowable(): Boolean {
|
||||||
return generateSequence(this) { irClass ->
|
return generateSequence(this) { irClass ->
|
||||||
if (irClass.defaultType.isAny()) return@generateSequence null
|
if (irClass.defaultType.isAny()) return@generateSequence null
|
||||||
@@ -142,8 +148,7 @@ internal fun IrClass.isSubclassOfThrowable(): Boolean {
|
|||||||
|
|
||||||
internal fun IrType.isUnsignedArray(): Boolean {
|
internal fun IrType.isUnsignedArray(): Boolean {
|
||||||
if (this !is IrSimpleType || classifier !is IrClassSymbol) return false
|
if (this !is IrSimpleType || classifier !is IrClassSymbol) return false
|
||||||
val fqName = (classifier.owner as IrDeclarationWithName).fqNameWhenAvailable?.asString()
|
return classifier.owner.fqName in setOf("kotlin.UByteArray", "kotlin.UShortArray", "kotlin.UIntArray", "kotlin.ULongArray")
|
||||||
return fqName in setOf("kotlin.UByteArray", "kotlin.UShortArray", "kotlin.UIntArray", "kotlin.ULongArray")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrType.isPrimitiveArray(): Boolean {
|
internal fun IrType.isPrimitiveArray(): Boolean {
|
||||||
@@ -179,7 +184,7 @@ internal fun IrFunction?.checkCast(environment: IrInterpreterEnvironment): Boole
|
|||||||
if (actualState is Primitive<*> && actualState.value == null) return true // this is handled in checkNullability
|
if (actualState is Primitive<*> && actualState.value == null) return true // this is handled in checkNullability
|
||||||
|
|
||||||
if (!actualState.isSubtypeOf(expectedType)) {
|
if (!actualState.isSubtypeOf(expectedType)) {
|
||||||
val convertibleClassName = environment.callStack.popState().irClass.fqNameWhenAvailable
|
val convertibleClassName = environment.callStack.popState().irClass.fqName
|
||||||
environment.callStack.dropFrame() // current frame is pointing on function and is redundant
|
environment.callStack.dropFrame() // current frame is pointing on function and is redundant
|
||||||
ClassCastException("$convertibleClassName cannot be cast to ${expectedType.render()}").handleUserException(environment)
|
ClassCastException("$convertibleClassName cannot be cast to ${expectedType.render()}").handleUserException(environment)
|
||||||
return false
|
return false
|
||||||
@@ -278,7 +283,7 @@ internal fun IrType.getTypeIfReified(getType: (IrClassifierSymbol) -> IrType): I
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrFunctionAccessExpression.getSuperEnumCall(): IrEnumConstructorCall {
|
internal fun IrFunctionAccessExpression.getSuperEnumCall(): IrEnumConstructorCall {
|
||||||
val name = this.symbol.owner.parentClassOrNull?.fqNameWhenAvailable?.asString()
|
val name = this.symbol.owner.parentClassOrNull?.fqName
|
||||||
if (this is IrEnumConstructorCall && name == "kotlin.Enum") return this
|
if (this is IrEnumConstructorCall && name == "kotlin.Enum") return this
|
||||||
return when (val delegatingCall = this.symbol.owner.body?.statements?.get(0)) {
|
return when (val delegatingCall = this.symbol.owner.body?.statements?.get(0)) {
|
||||||
is IrFunctionAccessExpression -> delegatingCall.getSuperEnumCall()
|
is IrFunctionAccessExpression -> delegatingCall.getSuperEnumCall()
|
||||||
|
|||||||
+2
-4
@@ -11,9 +11,7 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue
|
import org.jetbrains.kotlin.ir.expressions.IrGetObjectValue
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||||
import org.jetbrains.kotlin.ir.interpreter.compileTimeAnnotation
|
import org.jetbrains.kotlin.ir.interpreter.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.contractsDslAnnotation
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.evaluateIntrinsicAnnotation
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation
|
import org.jetbrains.kotlin.ir.interpreter.hasAnnotation
|
||||||
import org.jetbrains.kotlin.ir.interpreter.isUnsigned
|
import org.jetbrains.kotlin.ir.interpreter.isUnsigned
|
||||||
import org.jetbrains.kotlin.ir.types.isAny
|
import org.jetbrains.kotlin.ir.types.isAny
|
||||||
@@ -84,7 +82,7 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
|
|||||||
fun IrDeclaration.isMarkedAsCompileTime() = isMarkedWith(compileTimeAnnotation)
|
fun IrDeclaration.isMarkedAsCompileTime() = isMarkedWith(compileTimeAnnotation)
|
||||||
private fun IrDeclaration.isContract() = isMarkedWith(contractsDslAnnotation)
|
private fun IrDeclaration.isContract() = isMarkedWith(contractsDslAnnotation)
|
||||||
private fun IrDeclaration.isMarkedAsEvaluateIntrinsic() = isMarkedWith(evaluateIntrinsicAnnotation)
|
private fun IrDeclaration.isMarkedAsEvaluateIntrinsic() = isMarkedWith(evaluateIntrinsicAnnotation)
|
||||||
protected fun IrDeclaration.isCompileTimeTypeAlias() = this.parentClassOrNull?.fqNameWhenAvailable?.asString() in compileTimeTypeAliases
|
protected fun IrDeclaration.isCompileTimeTypeAlias() = this.parentClassOrNull?.fqName in compileTimeTypeAliases
|
||||||
|
|
||||||
protected fun IrDeclaration.isMarkedWith(annotation: FqName): Boolean {
|
protected fun IrDeclaration.isMarkedWith(annotation: FqName): Boolean {
|
||||||
if (this is IrClass && this.isCompanion) return false
|
if (this is IrClass && this.isCompanion) return false
|
||||||
|
|||||||
+3
-2
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.IrStatement
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField
|
import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
@@ -132,7 +133,7 @@ class IrCompileTimeChecker(
|
|||||||
override fun visitGetField(expression: IrGetField, data: Nothing?): Boolean {
|
override fun visitGetField(expression: IrGetField, data: Nothing?): Boolean {
|
||||||
val owner = expression.symbol.owner
|
val owner = expression.symbol.owner
|
||||||
val property = owner.correspondingPropertySymbol?.owner
|
val property = owner.correspondingPropertySymbol?.owner
|
||||||
val fqName = owner.fqNameForIrSerialization
|
val fqName = owner.fqName
|
||||||
fun isJavaStaticWithPrimitiveOrString(): Boolean {
|
fun isJavaStaticWithPrimitiveOrString(): Boolean {
|
||||||
return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic &&
|
return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic &&
|
||||||
(owner.type.isPrimitiveType() || owner.type.isStringClassType())
|
(owner.type.isPrimitiveType() || owner.type.isStringClassType())
|
||||||
@@ -140,7 +141,7 @@ class IrCompileTimeChecker(
|
|||||||
return when {
|
return when {
|
||||||
// TODO fix later; used it here because java boolean resolves very strange,
|
// TODO fix later; used it here because java boolean resolves very strange,
|
||||||
// its type is flexible (so its not primitive) and there is no initializer at backing field
|
// its type is flexible (so its not primitive) and there is no initializer at backing field
|
||||||
fqName.toString().let { it == "java.lang.Boolean.FALSE" || it == "java.lang.Boolean.TRUE" } -> true
|
fqName == "java.lang.Boolean.FALSE" || fqName == "java.lang.Boolean.TRUE" -> true
|
||||||
isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true
|
isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true
|
||||||
expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true
|
expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true
|
||||||
owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> {
|
owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> {
|
||||||
|
|||||||
+2
-2
@@ -8,11 +8,11 @@ package org.jetbrains.kotlin.ir.interpreter.intrinsics
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.interpreter.Instruction
|
import org.jetbrains.kotlin.ir.interpreter.Instruction
|
||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||||
|
|
||||||
internal object IntrinsicEvaluator {
|
internal object IntrinsicEvaluator {
|
||||||
fun unwindInstructions(irFunction: IrFunction, environment: IrInterpreterEnvironment): List<Instruction>? {
|
fun unwindInstructions(irFunction: IrFunction, environment: IrInterpreterEnvironment): List<Instruction>? {
|
||||||
val fqName = irFunction.fqNameWhenAvailable.toString()
|
val fqName = irFunction.fqName
|
||||||
return when {
|
return when {
|
||||||
EmptyArray.canHandleFunctionWithName(fqName, irFunction.origin) -> EmptyArray.unwind(irFunction, environment)
|
EmptyArray.canHandleFunctionWithName(fqName, irFunction.origin) -> EmptyArray.unwind(irFunction, environment)
|
||||||
ArrayOf.canHandleFunctionWithName(fqName, irFunction.origin) -> ArrayOf.unwind(irFunction, environment)
|
ArrayOf.canHandleFunctionWithName(fqName, irFunction.origin) -> ArrayOf.unwind(irFunction, environment)
|
||||||
|
|||||||
+4
-5
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState
|
|||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -84,7 +83,7 @@ internal object EnumValues : IntrinsicBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getEnumClass(irFunction: IrFunction, environment: IrInterpreterEnvironment): IrClass {
|
private fun getEnumClass(irFunction: IrFunction, environment: IrInterpreterEnvironment): IrClass {
|
||||||
return when (irFunction.fqNameWhenAvailable.toString()) {
|
return when (irFunction.fqName) {
|
||||||
"kotlin.enumValues" -> {
|
"kotlin.enumValues" -> {
|
||||||
val kType = environment.callStack.getState(irFunction.typeParameters.first().symbol) as KTypeState
|
val kType = environment.callStack.getState(irFunction.typeParameters.first().symbol) as KTypeState
|
||||||
kType.irType.classOrNull!!.owner
|
kType.irType.classOrNull!!.owner
|
||||||
@@ -114,7 +113,7 @@ internal object EnumValueOf : IntrinsicBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getEnumClass(irFunction: IrFunction, environment: IrInterpreterEnvironment): IrClass {
|
private fun getEnumClass(irFunction: IrFunction, environment: IrInterpreterEnvironment): IrClass {
|
||||||
return when (irFunction.fqNameWhenAvailable.toString()) {
|
return when (irFunction.fqName) {
|
||||||
"kotlin.enumValueOf" -> {
|
"kotlin.enumValueOf" -> {
|
||||||
val kType = environment.callStack.getState(irFunction.typeParameters.first().symbol) as KTypeState
|
val kType = environment.callStack.getState(irFunction.typeParameters.first().symbol) as KTypeState
|
||||||
kType.irType.classOrNull!!.owner
|
kType.irType.classOrNull!!.owner
|
||||||
@@ -128,7 +127,7 @@ internal object EnumValueOf : IntrinsicBase() {
|
|||||||
val enumEntryName = environment.callStack.getState(irFunction.valueParameters.first().symbol).asString()
|
val enumEntryName = environment.callStack.getState(irFunction.valueParameters.first().symbol).asString()
|
||||||
val enumEntry = enumClass.declarations.filterIsInstance<IrEnumEntry>().singleOrNull { it.name.asString() == enumEntryName }
|
val enumEntry = enumClass.declarations.filterIsInstance<IrEnumEntry>().singleOrNull { it.name.asString() == enumEntryName }
|
||||||
if (enumEntry == null) {
|
if (enumEntry == null) {
|
||||||
IllegalArgumentException("No enum constant ${enumClass.fqNameWhenAvailable}.$enumEntryName").handleUserException(environment)
|
IllegalArgumentException("No enum constant ${enumClass.fqName}.$enumEntryName").handleUserException(environment)
|
||||||
}
|
}
|
||||||
return enumEntry
|
return enumEntry
|
||||||
}
|
}
|
||||||
@@ -194,7 +193,7 @@ internal object JsPrimitives : IntrinsicBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
override fun evaluate(irFunction: IrFunction, environment: IrInterpreterEnvironment) {
|
||||||
when (irFunction.fqNameWhenAvailable.toString()) {
|
when (irFunction.fqName) {
|
||||||
"kotlin.Long.<init>" -> {
|
"kotlin.Long.<init>" -> {
|
||||||
val low = environment.callStack.getState(irFunction.valueParameters[0].symbol).asInt()
|
val low = environment.callStack.getState(irFunction.valueParameters[0].symbol).asInt()
|
||||||
val high = environment.callStack.getState(irFunction.valueParameters[1].symbol).asInt()
|
val high = environment.callStack.getState(irFunction.valueParameters[1].symbol).asInt()
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ package org.jetbrains.kotlin.ir.interpreter.proxy
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
|
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||||
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy
|
import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy
|
||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy.Companion.asProxy
|
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy.Companion.asProxy
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
|
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
|
||||||
import org.jetbrains.kotlin.ir.types.isArray
|
import org.jetbrains.kotlin.ir.types.isArray
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
|
|
||||||
internal interface Proxy {
|
internal interface Proxy {
|
||||||
@@ -44,7 +44,7 @@ internal fun State.wrap(callInterceptor: CallInterceptor, remainArraysAsIs: Bool
|
|||||||
* Prepare state object to be passed in outer world
|
* Prepare state object to be passed in outer world
|
||||||
*/
|
*/
|
||||||
internal fun List<State>.wrap(callInterceptor: CallInterceptor, irFunction: IrFunction, methodType: MethodType? = null): List<Any?> {
|
internal fun List<State>.wrap(callInterceptor: CallInterceptor, irFunction: IrFunction, methodType: MethodType? = null): List<Any?> {
|
||||||
val name = irFunction.fqNameWhenAvailable?.asString() ?: ""
|
val name = irFunction.fqName
|
||||||
if (name == "kotlin.internal.ir.EQEQ" && this.any { it is Common }) {
|
if (name == "kotlin.internal.ir.EQEQ" && this.any { it is Common }) {
|
||||||
// in case of custom `equals` it is important not to lose information obout type
|
// in case of custom `equals` it is important not to lose information obout type
|
||||||
// so all states remain as is, only common will be converted to Proxy
|
// so all states remain as is, only common will be converted to Proxy
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.ir.declarations.IrProperty
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
import org.jetbrains.kotlin.ir.interpreter.createCall
|
import org.jetbrains.kotlin.ir.interpreter.createCall
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
|
||||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -72,6 +72,6 @@ internal class Common private constructor(override val irClass: IrClass, overrid
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "Common(obj='${irClass.fqNameForIrSerialization}', values=$fields)"
|
return "Common(obj='${irClass.fqName}', values=$fields)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,11 +7,11 @@ package org.jetbrains.kotlin.ir.interpreter.state
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.fqName
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
|
||||||
import org.jetbrains.kotlin.ir.util.overrides
|
import org.jetbrains.kotlin.ir.util.overrides
|
||||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
|
|
||||||
@@ -19,9 +19,7 @@ internal interface Complex : State {
|
|||||||
var superWrapperClass: Wrapper?
|
var superWrapperClass: Wrapper?
|
||||||
var outerClass: Variable?
|
var outerClass: Variable?
|
||||||
|
|
||||||
fun irClassFqName(): String {
|
fun irClassFqName() = irClass.fqName
|
||||||
return irClass.fqNameForIrSerialization.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getIrFunctionFromGivenClass(irClass: IrClass, symbol: IrFunctionSymbol): IrFunction? {
|
private fun getIrFunctionFromGivenClass(irClass: IrClass, symbol: IrFunctionSymbol): IrFunction? {
|
||||||
val propertyGetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
val propertyGetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
|||||||
|
|
||||||
// This method is used to get correct java method name
|
// This method is used to get correct java method name
|
||||||
private fun getJavaOriginalName(irFunction: IrFunction): String? {
|
private fun getJavaOriginalName(irFunction: IrFunction): String? {
|
||||||
return when (irFunction.getLastOverridden().fqNameWhenAvailable?.asString()) {
|
return when (irFunction.getLastOverridden().fqName) {
|
||||||
"kotlin.collections.Map.<get-entries>" -> "entrySet"
|
"kotlin.collections.Map.<get-entries>" -> "entrySet"
|
||||||
"kotlin.collections.Map.<get-keys>" -> "keySet"
|
"kotlin.collections.Map.<get-keys>" -> "keySet"
|
||||||
"kotlin.CharSequence.get" -> "charAt"
|
"kotlin.CharSequence.get" -> "charAt"
|
||||||
@@ -111,8 +111,8 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
|||||||
javaClassToIrClass += javaClass to irClass
|
javaClassToIrClass += javaClass to irClass
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrDeclarationWithName.getSignature(): String? {
|
private fun IrDeclarationWithName.getSignature(): String {
|
||||||
val fqName = this.fqNameWhenAvailable?.asString()
|
val fqName = this.fqName
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is IrFunction -> {
|
is IrFunction -> {
|
||||||
val receiver = (dispatchReceiverParameter ?: extensionReceiverParameter)?.type?.getOnlyName()?.let { "$it." } ?: ""
|
val receiver = (dispatchReceiverParameter ?: extensionReceiverParameter)?.type?.getOnlyName()?.let { "$it." } ?: ""
|
||||||
@@ -127,10 +127,10 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun mustBeHandledWithWrapper(declaration: IrDeclarationWithName): Boolean {
|
fun mustBeHandledWithWrapper(declaration: IrDeclarationWithName): Boolean {
|
||||||
val fqName = declaration.fqNameWhenAvailable?.asString()
|
val fqName = declaration.fqName
|
||||||
return when (declaration) {
|
return when (declaration) {
|
||||||
is IrFunction -> declaration.getSignature() in intrinsicFunctionToHandler
|
is IrFunction -> declaration.getSignature() in intrinsicFunctionToHandler
|
||||||
else -> fqName in intrinsicClasses || fqName?.startsWith("java") == true
|
else -> fqName in intrinsicClasses || fqName.startsWith("java")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,15 +204,15 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
|
|||||||
|
|
||||||
private fun IrType.getClass(asObject: Boolean): Class<out Any> {
|
private fun IrType.getClass(asObject: Boolean): Class<out Any> {
|
||||||
val owner = this.classOrNull?.owner
|
val owner = this.classOrNull?.owner
|
||||||
val fqName = owner?.fqNameWhenAvailable?.asString()
|
val fqName = owner?.fqName
|
||||||
val notNullType = this.makeNotNull()
|
val notNullType = this.makeNotNull()
|
||||||
//TODO check if primitive array is possible here
|
//TODO check if primitive array is possible here
|
||||||
return when {
|
return when {
|
||||||
notNullType.isPrimitiveType() || notNullType.isString() -> getPrimitiveClass(notNullType, asObject)!!
|
notNullType.isPrimitiveType() || notNullType.isString() -> getPrimitiveClass(notNullType, asObject)!!
|
||||||
notNullType.isArray() -> {
|
notNullType.isArray() -> {
|
||||||
val argumentFqName = (this as IrSimpleType).arguments.single().typeOrNull?.classOrNull?.owner?.fqNameWhenAvailable
|
val argumentFqName = (this as IrSimpleType).arguments.single().typeOrNull?.classOrNull?.owner?.fqName
|
||||||
when {
|
when {
|
||||||
argumentFqName != null && argumentFqName.asString() != "kotlin.Any" -> argumentFqName.let { Class.forName("[L$it;") }
|
argumentFqName != null && argumentFqName != "kotlin.Any" -> argumentFqName.let { Class.forName("[L$it;") }
|
||||||
else -> Array<Any?>::class.java
|
else -> Array<Any?>::class.java
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user