IR interpreter: fix calculation of constant Java fields

#KT-42117 Fixed
This commit is contained in:
Mikhail Glukhikh
2020-09-22 13:22:47 +03:00
parent 44ebec05bb
commit 2fd752f8f6
12 changed files with 16 additions and 25 deletions
@@ -266,7 +266,9 @@ class Fir2IrConverter(
val components = Fir2IrComponentsStorage(session, scopeSession, symbolTable, irBuiltIns, irFactory, mangler)
val conversionScope = Fir2IrConversionScope()
val classifierStorage = Fir2IrClassifierStorage(components)
val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor)
val converter = Fir2IrConverter(moduleDescriptor, sourceManager, components)
val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope)
val declarationStorage = Fir2IrDeclarationStorage(components, fir2irVisitor, moduleDescriptor)
val typeConverter = Fir2IrTypeConverter(components)
val builtIns = Fir2IrBuiltIns(components, session)
components.declarationStorage = declarationStorage
@@ -276,7 +278,6 @@ class Fir2IrConverter(
components.builtIns = builtIns
val irFiles = mutableListOf<IrFile>()
val converter = Fir2IrConverter(moduleDescriptor, sourceManager, components)
for (firFile in firFiles) {
irFiles += converter.registerFileAndClasses(firFile)
}
@@ -295,7 +296,6 @@ class Fir2IrConverter(
session, scopeSession, classifierStorage, declarationStorage, conversionScope
)
components.fakeOverrideGenerator = fakeOverrideGenerator
val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope)
val callGenerator = CallAndReferenceGenerator(components, fir2irVisitor, conversionScope)
components.callGenerator = callGenerator
declarationStorage.annotationGenerator = AnnotationGenerator(components)
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ
@OptIn(ObsoleteDescriptorBasedAPI::class)
class Fir2IrDeclarationStorage(
private val components: Fir2IrComponents,
private val visitor: Fir2IrVisitor,
private val moduleDescriptor: FirModuleDescriptor
) : Fir2IrComponents by components {
@@ -812,6 +813,11 @@ class Fir2IrDeclarationStorage(
isExternal = false,
isStatic = field.isStatic
).apply {
field.initializer?.let {
val expression = visitor.convertToIrExpression(it)
expression.type = type
initializer = irFactory.createExpressionBody(expression)
}
descriptor.bind(this)
fieldCache[field] = this
}
@@ -12,10 +12,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.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.isString
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.FqName
@@ -173,19 +170,10 @@ class IrCompileTimeChecker(
val owner = expression.symbol.owner
val parent = owner.parent as IrSymbolOwner
val isJavaPrimitiveStatic = owner.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && owner.isStatic &&
owner.parentAsClass.fqNameWhenAvailable.isJavaPrimitive()
(owner.type.isPrimitiveType() || owner.type.isStringClassType())
return visitedStack.contains(parent) || isJavaPrimitiveStatic
}
// TODO find similar method in utils
private fun FqName?.isJavaPrimitive(): Boolean {
this ?: return false
return this.toString() in setOf(
"java.lang.Byte", "java.lang.Short", "java.lang.Integer", "java.lang.Long",
"java.lang.Float", "java.lang.Double", "java.lang.Boolean", "java.lang.Character"
)
}
override fun visitSetField(expression: IrSetField, data: Nothing?): Boolean {
//todo check receiver?
val parent = expression.symbol.owner.parent as IrSymbolOwner
@@ -533,6 +533,10 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
val field = expression.symbol.owner
// for java static variables
if (field.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && field.isStatic) {
val initializerExpression = field.initializer?.expression
if (initializerExpression is IrConst<*>) {
return interpretConst(initializerExpression)
}
stack.pushReturnValue(Wrapper.getStaticGetter(field)!!.invokeWithArguments().toState(field.type))
return Next
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// FILE: Foo.java
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// FILE: Foo.java
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// FILE: Foo.java
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: first/JavaSuperclass.java
package first;
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: first/Foo.java
package first;
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// FILE: JClass.java
import org.jetbrains.annotations.NotNull;
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
fun foo1(x: Int): Boolean {
when(x) {
0 -> return true
+1 -1
View File
@@ -8,7 +8,7 @@ FILE fqName:interop fileName:/Definitions.kt
PROPERTY name:KT_CONSTANT visibility:public modality:FINAL [const,val]
FIELD PROPERTY_BACKING_FIELD name:KT_CONSTANT type:kotlin.String? visibility:public [final]
EXPRESSION_BODY
GET_FIELD 'FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:CONSTANT type:kotlin.String? visibility:public [final,static]' type=kotlin.String? origin=GET_PROPERTY
CONST String type=kotlin.String value="constant"
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-KT_CONSTANT> visibility:public modality:FINAL <> ($this:interop.Definitions) returnType:kotlin.String?
correspondingProperty: PROPERTY name:KT_CONSTANT visibility:public modality:FINAL [const,val]
$this: VALUE_PARAMETER name:<this> type:interop.Definitions