@@ -134,6 +134,7 @@ open class LocalDeclarationsLowering(
134
134
val newParameterToOld : MutableMap <IrValueParameter , IrValueParameter > = mutableMapOf(),
135
135
val oldParameterToNew : MutableMap <IrValueParameter , IrValueParameter > = mutableMapOf(),
136
136
) : BodyLoweringPass {
137
+ internal val methodScopesWithCounter: MutableMap <IrClass , MutableMap <Name , ScopeWithCounter >> = mutableMapOf ()
137
138
138
139
open val invalidChars: Set <Char >
139
140
get() = emptySet()
@@ -221,6 +222,12 @@ open class LocalDeclarationsLowering(
221
222
private fun IrSymbolOwner.getOrCreateScopeWithCounter (): ScopeWithCounter =
222
223
scopeWithCounter ? : ScopeWithCounter (this ).also { scopeWithCounter = it }
223
224
225
+ private fun IrFunction.getOrCreateScopeWithCounter (): ScopeWithCounter ? {
226
+ val klass = parentClassOrNull ? : return null
227
+ return methodScopesWithCounter.getOrPut(klass, ::mutableMapOf)
228
+ .getOrPut(this .name) { ScopeWithCounter (this ) }
229
+ }
230
+
224
231
abstract class LocalContext {
225
232
val capturedTypeParameterToTypeParameter: MutableMap <IrTypeParameter , IrTypeParameter > = mutableMapOf ()
226
233
@@ -284,6 +291,7 @@ open class LocalDeclarationsLowering(
284
291
val index : Int ,
285
292
val ownerForLoweredDeclaration : OwnerForLoweredDeclaration ,
286
293
sourceFileWhenInlined : IrFileEntry ? ,
294
+ val isNestedInLambda : Boolean ,
287
295
) :
288
296
LocalContextWithClosureAsParameters (sourceFileWhenInlined) {
289
297
lateinit var closure: Closure
@@ -896,15 +904,20 @@ open class LocalDeclarationsLowering(
896
904
private fun suggestLocalName (declaration : IrDeclarationWithName ): String {
897
905
val declarationName = localNameSanitizer(declaration.name.asString())
898
906
localFunctions[declaration]?.let {
899
- val baseName = if (declaration.name.isSpecial) " lambda" else declarationName
907
+ val baseName = when {
908
+ declaration.name.isSpecial -> if (it.isNestedInLambda) " " else " lambda"
909
+ else -> declarationName
910
+ }
900
911
if (it.index >= 0 ) {
901
912
if (! suggestUniqueNames) return baseName
902
913
903
- val separator = if (
914
+ val separator = when {
904
915
compatibilityModeForInlinedLocalDelegatedPropertyAccessors &&
905
- declaration.origin == IrDeclarationOrigin .DELEGATED_PROPERTY_ACCESSOR &&
906
- container is IrFunction && container.isInline
907
- ) " -" else " $"
916
+ declaration.origin == IrDeclarationOrigin .DELEGATED_PROPERTY_ACCESSOR &&
917
+ container is IrFunction && container.isInline -> " -"
918
+ baseName.isEmpty() -> " "
919
+ else -> " $"
920
+ }
908
921
return " $baseName$separator${it.index} "
909
922
}
910
923
}
@@ -1213,37 +1226,57 @@ open class LocalDeclarationsLowering(
1213
1226
}
1214
1227
}
1215
1228
1229
+ private val IrFunction .isLambda: Boolean
1230
+ get() =
1231
+ origin == IrDeclarationOrigin .LOCAL_FUNCTION_FOR_LAMBDA || origin == IrDeclarationOrigin .INLINE_LAMBDA
1232
+
1233
+ private inline fun <reified T : IrElement > getEnclosing (): T ? {
1234
+ var currentParent = container as ? T ? : container.parent
1235
+ while (currentParent is IrDeclaration && currentParent !is T ) {
1236
+ currentParent = currentParent.parent
1237
+ }
1238
+
1239
+ return currentParent as ? T
1240
+ }
1241
+
1216
1242
private fun collectLocalDeclarations () {
1217
1243
val enclosingPackageFragment = container.getPackageFragment()
1218
- val enclosingClass = run {
1219
- var currentParent = container as ? IrClass ? : container.parent
1220
- while (currentParent is IrDeclaration && currentParent !is IrClass ) {
1221
- currentParent = currentParent.parent
1222
- }
1223
-
1224
- currentParent as ? IrClass
1244
+ val enclosingClass = getEnclosing<IrClass >()
1245
+ val enclosingFunction = getEnclosing<IrFunction >().takeIf {
1246
+ it !is IrConstructor && it?.parentClassOrNull != null
1225
1247
}
1226
1248
1227
1249
class Data (
1228
- val currentClass : ScopeWithCounter ? ,
1250
+ val currentScope : ScopeWithCounter ? ,
1229
1251
val isInInlineFunction : Boolean ,
1230
1252
val sourceFileWhenInlined : IrFileEntry ? = null ,
1253
+ val isInLambdaFunction : Boolean ,
1231
1254
) {
1232
1255
fun withCurrentClass (currentClass : IrClass ): Data =
1233
1256
// Don't cache local declarations
1234
- Data (ScopeWithCounter (currentClass), isInInlineFunction, sourceFileWhenInlined)
1257
+ Data (ScopeWithCounter (currentClass), isInInlineFunction, sourceFileWhenInlined, false )
1258
+
1259
+ fun withCurrentFunction (currentFunction : IrFunction ): Data =
1260
+ Data (ScopeWithCounter (currentFunction), isInInlineFunction, sourceFileWhenInlined, currentFunction.isLambda)
1235
1261
1236
1262
fun withInline (isInline : Boolean , sourceFileWhenInlined : IrFileEntry ? ): Data =
1237
- if (isInline && ! isInInlineFunction) Data (currentClass , true , sourceFileWhenInlined) else this
1263
+ if (isInline && ! isInInlineFunction) Data (currentScope , true , sourceFileWhenInlined, false ) else this
1238
1264
}
1239
1265
1240
1266
irElement.accept(object : IrVisitor <Unit , Data >() {
1267
+
1241
1268
override fun visitElement (element : IrElement , data : Data ) {
1242
1269
element.acceptChildren(this , data)
1243
1270
}
1244
1271
1245
1272
override fun visitInlinedFunctionBlock (inlinedBlock : IrInlinedFunctionBlock , data : Data ) {
1246
- super .visitInlinedFunctionBlock(inlinedBlock, data.withInline(inlinedBlock.isFunctionInlining(),inlinedBlock.inlinedFunctionFileEntry))
1273
+ super .visitInlinedFunctionBlock(
1274
+ inlinedBlock,
1275
+ data.withInline(
1276
+ inlinedBlock.isFunctionInlining(),
1277
+ inlinedBlock.inlinedFunctionFileEntry
1278
+ )
1279
+ )
1247
1280
}
1248
1281
1249
1282
override fun visitFunctionExpression (expression : IrFunctionExpression , data : Data ) {
@@ -1268,10 +1301,10 @@ open class LocalDeclarationsLowering(
1268
1301
1269
1302
override fun visitSimpleFunction (declaration : IrSimpleFunction , data : Data ) {
1270
1303
if (functionsToSkip?.contains(declaration) == true ) return
1271
- super .visitSimpleFunction(declaration, data.withInline(declaration.isInline, data.sourceFileWhenInlined))
1272
1304
1273
1305
if (declaration.visibility == DescriptorVisibilities .LOCAL ) {
1274
- val enclosingScope = data.currentClass
1306
+ val enclosingScope = data.currentScope
1307
+ ? : enclosingFunction?.getOrCreateScopeWithCounter()
1275
1308
? : enclosingClass?.getOrCreateScopeWithCounter()
1276
1309
// File is required for K/N because file declarations are not split by classes.
1277
1310
? : enclosingPackageFragment.getOrCreateScopeWithCounter()
@@ -1280,14 +1313,34 @@ open class LocalDeclarationsLowering(
1280
1313
enclosingScope.counter++
1281
1314
else - 1
1282
1315
val ownerForLoweredDeclaration =
1283
- data.currentClass?.let { OwnerForLoweredDeclaration .DeclarationContainer (it.irElement as IrDeclarationContainer ) }
1316
+ data.currentScope?.let {
1317
+ when (it.irElement) {
1318
+ is IrDeclarationContainer -> OwnerForLoweredDeclaration .DeclarationContainer (it.irElement)
1319
+ is IrFunction -> localFunctions[enclosingScope.irElement]!! .ownerForLoweredDeclaration
1320
+ else -> error(" Unknown owner for lowered declaration" )
1321
+ }
1322
+ }
1284
1323
? : (irElement as ? IrBlock )?.let { OwnerForLoweredDeclaration .Block (irElement, closestParent!! ) }
1324
+ ? : (enclosingScope.irElement as ? IrFunction )?.let { enclosingFunction ->
1325
+ OwnerForLoweredDeclaration .DeclarationContainer (enclosingFunction.parentClassOrNull!! )
1326
+ }
1285
1327
? : OwnerForLoweredDeclaration .DeclarationContainer (enclosingScope.irElement as IrDeclarationContainer )
1286
- localFunctions[declaration] =
1287
- LocalFunctionContext (declaration, index, ownerForLoweredDeclaration, data.sourceFileWhenInlined)
1328
+ localFunctions[declaration] = LocalFunctionContext (
1329
+ declaration,
1330
+ index,
1331
+ ownerForLoweredDeclaration,
1332
+ data.sourceFileWhenInlined,
1333
+ data.isInLambdaFunction,
1334
+ )
1288
1335
1289
1336
enclosingScope.usedLocalFunctionNames.add(declaration.name)
1290
1337
}
1338
+
1339
+ val newData = data.withInline(declaration.isInline, data.sourceFileWhenInlined)
1340
+ super .visitSimpleFunction(
1341
+ declaration,
1342
+ if (declaration.isLambda) newData.withCurrentFunction(declaration) else newData
1343
+ )
1291
1344
}
1292
1345
1293
1346
override fun visitConstructor (declaration : IrConstructor , data : Data ) {
@@ -1323,7 +1376,7 @@ open class LocalDeclarationsLowering(
1323
1376
private val Data .inInlineFunctionScope: Boolean
1324
1377
get() = isInInlineFunction ||
1325
1378
generateSequence(container) { it.parent as ? IrDeclaration }.any { it is IrFunction && it.isInline }
1326
- }, Data (null , false , null ))
1379
+ }, Data (null , false , null , false ))
1327
1380
}
1328
1381
}
1329
1382
}
0 commit comments