[JVM IR] KTIJ-24206 Stub getters/setters of orphaned expect properties
- Property getters and setters are not marked as `isExpect` even if the corresponding property is. This commit fixes the generation of actual stubs for such functions.
This commit is contained in:
committed by
Space Team
parent
c9461a3827
commit
ba2e716682
+14
-7
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
@@ -42,6 +43,12 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
protected abstract fun getActualFunction(descriptor: FunctionDescriptor): IrSimpleFunctionSymbol?
|
||||
|
||||
/**
|
||||
* [isTargetDeclaration] can be overridden to customize if an element referring to [declaration] should be transformed. This check
|
||||
* precedes [getActualClass], [getActualProperty], and so on.
|
||||
*/
|
||||
protected open fun isTargetDeclaration(declaration: IrDeclaration): Boolean = declaration.isExpect
|
||||
|
||||
override fun visitElement(element: IrElement): IrElement {
|
||||
element.transformChildrenVoid()
|
||||
return element
|
||||
@@ -49,7 +56,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
val nExpression = super.visitConstructorCall(expression) as IrConstructorCall
|
||||
if (!nExpression.symbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
|
||||
val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
@@ -64,7 +71,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||
val nExpression = super.visitDelegatingConstructorCall(expression) as IrDelegatingConstructorCall
|
||||
if (!nExpression.symbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
|
||||
val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
@@ -79,7 +86,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
|
||||
val nExpression = super.visitEnumConstructorCall(expression) as IrEnumConstructorCall
|
||||
if (!nExpression.symbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
|
||||
val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
@@ -94,7 +101,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val nExpression = super.visitCall(expression) as IrCall
|
||||
if (!nExpression.symbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
|
||||
val newCallee = getActualFunction(nExpression.symbol.descriptor) ?: return nExpression
|
||||
return irCall(nExpression, newCallee).also {
|
||||
@@ -104,7 +111,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression {
|
||||
val nExpression = super.visitPropertyReference(expression) as IrPropertyReference
|
||||
if (!nExpression.symbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
|
||||
val (newSymbol, newGetter, newSetter) = getActualProperty(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
@@ -124,7 +131,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
val nExpression = super.visitFunctionReference(expression) as IrFunctionReference
|
||||
if (!nExpression.symbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
|
||||
val newCallee = getActualFunction(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
@@ -142,7 +149,7 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
override fun visitClassReference(expression: IrClassReference): IrExpression {
|
||||
val nExpression = super.visitClassReference(expression) as IrClassReference
|
||||
val oldSymbol = nExpression.symbol as? IrClassSymbol ?: return nExpression
|
||||
if (!oldSymbol.owner.isExpect) return nExpression
|
||||
if (!isTargetDeclaration(oldSymbol.owner)) return nExpression
|
||||
|
||||
val newSymbol = getActualClass(oldSymbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
|
||||
+9
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
@@ -77,6 +78,14 @@ private class StubOrphanedExpectSymbolTransformer(val stubGenerator: Declaration
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Property getters and setters are not marked as `isExpect` even if the corresponding property is. However, we still need to stub such
|
||||
* getters and setters, so [isTargetDeclaration] allows it.
|
||||
*/
|
||||
override fun isTargetDeclaration(declaration: IrDeclaration): Boolean =
|
||||
super.isTargetDeclaration(declaration) ||
|
||||
declaration is IrSimpleFunction && declaration.correspondingPropertySymbol?.owner?.isExpect == true
|
||||
|
||||
/**
|
||||
* If an `actual` symbol exists, we shouldn't stub the `expect` symbol. This will be performed by
|
||||
* [org.jetbrains.kotlin.backend.common.lower.ExpectDeclarationsRemoveLowering] during lowering.
|
||||
|
||||
Reference in New Issue
Block a user