[JS IR BE] Fix validation errors (duplicate nodes and incorrect parent)
This commit is contained in:
committed by
Anton Bannykh
parent
d36d62e226
commit
cb15570d75
+32
-10
@@ -111,17 +111,17 @@ open class DefaultArgumentStubGenerator(
|
|||||||
val defaultFlag =
|
val defaultFlag =
|
||||||
irCallOp(this@DefaultArgumentStubGenerator.context.ir.symbols.intAnd, context.irBuiltIns.intType, mask, bit)
|
irCallOp(this@DefaultArgumentStubGenerator.context.ir.symbols.intAnd, context.irBuiltIns.intType, mask, bit)
|
||||||
|
|
||||||
val expressionBody = valueParameter.defaultValue!!
|
val expression = valueParameter.defaultValue!!.expression
|
||||||
expressionBody.patchDeclarationParents(newIrFunction)
|
.prepareToBeUsedIn(newIrFunction)
|
||||||
expressionBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
.transform(object : IrElementTransformerVoid() {
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
log { "GetValue: ${expression.symbol.owner}" }
|
log { "GetValue: ${expression.symbol.owner}" }
|
||||||
val valueSymbol = variables[expression.symbol.owner] ?: return expression
|
val valueSymbol = variables[expression.symbol.owner] ?: return expression
|
||||||
return irGet(valueSymbol)
|
return irGet(valueSymbol)
|
||||||
}
|
}
|
||||||
})
|
}, null)
|
||||||
|
|
||||||
selectArgumentOrDefault(defaultFlag, parameter, expressionBody.expression)
|
selectArgumentOrDefault(defaultFlag, parameter, expression)
|
||||||
} else {
|
} else {
|
||||||
parameter
|
parameter
|
||||||
}
|
}
|
||||||
@@ -147,6 +147,28 @@ open class DefaultArgumentStubGenerator(
|
|||||||
return listOf(irFunction, newIrFunction)
|
return listOf(irFunction, newIrFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares the default value to be used inside the `function` body by patching the parents.
|
||||||
|
* In K/JS it also copies the expression in order to avoid duplicate declarations after this lowering.
|
||||||
|
*
|
||||||
|
* In K/JVM copying doesn't preserve metadata, so the following case won't work:
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* import kotlin.reflect.jvm.reflect
|
||||||
|
*
|
||||||
|
* fun foo(x: Function<*> = {}) {
|
||||||
|
* // Will print "null" if lambda is copied
|
||||||
|
* println(x.reflect())
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* Thus the duplicate declarations during the lowering pipeline is considered to be a lesser evil.
|
||||||
|
*/
|
||||||
|
protected open fun IrExpression.prepareToBeUsedIn(function: IrFunction): IrExpression {
|
||||||
|
return patchDeclarationParents(function)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
protected open fun IrBlockBodyBuilder.selectArgumentOrDefault(
|
protected open fun IrBlockBodyBuilder.selectArgumentOrDefault(
|
||||||
defaultFlag: IrExpression,
|
defaultFlag: IrExpression,
|
||||||
parameter: IrValueParameter,
|
parameter: IrValueParameter,
|
||||||
|
|||||||
+1
-4
@@ -407,12 +407,9 @@ class EnumClassCreateInitializerLowering(val context: JsIrBackendContext) : Decl
|
|||||||
|
|
||||||
irClass.enumEntries.forEach { entry ->
|
irClass.enumEntries.forEach { entry ->
|
||||||
entry.correspondingField?.let { instanceField ->
|
entry.correspondingField?.let { instanceField ->
|
||||||
+irSetField(null, instanceField, entry.initializerExpression!!.expression)
|
+irSetField(null, instanceField, entry.initializerExpression!!.expression.deepCopyWithSymbols(it))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.also {
|
|
||||||
// entry.initializerExpression can have local declarations
|
|
||||||
it.acceptVoid(PatchDeclarationParentsVisitor(irClass))
|
|
||||||
}.statements
|
}.statements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
|
import org.jetbrains.kotlin.backend.common.ir.isOverridableOrOverrides
|
||||||
import org.jetbrains.kotlin.backend.common.lower.DefaultArgumentStubGenerator
|
import org.jetbrains.kotlin.backend.common.lower.DefaultArgumentStubGenerator
|
||||||
import org.jetbrains.kotlin.backend.common.lower.DEFAULT_DISPATCH_CALL
|
import org.jetbrains.kotlin.backend.common.lower.DEFAULT_DISPATCH_CALL
|
||||||
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.*
|
|||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
|
||||||
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||||
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
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
|
||||||
@@ -44,6 +46,12 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun IrExpression.prepareToBeUsedIn(function: IrFunction): IrExpression {
|
||||||
|
return deepCopyWithVariables().also {
|
||||||
|
it.patchDeclarationParents(function)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun resolveInvoke(paramCount: Int): IrSimpleFunction {
|
private fun resolveInvoke(paramCount: Int): IrSimpleFunction {
|
||||||
assert(paramCount > 0)
|
assert(paramCount > 0)
|
||||||
val functionKlass = context.ir.symbols.functionN(paramCount).owner
|
val functionKlass = context.ir.symbols.functionN(paramCount).owner
|
||||||
|
|||||||
+12
-6
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.builders.*
|
|||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
|
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -35,11 +36,9 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
|
|||||||
|
|
||||||
private val throwISE = context.throwISEsymbol
|
private val throwISE = context.throwISEsymbol
|
||||||
|
|
||||||
private val newDeclarations = mutableListOf<IrDeclaration>()
|
|
||||||
|
|
||||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||||
newDeclarations.clear()
|
val currentParent = container as? IrDeclarationParent ?: container.parent
|
||||||
irBody.transformChildrenVoid(PropertyReferenceTransformer())
|
val newDeclarations = PropertyReferenceTransformer(currentParent).process(irBody)
|
||||||
if (!newDeclarations.isEmpty()) {
|
if (!newDeclarations.isEmpty()) {
|
||||||
val file = container.file
|
val file = container.file
|
||||||
newDeclarations.forEach { it.parent = file }
|
newDeclarations.forEach { it.parent = file }
|
||||||
@@ -47,7 +46,14 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class PropertyReferenceTransformer : IrElementTransformerVoid() {
|
private inner class PropertyReferenceTransformer(var currentParent: IrDeclarationParent) : IrElementTransformerVoid() {
|
||||||
|
|
||||||
|
val newDeclarations = mutableListOf<IrDeclaration>()
|
||||||
|
|
||||||
|
fun process(irBody: IrBody): List<IrDeclaration> {
|
||||||
|
irBody.transformChildrenVoid(this)
|
||||||
|
return newDeclarations
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildFactoryFunction(reference: IrPropertyReference): IrSimpleFunction {
|
private fun buildFactoryFunction(reference: IrPropertyReference): IrSimpleFunction {
|
||||||
val property = reference.symbol.owner
|
val property = reference.symbol.owner
|
||||||
@@ -240,7 +246,7 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
|
|||||||
name = Name.identifier("${delegatedVar.name}\$stub")
|
name = Name.identifier("${delegatedVar.name}\$stub")
|
||||||
}
|
}
|
||||||
|
|
||||||
function.parent = delegatedVar.parent
|
function.parent = currentParent
|
||||||
|
|
||||||
function.body = with(context.createIrBuilder(function.symbol)) {
|
function.body = with(context.createIrBuilder(function.symbol)) {
|
||||||
irBlockBody {
|
irBlockBody {
|
||||||
|
|||||||
+3
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.util.explicitParameters
|
import org.jetbrains.kotlin.ir.util.explicitParameters
|
||||||
|
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
import org.jetbrains.kotlin.utils.DFS
|
||||||
@@ -173,6 +174,8 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
|||||||
}
|
}
|
||||||
|
|
||||||
stateMachineFunction.transform(LiveLocalsTransformer(localToPropertyMap, { JsIrBuilder.buildGetValue(thisReceiver) }, unit), null)
|
stateMachineFunction.transform(LiveLocalsTransformer(localToPropertyMap, { JsIrBuilder.buildGetValue(thisReceiver) }, unit), null)
|
||||||
|
// TODO find out why some parents are incorrect
|
||||||
|
stateMachineFunction.body!!.patchDeclarationParents(stateMachineFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignStateIds(entryState: SuspendState, subject: IrVariableSymbol, switch: IrWhen, rootLoop: IrLoop) {
|
private fun assignStateIds(entryState: SuspendState, subject: IrVariableSymbol, switch: IrWhen, rootLoop: IrLoop) {
|
||||||
|
|||||||
Reference in New Issue
Block a user