@@ -85,6 +85,10 @@ open class KotlinFileExtractor(
8585 file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true , extractFunctionBodies = true ) }
8686 extractStaticInitializer(file, null )
8787 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+ }
8892 }
8993 }
9094
@@ -306,7 +310,7 @@ open class KotlinFileExtractor(
306310 }
307311 }.firstOrNull { it != null } ? : false )
308312
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 ())
310314
311315 return id
312316 }
@@ -415,7 +419,7 @@ open class KotlinFileExtractor(
415419 val locId = tw.getLocation(c)
416420 tw.writeHasLocation(id, locId)
417421
418- extractEnclosingClass(c, id, locId, listOf ())
422+ extractEnclosingClass(c.parent , id, c , locId, listOf ())
419423
420424 val javaClass = (c.source as ? JavaSourceElement )?.javaElement as ? JavaClass
421425
@@ -522,10 +526,15 @@ open class KotlinFileExtractor(
522526 }
523527 }
524528
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
529538 while (parent != null ) {
530539 if (parent is IrClass ) {
531540 val parentId =
@@ -535,13 +544,13 @@ open class KotlinFileExtractor(
535544 useClassInstance(parent, parentClassTypeArguments).typeResult.id
536545 }
537546 tw.writeEnclInReftype(innerId, parentId)
538- if (innerDeclaration is IrClass && innerDeclaration .isCompanion) {
547+ if (innerClass is IrClass && innerClass .isCompanion) {
539548 // If we are a companion then our parent has a
540549 // public static final ParentClass$CompanionObjectClass CompanionObjectName;
541550 // that we need to fabricate here
542- val instance = useCompanionObjectClassInstance(innerDeclaration )
551+ val instance = useCompanionObjectClassInstance(innerClass )
543552 if (instance != null ) {
544- val type = useSimpleTypeClass(innerDeclaration , emptyList(), false )
553+ val type = useSimpleTypeClass(innerClass , emptyList(), false )
545554 tw.writeFields(instance.id, instance.name, type.javaResult.id, parentId, instance.id)
546555 tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
547556 tw.writeHasLocation(instance.id, innerLocId)
@@ -552,7 +561,7 @@ open class KotlinFileExtractor(
552561
553562 break
554563 } else if (parent is IrFile ) {
555- if (innerDeclaration is IrClass ) {
564+ if (innerClass is IrClass ) {
556565 // We don't have to extract file class containers for classes
557566 break
558567 }
@@ -2440,9 +2449,6 @@ open class KotlinFileExtractor(
24402449 }
24412450 }
24422451
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-
24462452 abstract inner class StmtExprParent {
24472453 abstract fun stmt (e : IrExpression , callable : Label <out DbCallable >): StmtParent
24482454 abstract fun expr (e : IrExpression , callable : Label <out DbCallable >): ExprParent
@@ -3697,12 +3703,12 @@ open class KotlinFileExtractor(
36973703 constructorBlock = tw.getFreshIdLabel()
36983704 )
36993705
3700- val currentDeclaration = declarationStack.peek ()
3706+ val declarationParent = declarationStack.peekAsDeclarationParent ()
37013707 val prefix = if (kPropertyClass.owner.name.asString().startsWith(" KMutableProperty" )) " Mutable" else " "
37023708 val baseClass = pluginContext.referenceClass(FqName (" kotlin.jvm.internal.${prefix} PropertyReference${kPropertyType.arguments.size - 1 } " ))?.owner?.typeWith()
37033709 ? : pluginContext.irBuiltIns.anyType
37043710
3705- val classId = extractGeneratedClass(ids, listOf (baseClass, kPropertyType), locId, currentDeclaration )
3711+ val classId = extractGeneratedClass(ids, listOf (baseClass, kPropertyType), locId, propertyReferenceExpr, declarationParent )
37063712
37073713 val helper = PropertyReferenceHelper (propertyReferenceExpr, locId, ids)
37083714
@@ -3904,12 +3910,12 @@ open class KotlinFileExtractor(
39043910 if (fnInterfaceType == null ) {
39053911 logger.warnElement(" Cannot find functional interface type for function reference" , functionReferenceExpr)
39063912 } else {
3907- val currentDeclaration = declarationStack.peek ()
3913+ val declarationParent = declarationStack.peekAsDeclarationParent ()
39083914 // `FunctionReference` base class is required, because that's implementing `KFunction`.
39093915 val baseClass = pluginContext.referenceClass(FqName (" kotlin.jvm.internal.FunctionReference" ))?.owner?.typeWith()
39103916 ? : pluginContext.irBuiltIns.anyType
39113917
3912- val classId = extractGeneratedClass(ids, listOf (baseClass, fnInterfaceType), locId, currentDeclaration )
3918+ val classId = extractGeneratedClass(ids, listOf (baseClass, fnInterfaceType), locId, functionReferenceExpr, declarationParent )
39133919
39143920 helper.extractReceiverField()
39153921
@@ -4513,8 +4519,8 @@ open class KotlinFileExtractor(
45134519 val locId = tw.getLocation(e)
45144520 val helper = GeneratedClassHelper (locId, ids)
45154521
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 )
45184524
45194525 // add field
45204526 val fieldId = tw.getFreshIdLabel<DbField >()
@@ -4656,7 +4662,8 @@ open class KotlinFileExtractor(
46564662 ids : GeneratedClassLabels ,
46574663 superTypes : List <IrType >,
46584664 locId : Label <DbLocation >,
4659- currentDeclaration : IrDeclaration
4665+ elementToReportOn : IrElement ,
4666+ declarationParent : IrDeclarationParent
46604667 ): Label <out DbClass > {
46614668 // Write class
46624669 val id = ids.type.javaResult.id.cast<DbClass >()
@@ -4679,7 +4686,7 @@ open class KotlinFileExtractor(
46794686 // Super call
46804687 val baseClass = superTypes.first().classOrNull
46814688 if (baseClass == null ) {
4682- logger.warnElement(" Cannot find base class" , currentDeclaration )
4689+ logger.warnElement(" Cannot find base class" , elementToReportOn )
46834690 } else {
46844691 val baseConstructor = baseClass.owner.declarations.findSubType<IrFunction > { it.symbol is IrConstructorSymbol }
46854692 if (baseConstructor == null ) {
@@ -4699,7 +4706,7 @@ open class KotlinFileExtractor(
46994706 addVisibilityModifierToLocalOrAnonymousClass(id)
47004707 extractClassSupertypes(superTypes, listOf (), id, inReceiverContext = true )
47014708
4702- extractEnclosingClass(currentDeclaration , id, locId, listOf ())
4709+ extractEnclosingClass(declarationParent , id, null , locId, listOf ())
47034710
47044711 return id
47054712 }
@@ -4711,7 +4718,7 @@ open class KotlinFileExtractor(
47114718 with (" generated class" , localFunction) {
47124719 val ids = getLocallyVisibleFunctionLabels(localFunction)
47134720
4714- val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction)
4721+ val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction, localFunction.parent )
47154722
47164723 // Extract local function as a member
47174724 extractFunction(localFunction, id, extractBody = true , extractMethodAndParameterTypeAccesses = true , null , listOf ())
@@ -4720,6 +4727,30 @@ open class KotlinFileExtractor(
47204727 }
47214728 }
47224729
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+ }
47234754
47244755 private inner class DeclarationStackAdjuster (declaration : IrDeclaration ): Closeable {
47254756 init {
0 commit comments