@@ -7,6 +7,8 @@ import org.jetbrains.kotlin.backend.jvm.codegen.isRawType
77import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
88import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
99import org.jetbrains.kotlin.ir.declarations.*
10+ import org.jetbrains.kotlin.ir.expressions.IrConst
11+ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
1012import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
1113import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
1214import org.jetbrains.kotlin.ir.types.*
@@ -39,6 +41,42 @@ open class KotlinUsesExtractor(
3941 return id
4042 }
4143
44+
45+ @OptIn(kotlin.ExperimentalStdlibApi ::class ) // Annotation required by kotlin versions < 1.5
46+ fun extractFileClass (f : IrFile ): Label <out DbClass > {
47+ val fileName = f.fileEntry.name
48+ val pkg = f.fqName.asString()
49+ val defaultName = fileName.replaceFirst(Regex (""" .*[/\\]""" ), " " ).replaceFirst(Regex (""" \.kt$""" ), " " ).replaceFirstChar({ it.uppercase() }) + " Kt"
50+ var jvmName = defaultName
51+ for (a: IrConstructorCall in f.annotations) {
52+ val t = a.type
53+ if (t is IrSimpleType && a.valueArgumentsCount == 1 ) {
54+ val owner = t.classifier.owner
55+ val v = a.getValueArgument(0 )
56+ if (owner is IrClass ) {
57+ val aPkg = owner.packageFqName?.asString()
58+ val name = owner.name.asString()
59+ if (aPkg == " kotlin.jvm" && name == " JvmName" && v is IrConst <* >) {
60+ val value = v.value
61+ if (value is String ) {
62+ jvmName = value
63+ }
64+ }
65+ }
66+ }
67+ }
68+ val qualClassName = if (pkg.isEmpty()) jvmName else " $pkg .$jvmName "
69+ val label = " @\" class;$qualClassName \" "
70+ val id: Label <DbClass > = tw.getLabelFor(label)
71+ val fileId = tw.mkFileId(f.path, false )
72+ val locId = tw.getWholeFileLocation(fileId)
73+ val pkgId = extractPackage(pkg)
74+ tw.writeClasses(id, jvmName, pkgId, id)
75+ tw.writeFile_class(id)
76+ tw.writeHasLocation(id, locId)
77+ return id
78+ }
79+
4280 data class UseClassInstanceResult (val typeResult : TypeResult <DbClassorinterface >, val javaClass : IrClass )
4381 /* *
4482 * A triple of a type's database label, its signature for use in callable signatures, and its short name for use
@@ -481,9 +519,24 @@ class X {
481519 }
482520 }
483521
484- fun useDeclarationParent (dp : IrDeclarationParent , classTypeArguments : List <IrTypeArgument >? = null, inReceiverContext : Boolean = false): Label <out DbElement > =
522+ fun useDeclarationParent (
523+ // The declaration parent according to Kotlin
524+ dp : IrDeclarationParent ,
525+ // Whether the type of entity whose parent this is can be a
526+ // top-level entity in the JVM's eyes. If so, then its parent may
527+ // be a file; otherwise, if dp is a file foo.kt, then the parent
528+ // is really the JVM class FooKt.
529+ canBeTopLevel : Boolean ,
530+ classTypeArguments : List <IrTypeArgument >? = null,
531+ inReceiverContext : Boolean = false):
532+ Label <out DbElement > =
485533 when (dp) {
486- is IrFile -> usePackage(dp.fqName.asString())
534+ is IrFile ->
535+ if (canBeTopLevel) {
536+ usePackage(dp.fqName.asString())
537+ } else {
538+ extractFileClass(dp)
539+ }
487540 is IrClass -> if (classTypeArguments != null && ! dp.isAnonymousObject) useClassInstance(dp, classTypeArguments, inReceiverContext).typeResult.id else useClassSource(dp)
488541 is IrFunction -> useFunction(dp)
489542 else -> {
@@ -525,7 +578,7 @@ class X {
525578 extensionReceiverParameter : IrValueParameter ? ,
526579 classTypeArguments : List <IrTypeArgument >? = null
527580 ): String {
528- val parentId = useDeclarationParent(parent, classTypeArguments, true )
581+ val parentId = useDeclarationParent(parent, false , classTypeArguments, true )
529582 return getFunctionLabel(parentId, name, parameters, returnType, extensionReceiverParameter)
530583 }
531584
@@ -726,7 +779,7 @@ class X {
726779 }
727780
728781 fun getTypeParameterLabel (param : IrTypeParameter ): String {
729- val parentLabel = useDeclarationParent(param.parent)
782+ val parentLabel = useDeclarationParent(param.parent, false )
730783 return " @\" typevar;{$parentLabel };${param.name} \" "
731784 }
732785
@@ -844,7 +897,7 @@ class X {
844897 * `parent` is null.
845898 */
846899 fun getValueParameterLabel (vp : IrValueParameter , parent : Label <out DbCallable >? ): String {
847- val parentId = parent ? : useDeclarationParent(vp.parent)
900+ val parentId = parent ? : useDeclarationParent(vp.parent, false )
848901 val idx = vp.index
849902 if (idx < 0 ) {
850903 // We're not extracting this and this@TYPE parameters of functions:
@@ -858,15 +911,15 @@ class X {
858911 tw.getLabelFor(getValueParameterLabel(vp, parent))
859912
860913 fun getFieldLabel (f : IrField ): String {
861- val parentId = useDeclarationParent(f.parent)
914+ val parentId = useDeclarationParent(f.parent, false )
862915 return " @\" field;{$parentId };${f.name.asString()} \" "
863916 }
864917
865918 fun useField (f : IrField ): Label <out DbField > =
866919 tw.getLabelFor(getFieldLabel(f))
867920
868921 fun getPropertyLabel (p : IrProperty ) =
869- getPropertyLabel(p, useDeclarationParent(p.parent))
922+ getPropertyLabel(p, useDeclarationParent(p.parent, false ))
870923
871924 fun getPropertyLabel (p : IrProperty , parentId : Label <out DbElement >) =
872925 " @\" property;{$parentId };${p.name.asString()} \" "
@@ -878,15 +931,15 @@ class X {
878931 tw.getLabelFor(getPropertyLabel(p, parentId))
879932
880933 fun getEnumEntryLabel (ee : IrEnumEntry ): String {
881- val parentId = useDeclarationParent(ee.parent)
934+ val parentId = useDeclarationParent(ee.parent, false )
882935 return " @\" field;{$parentId };${ee.name.asString()} \" "
883936 }
884937
885938 fun useEnumEntry (ee : IrEnumEntry ): Label <out DbField > =
886939 tw.getLabelFor(getEnumEntryLabel(ee))
887940
888941 private fun getTypeAliasLabel (ta : IrTypeAlias ): String {
889- val parentId = useDeclarationParent(ta.parent)
942+ val parentId = useDeclarationParent(ta.parent, true )
890943 return " @\" type_alias;{$parentId };${ta.name.asString()} \" "
891944 }
892945
0 commit comments