MoveBodilessDeclarationsToSeparatePlace
This commit is contained in:
committed by
Anton Bannykh
parent
09a2c145a9
commit
ce625075f6
+29
-8
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.backend.common.ir.Symbols
|
|||||||
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
import org.jetbrains.kotlin.backend.js.JsDeclarationFactory
|
||||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
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.lower.CallableReferenceKey
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
@@ -60,11 +58,34 @@ class JsIrBackendContext(
|
|||||||
|
|
||||||
val devMode = configuration[JSConfigurationKeys.DEVELOPER_MODE] ?: false
|
val devMode = configuration[JSConfigurationKeys.DEVELOPER_MODE] ?: false
|
||||||
|
|
||||||
var externalPackageFragment = mutableMapOf<IrFileSymbol, IrFile>()
|
val externalPackageFragment = mutableMapOf<IrFileSymbol, IrFile>()
|
||||||
lateinit var bodilessBuiltInsPackageFragment: IrPackageFragment
|
val bodilessBuiltInsPackageFragment: IrPackageFragment = run {
|
||||||
|
|
||||||
val externalNestedClasses = mutableListOf<IrClass>()
|
class DescriptorlessExternalPackageFragmentSymbol : IrExternalPackageFragmentSymbol {
|
||||||
val packageLevelJsModules = mutableListOf<IrFile>()
|
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<IrFile>()
|
||||||
val declarationLevelJsModules = mutableListOf<IrDeclarationWithName>()
|
val declarationLevelJsModules = mutableListOf<IrDeclarationWithName>()
|
||||||
|
|
||||||
val internalPackageFragmentDescriptor = EmptyPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
|
val internalPackageFragmentDescriptor = EmptyPackageFragmentDescriptor(builtIns.builtInsModule, FqName("kotlin.js.internal"))
|
||||||
|
|||||||
+30
-64
@@ -5,20 +5,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
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.backend.common.ir.addChild
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
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.getJsModule
|
||||||
import org.jetbrains.kotlin.ir.backend.js.utils.getJsQualifier
|
import org.jetbrains.kotlin.ir.backend.js.utils.getJsQualifier
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
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.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrExternalPackageFragmentSymbol
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.UniqId
|
import org.jetbrains.kotlin.ir.util.UniqId
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
private val BODILESS_BUILTIN_CLASSES = listOf(
|
private val BODILESS_BUILTIN_CLASSES = listOf(
|
||||||
@@ -43,24 +41,6 @@ private val BODILESS_BUILTIN_CLASSES = listOf(
|
|||||||
"kotlin.Function"
|
"kotlin.Function"
|
||||||
).map { FqName(it) }.toSet()
|
).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 {
|
private class DescriptorlessIrFileSymbol : IrFileSymbol {
|
||||||
override fun bind(owner: IrFile) {
|
override fun bind(owner: IrFile) {
|
||||||
_owner = owner
|
_owner = owner
|
||||||
@@ -79,33 +59,22 @@ private class DescriptorlessIrFileSymbol : IrFileSymbol {
|
|||||||
override val isBound get() = _owner != null
|
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) {
|
fun moveBodilessDeclarationsToSeparatePlace(context: JsIrBackendContext, moduleFragment: IrModuleFragment) {
|
||||||
|
MoveBodilessDeclarationsToSeparatePlaceLowering(context).let { moveBodiless ->
|
||||||
val bodilessBuiltInsPackageFragment = IrExternalPackageFragmentImpl(
|
moduleFragment.files.forEach {
|
||||||
DescriptorlessExternalPackageFragmentSymbol(),
|
moveBodiless.lower(it)
|
||||||
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<IrClass> {
|
|
||||||
val externalClasses =
|
|
||||||
container.declarations.filterIsInstance<IrClass>().filter { it.isEffectivelyExternal() }
|
|
||||||
|
|
||||||
val nestedExternalClasses =
|
|
||||||
externalClasses.flatMap { collectExternalClasses(it, true) }
|
|
||||||
|
|
||||||
return if (includeCurrentLevel)
|
|
||||||
externalClasses + nestedExternalClasses
|
|
||||||
else
|
|
||||||
nestedExternalClasses
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveBodilessDeclarationsToSeparatePlaceLowering(private val context: JsIrBackendContext) : DeclarationTransformer {
|
||||||
|
|
||||||
|
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||||
|
val irFile = declaration.parent as? IrFile ?: return null
|
||||||
|
|
||||||
fun lowerFile(irFile: IrFile): IrFile? {
|
|
||||||
val externalPackageFragment by lazy {
|
val externalPackageFragment by lazy {
|
||||||
context.externalPackageFragment.getOrPut(irFile.symbol) {
|
context.externalPackageFragment.getOrPut(irFile.symbol) {
|
||||||
IrFileImpl(fileEntry = irFile.fileEntry, fqName = irFile.fqName, symbol = DescriptorlessIrFileSymbol()).also {
|
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) {
|
if (irFile.getJsModule() != null || irFile.getJsQualifier() != null) {
|
||||||
context.packageLevelJsModules.add(irFile)
|
externalPackageFragment.declarations += declaration
|
||||||
return null
|
declaration.parent = externalPackageFragment
|
||||||
}
|
|
||||||
|
|
||||||
val it = irFile.declarations.iterator()
|
context.packageLevelJsModules += externalPackageFragment
|
||||||
|
|
||||||
while (it.hasNext()) {
|
return emptyList()
|
||||||
val d = it.next() as? IrDeclarationWithName ?: continue
|
} else {
|
||||||
|
val d = declaration as? IrDeclarationWithName ?: return null
|
||||||
|
|
||||||
if (isBuiltInClass(d)) {
|
if (isBuiltInClass(d)) {
|
||||||
it.remove()
|
context.bodilessBuiltInsPackageFragment.addChild(d)
|
||||||
bodilessBuiltInsPackageFragment.addChild(d)
|
return emptyList()
|
||||||
} else if (d.isEffectivelyExternal()) {
|
} else if (d.isEffectivelyExternal()) {
|
||||||
if (d.getJsModule() != null)
|
if (d.getJsModule() != null)
|
||||||
context.declarationLevelJsModules.add(d)
|
context.declarationLevelJsModules.add(d)
|
||||||
|
|
||||||
it.remove()
|
externalPackageFragment.declarations += d
|
||||||
externalPackageFragment.addChild(d)
|
d.parent = externalPackageFragment
|
||||||
}
|
|
||||||
}
|
|
||||||
return irFile
|
|
||||||
}
|
|
||||||
|
|
||||||
module.files.transformFlat { irFile ->
|
return emptyList()
|
||||||
listOfNotNull(lowerFile(irFile))
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user