@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
24
24
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
25
25
import org.jetbrains.kotlin.load.java.structure.*
26
26
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
27
+ import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
27
28
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
28
29
import org.jetbrains.kotlin.name.FqName
29
30
import org.jetbrains.kotlin.name.NameUtils
@@ -784,6 +785,55 @@ open class KotlinUsesExtractor(
784
785
}
785
786
}
786
787
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
787
837
fun useDeclarationParent (
788
838
// The declaration parent according to Kotlin
789
839
dp : IrDeclarationParent ,
@@ -815,8 +865,7 @@ open class KotlinUsesExtractor(
815
865
}
816
866
is IrFunction -> useFunction(dp)
817
867
is IrExternalPackageFragment -> {
818
- // TODO
819
- logger.error(" Unhandled IrExternalPackageFragment" )
868
+ logger.error(" Unable to handle IrExternalPackageFragment as an IrDeclarationParent" )
820
869
null
821
870
}
822
871
else -> {
@@ -1058,7 +1107,7 @@ open class KotlinUsesExtractor(
1058
1107
* in.
1059
1108
*/
1060
1109
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 )
1062
1111
if (parentId == null ) {
1063
1112
logger.error(" Couldn't get parent ID for function label" )
1064
1113
return null
@@ -1355,7 +1404,7 @@ open class KotlinUsesExtractor(
1355
1404
return ids.function.cast<T >()
1356
1405
}
1357
1406
val javaFun = kotlinFunctionToJavaEquivalent(f, noReplace)
1358
- val parentId = useDeclarationParent (javaFun.parent , false , classTypeArgsIncludingOuterClasses, true )
1407
+ val parentId = useDeclarationParentOf (javaFun, false , classTypeArgsIncludingOuterClasses, true )
1359
1408
if (parentId == null ) {
1360
1409
logger.error(" Couldn't find parent ID for function ${f.name.asString()} " )
1361
1410
return null
@@ -1662,7 +1711,7 @@ open class KotlinUsesExtractor(
1662
1711
val overriddenParentAttributes = (declarationParent as ? IrFunction )?.let {
1663
1712
(this as ? KotlinFileExtractor )?.declarationStack?.findOverriddenAttributes(it)
1664
1713
}
1665
- val parentId = parent ? : overriddenParentAttributes?.id ? : useDeclarationParent(declarationParent , false )
1714
+ val parentId = parent ? : overriddenParentAttributes?.id ? : useDeclarationParentOf(vp , false )
1666
1715
1667
1716
val idxBase = overriddenParentAttributes?.valueParameters?.indexOf(vp) ? : vp.index
1668
1717
val idxOffset = if (declarationParent is IrFunction && declarationParent.extensionReceiverParameter != null )
@@ -1707,7 +1756,7 @@ open class KotlinUsesExtractor(
1707
1756
}
1708
1757
1709
1758
fun getFieldLabel (f : IrField ): String {
1710
- val parentId = useDeclarationParent(getFieldParent(f) , false )
1759
+ val parentId = useDeclarationParentOf(f , false )
1711
1760
// Distinguish backing fields of properties based on their extension receiver type;
1712
1761
// otherwise two extension properties declared in the same enclosing context will get
1713
1762
// clashing trap labels. These are always private, so we can just make up a label without
@@ -1720,7 +1769,7 @@ open class KotlinUsesExtractor(
1720
1769
tw.getLabelFor<DbField >(getFieldLabel(f)).also { extractFieldLaterIfExternalFileMember(f) }
1721
1770
1722
1771
fun getPropertyLabel (p : IrProperty ): String? {
1723
- val parentId = useDeclarationParent(p.parent , false )
1772
+ val parentId = useDeclarationParentOf(p , false )
1724
1773
if (parentId == null ) {
1725
1774
return null
1726
1775
} else {
@@ -1752,15 +1801,15 @@ open class KotlinUsesExtractor(
1752
1801
}
1753
1802
1754
1803
fun getEnumEntryLabel (ee : IrEnumEntry ): String {
1755
- val parentId = useDeclarationParent (ee.parent , false )
1804
+ val parentId = useDeclarationParentOf (ee, false )
1756
1805
return " @\" field;{$parentId };${ee.name.asString()} \" "
1757
1806
}
1758
1807
1759
1808
fun useEnumEntry (ee : IrEnumEntry ): Label <out DbField > =
1760
1809
tw.getLabelFor(getEnumEntryLabel(ee))
1761
1810
1762
1811
fun getTypeAliasLabel (ta : IrTypeAlias ): String {
1763
- val parentId = useDeclarationParent (ta.parent , true )
1812
+ val parentId = useDeclarationParentOf (ta, true )
1764
1813
return " @\" type_alias;{$parentId };${ta.name.asString()} \" "
1765
1814
}
1766
1815
0 commit comments