[JS IR BE] Validate parents
This commit is contained in:
+1
-2
@@ -19,8 +19,7 @@ package org.jetbrains.kotlin.backend.common
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrDynamicType
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.backend.common
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
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
|
||||
@@ -85,3 +86,32 @@ class IrValidator(val context: CommonBackendContext, val config: IrValidatorConf
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
}
|
||||
|
||||
fun IrModuleFragment.checkDeclarationParents() {
|
||||
this.accept(CheckDeclarationParentsVisitor, null)
|
||||
}
|
||||
|
||||
object CheckDeclarationParentsVisitor : IrElementVisitor<Unit, IrDeclarationParent?> {
|
||||
|
||||
override fun visitElement(element: IrElement, data: IrDeclarationParent?) {
|
||||
element.acceptChildren(this, element as? IrDeclarationParent ?: data)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration, data: IrDeclarationParent?) {
|
||||
checkParent(declaration, data)
|
||||
super.visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
private fun checkParent(declaration: IrDeclaration, expectedParent: IrDeclarationParent?) {
|
||||
val parent = try {
|
||||
declaration.parent
|
||||
} catch (e: Throwable) {
|
||||
error("$declaration for ${declaration.descriptor} has no parent")
|
||||
}
|
||||
|
||||
if (parent != expectedParent) {
|
||||
error("$declaration for ${declaration.descriptor} has unexpected parent $parent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.backend.common.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -44,6 +45,7 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.io.StringWriter
|
||||
@@ -164,13 +166,15 @@ fun IrValueParameter.copyTo(
|
||||
): IrValueParameter {
|
||||
val descriptor = WrappedValueParameterDescriptor(symbol.descriptor.annotations, symbol.descriptor.source)
|
||||
val symbol = IrValueParameterSymbolImpl(descriptor)
|
||||
val defaultValueCopy = defaultValue?.deepCopyWithVariables()
|
||||
defaultValueCopy?.patchDeclarationParents(irFunction)
|
||||
return IrValueParameterImpl(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
name, shift + index, type, varargElementType, isCrossinline, isNoinline
|
||||
).also {
|
||||
descriptor.bind(it)
|
||||
it.parent = irFunction
|
||||
it.defaultValue = defaultValue
|
||||
it.defaultValue = defaultValueCopy
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
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.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -106,6 +107,7 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
}, irInt(0))
|
||||
|
||||
val expressionBody = valueParameter.defaultValue!!
|
||||
expressionBody.patchDeclarationParents(newIrFunction)
|
||||
|
||||
expressionBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
@@ -126,6 +128,7 @@ open class DefaultArgumentStubGenerator constructor(val context: CommonBackendCo
|
||||
}
|
||||
|
||||
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
|
||||
temporaryVariable.parent = newIrFunction
|
||||
|
||||
params.add(temporaryVariable)
|
||||
variables[valueParameter] = temporaryVariable
|
||||
|
||||
+6
-1
@@ -19,12 +19,16 @@ import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrInstanceInitializerCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
|
||||
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.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -55,6 +59,7 @@ class InitializersLowering(
|
||||
val staticInitializerStatements = handleStatics(irClass)
|
||||
if (clinitNeeded && staticInitializerStatements.isNotEmpty())
|
||||
createStaticInitializationMethod(irClass, staticInitializerStatements)
|
||||
irClass.patchDeclarationParents(irClass.parent)
|
||||
}
|
||||
|
||||
fun handleNonStatics(irClass: IrClass) =
|
||||
|
||||
+9
-3
@@ -75,6 +75,7 @@ class InlineClassLowering(val context: BackendContext) {
|
||||
typeHint = irClass.defaultType.toKotlinType(),
|
||||
irType = irClass.defaultType
|
||||
)
|
||||
thisVar.parent = result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +89,13 @@ class InlineClassLowering(val context: BackendContext) {
|
||||
return expression
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
if (declaration.parent == irConstructor)
|
||||
declaration.parent = result
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
expression.transformChildrenVoid()
|
||||
if (expression.returnTargetSymbol == irConstructor.symbol) {
|
||||
@@ -121,9 +129,7 @@ class InlineClassLowering(val context: BackendContext) {
|
||||
function.body!!.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitDeclaration(declaration: IrDeclaration): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
|
||||
// TODO: Variable parents might not be initialized
|
||||
if (declaration !is IrVariable && declaration.parent == function)
|
||||
if (declaration.parent == function)
|
||||
declaration.parent = staticMethod
|
||||
|
||||
return declaration
|
||||
|
||||
+2
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -101,7 +102,7 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||
delegatingConstructorCall.startOffset, delegatingConstructorCall.endOffset, outerThisValueParameter
|
||||
)
|
||||
}
|
||||
|
||||
blockBody.patchDeclarationParents(loweredConstructor)
|
||||
loweredConstructor.body = blockBody
|
||||
return loweredConstructor
|
||||
}
|
||||
|
||||
+1
@@ -111,6 +111,7 @@ class LateinitLowering(
|
||||
val resultVar = scope.createTemporaryVariable(
|
||||
irGetField(getter.dispatchReceiverParameter?.let { irGet(it) }, backingField)
|
||||
)
|
||||
resultVar.parent = getter
|
||||
body.statements.add(resultVar)
|
||||
val throwIfNull = irIfThenElse(
|
||||
context.irBuiltIns.nothingType,
|
||||
|
||||
+6
-2
@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
@@ -215,7 +215,11 @@ open class LocalDeclarationsLowering(
|
||||
|
||||
rewriteDeclarations()
|
||||
|
||||
return collectRewrittenDeclarations()
|
||||
val rewrittenDeclarations = collectRewrittenDeclarations()
|
||||
rewrittenDeclarations.forEach {
|
||||
it.patchDeclarationParents(memberDeclaration.parent)
|
||||
}
|
||||
return rewrittenDeclarations
|
||||
}
|
||||
|
||||
private fun collectRewrittenDeclarations(): ArrayList<IrDeclaration> =
|
||||
|
||||
@@ -105,6 +105,7 @@ private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment, dependenc
|
||||
val validateIr = {
|
||||
val visitor = IrValidator(this, validatorConfig)
|
||||
moduleFragment.acceptVoid(visitor)
|
||||
moduleFragment.checkDeclarationParents()
|
||||
}
|
||||
validateIr()
|
||||
ThrowableSuccessorsLowering(this).lower(moduleFragment)
|
||||
@@ -144,7 +145,8 @@ private fun JsIrBackendContext.lower(moduleFragment: IrModuleFragment, dependenc
|
||||
validateIr()
|
||||
AutoboxingTransformer(this).lower(moduleFragment)
|
||||
BlockDecomposerLowering(this).runOnFilesPostfix(moduleFragment)
|
||||
|
||||
// TODO: Fix BlockDecomposerLowering parents
|
||||
moduleFragment.patchDeclarationParents()
|
||||
ClassReferenceLowering(this).lower(moduleFragment)
|
||||
PrimitiveCompanionLowering(this).lower(moduleFragment)
|
||||
ConstLowering(this).lower(moduleFragment)
|
||||
|
||||
+5
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||
import org.jetbrains.kotlin.ir.util.getInlinedClass
|
||||
import org.jetbrains.kotlin.ir.util.isInlined
|
||||
import org.jetbrains.kotlin.ir.util.isNullable
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
|
||||
|
||||
// Copied and adapted from Kotlin/Native
|
||||
@@ -24,6 +25,9 @@ import org.jetbrains.kotlin.ir.util.isNullable
|
||||
class AutoboxingTransformer(val context: JsIrBackendContext) : AbstractValueUsageTransformer(context.irBuiltIns), FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid()
|
||||
|
||||
// TODO: Track & insert parents for temporary variables
|
||||
irFile.patchDeclarationParents()
|
||||
}
|
||||
|
||||
override fun IrExpression.useAs(type: IrType): IrExpression {
|
||||
@@ -101,6 +105,7 @@ class AutoboxingTransformer(val context: JsIrBackendContext) : AbstractValueUsag
|
||||
if (!actualType.isNullable())
|
||||
return call(arg)
|
||||
return JsIrBuilder.run {
|
||||
// TODO: Set parent of local variables
|
||||
val tmp = buildVar(actualType, parent = null, initializer = arg)
|
||||
val nullCheck = buildIfElse(
|
||||
type = resultType,
|
||||
|
||||
+3
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
@@ -47,6 +48,7 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine
|
||||
}
|
||||
|
||||
private fun IrExpressionBody.toBlockBody(containingFunction: IrFunction): IrBlockBody {
|
||||
expression.patchDeclarationParents(containingFunction)
|
||||
val returnStatement = JsIrBuilder.buildReturn(containingFunction.symbol, expression, nothingType)
|
||||
return IrBlockBodyImpl(expression.startOffset, expression.endOffset).apply {
|
||||
statements += returnStatement
|
||||
@@ -63,7 +65,7 @@ class BlockDecomposerLowering(context: JsIrBackendContext) : DeclarationContaine
|
||||
)
|
||||
|
||||
val newBody = toBlockBody(initFunction)
|
||||
|
||||
newBody.patchDeclarationParents(initFunction)
|
||||
initFunction.body = newBody
|
||||
|
||||
lower(initFunction)
|
||||
|
||||
+6
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import java.util.*
|
||||
|
||||
@@ -332,6 +333,9 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
|
||||
for ((entry, instanceVar) in enumEntries.zip(entryInstances)) {
|
||||
+irSetVar(instanceVar.symbol, entry.initializerExpression!!)
|
||||
}
|
||||
}.also {
|
||||
// entry.initializerExpression can have local declarations
|
||||
it.acceptVoid(PatchDeclarationParentsVisitor(irClass))
|
||||
}
|
||||
|
||||
private fun createEntryInstancesInitializedVar(): IrVariable {
|
||||
@@ -429,6 +433,8 @@ class EnumClassTransformer(val context: JsIrBackendContext, private val irClass:
|
||||
copyParameterDeclarationsFrom(enumConstructor)
|
||||
body = enumConstructor.body
|
||||
loweredEnumConstructors[enumConstructor.symbol] = this
|
||||
|
||||
this.acceptVoid(PatchDeclarationParentsVisitor(enumClass))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -11,9 +11,9 @@ import org.jetbrains.kotlin.backend.common.utils.isSubtypeOf
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBranchImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCatchImpl
|
||||
@@ -58,8 +58,9 @@ class MultipleCatchesLowering(val context: JsIrBackendContext) : FileLoweringPas
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildren(object : IrElementTransformer<IrDeclarationParent> {
|
||||
|
||||
override fun visitFunction(declaration: IrFunction, data: IrDeclarationParent): IrStatement {
|
||||
return super.visitFunction(declaration, declaration)
|
||||
override fun visitDeclaration(declaration: IrDeclaration, data: IrDeclarationParent): IrStatement {
|
||||
val parent = (declaration as? IrDeclarationParent) ?: data
|
||||
return super.visitDeclaration(declaration, parent)
|
||||
}
|
||||
|
||||
override fun visitTry(aTry: IrTry, data: IrDeclarationParent): IrExpression {
|
||||
|
||||
+3
-2
@@ -258,8 +258,9 @@ internal class SuspendFunctionsLowering(val context: JsIrBackendContext): FileLo
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return coroutine.coroutineClass
|
||||
val coroutineClass = coroutine.coroutineClass
|
||||
coroutineClass.patchDeclarationParents(coroutineClass.parent)
|
||||
return coroutineClass
|
||||
}
|
||||
|
||||
private class BuiltCoroutine(
|
||||
|
||||
Reference in New Issue
Block a user