Extract common checker logic into accessesTopLevelOrObjectField
This commit is contained in:
committed by
TeamCityServer
parent
49d8bd5845
commit
6e12cee626
+1
-3
@@ -211,9 +211,7 @@ private fun unfoldReturn(expression: IrReturn, callStack: CallStack) {
|
||||
|
||||
private fun unfoldSetField(expression: IrSetField, callStack: CallStack) {
|
||||
// receiver is null, for example, for top level fields; cannot interpret set on top level var
|
||||
if (expression.receiver.let { it == null || (it.type.classifierOrNull?.owner as? IrClass)?.isObject == true }) {
|
||||
error("Cannot interpret set method on top level properties")
|
||||
}
|
||||
if (expression.accessesTopLevelOrObjectField()) error("Cannot interpret set method on top level properties")
|
||||
|
||||
callStack.addInstruction(SimpleInstruction(expression))
|
||||
callStack.addInstruction(CompoundInstruction(expression.value))
|
||||
|
||||
@@ -369,7 +369,7 @@ class IrInterpreter private constructor(
|
||||
field.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && field.correspondingPropertySymbol?.owner?.isConst == true -> {
|
||||
callStack.addInstruction(CompoundInstruction(field.initializer?.expression))
|
||||
}
|
||||
expression.receiver.let { it == null || it.type.classOrNull?.owner?.isObject == true } -> {
|
||||
expression.accessesTopLevelOrObjectField() -> {
|
||||
// receiver is null, for example, for top level fields
|
||||
val propertyOwner = field.correspondingPropertySymbol?.owner
|
||||
val isConst = propertyOwner?.isConst == true || propertyOwner?.backingField?.initializer?.expression is IrConst<*>
|
||||
|
||||
@@ -266,4 +266,8 @@ internal fun IrFunction.getArgsForMethodInvocation(
|
||||
internal fun IrType.getOnlyName(): String {
|
||||
if (this !is IrSimpleType) return this.render()
|
||||
return (this.classifierOrFail.owner as IrDeclarationWithName).name.asString() + (if (this.hasQuestionMark) "?" else "")
|
||||
}
|
||||
|
||||
internal fun IrFieldAccessExpression.accessesTopLevelOrObjectField(): Boolean {
|
||||
return this.receiver == null || (this.receiver?.type?.classifierOrNull?.owner as? IrClass)?.isObject == true
|
||||
}
|
||||
+8
-11
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.accessesTopLevelOrObjectField
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
@@ -131,18 +132,16 @@ class IrCompileTimeChecker(
|
||||
val owner = expression.symbol.owner
|
||||
val property = owner.correspondingPropertySymbol?.owner
|
||||
val fqName = owner.fqNameForIrSerialization
|
||||
fun isJavaStaticWithPrimitiveOrString(): Boolean {
|
||||
return owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic &&
|
||||
(owner.type.isPrimitiveType() || owner.type.isStringClassType())
|
||||
}
|
||||
return when {
|
||||
// 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
|
||||
fqName.toString().let { it == "java.lang.Boolean.FALSE" || it == "java.lang.Boolean.TRUE" } -> true
|
||||
owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic &&
|
||||
(owner.type.isPrimitiveType() || owner.type.isStringClassType()) -> {
|
||||
// if is java primitive static
|
||||
owner.initializer?.accept(this, data) == true
|
||||
}
|
||||
expression.receiver == null -> {
|
||||
property?.isConst == true && owner.initializer?.accept(this, null) == true
|
||||
}
|
||||
isJavaStaticWithPrimitiveOrString() -> owner.initializer?.accept(this, data) == true
|
||||
expression.receiver == null -> property?.isConst == true && owner.initializer?.accept(this, null) == true
|
||||
owner.origin == IrDeclarationOrigin.PROPERTY_BACKING_FIELD && property?.isConst == true -> {
|
||||
val receiverComputable = expression.receiver?.accept(this, null) ?: true
|
||||
val initializerComputable = owner.initializer?.accept(this, null) ?: false
|
||||
@@ -157,9 +156,7 @@ class IrCompileTimeChecker(
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField, data: Nothing?): Boolean {
|
||||
if (expression.receiver.let { it == null || it.type.classOrNull?.owner?.isObject == true }) {
|
||||
return false
|
||||
}
|
||||
if (expression.accessesTopLevelOrObjectField()) return false
|
||||
//todo check receiver?
|
||||
val property = expression.symbol.owner.correspondingPropertySymbol?.owner
|
||||
val parent = expression.symbol.owner.parent as IrDeclarationContainer
|
||||
|
||||
@@ -15,9 +15,7 @@ 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.isAny
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal interface Complex: State {
|
||||
var superWrapperClass: Wrapper?
|
||||
@@ -27,10 +25,10 @@ internal interface Complex: State {
|
||||
return irClass.fqNameForIrSerialization.toString()
|
||||
}
|
||||
|
||||
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>()
|
||||
private fun getIrFunctionFromGivenClass(irClass: IrClass, 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>()
|
||||
return (propertyGetters + propertySetters + functions).firstOrNull {
|
||||
val owner = symbol.owner
|
||||
when {
|
||||
@@ -58,7 +56,7 @@ internal interface Complex: State {
|
||||
|
||||
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? {
|
||||
val receiver = getThisOrSuperReceiver(expression.superQualifierSymbol?.owner) ?: return null
|
||||
val irFunction = receiver.getIrFunction(expression.symbol) ?: return null
|
||||
val irFunction = getIrFunctionFromGivenClass(receiver, expression.symbol) ?: return null
|
||||
return getOverridden(irFunction as IrSimpleFunction)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user