IR: remove IrElementVisitorVoidWithContext
It was only used as a superclass in IrInlineReferenceLocator and LocalDeclarationsLowering. In both cases it's clearer and more optimal to pass the necessary data via the visitor 'data' variable.
This commit is contained in:
+4
-97
@@ -21,9 +21,11 @@ import org.jetbrains.kotlin.ir.IrStatement
|
|||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
import org.jetbrains.kotlin.ir.builders.Scope
|
import org.jetbrains.kotlin.ir.builders.Scope
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
|
||||||
|
|
||||||
open class ScopeWithIr(val scope: Scope, val irElement: IrElement)
|
open class ScopeWithIr(val scope: Scope, val irElement: IrElement)
|
||||||
|
|
||||||
@@ -139,98 +141,3 @@ abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid()
|
|||||||
return super.visitScript(declaration)
|
return super.visitScript(declaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
|
||||||
abstract class IrElementVisitorVoidWithContext : IrElementVisitorVoid {
|
|
||||||
|
|
||||||
private val scopeStack = mutableListOf<ScopeWithIr>()
|
|
||||||
|
|
||||||
protected open fun createScope(declaration: IrSymbolOwner): ScopeWithIr =
|
|
||||||
ScopeWithIr(Scope(declaration.symbol), declaration)
|
|
||||||
|
|
||||||
final override fun visitFile(declaration: IrFile) {
|
|
||||||
scopeStack.push(createScope(declaration))
|
|
||||||
visitFileNew(declaration)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitClass(declaration: IrClass) {
|
|
||||||
scopeStack.push(createScope(declaration))
|
|
||||||
visitClassNew(declaration)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitProperty(declaration: IrProperty) {
|
|
||||||
scopeStack.push(createScope(declaration))
|
|
||||||
visitPropertyNew(declaration)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitField(declaration: IrField) {
|
|
||||||
val isDelegated = declaration.descriptor.isDelegated
|
|
||||||
if (isDelegated) scopeStack.push(createScope(declaration))
|
|
||||||
visitFieldNew(declaration)
|
|
||||||
if (isDelegated) scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitFunction(declaration: IrFunction) {
|
|
||||||
scopeStack.push(createScope(declaration))
|
|
||||||
visitFunctionNew(declaration)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
|
|
||||||
scopeStack.push(createScope(declaration))
|
|
||||||
visitAnonymousInitializerNew(declaration)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
final override fun visitValueParameter(declaration: IrValueParameter) {
|
|
||||||
scopeStack.push(createScope(declaration))
|
|
||||||
visitValueParameterNew(declaration)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected val currentFile get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFileSymbol }
|
|
||||||
protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrClassSymbol }
|
|
||||||
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFunctionSymbol }
|
|
||||||
protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrPropertySymbol }
|
|
||||||
protected val currentAnonymousInitializer get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrAnonymousInitializer }
|
|
||||||
protected val currentValueParameter get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrValueParameter }
|
|
||||||
protected val currentScope get() = scopeStack.peek()
|
|
||||||
protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2]
|
|
||||||
protected val allScopes get() = scopeStack
|
|
||||||
|
|
||||||
@ObsoleteDescriptorBasedAPI
|
|
||||||
fun printScopeStack() {
|
|
||||||
scopeStack.forEach { println(it.scope.scopeOwner) }
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitFileNew(declaration: IrFile) {
|
|
||||||
super.visitFile(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitClassNew(declaration: IrClass) {
|
|
||||||
super.visitClass(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitFunctionNew(declaration: IrFunction) {
|
|
||||||
super.visitFunction(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitPropertyNew(declaration: IrProperty) {
|
|
||||||
super.visitProperty(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitFieldNew(declaration: IrField) {
|
|
||||||
super.visitField(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitAnonymousInitializerNew(declaration: IrAnonymousInitializer) {
|
|
||||||
super.visitAnonymousInitializer(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun visitValueParameterNew(declaration: IrValueParameter) {
|
|
||||||
super.visitValueParameter(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+38
-34
@@ -5,15 +5,16 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.common.lower
|
package org.jetbrains.kotlin.backend.common.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
|
||||||
import org.jetbrains.kotlin.backend.common.ir.*
|
import org.jetbrains.kotlin.backend.common.ir.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.ir.*
|
import org.jetbrains.kotlin.ir.*
|
||||||
import org.jetbrains.kotlin.ir.builders.Scope
|
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||||
@@ -33,8 +34,7 @@ import org.jetbrains.kotlin.ir.util.file
|
|||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
@@ -109,7 +109,7 @@ class LocalDeclarationsLowering(
|
|||||||
LocalDeclarationsTransformer(irElement, container, classesToLower).lowerLocalDeclarations()
|
LocalDeclarationsTransformer(irElement, container, classesToLower).lowerLocalDeclarations()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ScopeWithCounter(scope: Scope, irElement: IrElement) : ScopeWithIr(scope, irElement) {
|
internal class ScopeWithCounter(val irElement: IrElement) {
|
||||||
// Continuous numbering across all declarations in the container.
|
// Continuous numbering across all declarations in the container.
|
||||||
var counter: Int = 0
|
var counter: Int = 0
|
||||||
val usedLocalFunctionNames: MutableSet<Name> = hashSetOf()
|
val usedLocalFunctionNames: MutableSet<Name> = hashSetOf()
|
||||||
@@ -122,7 +122,7 @@ class LocalDeclarationsLowering(
|
|||||||
// Need to keep LocalFunctionContext.index
|
// Need to keep LocalFunctionContext.index
|
||||||
private val IrSymbolOwner.scopeWithCounter: ScopeWithCounter
|
private val IrSymbolOwner.scopeWithCounter: ScopeWithCounter
|
||||||
get() = context.ir.localScopeWithCounterMap.scopeMap.getOrPut(this) {
|
get() = context.ir.localScopeWithCounterMap.scopeMap.getOrPut(this) {
|
||||||
ScopeWithCounter(Scope(symbol), this)
|
ScopeWithCounter(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private abstract class LocalContext {
|
private abstract class LocalContext {
|
||||||
@@ -857,66 +857,70 @@ class LocalDeclarationsLowering(
|
|||||||
currentParent as? IrClass
|
currentParent as? IrClass
|
||||||
}
|
}
|
||||||
|
|
||||||
irElement.acceptVoid(object : IrElementVisitorVoidWithContext() {
|
class Data(val currentClass: ScopeWithCounter?, val isInInlineFunction: Boolean) {
|
||||||
override fun visitElement(element: IrElement) {
|
fun withCurrentClass(currentClass: IrClass): Data =
|
||||||
element.acceptChildrenVoid(this)
|
// Don't cache local declarations
|
||||||
|
Data(ScopeWithCounter(currentClass), isInInlineFunction)
|
||||||
|
|
||||||
|
fun withInline(isInline: Boolean): Data =
|
||||||
|
if (isInline && !isInInlineFunction) Data(currentClass, true) else this
|
||||||
|
}
|
||||||
|
|
||||||
|
irElement.accept(object : IrElementVisitor<Unit, Data> {
|
||||||
|
override fun visitElement(element: IrElement, data: Data) {
|
||||||
|
element.acceptChildren(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createScope(declaration: IrSymbolOwner): ScopeWithIr {
|
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Data) {
|
||||||
return ScopeWithCounter(Scope(declaration.symbol), declaration) // Don't cache local declarations
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitFunctionExpression(expression: IrFunctionExpression) {
|
|
||||||
// TODO: For now IrFunctionExpression can only be encountered here if this was called from the inliner,
|
// TODO: For now IrFunctionExpression can only be encountered here if this was called from the inliner,
|
||||||
// then all IrFunctionExpression will be replaced by IrFunctionReferenceExpression.
|
// then all IrFunctionExpression will be replaced by IrFunctionReferenceExpression.
|
||||||
// Don't forget to fix this when that replacement has been dropped.
|
// Don't forget to fix this when that replacement has been dropped.
|
||||||
// Also, a note: even if a lambda is not an inline one, there still cannot be a reference to it
|
// Also, a note: even if a lambda is not an inline one, there still cannot be a reference to it
|
||||||
// from an outside declaration, so it is safe to skip them here and correctly handle later, after the above conversion.
|
// from an outside declaration, so it is safe to skip them here and correctly handle later, after the above conversion.
|
||||||
expression.function.acceptChildrenVoid(this)
|
expression.function.acceptChildren(this, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
override fun visitSimpleFunction(declaration: IrSimpleFunction, data: Data) {
|
||||||
super.visitSimpleFunction(declaration)
|
super.visitSimpleFunction(declaration, data.withInline(declaration.isInline))
|
||||||
|
|
||||||
if (declaration.visibility == Visibilities.LOCAL) {
|
if (declaration.visibility == Visibilities.LOCAL) {
|
||||||
val enclosingScope =
|
val enclosingScope = data.currentClass
|
||||||
|
?: enclosingClass?.scopeWithCounter
|
||||||
// File is required for K/N because file declarations are not split by classes.
|
// File is required for K/N because file declarations are not split by classes.
|
||||||
currentClass ?: enclosingClass?.scopeWithCounter ?: enclosingFile.scopeWithCounter
|
?: enclosingFile.scopeWithCounter
|
||||||
val index =
|
val index =
|
||||||
if (enclosingScope is ScopeWithCounter &&
|
if (declaration.name.isSpecial || declaration.name in enclosingScope.usedLocalFunctionNames)
|
||||||
(declaration.name.isSpecial || declaration.name in enclosingScope.usedLocalFunctionNames)
|
enclosingScope.counter++
|
||||||
) enclosingScope.counter++ else -1
|
else -1
|
||||||
localFunctions[declaration] =
|
localFunctions[declaration] =
|
||||||
LocalFunctionContext(declaration, index, enclosingScope.irElement as IrDeclarationContainer)
|
LocalFunctionContext(declaration, index, enclosingScope.irElement as IrDeclarationContainer)
|
||||||
(enclosingScope as? ScopeWithCounter)?.usedLocalFunctionNames?.add(declaration.name)
|
enclosingScope.usedLocalFunctionNames.add(declaration.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitConstructor(declaration: IrConstructor) {
|
override fun visitConstructor(declaration: IrConstructor, data: Data) {
|
||||||
super.visitConstructor(declaration)
|
super.visitConstructor(declaration, data)
|
||||||
|
|
||||||
if (!declaration.constructedClass.isLocalNotInner()) return
|
if (!declaration.constructedClass.isLocalNotInner()) return
|
||||||
|
|
||||||
localClassConstructors[declaration] = LocalClassConstructorContext(declaration, inInlineFunctionScope)
|
localClassConstructors[declaration] = LocalClassConstructorContext(declaration, data.inInlineFunctionScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClassNew(declaration: IrClass) {
|
override fun visitClass(declaration: IrClass, data: Data) {
|
||||||
if (classesToLower?.contains(declaration) == false) return
|
if (classesToLower?.contains(declaration) == false) return
|
||||||
super.visitClassNew(declaration)
|
super.visitClass(declaration, data.withCurrentClass(declaration))
|
||||||
|
|
||||||
if (!declaration.isLocalNotInner()) return
|
if (!declaration.isLocalNotInner()) return
|
||||||
|
|
||||||
val localClassContext = LocalClassContext(declaration, inInlineFunctionScope)
|
localClasses[declaration] = LocalClassContext(declaration, data.inInlineFunctionScope)
|
||||||
localClasses[declaration] = localClassContext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private val inInlineFunctionScope: Boolean
|
private val Data.inInlineFunctionScope: Boolean
|
||||||
get() = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false } ||
|
get() = isInInlineFunction ||
|
||||||
generateSequence(container) { it.parent as? IrDeclaration }.any { it is IrFunction && it.isInline }
|
generateSequence(container) { it.parent as? IrDeclaration }.any { it is IrFunction && it.isInline }
|
||||||
})
|
}, Data(null, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local inner classes capture anything through outer
|
// Local inner classes capture anything through outer
|
||||||
|
|||||||
+13
-7
@@ -5,25 +5,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.ir
|
package org.jetbrains.kotlin.backend.jvm.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementVisitorVoidWithContext
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineFunctionCall
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||||
import org.jetbrains.kotlin.ir.util.isLambda
|
import org.jetbrains.kotlin.ir.util.isLambda
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrCallableReference
|
import org.jetbrains.kotlin.ir.expressions.IrCallableReference
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||||
|
|
||||||
internal open class IrInlineReferenceLocator(private val context: JvmBackendContext) : IrElementVisitorVoidWithContext() {
|
internal open class IrInlineReferenceLocator(private val context: JvmBackendContext) : IrElementVisitor<Unit, IrDeclaration?> {
|
||||||
override fun visitElement(element: IrElement) = element.acceptChildrenVoid(this)
|
override fun visitElement(element: IrElement, data: IrDeclaration?) {
|
||||||
|
element.acceptChildren(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitFunctionAccess(expression: IrFunctionAccessExpression) {
|
override fun visitDeclaration(declaration: IrDeclarationBase, data: IrDeclaration?) {
|
||||||
|
declaration.acceptChildren(this, declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunctionAccess(expression: IrFunctionAccessExpression, data: IrDeclaration?) {
|
||||||
val function = expression.symbol.owner
|
val function = expression.symbol.owner
|
||||||
if (function.isInlineFunctionCall(context)) {
|
if (function.isInlineFunctionCall(context)) {
|
||||||
for (parameter in function.valueParameters) {
|
for (parameter in function.valueParameters) {
|
||||||
@@ -36,13 +42,13 @@ internal open class IrInlineReferenceLocator(private val context: JvmBackendCont
|
|||||||
|
|
||||||
if (valueArgument is IrBlock && valueArgument.origin.isLambda) {
|
if (valueArgument is IrBlock && valueArgument.origin.isLambda) {
|
||||||
val reference = valueArgument.statements.last() as IrFunctionReference
|
val reference = valueArgument.statements.last() as IrFunctionReference
|
||||||
visitInlineLambda(reference, function, parameter, currentScope!!.irElement as IrDeclaration)
|
visitInlineLambda(reference, function, parameter, data!!)
|
||||||
} else if (valueArgument is IrCallableReference<*>) {
|
} else if (valueArgument is IrCallableReference<*>) {
|
||||||
visitInlineReference(valueArgument)
|
visitInlineReference(valueArgument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.visitFunctionAccess(expression)
|
return super.visitFunctionAccess(expression, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun visitInlineReference(argument: IrCallableReference<*>) {}
|
open fun visitInlineReference(argument: IrCallableReference<*>) {}
|
||||||
|
|||||||
+4
-5
@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
|||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
import org.jetbrains.kotlin.load.java.JavaVisibilities
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -96,13 +95,13 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
private fun transformSuspendLambdasIntoContinuations(irFile: IrFile) {
|
private fun transformSuspendLambdasIntoContinuations(irFile: IrFile) {
|
||||||
val inlineReferences = mutableSetOf<IrCallableReference<*>>()
|
val inlineReferences = mutableSetOf<IrCallableReference<*>>()
|
||||||
val suspendLambdas = mutableMapOf<IrFunctionReference, SuspendLambdaInfo>()
|
val suspendLambdas = mutableMapOf<IrFunctionReference, SuspendLambdaInfo>()
|
||||||
irFile.acceptChildrenVoid(object : IrInlineReferenceLocator(context) {
|
irFile.acceptChildren(object : IrInlineReferenceLocator(context) {
|
||||||
override fun visitInlineReference(argument: IrCallableReference<*>) {
|
override fun visitInlineReference(argument: IrCallableReference<*>) {
|
||||||
inlineReferences.add(argument)
|
inlineReferences.add(argument)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionReference(expression: IrFunctionReference) {
|
override fun visitFunctionReference(expression: IrFunctionReference, data: IrDeclaration?) {
|
||||||
expression.acceptChildrenVoid(this)
|
expression.acceptChildren(this, data)
|
||||||
if (expression.isSuspend && expression.shouldBeTreatedAsSuspendLambda() && expression !in inlineReferences) {
|
if (expression.isSuspend && expression.shouldBeTreatedAsSuspendLambda() && expression !in inlineReferences) {
|
||||||
val isRestricted = expression.symbol.owner.extensionReceiverParameter?.type?.classOrNull?.owner?.annotations?.any {
|
val isRestricted = expression.symbol.owner.extensionReceiverParameter?.type?.classOrNull?.owner?.annotations?.any {
|
||||||
it.type.classOrNull?.signature == IdSignature.PublicSignature("kotlin.coroutines", "RestrictsSuspension", null, 0)
|
it.type.classOrNull?.signature == IdSignature.PublicSignature("kotlin.coroutines", "RestrictsSuspension", null, 0)
|
||||||
@@ -115,7 +114,7 @@ private class AddContinuationLowering(private val context: JvmBackendContext) :
|
|||||||
origin == IrStatementOrigin.LAMBDA ||
|
origin == IrStatementOrigin.LAMBDA ||
|
||||||
origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE ||
|
origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE ||
|
||||||
origin == IrStatementOrigin.SUSPEND_CONVERSION
|
origin == IrStatementOrigin.SUSPEND_CONVERSION
|
||||||
})
|
}, null)
|
||||||
|
|
||||||
for (lambda in suspendLambdas.values) {
|
for (lambda in suspendLambdas.values) {
|
||||||
(lambda.function.parent as IrDeclarationContainer).declarations.remove(lambda.function)
|
(lambda.function.parent as IrDeclarationContainer).declarations.remove(lambda.function)
|
||||||
|
|||||||
+3
-5
@@ -19,8 +19,6 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
|
|
||||||
internal val fakeInliningLocalVariablesLowering = makeIrFilePhase(
|
internal val fakeInliningLocalVariablesLowering = makeIrFilePhase(
|
||||||
@@ -31,11 +29,11 @@ internal val fakeInliningLocalVariablesLowering = makeIrFilePhase(
|
|||||||
|
|
||||||
internal class FakeInliningLocalVariablesLowering(val context: JvmBackendContext) : IrInlineReferenceLocator(context), FileLoweringPass {
|
internal class FakeInliningLocalVariablesLowering(val context: JvmBackendContext) : IrInlineReferenceLocator(context), FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.acceptVoid(this)
|
irFile.accept(this, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionNew(declaration: IrFunction) {
|
override fun visitFunction(declaration: IrFunction, data: IrDeclaration?) {
|
||||||
declaration.acceptChildrenVoid(this)
|
super.visitFunction(declaration, data)
|
||||||
if (declaration.isInline && !declaration.origin.isSynthetic && declaration.body != null) {
|
if (declaration.isInline && !declaration.origin.isSynthetic && declaration.body != null) {
|
||||||
declaration.addFakeInliningLocalVariables()
|
declaration.addFakeInliningLocalVariables()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user