Remove method getOriginal from Complex class
Common class no longer contains Common super classes, all fields are now inside one single object.
This commit is contained in:
committed by
TeamCityServer
parent
4c75576414
commit
6808151af7
+25
-24
@@ -89,7 +89,13 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
}
|
||||
}
|
||||
|
||||
internal class Proxy(val state: Common, val interpreter: IrInterpreter) {
|
||||
/**
|
||||
* calledFromBuiltIns - used to avoid cyclic calls. For example:
|
||||
* override fun toString(): String {
|
||||
* return super.toString()
|
||||
* }
|
||||
*/
|
||||
internal class Proxy(val state: Common, val interpreter: IrInterpreter, private val calledFromBuiltIns: Boolean = false) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
@@ -98,7 +104,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
|
||||
val valueArguments = mutableListOf<Variable>()
|
||||
val equalsFun = state.getEqualsFunction()
|
||||
if (equalsFun.isFakeOverriddenFromAny()) return this.state.getOriginal() === other.state.getOriginal()
|
||||
if (equalsFun.isFakeOverriddenFromAny() || calledFromBuiltIns) return this.state === other.state
|
||||
|
||||
equalsFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
|
||||
valueArguments.add(Variable(equalsFun.valueParameters.single().symbol, other.state))
|
||||
@@ -114,7 +120,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
override fun hashCode(): Int {
|
||||
val valueArguments = mutableListOf<Variable>()
|
||||
val hashCodeFun = state.getHashCodeFunction()
|
||||
if (hashCodeFun.isFakeOverriddenFromAny()) return System.identityHashCode(state.getOriginal())
|
||||
if (hashCodeFun.isFakeOverriddenFromAny() || calledFromBuiltIns) return System.identityHashCode(state)
|
||||
|
||||
hashCodeFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
|
||||
return with(interpreter) {
|
||||
@@ -128,8 +134,8 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
override fun toString(): String {
|
||||
val valueArguments = mutableListOf<Variable>()
|
||||
val toStringFun = state.getToStringFunction()
|
||||
if (toStringFun.isFakeOverriddenFromAny()) {
|
||||
return "${state.getOriginal().irClass.internalName()}@" + System.identityHashCode(state).toString(16).padStart(8, '0')
|
||||
if (toStringFun.isFakeOverriddenFromAny() || calledFromBuiltIns) {
|
||||
return "${state.irClass.internalName()}@" + hashCode().toString(16).padStart(8, '0')
|
||||
}
|
||||
|
||||
toStringFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
|
||||
@@ -142,12 +148,12 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
}
|
||||
}
|
||||
|
||||
internal fun State.wrapAsProxyIfNeeded(): Any? {
|
||||
internal fun State.wrapAsProxyIfNeeded(calledFromBuiltIns: Boolean = false): Any? {
|
||||
return when (this) {
|
||||
is ExceptionState -> this.getThisAsCauseForException()
|
||||
is Wrapper -> this.value
|
||||
is Primitive<*> -> this.value
|
||||
is Common -> Proxy(this, this@IrInterpreter)
|
||||
is Common -> Proxy(this, this@IrInterpreter, calledFromBuiltIns)
|
||||
is Lambda -> this // TODO as Proxy
|
||||
else -> throw AssertionError("${this::class} is unsupported as argument for wrap function")
|
||||
}
|
||||
@@ -250,7 +256,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
|
||||
val receiverType = irFunction.dispatchReceiverParameter?.type
|
||||
val argsType = listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }
|
||||
val argsValues = args.map { it.wrapAsProxyIfNeeded() }
|
||||
val argsValues = args.map { it.wrapAsProxyIfNeeded(methodName !in setOf("plus", IrBuiltIns.OperatorNames.EQEQ)) }
|
||||
|
||||
fun IrType.getOnlyName(): String {
|
||||
return when {
|
||||
@@ -351,12 +357,10 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
rawExtensionReceiver?.interpret()?.check { return it }
|
||||
val extensionReceiver = rawExtensionReceiver?.let { stack.popReturnValue() }?.checkNullability(expression.extensionReceiver?.type)
|
||||
|
||||
// get correct ir function
|
||||
val irFunction = dispatchReceiver?.getIrFunctionByIrCall(expression) ?: expression.symbol.owner
|
||||
val functionReceiver = dispatchReceiver.getCorrectReceiverByFunction(irFunction)
|
||||
|
||||
// it is important firstly to add receiver, then arguments; this order is used in builtin method call
|
||||
irFunction.getDispatchReceiver()?.let { functionReceiver?.let { receiver -> valueArguments.add(Variable(it, receiver)) } }
|
||||
irFunction.getDispatchReceiver()?.let { dispatchReceiver?.let { receiver -> valueArguments.add(Variable(it, receiver)) } }
|
||||
irFunction.getExtensionReceiver()?.let { extensionReceiver?.let { receiver -> valueArguments.add(Variable(it, receiver)) } }
|
||||
|
||||
interpretValueParameters(expression, irFunction, valueArguments).check { return it }
|
||||
@@ -365,11 +369,12 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
if (dispatchReceiver is Complex) valueArguments.addAll(dispatchReceiver.typeArguments)
|
||||
if (extensionReceiver is Complex) valueArguments.addAll(extensionReceiver.typeArguments)
|
||||
|
||||
val isLocal = (dispatchReceiver as? Complex)?.getOriginal()?.irClass?.isLocal ?: irFunction.isLocal
|
||||
if (isLocal) valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
||||
if (dispatchReceiver?.irClass?.isLocal == true || irFunction.isLocal) {
|
||||
valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
|
||||
}
|
||||
|
||||
if (functionReceiver is Complex && irFunction.parentClassOrNull?.isInner == true) {
|
||||
generateSequence(functionReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { valueArguments.add(it) }
|
||||
if (dispatchReceiver is Complex && irFunction.parentClassOrNull?.isInner == true) {
|
||||
generateSequence(dispatchReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { valueArguments.add(it) }
|
||||
}
|
||||
|
||||
return stack.newFrame(asSubFrame = irFunction.isInline || irFunction.isLocal, initPool = valueArguments) {
|
||||
@@ -469,7 +474,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
|
||||
for (i in 1 until statements.size) statements[i].interpret().check { return@newFrame it }
|
||||
|
||||
stack.pushReturnValue(state.apply { this.setSuperClassInstance(returnedState) })
|
||||
stack.pushReturnValue(state.apply { this.copyFieldsFrom(returnedState) })
|
||||
Next
|
||||
}
|
||||
}
|
||||
@@ -661,7 +666,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
|
||||
val objectState = when {
|
||||
objectClass.hasAnnotation(evaluateIntrinsicAnnotation) -> Wrapper.getCompanionObject(objectClass)
|
||||
else -> Common(objectClass).apply { setSuperClassRecursive() } // TODO test type arguments
|
||||
else -> Common(objectClass) // TODO test type arguments
|
||||
}
|
||||
mapOfObjects[objectClass.symbol] = objectState
|
||||
stack.pushReturnValue(objectState)
|
||||
@@ -769,7 +774,6 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
is Primitive<*> -> arrayToList(result.value)
|
||||
is Common -> when {
|
||||
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
||||
result.irClass.defaultType.isUnsigned() -> listOf(result)
|
||||
else -> listOf(Proxy(result, this))
|
||||
}
|
||||
else -> listOf(result)
|
||||
@@ -782,15 +786,12 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
val storageProperty = owner.declarations.filterIsInstance<IrProperty>().first { it.name.asString() == "storage" }
|
||||
val primitiveArray = args.map {
|
||||
when (it) {
|
||||
is Common -> (it.fields.single().state as Primitive<*>).value // is unsigned number
|
||||
else -> it // is primitive number
|
||||
is Proxy -> (it.state.fields.single().state as Primitive<*>).value // is unsigned number
|
||||
else -> it // is primitive number
|
||||
}
|
||||
}
|
||||
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
|
||||
Common(owner).apply {
|
||||
setSuperClassRecursive()
|
||||
fields.add(Variable(storageProperty.symbol, unsignedArray))
|
||||
}
|
||||
Common(owner).apply { fields.add(Variable(storageProperty.symbol, unsignedArray)) }
|
||||
}
|
||||
else -> args.toPrimitiveStateArray(expression.type).apply {
|
||||
if (expression.type.isArray()) {
|
||||
|
||||
@@ -180,16 +180,7 @@ internal fun getTypeArguments(
|
||||
|
||||
internal fun State?.extractNonLocalDeclarations(): List<Variable> {
|
||||
this ?: return listOf()
|
||||
val state = this.takeIf { it !is Complex } ?: (this as Complex).getOriginal()
|
||||
return state.fields.filter { it.symbol !is IrFieldSymbol }
|
||||
}
|
||||
|
||||
internal fun State?.getCorrectReceiverByFunction(irFunction: IrFunction): State? {
|
||||
if (this !is Complex) return this
|
||||
|
||||
val original: Complex? = this.getOriginal()
|
||||
val other = irFunction.parentClassOrNull?.thisReceiver ?: return this
|
||||
return generateSequence(original) { it.superClass }.firstOrNull { it.irClass.thisReceiver == other } ?: this
|
||||
return this.fields.filter { it.symbol !is IrFieldSymbol }
|
||||
}
|
||||
|
||||
internal fun IrFunction.getCapitalizedFileName() = this.file.name.replace(".kt", "Kt").capitalizeAsciiOnly()
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.interpreter.state
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.interpreter.isInterface
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
|
||||
internal class Common private constructor(
|
||||
@@ -17,29 +15,12 @@ internal class Common private constructor(
|
||||
|
||||
constructor(irClass: IrClass) : this(irClass, mutableListOf())
|
||||
|
||||
fun setSuperClassRecursive() {
|
||||
var thisClass: Common? = this
|
||||
while (thisClass != null) {
|
||||
val superClass = thisClass.irClass.superTypes.filterNot { it.isInterface() }.singleOrNull()
|
||||
val superClassOwner = superClass?.classOrNull?.owner
|
||||
val superClassState = superClassOwner?.let { Common(it) }
|
||||
superClassState?.let { thisClass!!.setSuperClassInstance(it) }
|
||||
|
||||
if (superClass == null && thisClass.irClass.superTypes.isNotEmpty()) {
|
||||
// cover the case when super type implement an interface and so doesn't have explicit any as super class
|
||||
thisClass.setSuperClassInstance(Common(getAnyClassRecursive()))
|
||||
}
|
||||
thisClass = superClassState
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAnyClassRecursive(): IrClass {
|
||||
var owner = irClass.superTypes.first().classOrNull!!.owner
|
||||
while (owner.superTypes.isNotEmpty()) owner = owner.superTypes.first().classOrNull!!.owner
|
||||
return owner
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Common(obj='${irClass.fqNameForIrSerialization}', super=$superClass, values=$fields)"
|
||||
return "Common(obj='${irClass.fqNameForIrSerialization}', values=$fields)"
|
||||
}
|
||||
|
||||
fun copyFieldsFrom(state: Complex) {
|
||||
this.fields.addAll(state.fields)
|
||||
superWrapperClass = state.superWrapperClass ?: state as? Wrapper
|
||||
}
|
||||
}
|
||||
+21
-55
@@ -5,7 +5,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.state
|
||||
|
||||
import org.jetbrains.kotlin.ir.interpreter.getCorrectReceiverByFunction
|
||||
import org.jetbrains.kotlin.ir.interpreter.getLastOverridden
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
@@ -14,83 +13,50 @@ import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.isAny
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.ir.util.overrides
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal abstract class Complex(override val irClass: IrClass, override val fields: MutableList<Variable>) : State {
|
||||
var superClass: Complex? = null
|
||||
var subClass: Complex? = null
|
||||
val interfaces: MutableList<Complex> = mutableListOf() // filled lazily, as needed
|
||||
var superWrapperClass: Wrapper? = null
|
||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
||||
var outerClass: Variable? = null
|
||||
|
||||
fun setSuperClassInstance(superClass: Complex) {
|
||||
if (this.irClass == superClass.irClass) {
|
||||
// if superClass is just secondary constructor instance, then copy properties that isn't already present in instance
|
||||
superClass.fields.forEach { if (!this.contains(it)) fields.add(it) }
|
||||
this.superClass = superClass.superClass
|
||||
superClass.superClass?.subClass = this
|
||||
} else {
|
||||
this.superClass = superClass
|
||||
superClass.subClass = this
|
||||
}
|
||||
}
|
||||
|
||||
fun getOriginal(): Complex {
|
||||
return subClass?.getOriginal() ?: this
|
||||
}
|
||||
|
||||
fun irClassFqName(): String {
|
||||
return irClass.fqNameForIrSerialization.toString()
|
||||
}
|
||||
|
||||
private fun contains(variable: Variable) = fields.any { it.symbol == variable.symbol }
|
||||
|
||||
private fun getIrFunction(symbol: IrFunctionSymbol): IrFunction? {
|
||||
val propertyGetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
||||
val propertySetters = irClass.declarations.filterIsInstance<IrProperty>().mapNotNull { it.setter }
|
||||
val functions = irClass.declarations.filterIsInstance<IrFunction>()
|
||||
private fun IrClass.getIrFunction(symbol: IrFunctionSymbol): IrFunction? {
|
||||
val propertyGetters = this.declarations.filterIsInstance<IrProperty>().mapNotNull { it.getter }
|
||||
val propertySetters = this.declarations.filterIsInstance<IrProperty>().mapNotNull { it.setter }
|
||||
val functions = this.declarations.filterIsInstance<IrFunction>()
|
||||
return (propertyGetters + propertySetters + functions).firstOrNull {
|
||||
if (it is IrSimpleFunction) it.overrides(symbol.owner as IrSimpleFunction) else it == symbol.owner
|
||||
}
|
||||
}
|
||||
|
||||
private fun getThisOrSuperReceiver(superIrClass: IrClass?): Complex? {
|
||||
private fun getThisOrSuperReceiver(superIrClass: IrClass?): IrClass? {
|
||||
return when {
|
||||
superIrClass == null -> this.getOriginal()
|
||||
superIrClass.isInterface -> Common(superIrClass).apply {
|
||||
interfaces.add(this)
|
||||
this.subClass = this@Complex
|
||||
}
|
||||
else -> this.superClass
|
||||
superIrClass == null -> this.irClass
|
||||
superIrClass.isInterface -> superIrClass
|
||||
else -> irClass.superTypes.map { it.classOrNull?.owner }.singleOrNull { it?.isInterface == false }
|
||||
}
|
||||
}
|
||||
|
||||
protected fun getOverridden(owner: IrSimpleFunction, qualifier: State?): IrSimpleFunction {
|
||||
if (!owner.isFakeOverride) return owner
|
||||
if (qualifier == null || qualifier is ExceptionState || (qualifier as? Complex)?.superClass == null) {
|
||||
return owner.getLastOverridden() as IrSimpleFunction
|
||||
}
|
||||
protected fun getOverridden(owner: IrSimpleFunction): IrSimpleFunction {
|
||||
if (!owner.isFakeOverride || owner.body != null || owner.parentAsClass.defaultType.isAny()) return owner
|
||||
|
||||
val overriddenOwner = owner.overriddenSymbols.single().owner
|
||||
return when {
|
||||
overriddenOwner.body != null -> overriddenOwner
|
||||
else -> getOverridden(overriddenOwner, qualifier.superClass!!)
|
||||
}
|
||||
val overriddenOwner = owner.overriddenSymbols.singleOrNull { !it.owner.parentAsClass.isInterface }?.owner
|
||||
return overriddenOwner?.let { getOverridden(it) } ?: owner.getLastOverridden() as IrSimpleFunction
|
||||
}
|
||||
|
||||
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? {
|
||||
val receiver = getThisOrSuperReceiver(expression.superQualifierSymbol?.owner) ?: return null
|
||||
|
||||
val irFunction = receiver.getIrFunction(expression.symbol) ?: return null
|
||||
|
||||
return when (irFunction.body) {
|
||||
null -> getOverridden(irFunction as IrSimpleFunction, this.getCorrectReceiverByFunction(irFunction))
|
||||
else -> irFunction
|
||||
}
|
||||
return getOverridden(irFunction as IrSimpleFunction)
|
||||
}
|
||||
|
||||
fun getEqualsFunction(): IrSimpleFunction {
|
||||
@@ -100,20 +66,20 @@ internal abstract class Complex(override val irClass: IrClass, override val fiel
|
||||
it.name == Name.identifier("equals") && it.dispatchReceiverParameter != null
|
||||
&& it.valueParameters.size == 1 && it.valueParameters[0].type.isNullableAny()
|
||||
}
|
||||
return getOverridden(equalsFun, this)
|
||||
return getOverridden(equalsFun)
|
||||
}
|
||||
|
||||
fun getHashCodeFunction(): IrSimpleFunction {
|
||||
return irClass.declarations.filterIsInstance<IrSimpleFunction>()
|
||||
.filter { it.name.asString() == "hashCode" }
|
||||
.first { it.valueParameters.isEmpty() }
|
||||
.let { getOverridden(it, this) }
|
||||
.let { getOverridden(it) }
|
||||
}
|
||||
|
||||
fun getToStringFunction(): IrSimpleFunction {
|
||||
return irClass.declarations.filterIsInstance<IrSimpleFunction>()
|
||||
.filter { it.name.asString() == "toString" }
|
||||
.first { it.valueParameters.isEmpty() }
|
||||
.let { getOverridden(it, this) }
|
||||
.let { getOverridden(it) }
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -35,9 +35,7 @@ internal class ExceptionState private constructor(
|
||||
}
|
||||
|
||||
constructor(common: Common, stackTrace: List<String>) : this(common.irClass, common.fields, stackTrace) {
|
||||
var wrapperSuperType: Complex? = common
|
||||
while (wrapperSuperType != null && wrapperSuperType !is Wrapper) wrapperSuperType = (wrapperSuperType as Common).superClass
|
||||
setUpCauseIfNeeded(wrapperSuperType as? Wrapper)
|
||||
setUpCauseIfNeeded(common.superWrapperClass)
|
||||
}
|
||||
|
||||
constructor(wrapper: Wrapper, stackTrace: List<String>) : this(wrapper.value as Throwable, wrapper.irClass, stackTrace) {
|
||||
|
||||
Reference in New Issue
Block a user