[JS IR BE] Codegen class model refactorings
Reduce JsScope usage
This commit is contained in:
+2
-2
@@ -128,14 +128,14 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
|
||||
override fun visitWhileLoop(loop: IrWhileLoop, context: JsGenerationContext): JsStatement {
|
||||
//TODO what if body null?
|
||||
val label = context.getNameForLoop(loop)?.let { context.staticContext.rootScope.declareName(it) }
|
||||
val label = context.getNameForLoop(loop)
|
||||
val loopStatement = JsWhile(loop.condition.accept(IrElementToJsExpressionTransformer(), context), loop.body?.accept(this, context))
|
||||
return label?.let { JsLabel(it, loopStatement) } ?: loopStatement
|
||||
}
|
||||
|
||||
override fun visitDoWhileLoop(loop: IrDoWhileLoop, context: JsGenerationContext): JsStatement {
|
||||
//TODO what if body null?
|
||||
val label = context.getNameForLoop(loop)?.let { context.staticContext.rootScope.declareName(it) }
|
||||
val label = context.getNameForLoop(loop)
|
||||
val loopStatement =
|
||||
JsDoWhile(loop.condition.accept(IrElementToJsExpressionTransformer(), context), loop.body?.accept(this, context))
|
||||
return label?.let { JsLabel(it, loopStatement) } ?: loopStatement
|
||||
|
||||
+11
-17
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
@@ -120,8 +121,6 @@ class IrModuleToJsTransformer(
|
||||
return JsExpressionStatement(expression)
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun generateModule(module: IrModuleFragment): JsProgram {
|
||||
val additionalPackages = with(backendContext) {
|
||||
externalPackageFragment.values + listOf(
|
||||
@@ -135,13 +134,11 @@ class IrModuleToJsTransformer(
|
||||
val program = JsProgram()
|
||||
|
||||
val nameGenerator = IrNamerImpl(
|
||||
newNameTables = namer,
|
||||
rootScope = program.rootScope
|
||||
newNameTables = namer
|
||||
)
|
||||
val staticContext = JsStaticContext(
|
||||
backendContext = backendContext,
|
||||
irNamer = nameGenerator,
|
||||
rootScope = program.rootScope
|
||||
irNamer = nameGenerator
|
||||
)
|
||||
val rootContext = JsGenerationContext(
|
||||
parent = null,
|
||||
@@ -261,13 +258,13 @@ class IrModuleToJsTransformer(
|
||||
generateModule(declaration)
|
||||
|
||||
private fun processClassModels(
|
||||
classModelMap: Map<JsName, JsClassModel>,
|
||||
classModelMap: Map<IrClassSymbol, JsIrClassModel>,
|
||||
preDeclarationBlock: JsBlock,
|
||||
postDeclarationBlock: JsBlock
|
||||
) {
|
||||
val declarationHandler = object : DFS.AbstractNodeHandler<JsName, Unit>() {
|
||||
val declarationHandler = object : DFS.AbstractNodeHandler<IrClassSymbol, Unit>() {
|
||||
override fun result() {}
|
||||
override fun afterChildren(current: JsName) {
|
||||
override fun afterChildren(current: IrClassSymbol) {
|
||||
classModelMap[current]?.let {
|
||||
preDeclarationBlock.statements += it.preDeclarationBlock.statements
|
||||
postDeclarationBlock.statements += it.postDeclarationBlock.statements
|
||||
@@ -275,13 +272,10 @@ class IrModuleToJsTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
DFS.dfs(classModelMap.keys, {
|
||||
val neighbors = mutableListOf<JsName>()
|
||||
classModelMap[it]?.run {
|
||||
if (superName != null) neighbors += superName!!
|
||||
neighbors += interfaces
|
||||
}
|
||||
neighbors
|
||||
}, declarationHandler)
|
||||
DFS.dfs(
|
||||
classModelMap.keys,
|
||||
{ klass -> classModelMap[klass]?.superClasses ?: emptyList() },
|
||||
declarationHandler
|
||||
)
|
||||
}
|
||||
}
|
||||
+9
-2
@@ -31,7 +31,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
}
|
||||
private val classPrototypeRef = prototypeOf(classNameRef)
|
||||
private val classBlock = JsGlobalBlock()
|
||||
private val classModel = JsClassModel(className, baseClassName)
|
||||
private val classModel = JsIrClassModel(irClass)
|
||||
|
||||
fun generate(): JsStatement {
|
||||
assert(!irClass.descriptor.isExpect)
|
||||
@@ -103,7 +103,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
}
|
||||
}
|
||||
}
|
||||
context.staticContext.classModels[className] = classModel
|
||||
context.staticContext.classModels[irClass.symbol] = classModel
|
||||
return classBlock
|
||||
}
|
||||
|
||||
@@ -278,3 +278,10 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
|
||||
private val IrClassifierSymbol.isInterface get() = (owner as? IrClass)?.isInterface == true
|
||||
private val IrClassifierSymbol.isEffectivelyExternal get() = (owner as? IrDeclaration)?.isEffectivelyExternal() == true
|
||||
|
||||
class JsIrClassModel(val klass: IrClass) {
|
||||
val superClasses = klass.superTypes.map { it.classifierOrFail as IrClassSymbol }
|
||||
|
||||
val preDeclarationBlock = JsGlobalBlock()
|
||||
val postDeclarationBlock = JsGlobalBlock()
|
||||
}
|
||||
|
||||
@@ -21,5 +21,5 @@ interface IrNamer {
|
||||
fun getNameForStaticDeclaration(declaration: IrDeclarationWithName): JsName
|
||||
fun getNameForProperty(property: IrProperty): JsName
|
||||
fun getRefForExternalClass(klass: IrClass): JsNameRef
|
||||
fun getNameForLoop(loop: IrLoop): String?
|
||||
fun getNameForLoop(loop: IrLoop): JsName?
|
||||
}
|
||||
+11
-15
@@ -12,18 +12,15 @@ import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsNameRef
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsRootScope
|
||||
|
||||
class IrNamerImpl(
|
||||
private val newNameTables: NameTables,
|
||||
private val rootScope: JsRootScope // TODO: Don't use scopes
|
||||
) : IrNamer {
|
||||
class IrNamerImpl(private val newNameTables: NameTables) : IrNamer {
|
||||
|
||||
override fun getNameForStaticDeclaration(declaration: IrDeclarationWithName): JsName {
|
||||
val name = newNameTables.getNameForStaticDeclaration(declaration)
|
||||
return rootScope.declareName(name)
|
||||
}
|
||||
private fun String.toJsName() = JsName(this)
|
||||
|
||||
override fun getNameForLoop(loop: IrLoop): String? =
|
||||
newNameTables.getNameForLoop(loop)
|
||||
override fun getNameForStaticDeclaration(declaration: IrDeclarationWithName): JsName =
|
||||
newNameTables.getNameForStaticDeclaration(declaration).toJsName()
|
||||
|
||||
override fun getNameForLoop(loop: IrLoop): JsName? =
|
||||
newNameTables.getNameForLoop(loop)?.toJsName()
|
||||
|
||||
override fun getNameForConstructor(constructor: IrConstructor): JsName {
|
||||
return getNameForStaticDeclaration(constructor.parentAsClass)
|
||||
@@ -31,12 +28,12 @@ class IrNamerImpl(
|
||||
|
||||
override fun getNameForMemberFunction(function: IrSimpleFunction): JsName {
|
||||
require(function.dispatchReceiverParameter != null)
|
||||
return rootScope.declareName(newNameTables.getNameForMemberFunction(function))
|
||||
return newNameTables.getNameForMemberFunction(function).toJsName()
|
||||
}
|
||||
|
||||
override fun getNameForMemberField(field: IrField): JsName {
|
||||
require(!field.isStatic)
|
||||
return rootScope.declareName(newNameTables.getNameForMemberField(field))
|
||||
return newNameTables.getNameForMemberField(field).toJsName()
|
||||
}
|
||||
|
||||
override fun getNameForField(field: IrField): JsName {
|
||||
@@ -56,9 +53,8 @@ class IrNamerImpl(
|
||||
override fun getNameForStaticFunction(function: IrSimpleFunction): JsName =
|
||||
getNameForStaticDeclaration(function)
|
||||
|
||||
override fun getNameForProperty(property: IrProperty): JsName {
|
||||
return rootScope.declareName(property.getJsNameOrKotlinName().asString())
|
||||
}
|
||||
override fun getNameForProperty(property: IrProperty): JsName =
|
||||
property.getJsNameOrKotlinName().asString().toJsName()
|
||||
|
||||
override fun getRefForExternalClass(klass: IrClass): JsNameRef {
|
||||
val parent = klass.parent
|
||||
|
||||
+3
-6
@@ -7,22 +7,19 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIntrinsicTransformers
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrClassModel
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsClassModel
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsName
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsRootScope
|
||||
|
||||
|
||||
class JsStaticContext(
|
||||
val rootScope: JsRootScope,
|
||||
val backendContext: JsIrBackendContext,
|
||||
private val irNamer: IrNamer
|
||||
) : IrNamer by irNamer {
|
||||
|
||||
val intrinsics = JsIntrinsicTransformers(backendContext)
|
||||
// TODO: use IrSymbol instead of JsName
|
||||
val classModels = mutableMapOf<JsName, JsClassModel>()
|
||||
val classModels = mutableMapOf<IrClassSymbol, JsIrClassModel>()
|
||||
val coroutineImplDeclaration = backendContext.ir.symbols.coroutineImpl.owner
|
||||
val doResumeFunctionSymbol = coroutineImplDeclaration.declarations
|
||||
.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == "doResume" }.symbol
|
||||
|
||||
@@ -18,6 +18,5 @@ package org.jetbrains.kotlin.js.backend.ast
|
||||
|
||||
class JsClassModel(val name: JsName, val superName: JsName?) {
|
||||
val interfaces: MutableSet<JsName> = mutableSetOf()
|
||||
val preDeclarationBlock = JsGlobalBlock() // TODO only used in IR backend => hide from current backend
|
||||
val postDeclarationBlock = JsGlobalBlock()
|
||||
}
|
||||
|
||||
@@ -20,11 +20,15 @@ public class JsName extends HasMetadata implements Symbol {
|
||||
/**
|
||||
* @param ident the unmangled ident to use for this name
|
||||
*/
|
||||
JsName(@NotNull String ident, boolean temporary) {
|
||||
public JsName(@NotNull String ident, boolean temporary) {
|
||||
this.ident = ident;
|
||||
this.temporary = temporary;
|
||||
}
|
||||
|
||||
public JsName(@NotNull String ident) {
|
||||
this(ident, false);
|
||||
}
|
||||
|
||||
public boolean isTemporary() {
|
||||
return temporary;
|
||||
}
|
||||
|
||||
@@ -137,9 +137,7 @@ class ImportIntoFragmentInliningScope private constructor(
|
||||
get() = JsBlock(
|
||||
JsBlock(fragment.inlinedLocalDeclarations.values.toList()),
|
||||
fragment.declarationBlock,
|
||||
JsBlock(fragment.classes.values.flatMap {
|
||||
listOf(it.preDeclarationBlock, it.postDeclarationBlock)
|
||||
}),
|
||||
JsBlock(fragment.classes.values.map { it.postDeclarationBlock }),
|
||||
fragment.exportBlock,
|
||||
JsExpressionStatement(JsFunction(JsDynamicScope, fragment.initializerBlock, ""))
|
||||
).also { block ->
|
||||
|
||||
Reference in New Issue
Block a user