Skip to content

Commit 72af8ac

Browse files
committed
Kotlin: Switch to useDeclarationParentOf
This lets us handle Kotlin 2 declarations whose parent is an IrExternalPackageFragment, indicating that they are in a (multi)file class.
1 parent 4f33682 commit 72af8ac

File tree

2 files changed

+66
-17
lines changed

2 files changed

+66
-17
lines changed

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ open class KotlinFileExtractor(
192192
}
193193
}
194194
is IrFunction -> {
195-
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
195+
val parentId = useDeclarationParentOf(declaration, false)?.cast<DbReftype>()
196196
if (parentId != null) {
197197
extractFunction(declaration, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, extractAnnotations = extractAnnotations, null, listOf())
198198
}
@@ -202,21 +202,21 @@ open class KotlinFileExtractor(
202202
// Leaving this intentionally empty. init blocks are extracted during class extraction.
203203
}
204204
is IrProperty -> {
205-
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
205+
val parentId = useDeclarationParentOf(declaration, false)?.cast<DbReftype>()
206206
if (parentId != null) {
207207
extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, extractAnnotations = extractAnnotations, null, listOf())
208208
}
209209
Unit
210210
}
211211
is IrEnumEntry -> {
212-
val parentId = useDeclarationParent(declaration.parent, false)?.cast<DbReftype>()
212+
val parentId = useDeclarationParentOf(declaration, false)?.cast<DbReftype>()
213213
if (parentId != null) {
214214
extractEnumEntry(declaration, parentId, extractPrivateMembers, extractFunctionBodies)
215215
}
216216
Unit
217217
}
218218
is IrField -> {
219-
val parentId = useDeclarationParent(getFieldParent(declaration), false)?.cast<DbReftype>()
219+
val parentId = useDeclarationParentOf(declaration, false)?.cast<DbReftype>()
220220
if (parentId != null) {
221221
// For consistency with the Java extractor, enum entries get type accesses only if we're extracting from .kt source (i.e., when `extractFunctionBodies` is set)
222222
extractField(declaration, parentId, extractAnnotationEnumTypeAccesses = extractFunctionBodies)
@@ -1286,7 +1286,7 @@ open class KotlinFileExtractor(
12861286
val sourceParentId =
12871287
maybeSourceParentId ?:
12881288
if (typeSubstitution != null)
1289-
useDeclarationParent(f.parent, false)
1289+
useDeclarationParentOf(f, false)
12901290
else
12911291
parentId
12921292
if (sourceParentId == null) {
@@ -1618,7 +1618,7 @@ open class KotlinFileExtractor(
16181618
}
16191619

16201620
if (bf != null && extractBackingField) {
1621-
val fieldParentId = useDeclarationParent(getFieldParent(bf), false)
1621+
val fieldParentId = useDeclarationParentOf(bf, false)
16221622
if (fieldParentId != null) {
16231623
val fieldId = extractField(bf, fieldParentId.cast(), extractFunctionBodies)
16241624
tw.writeKtPropertyBackingFields(id, fieldId)
@@ -2092,7 +2092,7 @@ open class KotlinFileExtractor(
20922092

20932093
private fun getDefaultsMethodLabel(f: IrFunction): Label<out DbCallable>? {
20942094
val classTypeArgsIncludingOuterClasses = null
2095-
val parentId = useDeclarationParent(f.parent, false, classTypeArgsIncludingOuterClasses, true)
2095+
val parentId = useDeclarationParentOf(f, false, classTypeArgsIncludingOuterClasses, true)
20962096
if (parentId == null) {
20972097
logger.errorElement("Couldn't get parent ID for defaults method", f)
20982098
return null
@@ -3863,7 +3863,7 @@ open class KotlinFileExtractor(
38633863
val type = useType(pluginContext.irBuiltIns.unitType)
38643864
val locId = tw.getLocation(e)
38653865
val parentClass = irConstructor.parentAsClass
3866-
val parentId = useDeclarationParent(parentClass, false, null, true)
3866+
val parentId = useDeclarationParentOf(irConstructor, false, null, true)
38673867
if (parentId == null) {
38683868
logger.errorElement("Cannot get parent ID for obinit", e)
38693869
return

java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
2424
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
2525
import org.jetbrains.kotlin.load.java.structure.*
2626
import org.jetbrains.kotlin.load.java.typeEnhancement.hasEnhancedNullability
27+
import org.jetbrains.kotlin.load.kotlin.FacadeClassSource
2728
import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor
2829
import org.jetbrains.kotlin.name.FqName
2930
import 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

Comments
 (0)