diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index cb032dbcd7f..c401c90df1b 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -11,10 +11,7 @@ import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.js.JsDeclarationFactory import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.IrElement @@ -25,6 +22,7 @@ import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder import org.jetbrains.kotlin.ir.backend.js.lower.CallableReferenceKey import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.* @@ -60,11 +58,34 @@ class JsIrBackendContext( val devMode = configuration[JSConfigurationKeys.DEVELOPER_MODE] ?: false - var externalPackageFragment = mutableMapOf() - lateinit var bodilessBuiltInsPackageFragment: IrPackageFragment + val externalPackageFragment = mutableMapOf() + val bodilessBuiltInsPackageFragment: IrPackageFragment = run { - val externalNestedClasses = mutableListOf() - val packageLevelJsModules = mutableListOf() + class DescriptorlessExternalPackageFragmentSymbol : IrExternalPackageFragmentSymbol { + override val descriptor: PackageFragmentDescriptor + get() = error("Operation is unsupported") + + private var _owner: IrExternalPackageFragment? = null + override val owner get() = _owner!! + + override var uniqId: UniqId + get() = error("Operation is unsupported") + set(value) { error("Operation is unsupported") } + + override val isBound get() = _owner != null + + override fun bind(owner: IrExternalPackageFragment) { + _owner = owner + } + } + + IrExternalPackageFragmentImpl( + DescriptorlessExternalPackageFragmentSymbol(), + FqName("kotlin") + ) + } + + val packageLevelJsModules = mutableSetOf() val declarationLevelJsModules = mutableListOf() val internalPackageFragmentDescriptor = EmptyPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal")) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt index fb6df3de1aa..997a5174d6f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/MoveBodilessDeclarationsToSeparatePlace.kt @@ -5,20 +5,18 @@ package org.jetbrains.kotlin.ir.backend.js.lower +import org.jetbrains.kotlin.backend.common.DeclarationTransformer import org.jetbrains.kotlin.backend.common.ir.addChild import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext import org.jetbrains.kotlin.ir.backend.js.utils.getJsModule import org.jetbrains.kotlin.ir.backend.js.utils.getJsQualifier import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl -import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.util.UniqId import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.ir.util.isEffectivelyExternal -import org.jetbrains.kotlin.ir.util.transformFlat import org.jetbrains.kotlin.name.FqName private val BODILESS_BUILTIN_CLASSES = listOf( @@ -43,24 +41,6 @@ private val BODILESS_BUILTIN_CLASSES = listOf( "kotlin.Function" ).map { FqName(it) }.toSet() -private class DescriptorlessExternalPackageFragmentSymbol : IrExternalPackageFragmentSymbol { - override val descriptor: PackageFragmentDescriptor - get() = error("Operation is unsupported") - - private var _owner: IrExternalPackageFragment? = null - override val owner get() = _owner!! - - override var uniqId: UniqId - get() = error("Operation is unsupported") - set(value) { error("Operation is unsupported") } - - override val isBound get() = _owner != null - - override fun bind(owner: IrExternalPackageFragment) { - _owner = owner - } -} - private class DescriptorlessIrFileSymbol : IrFileSymbol { override fun bind(owner: IrFile) { _owner = owner @@ -79,33 +59,22 @@ private class DescriptorlessIrFileSymbol : IrFileSymbol { override val isBound get() = _owner != null } +private fun isBuiltInClass(declaration: IrDeclaration): Boolean = + declaration is IrClass && declaration.fqNameWhenAvailable in BODILESS_BUILTIN_CLASSES -fun moveBodilessDeclarationsToSeparatePlace(context: JsIrBackendContext, module: IrModuleFragment) { - - val bodilessBuiltInsPackageFragment = IrExternalPackageFragmentImpl( - DescriptorlessExternalPackageFragmentSymbol(), - FqName("kotlin") - ) - - context.bodilessBuiltInsPackageFragment = bodilessBuiltInsPackageFragment - - fun isBuiltInClass(declaration: IrDeclaration): Boolean = - declaration is IrClass && declaration.fqNameWhenAvailable in BODILESS_BUILTIN_CLASSES - - fun collectExternalClasses(container: IrDeclarationContainer, includeCurrentLevel: Boolean): List { - val externalClasses = - container.declarations.filterIsInstance().filter { it.isEffectivelyExternal() } - - val nestedExternalClasses = - externalClasses.flatMap { collectExternalClasses(it, true) } - - return if (includeCurrentLevel) - externalClasses + nestedExternalClasses - else - nestedExternalClasses +fun moveBodilessDeclarationsToSeparatePlace(context: JsIrBackendContext, moduleFragment: IrModuleFragment) { + MoveBodilessDeclarationsToSeparatePlaceLowering(context).let { moveBodiless -> + moduleFragment.files.forEach { + moveBodiless.lower(it) + } } +} + +class MoveBodilessDeclarationsToSeparatePlaceLowering(private val context: JsIrBackendContext) : DeclarationTransformer { + + override fun transformFlat(declaration: IrDeclaration): List? { + val irFile = declaration.parent as? IrFile ?: return null - fun lowerFile(irFile: IrFile): IrFile? { val externalPackageFragment by lazy { context.externalPackageFragment.getOrPut(irFile.symbol) { IrFileImpl(fileEntry = irFile.fileEntry, fqName = irFile.fqName, symbol = DescriptorlessIrFileSymbol()).also { @@ -114,33 +83,30 @@ fun moveBodilessDeclarationsToSeparatePlace(context: JsIrBackendContext, module: } } - context.externalNestedClasses += collectExternalClasses(irFile, includeCurrentLevel = false) - if (irFile.getJsModule() != null || irFile.getJsQualifier() != null) { - context.packageLevelJsModules.add(irFile) - return null - } + externalPackageFragment.declarations += declaration + declaration.parent = externalPackageFragment - val it = irFile.declarations.iterator() + context.packageLevelJsModules += externalPackageFragment - while (it.hasNext()) { - val d = it.next() as? IrDeclarationWithName ?: continue + return emptyList() + } else { + val d = declaration as? IrDeclarationWithName ?: return null if (isBuiltInClass(d)) { - it.remove() - bodilessBuiltInsPackageFragment.addChild(d) + context.bodilessBuiltInsPackageFragment.addChild(d) + return emptyList() } else if (d.isEffectivelyExternal()) { if (d.getJsModule() != null) context.declarationLevelJsModules.add(d) - it.remove() - externalPackageFragment.addChild(d) - } - } - return irFile - } + externalPackageFragment.declarations += d + d.parent = externalPackageFragment - module.files.transformFlat { irFile -> - listOfNotNull(lowerFile(irFile)) + return emptyList() + } + + return null + } } -} +} \ No newline at end of file