Make `name` immutable
diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt
index 19609b6..b847839 100644
--- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt
+++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt
@@ -22,6 +22,7 @@
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
+import org.jetbrains.kotlin.ir.builders.declarations.withName
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
@@ -877,7 +878,7 @@
)
if (alwaysCreateTemporaryVariablesForArguments) {
- variable.name = Name.identifier(parameter.name.asStringStripSpecialMarkers())
+ return variable.withName(Name.identifier(parameter.name.asStringStripSpecialMarkers()))
}
return variable
diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt
index a04ac07..9b0467b 100644
--- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt
+++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FakeLocalVariablesForIrInlinerLowering.kt
@@ -8,6 +8,8 @@
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.*
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
+import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_ARGUMENTS
+import org.jetbrains.kotlin.backend.common.lower.inline.INLINED_FUNCTION_DEFAULT_ARGUMENTS
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
@@ -17,17 +19,16 @@
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.createTmpVariable
+import org.jetbrains.kotlin.ir.builders.declarations.buildVariable
+import org.jetbrains.kotlin.ir.builders.declarations.withName
import org.jetbrains.kotlin.ir.builders.irInt
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBlock
+import org.jetbrains.kotlin.ir.expressions.IrComposite
+import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrInlinedFunctionBlock
-import org.jetbrains.kotlin.ir.util.inlineDeclaration
-import org.jetbrains.kotlin.ir.util.isFunctionInlining
-import org.jetbrains.kotlin.ir.util.isLambdaInlining
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
-import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
-import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
-import org.jetbrains.kotlin.ir.visitors.acceptVoid
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.ir.visitors.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
@@ -43,7 +44,7 @@
)
internal class FakeLocalVariablesForIrInlinerLowering(
- override val context: JvmBackendContext
+ override val context: JvmBackendContext,
) : IrElementVisitorVoid, FakeInliningLocalVariables<IrInlinedFunctionBlock>, FileLoweringPass {
private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
private var container: IrDeclaration? = null
@@ -102,7 +103,7 @@
}
}
-private class LocalVariablesProcessor : IrElementVisitor<Unit, LocalVariablesProcessor.Data> {
+private class LocalVariablesProcessor : IrElementTransformer<LocalVariablesProcessor.Data> {
data class Data(val processingOriginalDeclarations: Boolean)
private val inlinedStack = mutableListOf<IrInlinedFunctionBlock>()
@@ -113,19 +114,15 @@
inlinedStack.removeLast()
}
- override fun visitElement(element: IrElement, data: Data) {
- element.acceptChildren(this, data)
- }
-
- override fun visitClass(declaration: IrClass, data: Data) {
+ override fun visitClass(declaration: IrClass, data: Data): IrStatement {
if (declaration.originalBeforeInline != null) {
// Don't take into account regenerated classes
return super.visitClass(declaration, data.copy(processingOriginalDeclarations = false))
}
- super.visitClass(declaration, data)
+ return super.visitClass(declaration, data)
}
- override fun visitBlock(expression: IrBlock, data: Data) {
+ override fun visitBlock(expression: IrBlock, data: Data): IrExpression {
if (expression !is IrInlinedFunctionBlock) {
return super.visitBlock(expression, data)
}
@@ -133,19 +130,20 @@
if (expression.isLambdaInlining()) {
val argument = expression.inlinedElement as IrAttributeContainer
val callee = inlinedStack.extractDeclarationWhereGivenElementWasInlined(argument)
- if (callee == null || callee != inlinedStack.lastOrNull()) return
+ if (callee == null || callee != inlinedStack.lastOrNull()) return expression
}
- super.visitBlock(expression, data)
-
- expression.insertInStackAndProcess {
- getOriginalStatementsFromInlinedBlock().forEach {
- it.accept(this@LocalVariablesProcessor, data.copy(processingOriginalDeclarations = true))
+ return super.visitBlock(expression, data).also {
+ expression.insertInStackAndProcess {
+ getOriginalStatementsFromInlinedBlock().forEach {
+ it.accept(this@LocalVariablesProcessor, data.copy(processingOriginalDeclarations = true))
+ }
}
}
}
- override fun visitVariable(declaration: IrVariable, data: Data) {
+
+ override fun visitVariable(declaration: IrVariable, data: Data): IrStatement {
if (!data.processingOriginalDeclarations) return super.visitVariable(declaration, data)
val varName = declaration.name.asString()
@@ -157,8 +155,9 @@
varSuffix.isNotEmpty() && varName == SpecialNames.THIS.asStringStripSpecialMarkers() -> "this_"
else -> varName
}
- declaration.name = Name.identifier(newName + varSuffix)
- super.visitVariable(declaration, data)
+ val transformed = super.visitVariable(declaration, data)
+ require(transformed is IrVariable) { "Expected IrVariable, but got ${transformed.render()}" }
+ return transformed.withName(Name.identifier(newName + varSuffix))
}
}
@@ -173,14 +172,16 @@
}
super.visitBlock(expression)
- expression.getAdditionalStatementsFromInlinedBlock().forEach {
- it.processFunctionParameter(expression)
- }
+ expression.statements
+ .filterIsInstance<IrComposite>()
+ .filter { it.origin == INLINED_FUNCTION_ARGUMENTS || it.origin == INLINED_FUNCTION_DEFAULT_ARGUMENTS }
+ .forEach {
+ it.statements.transformInPlace { statement -> statement.processFunctionParameter(expression) }
+ }
}
- private fun IrStatement.processFunctionParameter(inlinedBlock: IrInlinedFunctionBlock) {
- if (this !is IrVariable || !this.isTmpForInline) return
-
+ private fun IrStatement.processFunctionParameter(inlinedBlock: IrInlinedFunctionBlock): IrStatement {
+ if (this !is IrVariable || !this.isTmpForInline) return this
val varName = this.name.asString().substringAfterLast("_")
val varNewName = when {
this.origin == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_EXTENSION_RECEIVER -> {
@@ -190,7 +191,7 @@
varName == SpecialNames.THIS.asStringStripSpecialMarkers() -> "this_"
else -> varName
}
- this.name = Name.identifier(varNewName + INLINE_FUN_VAR_SUFFIX)
this.origin = IrDeclarationOrigin.DEFINED
+ return this.withName(Name.identifier(varNewName + INLINE_FUN_VAR_SUFFIX))
}
}
diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt
index dea11b8..c791041 100644
--- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt
+++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/RenameFieldsLowering.kt
@@ -8,8 +8,11 @@
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
+import org.jetbrains.kotlin.ir.builders.declarations.withName
import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.util.fields
+import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.name.Name
internal val renameFieldsPhase = makeIrFilePhase<CommonBackendContext>(
@@ -38,13 +41,25 @@
}
val count = hashMapOf<Name, Int>()
- for (field in fields) {
+
+ val originalToTransformedField = fields.associateWith { field ->
val oldName = field.name
val index = count[oldName] ?: 0
- if (index != 0 && !field.visibility.isPublicAPI) {
- field.name = Name.identifier("$oldName$$index")
+ val transformedField = if (index != 0 && !field.visibility.isPublicAPI) {
+ field.withName(Name.identifier("$oldName$$index"))
+ } else {
+ field
}
count[oldName] = index + 1
+ transformedField
+ }
+
+ irClass.declarations.transformInPlace {
+ if (it is IrField) {
+ originalToTransformedField[it] ?: it
+ } else {
+ it
+ }
}
}
}
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt
index 18d540e..8f2d973 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt
@@ -16,6 +16,7 @@
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
+import org.jetbrains.kotlin.ir.builders.declarations.withName
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
@@ -31,7 +32,7 @@
class MemoizedInlineClassReplacements(
private val mangleReturnTypes: Boolean,
irFactory: IrFactory,
- context: JvmBackendContext
+ context: JvmBackendContext,
) : MemoizedValueClassAbstractReplacements(irFactory, context, LockBasedStorageManager("inline-class-replacements")) {
val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
@@ -63,10 +64,11 @@
// Mangle all functions in the body of an inline class
(it.parent as? IrClass)?.isSingleFieldValueClass == true ->
when {
- it.isValueClassTypedEquals -> createStaticReplacement(it).also {
- it.name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
- specializedEqualsCache.computeIfAbsent(it.parentAsClass) { it }
- }
+ it.isValueClassTypedEquals -> createStaticReplacement(it)
+ .withName(InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME)
+ .also {
+ specializedEqualsCache.computeIfAbsent(it.parentAsClass) { it }
+ }
it.isRemoveAtSpecialBuiltinStub() ->
null
@@ -218,7 +220,7 @@
function: IrFunction,
replacementOrigin: IrDeclarationOrigin,
noFakeOverride: Boolean = false,
- body: IrFunction.() -> Unit
+ body: IrFunction.() -> Unit,
): IrSimpleFunction {
val useOldManglingScheme = context.config.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures
val replacement = buildReplacementInner(function, replacementOrigin, noFakeOverride, useOldManglingScheme, body)
diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt
index 8c9fe3a..2f6e025 100644
--- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt
+++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedMultiFieldValueClassReplacements.kt
@@ -14,6 +14,7 @@
import org.jetbrains.kotlin.ir.builders.IrBlockBuilder
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
+import org.jetbrains.kotlin.ir.builders.declarations.withName
import org.jetbrains.kotlin.ir.builders.irComposite
import org.jetbrains.kotlin.ir.builders.irExprBody
import org.jetbrains.kotlin.ir.builders.irGet
@@ -35,7 +36,7 @@
*/
class MemoizedMultiFieldValueClassReplacements(
irFactory: IrFactory,
- context: JvmBackendContext
+ context: JvmBackendContext,
) : MemoizedValueClassAbstractReplacements(irFactory, context, LockBasedStorageManager("multi-field-value-class-replacements")) {
val originalFunctionForStaticReplacement: MutableMap<IrFunction, IrFunction> = ConcurrentHashMap()
@@ -262,9 +263,8 @@
function.isMultiFieldValueClassFieldGetter -> null
(function.parent as? IrClass)?.isMultiFieldValueClass == true -> when {
- function.isValueClassTypedEquals -> createStaticReplacement(function).also {
- it.name = InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME
- }
+ function.isValueClassTypedEquals -> createStaticReplacement(function)
+ .withName(InlineClassDescriptorResolver.SPECIALIZED_EQUALS_NAME)
function.isRemoveAtSpecialBuiltinStub() ->
null
@@ -394,7 +394,7 @@
irBuilder: IrBlockBuilder,
targetFunction: IrFunction,
sourceFunction: IrFunction,
- getArgument: (sourceParameter: IrValueParameter, targetParameterType: IrType) -> IrExpression?
+ getArgument: (sourceParameter: IrValueParameter, targetParameterType: IrType) -> IrExpression?,
): Map<IrValueParameter, IrExpression?> {
val targetStructure = bindingNewFunctionToParameterTemplateStructure[targetFunction]
?: targetFunction.explicitParameters.map { RegularMapping(it) }
@@ -469,7 +469,7 @@
@OptIn(ExperimentalStdlibApi::class)
private fun verifyStructureCompatibility(
targetStructure: List<RemappedParameter>,
- sourceStructure: List<RemappedParameter>
+ sourceStructure: List<RemappedParameter>,
) {
for ((targetParameterStructure, sourceParameterStructure) in targetStructure zip sourceStructure) {
if (targetParameterStructure is MultiFieldValueClassMapping && sourceParameterStructure is MultiFieldValueClassMapping) {
diff --git a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt
index a8c6f7c..1e581a6 100644
--- a/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt
+++ b/compiler/ir/ir.tree/gen/org/jetbrains/kotlin/ir/declarations/IrDeclarationWithName.kt
@@ -16,5 +16,5 @@
* Generated from: [org.jetbrains.kotlin.ir.generator.IrTree.declarationWithName]
*/
interface IrDeclarationWithName : IrDeclaration {
- var name: Name
+ val name: Name
}
diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt
index 051712db..c84bc3c 100644
--- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt
+++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/declarations/declarationBuilders.kt
@@ -91,7 +91,7 @@
fun IrClass.addField(
fieldName: String,
fieldType: IrType,
- fieldVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE
+ fieldVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE,
): IrField =
addField(Name.identifier(fieldName), fieldType, fieldVisibility)
@@ -258,7 +258,7 @@
isInline: Boolean = false,
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED,
startOffset: Int = UNDEFINED_OFFSET,
- endOffset: Int = UNDEFINED_OFFSET
+ endOffset: Int = UNDEFINED_OFFSET,
): IrSimpleFunction =
addFunction {
this.startOffset = startOffset
@@ -298,7 +298,7 @@
origin: IrDeclarationOrigin,
type: IrType,
startOffset: Int = parent.startOffset,
- endOffset: Int = parent.endOffset
+ endOffset: Int = parent.endOffset,
): IrValueParameter
where D : IrDeclaration, D : IrDeclarationParent =
parent.factory.createValueParameter(
@@ -409,6 +409,37 @@
this.superTypes.add(upperBound)
}
+fun IrSimpleFunction.withName(name: Name) = factory.buildFun {
+ updateFrom(this@withName)
+ this.name = name
+ returnType = this@withName.returnType
+}.apply {
+ parent = this@withName.parent
+ metadata = this@withName.metadata
+ valueParameters = this@withName.valueParameters
+ typeParameters = this@withName.typeParameters
+ dispatchReceiverParameter = this@withName.dispatchReceiverParameter
+ extensionReceiverParameter = this@withName.extensionReceiverParameter
+ contextReceiverParametersCount = this@withName.contextReceiverParametersCount
+ body = this@withName.body
+ overriddenSymbols = this@withName.overriddenSymbols
+ attributeOwnerId = this@withName.attributeOwnerId
+ originalBeforeInline = this@withName.originalBeforeInline
+ correspondingPropertySymbol = this@withName.correspondingPropertySymbol
+}
+
+fun IrVariable.withName(name: Name) =
+ buildVariable(parent, startOffset, endOffset, origin, name, type, isVar, isConst, isLateinit).also { it.initializer = initializer }
+
+fun IrField.withName(name: Name) = factory.buildField {
+ this.name = name
+ updateFrom(this@withName)
+}.apply {
+ parent = this@withName.parent
+ initializer = this@withName.initializer
+ correspondingPropertySymbol = this@withName.correspondingPropertySymbol
+}
+
fun buildVariable(
parent: IrDeclarationParent?,
startOffset: Int,
diff --git a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt
index 8418b42..5297007 100644
--- a/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt
+++ b/compiler/ir/ir.tree/tree-generator/src/org/jetbrains/kotlin/ir/generator/IrTree.kt
@@ -125,7 +125,7 @@
val declarationWithName: ElementConfig by element(Declaration) {
parent(declaration)
- +field("name", type<Name>())
+ +field("name", type<Name>(), mutable = false)
}
val possiblyExternalDeclaration: ElementConfig by element(Declaration) {
parent(declarationWithName)