@@ -85,6 +85,10 @@ open class KotlinFileExtractor(
85
85
file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true , extractFunctionBodies = true ) }
86
86
extractStaticInitializer(file, null )
87
87
CommentExtractor (this , file, tw.fileId).extract()
88
+
89
+ if (! declarationStack.isEmpty()) {
90
+ logger.errorElement(" Declaration stack is not empty after processing the file" , file)
91
+ }
88
92
}
89
93
}
90
94
@@ -306,7 +310,7 @@ open class KotlinFileExtractor(
306
310
}
307
311
}.firstOrNull { it != null } ? : false )
308
312
309
- extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf ())
313
+ extractEnclosingClass(c.parent , id, c , locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf ())
310
314
311
315
return id
312
316
}
@@ -415,7 +419,7 @@ open class KotlinFileExtractor(
415
419
val locId = tw.getLocation(c)
416
420
tw.writeHasLocation(id, locId)
417
421
418
- extractEnclosingClass(c, id, locId, listOf ())
422
+ extractEnclosingClass(c.parent , id, c , locId, listOf ())
419
423
420
424
val javaClass = (c.source as ? JavaSourceElement )?.javaElement as ? JavaClass
421
425
@@ -522,10 +526,15 @@ open class KotlinFileExtractor(
522
526
}
523
527
}
524
528
525
- // If `parentClassTypeArguments` is null, the parent class is a raw type.
526
- private fun extractEnclosingClass (innerDeclaration : IrDeclaration , innerId : Label <out DbClassorinterface >, innerLocId : Label <DbLocation >, parentClassTypeArguments : List <IrTypeArgument >? ) {
527
- with (" enclosing class" , innerDeclaration) {
528
- var parent: IrDeclarationParent ? = innerDeclaration.parent
529
+ private fun extractEnclosingClass (
530
+ declarationParent : IrDeclarationParent , // The declaration parent if the element for which we are extracting the enclosing class
531
+ innerId : Label <out DbClassorinterface >, // ID of the inner class
532
+ innerClass : IrClass ? , // The inner class, if available. It's not available if the enclosing class of a generated class is being extracted
533
+ innerLocId : Label <DbLocation >, // Location of the inner class
534
+ parentClassTypeArguments : List <IrTypeArgument >? // Type arguments of the parent class. If `parentClassTypeArguments` is null, the parent class is a raw type
535
+ ) {
536
+ with (" enclosing class" , declarationParent) {
537
+ var parent: IrDeclarationParent ? = declarationParent
529
538
while (parent != null ) {
530
539
if (parent is IrClass ) {
531
540
val parentId =
@@ -535,13 +544,13 @@ open class KotlinFileExtractor(
535
544
useClassInstance(parent, parentClassTypeArguments).typeResult.id
536
545
}
537
546
tw.writeEnclInReftype(innerId, parentId)
538
- if (innerDeclaration is IrClass && innerDeclaration .isCompanion) {
547
+ if (innerClass is IrClass && innerClass .isCompanion) {
539
548
// If we are a companion then our parent has a
540
549
// public static final ParentClass$CompanionObjectClass CompanionObjectName;
541
550
// that we need to fabricate here
542
- val instance = useCompanionObjectClassInstance(innerDeclaration )
551
+ val instance = useCompanionObjectClassInstance(innerClass )
543
552
if (instance != null ) {
544
- val type = useSimpleTypeClass(innerDeclaration , emptyList(), false )
553
+ val type = useSimpleTypeClass(innerClass , emptyList(), false )
545
554
tw.writeFields(instance.id, instance.name, type.javaResult.id, parentId, instance.id)
546
555
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
547
556
tw.writeHasLocation(instance.id, innerLocId)
@@ -552,7 +561,7 @@ open class KotlinFileExtractor(
552
561
553
562
break
554
563
} else if (parent is IrFile ) {
555
- if (innerDeclaration is IrClass ) {
564
+ if (innerClass is IrClass ) {
556
565
// We don't have to extract file class containers for classes
557
566
break
558
567
}
@@ -2440,9 +2449,6 @@ open class KotlinFileExtractor(
2440
2449
}
2441
2450
}
2442
2451
2443
- // todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain
2444
- private val declarationStack: Stack <IrDeclaration > = Stack ()
2445
-
2446
2452
abstract inner class StmtExprParent {
2447
2453
abstract fun stmt (e : IrExpression , callable : Label <out DbCallable >): StmtParent
2448
2454
abstract fun expr (e : IrExpression , callable : Label <out DbCallable >): ExprParent
@@ -3697,12 +3703,12 @@ open class KotlinFileExtractor(
3697
3703
constructorBlock = tw.getFreshIdLabel()
3698
3704
)
3699
3705
3700
- val currentDeclaration = declarationStack.peek ()
3706
+ val declarationParent = declarationStack.peekAsDeclarationParent ()
3701
3707
val prefix = if (kPropertyClass.owner.name.asString().startsWith(" KMutableProperty" )) " Mutable" else " "
3702
3708
val baseClass = pluginContext.referenceClass(FqName (" kotlin.jvm.internal.${prefix} PropertyReference${kPropertyType.arguments.size - 1 } " ))?.owner?.typeWith()
3703
3709
? : pluginContext.irBuiltIns.anyType
3704
3710
3705
- val classId = extractGeneratedClass(ids, listOf (baseClass, kPropertyType), locId, currentDeclaration )
3711
+ val classId = extractGeneratedClass(ids, listOf (baseClass, kPropertyType), locId, propertyReferenceExpr, declarationParent )
3706
3712
3707
3713
val helper = PropertyReferenceHelper (propertyReferenceExpr, locId, ids)
3708
3714
@@ -3904,12 +3910,12 @@ open class KotlinFileExtractor(
3904
3910
if (fnInterfaceType == null ) {
3905
3911
logger.warnElement(" Cannot find functional interface type for function reference" , functionReferenceExpr)
3906
3912
} else {
3907
- val currentDeclaration = declarationStack.peek ()
3913
+ val declarationParent = declarationStack.peekAsDeclarationParent ()
3908
3914
// `FunctionReference` base class is required, because that's implementing `KFunction`.
3909
3915
val baseClass = pluginContext.referenceClass(FqName (" kotlin.jvm.internal.FunctionReference" ))?.owner?.typeWith()
3910
3916
? : pluginContext.irBuiltIns.anyType
3911
3917
3912
- val classId = extractGeneratedClass(ids, listOf (baseClass, fnInterfaceType), locId, currentDeclaration )
3918
+ val classId = extractGeneratedClass(ids, listOf (baseClass, fnInterfaceType), locId, functionReferenceExpr, declarationParent )
3913
3919
3914
3920
helper.extractReceiverField()
3915
3921
@@ -4513,8 +4519,8 @@ open class KotlinFileExtractor(
4513
4519
val locId = tw.getLocation(e)
4514
4520
val helper = GeneratedClassHelper (locId, ids)
4515
4521
4516
- val currentDeclaration = declarationStack.peek ()
4517
- val classId = extractGeneratedClass(ids, listOf (pluginContext.irBuiltIns.anyType, e.typeOperand), locId, currentDeclaration )
4522
+ val declarationParent = declarationStack.peekAsDeclarationParent ()
4523
+ val classId = extractGeneratedClass(ids, listOf (pluginContext.irBuiltIns.anyType, e.typeOperand), locId, e, declarationParent )
4518
4524
4519
4525
// add field
4520
4526
val fieldId = tw.getFreshIdLabel<DbField >()
@@ -4656,7 +4662,8 @@ open class KotlinFileExtractor(
4656
4662
ids : GeneratedClassLabels ,
4657
4663
superTypes : List <IrType >,
4658
4664
locId : Label <DbLocation >,
4659
- currentDeclaration : IrDeclaration
4665
+ elementToReportOn : IrElement ,
4666
+ declarationParent : IrDeclarationParent
4660
4667
): Label <out DbClass > {
4661
4668
// Write class
4662
4669
val id = ids.type.javaResult.id.cast<DbClass >()
@@ -4679,7 +4686,7 @@ open class KotlinFileExtractor(
4679
4686
// Super call
4680
4687
val baseClass = superTypes.first().classOrNull
4681
4688
if (baseClass == null ) {
4682
- logger.warnElement(" Cannot find base class" , currentDeclaration )
4689
+ logger.warnElement(" Cannot find base class" , elementToReportOn )
4683
4690
} else {
4684
4691
val baseConstructor = baseClass.owner.declarations.findSubType<IrFunction > { it.symbol is IrConstructorSymbol }
4685
4692
if (baseConstructor == null ) {
@@ -4699,7 +4706,7 @@ open class KotlinFileExtractor(
4699
4706
addVisibilityModifierToLocalOrAnonymousClass(id)
4700
4707
extractClassSupertypes(superTypes, listOf (), id, inReceiverContext = true )
4701
4708
4702
- extractEnclosingClass(currentDeclaration , id, locId, listOf ())
4709
+ extractEnclosingClass(declarationParent , id, null , locId, listOf ())
4703
4710
4704
4711
return id
4705
4712
}
@@ -4711,7 +4718,7 @@ open class KotlinFileExtractor(
4711
4718
with (" generated class" , localFunction) {
4712
4719
val ids = getLocallyVisibleFunctionLabels(localFunction)
4713
4720
4714
- val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction)
4721
+ val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent )
4715
4722
4716
4723
// Extract local function as a member
4717
4724
extractFunction(localFunction, id, extractBody = true , extractMethodAndParameterTypeAccesses = true , null , listOf ())
@@ -4720,6 +4727,30 @@ open class KotlinFileExtractor(
4720
4727
}
4721
4728
}
4722
4729
4730
+ // todo: calculating the enclosing ref type could be done through this, instead of walking up the declaration parent chain
4731
+ private val declarationStack = DeclarationStack ()
4732
+
4733
+ private inner class DeclarationStack {
4734
+ private val stack: Stack <IrDeclaration > = Stack ()
4735
+
4736
+ fun push (item : IrDeclaration ) = stack.push(item)
4737
+
4738
+ fun pop () = stack.pop()
4739
+
4740
+ fun isEmpty () = stack.isEmpty()
4741
+
4742
+ fun peek () = stack.peek()
4743
+
4744
+ fun peekAsDeclarationParent (): IrDeclarationParent {
4745
+ val trapWriter = tw
4746
+ if (isEmpty() && trapWriter is SourceFileTrapWriter ) {
4747
+ // If the current declaration is used as a parent, we might end up with an empty stack. In this case, the source file is the parent.
4748
+ return trapWriter.irFile
4749
+ }
4750
+
4751
+ return peek() as IrDeclarationParent
4752
+ }
4753
+ }
4723
4754
4724
4755
private inner class DeclarationStackAdjuster (declaration : IrDeclaration ): Closeable {
4725
4756
init {
0 commit comments