IR: remove unnecessary calls to deepCopyWithSymbols

to make it harder to hide incorrect uses.
This commit is contained in:
pyos
2020-10-13 14:33:24 +02:00
committed by Alexander Udalov
parent 45a0850d95
commit 13def12731
14 changed files with 94 additions and 108 deletions
@@ -149,7 +149,7 @@ fun IrValueParameter.copyTo(
descriptor.bind(it)
it.parent = irFunction
it.defaultValue = defaultValueCopy
it.annotations = annotations.map { it.deepCopyWithSymbols() }
it.copyAnnotationsFrom(this)
}
}
@@ -229,6 +229,10 @@ private fun IrTypeParameter.copySuperTypesFrom(source: IrTypeParameter, srcToDst
}
}
fun IrMutableAnnotationContainer.copyAnnotationsFrom(source: IrAnnotationContainer) {
annotations += source.annotations.map { it.deepCopyWithSymbols(this as? IrDeclarationParent) }
}
// Copy value parameters, dispatch receiver, and extension receiver from source to value parameters of this function.
// Type of dispatch receiver defaults to source's dispatch receiver. It is overridable in case the new function and the old one are used in
// different contexts and expect different type of dispatch receivers. The overriding type should be assign compatible to the old type.
@@ -606,7 +606,7 @@ private fun IrFunction.generateDefaultsFunctionImpl(
}
// TODO some annotations are needed (e.g. @JvmStatic), others need different values (e.g. @JvmName), the rest are redundant.
newFunction.annotations = annotations.map { it.deepCopyWithSymbols() }
newFunction.copyAnnotationsFrom(this)
return newFunction
}
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -260,20 +259,20 @@ private class Transformer(
additionalStatements.addIfNotNull(lowerVar)
additionalStatements.addIfNotNull(upperVar)
}
lowerExpression = tmpLowerExpression
upperExpression = tmpUpperExpression
lowerExpression = tmpLowerExpression.copy()
upperExpression = tmpUpperExpression.copy()
useLowerClauseOnLeftSide = true
} else if (lower.canHaveSideEffects && upper.canHaveSideEffects) {
if (shouldUpperComeFirst) {
val (upperVar, tmpUpperExpression) = createTemporaryVariableIfNecessary(upper, "containsUpper")
additionalStatements.add(upperVar!!)
lowerExpression = lower
upperExpression = tmpUpperExpression
upperExpression = tmpUpperExpression.copy()
useLowerClauseOnLeftSide = true
} else {
val (lowerVar, tmpLowerExpression) = createTemporaryVariableIfNecessary(lower, "containsLower")
additionalStatements.add(lowerVar!!)
lowerExpression = tmpLowerExpression
lowerExpression = tmpLowerExpression.copy()
upperExpression = upper
useLowerClauseOnLeftSide = false
}
@@ -309,27 +308,27 @@ private class Transformer(
irCall(lowerCompFun).apply {
putValueArgument(0, irInt(0))
putValueArgument(1, irCall(compareToFun).apply {
dispatchReceiver = argExpression
dispatchReceiver = argExpression.copy()
putValueArgument(0, lowerExpression)
})
}
} else {
irCall(lowerCompFun).apply {
putValueArgument(0, lowerExpression)
putValueArgument(1, argExpression)
putValueArgument(1, argExpression.copy())
}
}
val upperClause = if (useCompareTo) {
irCall(upperCompFun).apply {
putValueArgument(0, irCall(compareToFun).apply {
dispatchReceiver = argExpression.deepCopyWithSymbols()
dispatchReceiver = argExpression.copy()
putValueArgument(0, upperExpression)
})
putValueArgument(1, irInt(0))
}
} else {
irCall(upperCompFun).apply {
putValueArgument(0, argExpression.deepCopyWithSymbols())
putValueArgument(0, argExpression.copy())
putValueArgument(1, upperExpression)
}
}
@@ -13,15 +13,13 @@ import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrLoop
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrWhileLoopImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.util.OperatorNameConventions
/**
@@ -68,14 +66,13 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
val inductionVariable: IrVariable
protected val stepVariable: IrVariable?
val stepExpression: IrExpression
// Always copy `stepExpression` is it may be used multiple times.
get() = field.deepCopyWithSymbols()
val stepExpression: IrExpressionWithCopy
protected val lastVariableIfCanCacheLast: IrVariable?
protected val lastExpression: IrExpression
// Always copy `lastExpression` is it may be used in multiple conditions.
get() = field.deepCopyWithSymbols()
// If this is not `IrExpressionWithCopy`, then it is `<IrGetValue>.getSize()` built in `IndexedGetIterationHandler`.
// It is therefore safe to deep-copy as it does not contain any functions or classes.
get() = if (field is IrExpressionWithCopy) field.copy() else field.deepCopyWithSymbols()
protected val symbols = context.ir.symbols
@@ -105,11 +102,14 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
// TODO: Confirm if casting to non-nullable is still necessary
val last = headerInfo.last.asElementType()
lastVariableIfCanCacheLast = if (headerInfo.canCacheLast) {
scope.createTmpVariable(last, nameHint = "last")
} else null
lastExpression = if (headerInfo.canCacheLast) irGet(lastVariableIfCanCacheLast!!) else last
if (headerInfo.canCacheLast) {
val (variable, expression) = createTemporaryVariableIfNecessary(last, nameHint = "last")
lastVariableIfCanCacheLast = variable
lastExpression = expression.copy()
} else {
lastVariableIfCanCacheLast = null
lastExpression = last
}
val (tmpStepVar, tmpStepExpression) =
createTemporaryVariableIfNecessary(
@@ -146,7 +146,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
inductionVariable.symbol, irCallOp(
plusFun.symbol, plusFun.returnType,
irGet(inductionVariable),
stepExpression, IrStatementOrigin.PLUSEQ
stepExpression.copy(), IrStatementOrigin.PLUSEQ
), IrStatementOrigin.PLUSEQ
)
}
@@ -225,14 +225,14 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
context.oror(
context.andand(
irCall(builtIns.greaterFunByOperandType.getValue(stepClass.symbol)).apply {
putValueArgument(0, stepExpression)
putValueArgument(0, stepExpression.copy())
putValueArgument(1, zeroStepExpression())
},
conditionForIncreasing()
),
context.andand(
irCall(builtIns.lessFunByOperandType.getValue(stepClass.symbol)).apply {
putValueArgument(0, stepExpression)
putValueArgument(0, stepExpression.copy())
putValueArgument(1, zeroStepExpression())
},
conditionForDecreasing()
@@ -351,19 +351,17 @@ internal class ProgressionLoopHeader(
}
}
private class InitializerCallReplacer(symbolRemapper: SymbolRemapper, typeRemapper: TypeRemapper, val replacementCall: IrCall) :
DeepCopyIrTreeWithSymbols(symbolRemapper, typeRemapper) {
private class InitializerCallReplacer(val replacementCall: IrCall) : IrElementTransformerVoid() {
var initializerCall: IrCall? = null
override fun visitCall(expression: IrCall): IrCall {
if (initializerCall == null) {
initializerCall = expression
return replacementCall
} else {
if (initializerCall != null) {
throw IllegalStateException(
"Multiple initializer calls found. First: ${initializerCall!!.render()}\nSecond: ${expression.render()}"
)
}
initializerCall = expression
return replacementCall
}
}
@@ -390,9 +388,7 @@ internal class IndexedGetLoopHeader(
}
// The call could be wrapped in an IMPLICIT_NOTNULL type-cast (see comment in ForLoopsLowering.gatherLoopVariableInfo()).
// Find and replace the call to preserve any type-casts.
loopVariable?.initializer = loopVariable?.initializer?.deepCopyWithSymbols { symbolRemapper, typeRemapper ->
InitializerCallReplacer(symbolRemapper, typeRemapper, get)
}
loopVariable?.initializer = loopVariable?.initializer?.transform(InitializerCallReplacer(get), null)
// Even if there is no loop variable, we always want to call `get()` as it may have side-effects.
// The un-lowered loop always calls `get()` on each iteration.
listOf(loopVariable ?: get) + incrementInductionVariable(this)
@@ -589,9 +585,7 @@ internal class IterableLoopHeader(
}
// The call could be wrapped in an IMPLICIT_NOTNULL type-cast (see comment in ForLoopsLowering.gatherLoopVariableInfo()).
// Find and replace the call to preserve any type-casts.
loopVariable?.initializer = loopVariable?.initializer?.deepCopyWithSymbols { symbolRemapper, typeRemapper ->
InitializerCallReplacer(symbolRemapper, typeRemapper, next)
}
loopVariable?.initializer = loopVariable?.initializer?.transform(InitializerCallReplacer(next), null)
// Even if there is no loop variable, we always want to call `next()` for iterables and sequences.
listOf(loopVariable ?: next.coerceToUnitIfNeeded(next.type, context.irBuiltIns))
}
@@ -31,8 +31,6 @@ internal sealed class ProgressionType(
val maxValueAsLong: Long,
val getProgressionLastElementFunction: IrSimpleFunctionSymbol?
) {
abstract fun DeclarationIrBuilder.minValueExpression(): IrExpression
abstract fun DeclarationIrBuilder.zeroStepExpression(): IrExpression
fun IrExpression.asElementType() = castIfNecessary(elementClass)
@@ -63,7 +61,6 @@ internal class IntProgressionType(symbols: Symbols<CommonBackendContext>) :
// Uses `getProgressionLastElement(Int, Int, Int): Int`
getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.int]
) {
override fun DeclarationIrBuilder.minValueExpression() = irInt(Int.MIN_VALUE)
override fun DeclarationIrBuilder.zeroStepExpression() = irInt(0)
}
@@ -77,7 +74,6 @@ internal class LongProgressionType(symbols: Symbols<CommonBackendContext>) :
// Uses `getProgressionLastElement(Long, Long, Long): Long`
getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.long]
) {
override fun DeclarationIrBuilder.minValueExpression() = irLong(Long.MIN_VALUE)
override fun DeclarationIrBuilder.zeroStepExpression() = irLong(0)
}
@@ -91,7 +87,6 @@ internal class CharProgressionType(symbols: Symbols<CommonBackendContext>) :
// Uses `getProgressionLastElement(Int, Int, Int): Int`
getProgressionLastElementFunction = symbols.getProgressionLastElementByReturnType[symbols.int]
) {
override fun DeclarationIrBuilder.minValueExpression() = irChar(Char.MIN_VALUE)
override fun DeclarationIrBuilder.zeroStepExpression() = irInt(0)
}
@@ -175,7 +170,7 @@ internal abstract class UnsignedProgressionType(
}
}
internal class UIntProgressionType(symbols: Symbols<CommonBackendContext>, allowUnsignedBounds: Boolean) :
internal class UIntProgressionType(symbols: Symbols<CommonBackendContext>, allowUnsignedBounds: Boolean) :
UnsignedProgressionType(
symbols,
elementClass = if (allowUnsignedBounds) symbols.uInt!!.owner else symbols.int.owner,
@@ -187,13 +182,11 @@ internal class UIntProgressionType(symbols: Symbols<CommonBackendContext>, allo
unsignedType = symbols.uInt!!.defaultType,
unsignedConversionFunction = symbols.toUIntByExtensionReceiver.getValue(symbols.int)
) {
@OptIn(ExperimentalUnsignedTypes::class)
override fun DeclarationIrBuilder.minValueExpression() = irInt(UInt.MIN_VALUE.toInt(), elementClass.defaultType)
override fun DeclarationIrBuilder.zeroStepExpression() = irInt(0)
}
internal class ULongProgressionType(symbols: Symbols<CommonBackendContext>, private val allowUnsignedBounds: Boolean) :
internal class ULongProgressionType(symbols: Symbols<CommonBackendContext>, allowUnsignedBounds: Boolean) :
UnsignedProgressionType(
symbols,
elementClass = if (allowUnsignedBounds) symbols.uLong!!.owner else symbols.long.owner,
@@ -205,8 +198,6 @@ internal class ULongProgressionType(symbols: Symbols<CommonBackendContext>, priv
unsignedType = symbols.uLong!!.defaultType,
unsignedConversionFunction = symbols.toULongByExtensionReceiver.getValue(symbols.long)
) {
@OptIn(ExperimentalUnsignedTypes::class)
override fun DeclarationIrBuilder.minValueExpression() = irLong(ULong.MIN_VALUE.toLong(), elementClass.defaultType)
override fun DeclarationIrBuilder.zeroStepExpression() = irLong(0)
}
@@ -10,10 +10,7 @@ import org.jetbrains.kotlin.ir.builders.createTmpVariable
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.types.IrType
@@ -73,16 +70,20 @@ internal fun IrExpression.decrement(): IrExpression {
}
internal val IrExpression.canHaveSideEffects: Boolean
get() = this !is IrConst<*> && this !is IrGetValue
get() = this !is IrExpressionWithCopy
private fun Any?.toLong(): Long? =
when (this) {
is Number -> toLong()
is Char -> toLong()
else -> null
}
internal val IrExpressionWithCopy.constLongValue: Long?
get() = if (this is IrConst<*>) value.toLong() else null
internal val IrExpression.constLongValue: Long?
get() = if (this is IrConst<*>) {
when (val value = this.value) {
is Number -> value.toLong()
is Char -> value.toLong()
else -> null
}
} else null
get() = if (this is IrConst<*>) value.toLong() else null
/**
* If [expression] can have side effects ([IrExpression.canHaveSideEffects]), this function creates a temporary local variable for that
@@ -93,8 +94,8 @@ internal val IrExpression.constLongValue: Long?
internal fun DeclarationIrBuilder.createTemporaryVariableIfNecessary(
expression: IrExpression, nameHint: String? = null,
irType: IrType? = null, isMutable: Boolean = false
): Pair<IrVariable?, IrExpression> =
if (expression.canHaveSideEffects) {
): Pair<IrVariable?, IrExpressionWithCopy> =
if (expression !is IrExpressionWithCopy) {
scope.createTmpVariable(expression, nameHint = nameHint, irType = irType, isMutable = isMutable).let { Pair(it, irGet(it)) }
} else {
Pair(null, expression)
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.getPropertyGetter
/** Builds a [HeaderInfo] for progressions not handled by more specialized handlers. */
@@ -34,27 +33,27 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte
with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) {
// Directly use the `first/last/step` properties of the progression.
val (progressionVar, progressionExpression) = createTemporaryVariableIfNecessary(expression, nameHint = "progression")
val progressionClass = progressionExpression.type.getClass()!!
val progressionClass = expression.type.getClass()!!
val first = irCall(progressionClass.symbol.getPropertyGetter("first")!!).apply {
dispatchReceiver = progressionExpression
dispatchReceiver = progressionExpression.copy()
}
val last = irCall(progressionClass.symbol.getPropertyGetter("last")!!).apply {
dispatchReceiver = progressionExpression.deepCopyWithSymbols()
dispatchReceiver = progressionExpression.copy()
}
// *Ranges (e.g., IntRange) have step == 1 and is always increasing.
val isRange = progressionExpression.type in rangeClassesTypes
val isRange = expression.type in rangeClassesTypes
val step = if (isRange) {
irInt(1)
} else {
irCall(progressionClass.symbol.getPropertyGetter("step")!!).apply {
dispatchReceiver = progressionExpression.deepCopyWithSymbols()
dispatchReceiver = progressionExpression.copy()
}
}
val direction = if (isRange) ProgressionDirection.INCREASING else ProgressionDirection.UNKNOWN
ProgressionHeaderInfo(
ProgressionType.fromIrType(progressionExpression.type, symbols, allowUnsignedBounds)!!,
ProgressionType.fromIrType(expression.type, symbols, allowUnsignedBounds)!!,
first,
last,
step,
@@ -16,11 +16,11 @@ import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.types.isInt
import org.jetbrains.kotlin.ir.types.isLong
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.name.FqName
import kotlin.math.absoluteValue
@@ -75,12 +75,11 @@ internal class StepHandler(
// We insert a similar check in the lowered form only if necessary.
val stepType = data.stepClass.defaultType
val stepCompFun = context.irBuiltIns.lessOrEqualFunByOperandType.getValue(data.stepClass.symbol)
val zeroStep = data.run { zeroStepExpression() }
val throwIllegalStepExceptionCall = {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
val exceptionMessage = irConcat()
exceptionMessage.addArgument(irString("Step must be positive, was: "))
exceptionMessage.addArgument(stepArgExpression.deepCopyWithSymbols())
exceptionMessage.addArgument(stepArgExpression.copy())
exceptionMessage.addArgument(irString("."))
putValueArgument(0, exceptionMessage)
}
@@ -90,8 +89,8 @@ internal class StepHandler(
stepArgValueAsLong == null -> {
// Step argument is not a constant. In this case, we check if step <= 0.
val stepNonPositiveCheck = irCall(stepCompFun).apply {
putValueArgument(0, stepArgExpression.deepCopyWithSymbols())
putValueArgument(1, zeroStep.deepCopyWithSymbols())
putValueArgument(0, stepArgExpression.copy())
putValueArgument(1, data.run { zeroStepExpression() })
}
irIfThen(
context.irBuiltIns.unitType,
@@ -119,7 +118,8 @@ internal class StepHandler(
ProgressionDirection.INCREASING -> stepArgExpression
ProgressionDirection.DECREASING -> {
if (stepArgVar == null) {
stepArgExpression.negate()
stepNegation = scope.createTmpVariable(stepArgExpression.copy().negate())
irGet(stepNegation)
} else {
// Step is already stored in a variable, just negate it.
stepNegation = irSet(stepArgVar.symbol, irGet(stepArgVar).negate())
@@ -133,8 +133,8 @@ internal class StepHandler(
val (tmpNestedStepVar, nestedStepExpression) = createTemporaryVariableIfNecessary(nestedStep, "nestedStep")
nestedStepVar = tmpNestedStepVar
val nestedStepNonPositiveCheck = irCall(stepCompFun).apply {
putValueArgument(0, nestedStepExpression)
putValueArgument(1, zeroStep.deepCopyWithSymbols())
putValueArgument(0, nestedStepExpression.copy())
putValueArgument(1, data.run { zeroStepExpression() })
}
if (stepArgVar == null) {
// Create a temporary variable for the possibly-negated step, so we don't have to re-check every time step is used.
@@ -142,8 +142,8 @@ internal class StepHandler(
irIfThenElse(
stepType,
nestedStepNonPositiveCheck,
stepArgExpression.deepCopyWithSymbols().negate(),
stepArgExpression.deepCopyWithSymbols()
stepArgExpression.copy().negate(),
stepArgExpression.copy()
),
nameHint = "maybeNegatedStep"
)
@@ -272,9 +272,9 @@ internal class StepHandler(
return ProgressionHeaderInfo(
data,
first = nestedFirstExpression,
first = nestedFirstExpression.copy(),
last = recalculatedLast,
step = finalStepExpression,
step = finalStepExpression.copy(),
isReversed = nestedInfo.isReversed,
additionalStatements = additionalStatements,
direction = nestedInfo.direction
@@ -283,13 +283,13 @@ internal class StepHandler(
private fun DeclarationIrBuilder.callGetProgressionLastElementIfNecessary(
progressionType: ProgressionType,
first: IrExpression,
last: IrExpression,
step: IrExpression
first: IrExpressionWithCopy,
last: IrExpressionWithCopy,
step: IrExpressionWithCopy
): IrExpression {
// Calling getProgressionLastElement() is not needed if step == 1 or -1; the "last" value is unchanged in such cases.
if (step.constLongValue?.absoluteValue == 1L) {
return last
return last.copy()
}
// Call `getProgressionLastElement(first, last, step)`. The following overloads are present in the stdlib:
@@ -304,17 +304,17 @@ internal class StepHandler(
// Bounds are signed for unsigned progressions but `getProgressionLastElement` expects unsigned.
// The return value is finally converted back to signed since it will be assigned back to `last`.
irCall(getProgressionLastElementFun).apply {
putValueArgument(0, first.deepCopyWithSymbols().asElementType().asUnsigned())
putValueArgument(1, last.deepCopyWithSymbols().asElementType().asUnsigned())
putValueArgument(2, step.deepCopyWithSymbols().asStepType())
putValueArgument(0, first.copy().asElementType().asUnsigned())
putValueArgument(1, last.copy().asElementType().asUnsigned())
putValueArgument(2, step.copy().asStepType())
}.asSigned()
} else {
irCall(getProgressionLastElementFun).apply {
// Step type is used for casting because it works for all signed progressions. In particular,
// getProgressionLastElement(Int, Int, Int) is called for CharProgression, which uses an Int step.
putValueArgument(0, first.deepCopyWithSymbols().asStepType())
putValueArgument(1, last.deepCopyWithSymbols().asStepType())
putValueArgument(2, step.deepCopyWithSymbols().asStepType())
putValueArgument(0, first.copy().asStepType())
putValueArgument(1, last.copy().asStepType())
putValueArgument(2, step.copy().asStepType())
}
}
}
@@ -291,7 +291,7 @@ private class AddContinuationLowering(context: JvmBackendContext) : SuspendLower
if (view.isInline) JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE
else JvmLoweredDeclarationOrigin.FOR_INLINE_STATE_MACHINE_TEMPLATE_CAPTURES_CROSSINLINE
}.apply {
annotations += view.annotations.map { it.deepCopyWithSymbols(this) }
copyAnnotationsFrom(view)
copyParameterDeclarationsFrom(view)
copyAttributes(view)
generateErrorForInlineBody()
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
@@ -219,10 +220,10 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded(
}
}
function.copyAnnotationsFrom(target)
function.copyParameterDeclarationsFrom(target)
function.returnType = target.returnType.substitute(target.typeParameters, function.typeParameters.map { it.defaultType })
function.parent = facadeClass
function.annotations = target.annotations.map { it.deepCopyWithSymbols() }
if (shouldGeneratePartHierarchy) {
function.origin = IrDeclarationOrigin.FAKE_OVERRIDE
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
@@ -17,7 +18,6 @@ import org.jetbrains.kotlin.ir.builders.irBlockBody
import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.hasDefaultValue
internal val jvmDefaultConstructorPhase = makeIrFilePhase(
@@ -53,7 +53,7 @@ private class JvmDefaultConstructorLowering(val context: JvmBackendContext) : Cl
visibility = primaryConstructor.visibility
}.apply {
val irBuilder = context.createIrBuilder(this.symbol, startOffset, endOffset)
annotations += primaryConstructor.annotations.map { it.deepCopyWithSymbols(this) }
copyAnnotationsFrom(primaryConstructor)
body = irBuilder.irBlockBody {
+irDelegatingConstructorCall(primaryConstructor).apply {
passTypeArgumentsFrom(irClass)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport
@@ -17,7 +18,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.parentAsClass
@@ -67,9 +67,9 @@ class JvmInnerClassesSupport(private val irFactory: IrFactory) : InnerClassesSup
updateFrom(oldConstructor)
returnType = oldConstructor.returnType
}.apply {
annotations = oldConstructor.annotations.map { it.deepCopyWithSymbols(this) }
parent = oldConstructor.parent
returnType = oldConstructor.returnType
copyAnnotationsFrom(oldConstructor)
copyTypeParametersFrom(oldConstructor)
val outerThisValueParameter = buildValueParameter(this) {
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.ir.copyAnnotationsFrom
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
@@ -20,7 +21,6 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.allTypeParameters
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_OVERLOADS_FQ_NAME
@@ -145,7 +145,7 @@ private class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : C
}
res.parent = oldFunction.parent
res.annotations += oldFunction.annotations.map { it.deepCopyWithSymbols(res) }
res.copyAnnotationsFrom(oldFunction)
res.copyTypeParametersFrom(oldFunction)
res.dispatchReceiverParameter = oldFunction.dispatchReceiverParameter?.copyTo(res)
res.extensionReceiverParameter = oldFunction.extensionReceiverParameter?.copyTo(res)
@@ -7,10 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
@@ -79,9 +76,9 @@ private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) :
returnType = jvmStaticFunction.returnType
}.apply {
copyTypeParametersFrom(jvmStaticFunction)
copyAnnotationsFrom(jvmStaticFunction)
extensionReceiverParameter = jvmStaticFunction.extensionReceiverParameter?.copyTo(this)
valueParameters = jvmStaticFunction.valueParameters.map { it.copyTo(this) }
annotations = jvmStaticFunction.annotations.map { it.deepCopyWithSymbols() }
}
companion.declarations.remove(jvmStaticFunction)
companion.addProxy(staticExternal, companion, isStatic = false)
@@ -106,12 +103,12 @@ private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) :
isSuspend = target.isSuspend
}.apply {
copyTypeParametersFrom(target)
copyAnnotationsFrom(target)
if (!isStatic) {
dispatchReceiverParameter = thisReceiver?.copyTo(this, type = defaultType)
}
extensionReceiverParameter = target.extensionReceiverParameter?.copyTo(this)
valueParameters = target.valueParameters.map { it.copyTo(this) }
annotations = target.annotations.map { it.deepCopyWithSymbols() }
val proxy = this
val companionInstanceField = context.cachedDeclarations.getFieldForObjectInstance(companion)