Associate certain companion object fields with the parent class

Specifically `const`, `lateinit` and `@JvmField` properties get a static field which belongs to the containing class not the companion object, such that Java can address them via the containing class name rather than have to navigate a companion object pointer.
This commit is contained in:
Chris Smowton
2022-05-19 20:51:38 +01:00
parent 5d4473bb2a
commit a204c742d8
2 changed files with 23 additions and 6 deletions

View File

@@ -135,7 +135,7 @@ open class KotlinFileExtractor(
Unit
}
is IrField -> {
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
val parentId = useDeclarationParent(getFieldParent(declaration), false)?.cast<DbReftype>()
if (parentId != null) {
extractField(declaration, parentId)
}
@@ -829,10 +829,13 @@ open class KotlinFileExtractor(
}
if (bf != null && extractBackingField) {
val fieldId = extractField(bf, parentId)
tw.writeKtPropertyBackingFields(id, fieldId)
if (p.isDelegated) {
tw.writeKtPropertyDelegates(id, fieldId)
val fieldParentId = useDeclarationParent(getFieldParent(bf), false)
if (fieldParentId != null) {
val fieldId = extractField(bf, fieldParentId.cast())
tw.writeKtPropertyBackingFields(id, fieldId)
if (p.isDelegated) {
tw.writeKtPropertyDelegates(id, fieldId)
}
}
}

View File

@@ -6,6 +6,7 @@ import com.semmle.extractor.java.OdasaOutput
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.ir.allOverridden
import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf
import org.jetbrains.kotlin.backend.jvm.ir.getJvmNameFromAnnotation
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.*
@@ -1268,9 +1269,22 @@ open class KotlinUsesExtractor(
fun useValueParameter(vp: IrValueParameter, parent: Label<out DbCallable>?): Label<out DbParam> =
tw.getLabelFor(getValueParameterLabel(vp, parent))
fun isDirectlyExposedCompanionObjectField(f: IrField) =
f.hasAnnotation(FqName("kotlin.jvm.JvmField")) ||
f.correspondingPropertySymbol?.owner?.let {
it.isConst || it.isLateinit
} ?: false
fun getFieldParent(f: IrField) =
f.parentClassOrNull?.let {
if (it.isCompanion && isDirectlyExposedCompanionObjectField(f))
it.parent
else
null
} ?: f.parent
fun getFieldLabel(f: IrField): String {
val parentId = useDeclarationParent(f.parent, false)
val parentId = useDeclarationParent(getFieldParent(f), false)
return "@\"field;{$parentId};${f.name.asString()}\""
}