From 685597d20a9c5c03627b475f5c6de2f22d590011 Mon Sep 17 00:00:00 2001 From: Svyatoslav Kuzmich Date: Mon, 24 Jun 2019 15:07:59 +0300 Subject: [PATCH] [JS IR BE] Codegen class model refactorings Reduce JsScope usage --- .../IrElementToJsStatementTransformer.kt | 4 +-- .../irToJs/IrModuleToJsTransformer.kt | 28 ++++++++----------- .../transformers/irToJs/JsClassGenerator.kt | 11 ++++++-- .../kotlin/ir/backend/js/utils/IrNamer.kt | 2 +- .../kotlin/ir/backend/js/utils/IrNamerImpl.kt | 26 ++++++++--------- .../ir/backend/js/utils/JsStaticContext.kt | 9 ++---- .../kotlin/js/backend/ast/JsClassModel.kt | 1 - .../kotlin/js/backend/ast/JsName.java | 6 +++- .../kotlin/js/inline/InliningScope.kt | 4 +-- 9 files changed, 43 insertions(+), 48 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt index de2cacedacb..39dad0cc1d0 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/IrElementToJsStatementTransformer.kt @@ -128,14 +128,14 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer, + classModelMap: Map, preDeclarationBlock: JsBlock, postDeclarationBlock: JsBlock ) { - val declarationHandler = object : DFS.AbstractNodeHandler() { + val declarationHandler = object : DFS.AbstractNodeHandler() { 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() - classModelMap[it]?.run { - if (superName != null) neighbors += superName!! - neighbors += interfaces - } - neighbors - }, declarationHandler) + DFS.dfs( + classModelMap.keys, + { klass -> classModelMap[klass]?.superClasses ?: emptyList() }, + declarationHandler + ) } } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt index 6945296715c..1c4dc89db32 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/transformers/irToJs/JsClassGenerator.kt @@ -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() +} diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt index 7c41be731fc..0cf646b81af 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamer.kt @@ -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? } \ No newline at end of file diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamerImpl.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamerImpl.kt index c40cabdb16a..967ca584f23 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamerImpl.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/IrNamerImpl.kt @@ -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 diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt index 14b575c108b..cf4dd75c1ae 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/JsStaticContext.kt @@ -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() + val classModels = mutableMapOf() val coroutineImplDeclaration = backendContext.ir.symbols.coroutineImpl.owner val doResumeFunctionSymbol = coroutineImplDeclaration.declarations .filterIsInstance().single { it.name.asString() == "doResume" }.symbol diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt index b6cc71dab8a..0a4df27a1cd 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsClassModel.kt @@ -18,6 +18,5 @@ package org.jetbrains.kotlin.js.backend.ast class JsClassModel(val name: JsName, val superName: JsName?) { val interfaces: MutableSet = mutableSetOf() - val preDeclarationBlock = JsGlobalBlock() // TODO only used in IR backend => hide from current backend val postDeclarationBlock = JsGlobalBlock() } diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsName.java b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsName.java index 2c1b27e0596..3d62d24eb4f 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsName.java +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/JsName.java @@ -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; } diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/InliningScope.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/InliningScope.kt index 429036fca65..8d4e70f3a37 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/InliningScope.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/InliningScope.kt @@ -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 ->