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:
Ivan Kylchik
2020-08-28 13:36:11 +03:00
committed by TeamCityServer
parent 4c75576414
commit 6808151af7
5 changed files with 54 additions and 117 deletions
@@ -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
}
}
@@ -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) }
}
}
@@ -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) {