IR: do not copy calls/references in ExpectSymbolTransformer
This is just a refactoring/optimization that makes use of the fact that IrCall.symbol and other similar fields are now mutable.
This commit is contained in:
committed by
Space Team
parent
978553c513
commit
bb4d25dfc9
@@ -115,9 +115,8 @@ fun generateIrForKlibSerialization(
|
||||
}
|
||||
|
||||
if (configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER) != true) {
|
||||
moduleFragment.transform(ExpectDeclarationRemover(psi2IrContext.symbolTable, false), null)
|
||||
moduleFragment.accept(ExpectDeclarationRemover(psi2IrContext.symbolTable, false), null)
|
||||
}
|
||||
|
||||
return moduleFragment to pluginContext
|
||||
}
|
||||
|
||||
|
||||
+36
-91
@@ -13,21 +13,18 @@ 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
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.util.copyTypeAndValueArgumentsFrom
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
|
||||
/**
|
||||
* [ExpectSymbolTransformer] replaces `expect` symbols in expressions with `actual` symbols. An `actual` symbol must be provided by
|
||||
* overriding [getActualClass], [getActualProperty], [getActualConstructor], and [getActualFunction].
|
||||
*/
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
abstract class ExpectSymbolTransformer : IrElementVisitorVoid {
|
||||
|
||||
protected abstract fun getActualClass(descriptor: ClassDescriptor): IrClassSymbol?
|
||||
|
||||
@@ -49,112 +46,60 @@ abstract class ExpectSymbolTransformer : IrElementTransformerVoid() {
|
||||
*/
|
||||
protected open fun isTargetDeclaration(declaration: IrDeclaration): Boolean = declaration.isExpect
|
||||
|
||||
override fun visitElement(element: IrElement): IrElement {
|
||||
element.transformChildrenVoid()
|
||||
return element
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptChildren(this, null)
|
||||
}
|
||||
|
||||
override fun visitConstructorCall(expression: IrConstructorCall): IrExpression {
|
||||
val nExpression = super.visitConstructorCall(expression) as IrConstructorCall
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
override fun visitConstructorCall(expression: IrConstructorCall) {
|
||||
super.visitConstructorCall(expression)
|
||||
if (!isTargetDeclaration(expression.symbol.owner)) return
|
||||
|
||||
val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
return IrConstructorCallImpl(
|
||||
startOffset, endOffset, type, newCallee, typeArgumentsCount, constructorTypeArgumentsCount, valueArgumentsCount, origin
|
||||
).also {
|
||||
it.attributeOwnerId = attributeOwnerId
|
||||
it.copyTypeAndValueArgumentsFrom(nExpression)
|
||||
}
|
||||
}
|
||||
expression.symbol = getActualConstructor(expression.symbol.descriptor) ?: return
|
||||
}
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||
val nExpression = super.visitDelegatingConstructorCall(expression) as IrDelegatingConstructorCall
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
|
||||
super.visitDelegatingConstructorCall(expression)
|
||||
if (!isTargetDeclaration(expression.symbol.owner)) return
|
||||
|
||||
val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
return IrDelegatingConstructorCallImpl(
|
||||
startOffset, endOffset, type, newCallee, typeArgumentsCount, valueArgumentsCount
|
||||
).also {
|
||||
it.attributeOwnerId = attributeOwnerId
|
||||
it.copyTypeAndValueArgumentsFrom(nExpression)
|
||||
}
|
||||
}
|
||||
expression.symbol = getActualConstructor(expression.symbol.descriptor) ?: return
|
||||
}
|
||||
|
||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrExpression {
|
||||
val nExpression = super.visitEnumConstructorCall(expression) as IrEnumConstructorCall
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall) {
|
||||
super.visitEnumConstructorCall(expression)
|
||||
if (!isTargetDeclaration(expression.symbol.owner)) return
|
||||
|
||||
val newCallee = getActualConstructor(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
return IrEnumConstructorCallImpl(
|
||||
startOffset, endOffset, type, newCallee, typeArgumentsCount, valueArgumentsCount
|
||||
).also {
|
||||
it.attributeOwnerId = attributeOwnerId
|
||||
it.copyTypeAndValueArgumentsFrom(nExpression)
|
||||
}
|
||||
}
|
||||
expression.symbol = getActualConstructor(expression.symbol.descriptor) ?: return
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
val nExpression = super.visitCall(expression) as IrCall
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
override fun visitCall(expression: IrCall) {
|
||||
super.visitCall(expression)
|
||||
if (!isTargetDeclaration(expression.symbol.owner)) return
|
||||
|
||||
val newCallee = getActualFunction(nExpression.symbol.descriptor) ?: return nExpression
|
||||
return irCall(nExpression, newCallee).also {
|
||||
it.attributeOwnerId = nExpression.attributeOwnerId
|
||||
}
|
||||
expression.symbol = getActualFunction(expression.symbol.descriptor) ?: return
|
||||
}
|
||||
|
||||
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression {
|
||||
val nExpression = super.visitPropertyReference(expression) as IrPropertyReference
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
override fun visitPropertyReference(expression: IrPropertyReference) {
|
||||
super.visitPropertyReference(expression)
|
||||
if (!isTargetDeclaration(expression.symbol.owner)) return
|
||||
|
||||
val (newSymbol, newGetter, newSetter) = getActualProperty(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
return IrPropertyReferenceImpl(
|
||||
startOffset, endOffset, type,
|
||||
newSymbol, typeArgumentsCount,
|
||||
field, newGetter, newSetter,
|
||||
origin
|
||||
).also {
|
||||
it.attributeOwnerId = attributeOwnerId
|
||||
copyTypeArgumentsFrom(nExpression)
|
||||
it.dispatchReceiver = dispatchReceiver
|
||||
it.extensionReceiver = extensionReceiver
|
||||
}
|
||||
}
|
||||
val (newSymbol, newGetter, newSetter) = getActualProperty(expression.symbol.descriptor) ?: return
|
||||
expression.symbol = newSymbol
|
||||
expression.getter = newGetter
|
||||
expression.setter = newSetter
|
||||
}
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
|
||||
val nExpression = super.visitFunctionReference(expression) as IrFunctionReference
|
||||
if (!isTargetDeclaration(nExpression.symbol.owner)) return nExpression
|
||||
override fun visitFunctionReference(expression: IrFunctionReference) {
|
||||
super.visitFunctionReference(expression)
|
||||
if (!isTargetDeclaration(expression.symbol.owner)) return
|
||||
|
||||
val newCallee = getActualFunction(nExpression.symbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
return IrFunctionReferenceImpl(
|
||||
startOffset, endOffset, type, newCallee, typeArgumentsCount, valueArgumentsCount, reflectionTarget, origin
|
||||
).also {
|
||||
it.attributeOwnerId = attributeOwnerId
|
||||
it.copyTypeArgumentsFrom(nExpression)
|
||||
it.dispatchReceiver = dispatchReceiver
|
||||
it.extensionReceiver = extensionReceiver
|
||||
}
|
||||
}
|
||||
expression.symbol = getActualFunction(expression.symbol.descriptor) ?: return
|
||||
}
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference): IrExpression {
|
||||
val nExpression = super.visitClassReference(expression) as IrClassReference
|
||||
val oldSymbol = nExpression.symbol as? IrClassSymbol ?: return nExpression
|
||||
if (!isTargetDeclaration(oldSymbol.owner)) return nExpression
|
||||
override fun visitClassReference(expression: IrClassReference) {
|
||||
super.visitClassReference(expression)
|
||||
val oldSymbol = expression.symbol as? IrClassSymbol ?: return
|
||||
if (!isTargetDeclaration(oldSymbol.owner)) return
|
||||
|
||||
val newSymbol = getActualClass(oldSymbol.descriptor) ?: return nExpression
|
||||
with(nExpression) {
|
||||
return IrClassReferenceImpl(startOffset, endOffset, type, newSymbol, classType)
|
||||
}
|
||||
expression.symbol = getActualClass(oldSymbol.descriptor) ?: return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-8
@@ -9,13 +9,14 @@ import org.jetbrains.kotlin.backend.common.BackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.ir.ExpectSymbolTransformer
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.extractTypeParameters
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
@@ -27,8 +28,8 @@ import kotlin.collections.set
|
||||
|
||||
// `doRemove` means should expect-declaration be removed from IR
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private val doRemove: Boolean)
|
||||
: ExpectSymbolTransformer(), FileLoweringPass {
|
||||
open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, private val doRemove: Boolean) : ExpectSymbolTransformer(),
|
||||
FileLoweringPass {
|
||||
|
||||
constructor(context: BackendContext) : this(context.ir.symbols.externalSymbolTable, true)
|
||||
|
||||
@@ -38,16 +39,16 @@ open class ExpectDeclarationRemover(val symbolTable: ReferenceSymbolTable, priva
|
||||
visitFile(irFile)
|
||||
}
|
||||
|
||||
override fun visitFile(declaration: IrFile): IrFile {
|
||||
override fun visitFile(declaration: IrFile) {
|
||||
if (doRemove) {
|
||||
declaration.declarations.removeAll { shouldRemoveTopLevelDeclaration(it) }
|
||||
}
|
||||
return super.visitFile(declaration)
|
||||
super.visitFile(declaration)
|
||||
}
|
||||
|
||||
override fun visitValueParameter(declaration: IrValueParameter): IrStatement {
|
||||
override fun visitValueParameter(declaration: IrValueParameter) {
|
||||
tryCopyDefaultArguments(declaration)
|
||||
return super.visitValueParameter(declaration)
|
||||
super.visitValueParameter(declaration)
|
||||
}
|
||||
|
||||
fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
|
||||
Reference in New Issue
Block a user