Extracted some common code.

Sometimes it would be nice to know context during IR rewriting, this is when
IrElementTransformerVoidWithContext comes in handy.
This commit is contained in:
Igor Chevdar
2017-03-06 14:28:03 +03:00
parent 8c1c9f5660
commit c76c214763
2 changed files with 47 additions and 20 deletions
@@ -0,0 +1,44 @@
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
abstract class IrElementTransformerVoidWithContext(): IrElementTransformerVoid() {
private fun <E> MutableList<E>.push(element: E) = this.add(element)
private fun <E> MutableList<E>.pop() = this.removeAt(size - 1)
private fun <E> MutableList<E>.peek(): E? = if (size == 0) null else this[size - 1]
private val functionsStack = mutableListOf<FunctionDescriptor>()
private val classesStack = mutableListOf<ClassDescriptor>()
override final fun visitFunction(declaration: IrFunction): IrStatement {
functionsStack.push(declaration.descriptor)
val result = visitFunctionNew(declaration)
functionsStack.pop()
return result
}
override final fun visitClass(declaration: IrClass): IrStatement {
classesStack.push(declaration.descriptor)
val result = visitClassNew(declaration)
classesStack.pop()
return result
}
protected val currentFunction get() = functionsStack.peek()
protected val currentClass get() = classesStack.peek()
open fun visitFunctionNew(declaration: IrFunction) : IrStatement {
return super.visitFunction(declaration)
}
open fun visitClassNew(declaration: IrClass) : IrStatement {
return super.visitClass(declaration)
}
}
@@ -1,14 +1,13 @@
package org.jetbrains.kotlin.backend.konan.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.lower.callsSuper
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
@@ -84,22 +82,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
}
private fun lowerOuterThisReferences() {
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
private fun <E> MutableList<E>.push(element: E) = this.add(element)
private fun <E> MutableList<E>.pop() = this.removeAt(size - 1)
private fun <E> MutableList<E>.peek(): E? = if (size == 0) null else this[size - 1]
private val functionsStack = mutableListOf<FunctionDescriptor>()
override fun visitFunction(declaration: IrFunction): IrStatement {
functionsStack.push(declaration.descriptor)
val result = super.visitFunction(declaration)
functionsStack.pop()
return result
}
irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
override fun visitGetValue(expression: IrGetValue): IrExpression {
expression.transformChildrenVoid(this)
@@ -108,7 +91,7 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
if (implicitThisClass == classDescriptor) return expression
val constructorDescriptor = functionsStack.peek()!! as? ConstructorDescriptor
val constructorDescriptor = currentFunction!! as? ConstructorDescriptor
val startOffset = expression.startOffset
val endOffset = expression.endOffset