@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
2424import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
2525import org.jetbrains.kotlin.load.java.structure.*
2626import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
27+ import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
2728import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
2829import org.jetbrains.kotlin.name.FqName
2930import org.jetbrains.kotlin.name.NameUtils
@@ -784,6 +785,55 @@ open class KotlinUsesExtractor(
784785 }
785786 }
786787
788+ fun parentOf (d : IrDeclaration ): IrDeclarationParent {
789+ if (d is IrField ) {
790+ return getFieldParent(d)
791+ }
792+ return d.parent
793+ }
794+
795+ fun useDeclarationParentOf (
796+ // The declaration
797+ d : IrDeclaration ,
798+ // Whether the type of entity whose parent this is can be a
799+ // top-level entity in the JVM's eyes. If so, then its parent may
800+ // be a file; otherwise, if dp is a file foo.kt, then the parent
801+ // is really the JVM class FooKt.
802+ canBeTopLevel : Boolean ,
803+ classTypeArguments : List <IrTypeArgument >? = null,
804+ inReceiverContext : Boolean = false):
805+ Label <out DbElement >? {
806+
807+ val parent = parentOf(d)
808+ if (parent is IrExternalPackageFragment ) {
809+ // This is in a file class.
810+ // Get the name in a similar way to the compiler's ExternalPackageParentPatcherLowering
811+ // visitMemberAccess/generateOrGetFacadeClass.
812+ if (d is IrMemberWithContainerSource ) {
813+ val containerSource = d.containerSource
814+ if (containerSource is FacadeClassSource ) {
815+ val facadeClassName = containerSource.facadeClassName
816+ if (facadeClassName != null ) {
817+ // TODO: This is really a multifile-class rather than a file-class
818+ return extractFileClass(facadeClassName.fqNameForTopLevelClassMaybeWithDollars)
819+ } else {
820+ return extractFileClass(containerSource.className.fqNameForTopLevelClassMaybeWithDollars)
821+ }
822+ } else {
823+ logger.error(" Unexpected container source ${containerSource?.javaClass} " )
824+ return null
825+ }
826+ } else {
827+ logger.error(" Element in external package fragment without container source ${d.javaClass} " )
828+ return null
829+ }
830+ }
831+ return useDeclarationParent(parent, canBeTopLevel, classTypeArguments, inReceiverContext)
832+ }
833+
834+ // Generally, useDeclarationParentOf should be used instead of
835+ // calling this directly, as this cannot handle
836+ // IrExternalPackageFragment
787837 fun useDeclarationParent (
788838 // The declaration parent according to Kotlin
789839 dp : IrDeclarationParent ,
@@ -815,8 +865,7 @@ open class KotlinUsesExtractor(
815865 }
816866 is IrFunction -> useFunction(dp)
817867 is IrExternalPackageFragment -> {
818- // TODO
819- logger.error(" Unhandled IrExternalPackageFragment" )
868+ logger.error(" Unable to handle IrExternalPackageFragment as an IrDeclarationParent" )
820869 null
821870 }
822871 else -> {
@@ -1058,7 +1107,7 @@ open class KotlinUsesExtractor(
10581107 * in.
10591108 */
10601109 fun getFunctionLabel (f : IrFunction , classTypeArgsIncludingOuterClasses : List <IrTypeArgument >? ): String? {
1061- val parentId = useDeclarationParent(f.parent , false , classTypeArgsIncludingOuterClasses, true )
1110+ val parentId = useDeclarationParentOf(f , false , classTypeArgsIncludingOuterClasses, true )
10621111 if (parentId == null ) {
10631112 logger.error(" Couldn't get parent ID for function label" )
10641113 return null
@@ -1355,7 +1404,7 @@ open class KotlinUsesExtractor(
13551404 return ids.function.cast<T >()
13561405 }
13571406 val javaFun = kotlinFunctionToJavaEquivalent(f, noReplace)
1358- val parentId = useDeclarationParent (javaFun.parent , false , classTypeArgsIncludingOuterClasses, true )
1407+ val parentId = useDeclarationParentOf (javaFun, false , classTypeArgsIncludingOuterClasses, true )
13591408 if (parentId == null ) {
13601409 logger.error(" Couldn't find parent ID for function ${f.name.asString()} " )
13611410 return null
@@ -1662,7 +1711,7 @@ open class KotlinUsesExtractor(
16621711 val overriddenParentAttributes = (declarationParent as ? IrFunction )?.let {
16631712 (this as ? KotlinFileExtractor )?.declarationStack?.findOverriddenAttributes(it)
16641713 }
1665- val parentId = parent ? : overriddenParentAttributes?.id ? : useDeclarationParent(declarationParent , false )
1714+ val parentId = parent ? : overriddenParentAttributes?.id ? : useDeclarationParentOf(vp , false )
16661715
16671716 val idxBase = overriddenParentAttributes?.valueParameters?.indexOf(vp) ? : vp.index
16681717 val idxOffset = if (declarationParent is IrFunction && declarationParent.extensionReceiverParameter != null )
@@ -1707,7 +1756,7 @@ open class KotlinUsesExtractor(
17071756 }
17081757
17091758 fun getFieldLabel (f : IrField ): String {
1710- val parentId = useDeclarationParent(getFieldParent(f) , false )
1759+ val parentId = useDeclarationParentOf(f , false )
17111760 // Distinguish backing fields of properties based on their extension receiver type;
17121761 // otherwise two extension properties declared in the same enclosing context will get
17131762 // clashing trap labels. These are always private, so we can just make up a label without
@@ -1720,7 +1769,7 @@ open class KotlinUsesExtractor(
17201769 tw.getLabelFor<DbField >(getFieldLabel(f)).also { extractFieldLaterIfExternalFileMember(f) }
17211770
17221771 fun getPropertyLabel (p : IrProperty ): String? {
1723- val parentId = useDeclarationParent(p.parent , false )
1772+ val parentId = useDeclarationParentOf(p , false )
17241773 if (parentId == null ) {
17251774 return null
17261775 } else {
@@ -1752,15 +1801,15 @@ open class KotlinUsesExtractor(
17521801 }
17531802
17541803 fun getEnumEntryLabel (ee : IrEnumEntry ): String {
1755- val parentId = useDeclarationParent (ee.parent , false )
1804+ val parentId = useDeclarationParentOf (ee, false )
17561805 return " @\" field;{$parentId };${ee.name.asString()} \" "
17571806 }
17581807
17591808 fun useEnumEntry (ee : IrEnumEntry ): Label <out DbField > =
17601809 tw.getLabelFor(getEnumEntryLabel(ee))
17611810
17621811 fun getTypeAliasLabel (ta : IrTypeAlias ): String {
1763- val parentId = useDeclarationParent (ta.parent , true )
1812+ val parentId = useDeclarationParentOf (ta, true )
17641813 return " @\" type_alias;{$parentId };${ta.name.asString()} \" "
17651814 }
17661815
0 commit comments