Make IrScript a statement container first, update JS support
The IrScript is now the IrStatementContainer with significant statements order, and the code is adapted accordingly
This commit is contained in:
@@ -5,14 +5,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.declarations
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||
|
||||
//TODO: make IrScript as IrPackageFragment, because script is used as a file, not as a class
|
||||
//NOTE: declarations and statements stored separately
|
||||
abstract class IrScript :
|
||||
IrDeclarationBase(), IrSymbolDeclaration<IrScriptSymbol>, IrDeclarationContainer, IrDeclarationWithName, IrDeclarationParent {
|
||||
abstract val statements: MutableList<IrStatement>
|
||||
IrDeclarationBase(), IrSymbolDeclaration<IrScriptSymbol>, IrDeclarationWithName,
|
||||
IrDeclarationParent, IrStatementContainer {
|
||||
|
||||
// NOTE: is the result of the FE conversion, because there script interpreted as a class and has receiver
|
||||
abstract var thisReceiver: IrValueParameter
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
private val SCRIPT_ORIGIN = object : IrDeclarationOriginImpl("FIELD_FOR_OBJECT_INSTANCE") {}
|
||||
private val SCRIPT_ORIGIN = object : IrDeclarationOriginImpl("SCRIPT") {}
|
||||
|
||||
class IrScriptImpl(
|
||||
override val symbol: IrScriptSymbol,
|
||||
@@ -38,7 +38,6 @@ class IrScriptImpl(
|
||||
|
||||
override var annotations: List<IrConstructorCall> = SmartList()
|
||||
|
||||
override val declarations: MutableList<IrDeclaration> = mutableListOf()
|
||||
override val statements: MutableList<IrStatement> = mutableListOf()
|
||||
|
||||
override lateinit var thisReceiver: IrValueParameter
|
||||
@@ -59,13 +58,11 @@ class IrScriptImpl(
|
||||
}
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
declarations.forEach { it.accept(visitor, data) }
|
||||
statements.forEach { it.accept(visitor, data) }
|
||||
thisReceiver.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
declarations.transformInPlace(transformer, data)
|
||||
statements.transformInPlace(transformer, data)
|
||||
thisReceiver = thisReceiver.transform(transformer, data)
|
||||
}
|
||||
|
||||
@@ -117,10 +117,9 @@ open class DeepCopyIrTreeWithSymbols(
|
||||
//TODO: something may go wrong, because expected using symbolRemapper
|
||||
IrScriptSymbolImpl(declaration.descriptor as ScriptDescriptor),
|
||||
declaration.name
|
||||
).also {
|
||||
it.thisReceiver = declaration.thisReceiver.transform()
|
||||
declaration.transformDeclarationsTo(it)
|
||||
it.statements.addAll(declaration.statements.map { it.transform() })
|
||||
).also { scriptCopy ->
|
||||
scriptCopy.thisReceiver = declaration.thisReceiver.transform()
|
||||
declaration.statements.mapTo(scriptCopy.statements) { it.transform() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ private tailrec fun erase(type: IrType): IrClass? {
|
||||
|
||||
return when (classifier) {
|
||||
is IrClassSymbol -> classifier.owner
|
||||
is IrScriptSymbol -> null // TODO: check if correct
|
||||
is IrTypeParameterSymbol -> erase(classifier.owner.superTypes.first())
|
||||
else -> error(classifier)
|
||||
}
|
||||
|
||||
@@ -46,19 +46,42 @@ inline fun <T> MutableList<T>.transformFlat(transformation: (T) -> List<T>?) {
|
||||
while (i < size) {
|
||||
val item = get(i)
|
||||
|
||||
val transformed = transformation(item)
|
||||
i = replaceInPlace(transformation(item), i)
|
||||
}
|
||||
}
|
||||
|
||||
when (transformed?.size) {
|
||||
null -> i++
|
||||
0 -> removeAt(i)
|
||||
1 -> set(i++, transformed.first())
|
||||
else -> {
|
||||
addAll(i, transformed)
|
||||
i += transformed.size
|
||||
removeAt(i)
|
||||
}
|
||||
/**
|
||||
* Transforms a subset of a mutable list in place.
|
||||
* Each element `it` that has a type S is replaced with a result of `transformation(it)`,
|
||||
* `null` means "keep existing element" (to avoid creating excessive singleton lists).
|
||||
*/
|
||||
inline fun <T, reified S : T> MutableList<T>.transformSubsetFlat(transformation: (S) -> List<S>?) {
|
||||
var i = 0
|
||||
while (i < size) {
|
||||
val item = get(i)
|
||||
|
||||
if (item !is S) {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
|
||||
i = replaceInPlace(transformation(item), i)
|
||||
}
|
||||
}
|
||||
|
||||
@PublishedApi internal fun <T> MutableList<T>.replaceInPlace(transformed: List<T>?, atIndex: Int): Int {
|
||||
var i = atIndex
|
||||
when (transformed?.size) {
|
||||
null -> i++
|
||||
0 -> removeAt(i)
|
||||
1 -> set(i++, transformed.first())
|
||||
else -> {
|
||||
addAll(i, transformed)
|
||||
i += transformed.size
|
||||
removeAt(i)
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user