[K/JS] Rework IR deserialization and lowering phases to consume less memory
This commit is contained in:
+9
-9
@@ -52,7 +52,7 @@ interface JsCommonBackendContext : CommonBackendContext {
|
||||
}
|
||||
|
||||
// TODO: investigate if it could be removed
|
||||
internal fun <T> BackendContext.lazy2(fn: () -> T) = lazy { irFactory.stageController.withInitialIr(fn) }
|
||||
internal fun <T> BackendContext.lazy2(fn: () -> T) = lazy(LazyThreadSafetyMode.NONE) { irFactory.stageController.withInitialIr(fn) }
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class JsCommonCoroutineSymbols(
|
||||
@@ -66,14 +66,14 @@ class JsCommonCoroutineSymbols(
|
||||
val coroutineImpl =
|
||||
symbolTable.referenceClass(findClass(coroutinePackage.memberScope, COROUTINE_IMPL_NAME))
|
||||
|
||||
val coroutineImplLabelPropertyGetter by lazy { coroutineImpl.getPropertyGetter("state")!!.owner }
|
||||
val coroutineImplLabelPropertySetter by lazy { coroutineImpl.getPropertySetter("state")!!.owner }
|
||||
val coroutineImplResultSymbolGetter by lazy { coroutineImpl.getPropertyGetter("result")!!.owner }
|
||||
val coroutineImplResultSymbolSetter by lazy { coroutineImpl.getPropertySetter("result")!!.owner }
|
||||
val coroutineImplExceptionPropertyGetter by lazy { coroutineImpl.getPropertyGetter("exception")!!.owner }
|
||||
val coroutineImplExceptionPropertySetter by lazy { coroutineImpl.getPropertySetter("exception")!!.owner }
|
||||
val coroutineImplExceptionStatePropertyGetter by lazy { coroutineImpl.getPropertyGetter("exceptionState")!!.owner }
|
||||
val coroutineImplExceptionStatePropertySetter by lazy { coroutineImpl.getPropertySetter("exceptionState")!!.owner }
|
||||
val coroutineImplLabelPropertyGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("state")!!.owner }
|
||||
val coroutineImplLabelPropertySetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("state")!!.owner }
|
||||
val coroutineImplResultSymbolGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("result")!!.owner }
|
||||
val coroutineImplResultSymbolSetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("result")!!.owner }
|
||||
val coroutineImplExceptionPropertyGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("exception")!!.owner }
|
||||
val coroutineImplExceptionPropertySetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("exception")!!.owner }
|
||||
val coroutineImplExceptionStatePropertyGetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertyGetter("exceptionState")!!.owner }
|
||||
val coroutineImplExceptionStatePropertySetter by lazy(LazyThreadSafetyMode.NONE) { coroutineImpl.getPropertySetter("exceptionState")!!.owner }
|
||||
|
||||
val continuationClass = symbolTable.referenceClass(
|
||||
coroutinePackage.memberScope.getContributedClassifier(
|
||||
|
||||
@@ -185,7 +185,7 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
||||
|
||||
private val _rangeUntilFunctions = irBuiltIns.findFunctions(Name.identifier("until"), "kotlin", "ranges")
|
||||
val rangeUntilFunctions by lazy {
|
||||
val rangeUntilFunctions by lazy(LazyThreadSafetyMode.NONE) {
|
||||
_rangeUntilFunctions
|
||||
.filter { it.owner.extensionReceiverParameter != null && it.owner.valueParameters.size == 1 }
|
||||
.associateBy { it.owner.extensionReceiverParameter!!.type to it.owner.valueParameters[0].type }
|
||||
@@ -324,11 +324,11 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsFunAnnotationSymbol = context.symbolTable.referenceClass(context.getJsInternalClass("JsFun"))
|
||||
val jsNameAnnotationSymbol = context.symbolTable.referenceClass(context.getJsInternalClass("JsName"))
|
||||
|
||||
val jsExportAnnotationSymbol by lazy {
|
||||
val jsExportAnnotationSymbol by lazy(LazyThreadSafetyMode.NONE) {
|
||||
context.symbolTable.referenceClass(context.getJsInternalClass("JsExport"))
|
||||
}
|
||||
|
||||
val jsExportIgnoreAnnotationSymbol by lazy {
|
||||
val jsExportIgnoreAnnotationSymbol by lazy(LazyThreadSafetyMode.NONE) {
|
||||
jsExportAnnotationSymbol.owner
|
||||
.findDeclaration<IrClass> { it.fqNameWhenAvailable == FqName("kotlin.js.JsExport.Ignore") }
|
||||
?.symbol ?: error("can't find kotlin.js.JsExport.Ignore annotation")
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.backend.common.ir.Ir
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.linkage.partial.createPartialLinkageSupportForLowerings
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrInterningService
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
@@ -48,9 +49,9 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.isNullable
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceMapNotNull
|
||||
import java.util.WeakHashMap
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
@@ -73,6 +74,7 @@ class JsIrBackendContext(
|
||||
|
||||
val polyfills = JsPolyfills()
|
||||
val fieldToInitializer = WeakHashMap<IrField, IrExpression>()
|
||||
val globalInternationService = IrInterningService()
|
||||
|
||||
val localClassNames = WeakHashMap<IrClass, String>()
|
||||
|
||||
@@ -102,17 +104,17 @@ class JsIrBackendContext(
|
||||
|
||||
val externalPackageFragment = mutableMapOf<IrFileSymbol, IrFile>()
|
||||
|
||||
val additionalExportedDeclarations = mutableSetOf<IrDeclaration>()
|
||||
val additionalExportedDeclarations = hashSetOf<IrDeclaration>()
|
||||
|
||||
val bodilessBuiltInsPackageFragment: IrPackageFragment = IrExternalPackageFragmentImpl(
|
||||
DescriptorlessExternalPackageFragmentSymbol(),
|
||||
FqName("kotlin")
|
||||
)
|
||||
|
||||
val packageLevelJsModules = mutableSetOf<IrFile>()
|
||||
val packageLevelJsModules = hashSetOf<IrFile>()
|
||||
val declarationLevelJsModules = mutableListOf<IrDeclarationWithName>()
|
||||
|
||||
val testFunsPerFile = mutableMapOf<IrFile, IrSimpleFunction>()
|
||||
val testFunsPerFile = hashMapOf<IrFile, IrSimpleFunction>()
|
||||
|
||||
override fun createTestContainerFun(irFile: IrFile): IrSimpleFunction {
|
||||
return testFunsPerFile.getOrPut(irFile) {
|
||||
@@ -263,13 +265,13 @@ class JsIrBackendContext(
|
||||
private val getProgressionLastElementSymbols =
|
||||
irBuiltIns.findFunctions(Name.identifier("getProgressionLastElement"), "kotlin", "internal")
|
||||
|
||||
override val getProgressionLastElementByReturnType: Map<IrClassifierSymbol, IrSimpleFunctionSymbol> by lazy {
|
||||
override val getProgressionLastElementByReturnType: Map<IrClassifierSymbol, IrSimpleFunctionSymbol> by lazy(LazyThreadSafetyMode.NONE) {
|
||||
getProgressionLastElementSymbols.associateBy { it.owner.returnType.classifierOrFail }
|
||||
}
|
||||
|
||||
private val toUIntSymbols = irBuiltIns.findFunctions(Name.identifier("toUInt"), "kotlin")
|
||||
|
||||
override val toUIntByExtensionReceiver: Map<IrClassifierSymbol, IrSimpleFunctionSymbol> by lazy {
|
||||
override val toUIntByExtensionReceiver: Map<IrClassifierSymbol, IrSimpleFunctionSymbol> by lazy(LazyThreadSafetyMode.NONE) {
|
||||
toUIntSymbols.associateBy {
|
||||
it.owner.extensionReceiverParameter?.type?.classifierOrFail
|
||||
?: error("Expected extension receiver for ${it.owner.render()}")
|
||||
@@ -278,7 +280,7 @@ class JsIrBackendContext(
|
||||
|
||||
private val toULongSymbols = irBuiltIns.findFunctions(Name.identifier("toULong"), "kotlin")
|
||||
|
||||
override val toULongByExtensionReceiver: Map<IrClassifierSymbol, IrSimpleFunctionSymbol> by lazy {
|
||||
override val toULongByExtensionReceiver: Map<IrClassifierSymbol, IrSimpleFunctionSymbol> by lazy(LazyThreadSafetyMode.NONE) {
|
||||
toULongSymbols.associateBy {
|
||||
it.owner.extensionReceiverParameter?.type?.classifierOrFail
|
||||
?: error("Expected extension receiver for ${it.owner.render()}")
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
|
||||
class PropertyLazyInitialization(val enabled: Boolean, eagerInitialization: IrClassSymbol) {
|
||||
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = mutableMapOf()
|
||||
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = mutableMapOf()
|
||||
val fileToInitializationFuns: MutableMap<IrFile, IrSimpleFunction?> = hashMapOf()
|
||||
val fileToInitializerPureness: MutableMap<IrFile, Boolean> = hashMapOf()
|
||||
val eagerInitialization: IrClassSymbol = eagerInitialization
|
||||
}
|
||||
@@ -122,6 +122,7 @@ fun compileIr(
|
||||
|
||||
irLinker.postProcess(inOrAfterLinkageStep = true)
|
||||
irLinker.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
|
||||
irLinker.clear()
|
||||
|
||||
allModules.forEach { module ->
|
||||
if (shouldGeneratePolyfills) {
|
||||
|
||||
-1
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.backend.js.lower.isEs6ConstructorReplacement
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ abstract class UsefulDeclarationProcessor(
|
||||
protected fun getMethodOfAny(name: String): IrDeclaration =
|
||||
context.irBuiltIns.anyClass.owner.declarations.filterIsInstance<IrFunction>().single { it.name.asString() == name }
|
||||
|
||||
protected val toStringMethod: IrDeclaration by lazy { getMethodOfAny("toString") }
|
||||
protected val toStringMethod: IrDeclaration by lazy(LazyThreadSafetyMode.NONE) { getMethodOfAny("toString") }
|
||||
protected abstract fun isExported(declaration: IrDeclaration): Boolean
|
||||
protected abstract val bodyVisitor: BodyVisitorBase
|
||||
|
||||
|
||||
+5
-4
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.isAny
|
||||
@@ -22,6 +21,8 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.js.config.RuntimeDiagnostic
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedFilter
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
|
||||
class UselessDeclarationsRemover(
|
||||
private val removeUnusedAssociatedObjects: Boolean,
|
||||
@@ -52,13 +53,13 @@ class UselessDeclarationsRemover(
|
||||
// Otherwise `JsClassGenerator.generateAssociatedKeyProperties` will try to reference the object factory (which is removed).
|
||||
// That will result in an error from the Namer. It cannot generate a name for an absent declaration.
|
||||
if (removeUnusedAssociatedObjects && declaration.annotations.any { !it.shouldKeepAnnotation() }) {
|
||||
declaration.annotations = declaration.annotations.filter { it.shouldKeepAnnotation() }
|
||||
declaration.annotations = declaration.annotations.memoryOptimizedFilter { it.shouldKeepAnnotation() }
|
||||
}
|
||||
|
||||
declaration.superTypes = declaration.superTypes
|
||||
.flatMap { it.classOrNull?.collectUsedSuperTypes() ?: emptyList() }
|
||||
.distinct()
|
||||
.map { it.defaultType }
|
||||
.memoryOptimizedMap { it.defaultType }
|
||||
}
|
||||
|
||||
private fun IrClassSymbol.collectUsedSuperTypes(): Set<IrClassSymbol> {
|
||||
@@ -68,7 +69,7 @@ class UselessDeclarationsRemover(
|
||||
} else {
|
||||
owner.superTypes
|
||||
.flatMap { it.takeIf { !it.isAny() }?.classOrNull?.collectUsedSuperTypes() ?: emptyList() }
|
||||
.toSet()
|
||||
.toHashSet()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+15
-16
@@ -23,9 +23,8 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
|
||||
private const val magicPropertyName = "__doNotUseOrImplementIt"
|
||||
|
||||
@@ -34,7 +33,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
|
||||
fun generateExport(file: IrPackageFragment): List<ExportedDeclaration> {
|
||||
val namespaceFqName = file.fqName
|
||||
val exports = file.declarations.flatMap { declaration -> listOfNotNull(exportDeclaration(declaration)) }
|
||||
val exports = file.declarations.memoryOptimizedFlatMap { declaration -> listOfNotNull(exportDeclaration(declaration)) }
|
||||
return when {
|
||||
exports.isEmpty() -> emptyList()
|
||||
!generateNamespacesForPackages || namespaceFqName.isRoot -> exports
|
||||
@@ -46,7 +45,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
ExportedModule(
|
||||
context.configuration[CommonConfigurationKeys.MODULE_NAME]!!,
|
||||
moduleKind,
|
||||
(context.externalPackageFragment.values + modules.flatMap { it.files }).flatMap {
|
||||
(context.externalPackageFragment.values + modules.flatMap { it.files }).memoryOptimizedFlatMap {
|
||||
generateExport(it)
|
||||
}
|
||||
)
|
||||
@@ -84,7 +83,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
ExportedFunction(
|
||||
function.getExportedIdentifier(),
|
||||
returnType = exportType(function.returnType),
|
||||
typeParameters = function.typeParameters.map(::exportTypeParameter),
|
||||
typeParameters = function.typeParameters.memoryOptimizedMap(::exportTypeParameter),
|
||||
isMember = parent is IrClass,
|
||||
isStatic = function.isStaticMethod,
|
||||
isAbstract = parent is IrClass && !parent.isInterface && function.modality == Modality.ABSTRACT,
|
||||
@@ -92,7 +91,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
ir = function,
|
||||
parameters = (listOfNotNull(function.extensionReceiverParameter) + function.valueParameters)
|
||||
.filter { it.shouldBeExported() }
|
||||
.map { exportParameter(it) },
|
||||
.memoryOptimizedMap { exportParameter(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -102,7 +101,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
if (!constructor.isPrimary) return null
|
||||
val allValueParameters = listOfNotNull(constructor.extensionReceiverParameter) + constructor.valueParameters
|
||||
return ExportedConstructor(
|
||||
parameters = allValueParameters.filterNot { it.isBoxParameter }.map { exportParameter(it) },
|
||||
parameters = allValueParameters.filterNot { it.isBoxParameter }.memoryOptimizedMap { exportParameter(it) },
|
||||
visibility = constructor.visibility.toExportedVisibility()
|
||||
)
|
||||
}
|
||||
@@ -219,11 +218,11 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
}
|
||||
|
||||
private fun exportDeclarationImplicitly(klass: IrClass, superTypes: Iterable<IrType>): ExportedDeclaration {
|
||||
val typeParameters = klass.typeParameters.map(::exportTypeParameter)
|
||||
val typeParameters = klass.typeParameters.memoryOptimizedMap(::exportTypeParameter)
|
||||
val superInterfaces = superTypes
|
||||
.filter { (it.classifierOrFail.owner as? IrDeclaration)?.isExportedImplicitlyOrExplicitly(context) ?: false }
|
||||
.map { exportType(it) }
|
||||
.filter { it !is ExportedType.ErrorType }
|
||||
.memoryOptimizedFilter { it !is ExportedType.ErrorType }
|
||||
|
||||
val name = klass.getExportedIdentifier()
|
||||
val (members, nestedClasses) = exportClassDeclarations(klass, superTypes)
|
||||
@@ -288,7 +287,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
return exportClass(
|
||||
klass,
|
||||
superTypes,
|
||||
listOf(privateConstructor) + members,
|
||||
listOf(privateConstructor) memoryOptimizedPlus members,
|
||||
nestedClasses
|
||||
)
|
||||
}
|
||||
@@ -424,17 +423,17 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
members: List<ExportedDeclaration>,
|
||||
nestedClasses: List<ExportedClass>,
|
||||
): ExportedDeclaration {
|
||||
val typeParameters = klass.typeParameters.map(::exportTypeParameter)
|
||||
val typeParameters = klass.typeParameters.memoryOptimizedMap(::exportTypeParameter)
|
||||
|
||||
val superClasses = superTypes
|
||||
.filter { !it.classifierOrFail.isInterface && it.canBeUsedAsSuperTypeOfExportedClasses() }
|
||||
.map { exportType(it, false) }
|
||||
.filter { it !is ExportedType.ErrorType }
|
||||
.memoryOptimizedFilter { it !is ExportedType.ErrorType }
|
||||
|
||||
val superInterfaces = superTypes
|
||||
.filter { it.shouldPresentInsideImplementsClause() }
|
||||
.map { exportType(it, false) }
|
||||
.filter { it !is ExportedType.ErrorType }
|
||||
.memoryOptimizedFilter { it !is ExportedType.ErrorType }
|
||||
|
||||
val name = klass.getExportedIdentifier()
|
||||
|
||||
@@ -594,7 +593,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
nonNullType.isArray() -> ExportedType.Array(exportTypeArgument(nonNullType.arguments[0]))
|
||||
nonNullType.isSuspendFunction() -> ExportedType.ErrorType("Suspend functions are not supported")
|
||||
nonNullType.isFunction() -> ExportedType.Function(
|
||||
parameterTypes = nonNullType.arguments.dropLast(1).map { exportTypeArgument(it) },
|
||||
parameterTypes = nonNullType.arguments.dropLast(1).memoryOptimizedMap { exportTypeArgument(it) },
|
||||
returnType = exportTypeArgument(nonNullType.arguments.last())
|
||||
)
|
||||
|
||||
@@ -610,7 +609,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
val exportedSupertype = runIf(shouldCalculateExportedSupertypeForImplicit && isImplicitlyExported) {
|
||||
val transitiveExportedType = nonNullType.collectSuperTransitiveHierarchy()
|
||||
if (transitiveExportedType.isEmpty()) return@runIf null
|
||||
transitiveExportedType.map(::exportType).reduce(ExportedType::IntersectionType)
|
||||
transitiveExportedType.memoryOptimizedMap(::exportType).reduce(ExportedType::IntersectionType)
|
||||
} ?: ExportedType.Primitive.Any
|
||||
|
||||
when (klass.kind) {
|
||||
@@ -625,7 +624,7 @@ class ExportModelGenerator(val context: JsIrBackendContext, val generateNamespac
|
||||
ClassKind.ENUM_CLASS,
|
||||
ClassKind.INTERFACE -> ExportedType.ClassType(
|
||||
name,
|
||||
type.arguments.map { exportTypeArgument(it) },
|
||||
type.arguments.memoryOptimizedMap { exportTypeArgument(it) },
|
||||
klass
|
||||
)
|
||||
}.withImplicitlyExported(isImplicitlyExported, exportedSupertype)
|
||||
|
||||
+2
-2
@@ -20,14 +20,14 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.util.companionObject
|
||||
import org.jetbrains.kotlin.ir.util.isObject
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
|
||||
class ExportModelToJsStatements(
|
||||
private val staticContext: JsStaticContext,
|
||||
private val es6mode: Boolean,
|
||||
private val declareNewNamespace: (String) -> String,
|
||||
) {
|
||||
private val namespaceToRefMap = mutableMapOf<String, JsNameRef>()
|
||||
private val namespaceToRefMap = hashMapOf<String, JsNameRef>()
|
||||
|
||||
fun generateModuleExport(
|
||||
module: ExportedModule,
|
||||
|
||||
@@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonJsKLibResolver
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.serialization.IrInterningService
|
||||
import org.jetbrains.kotlin.backend.common.serialization.cityHash64
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
@@ -19,6 +20,10 @@ import org.jetbrains.kotlin.library.KLIB_PROPERTY_DEPENDS
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.metadata.resolver.TopologicalLibraryOrder
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedFilter
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
|
||||
import org.jetbrains.kotlin.utils.newHashSetWithExpectedSize
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.util.EnumSet
|
||||
@@ -67,6 +72,8 @@ class CacheUpdater(
|
||||
|
||||
private val icHasher = ICHasher()
|
||||
|
||||
private val internationService = IrInterningService()
|
||||
|
||||
private val cacheRootDir = run {
|
||||
val configHash = icHasher.calculateConfigHash(compilerConfiguration)
|
||||
File(cacheDir, "version.${configHash.hash.lowBytes.toString(Character.MAX_RADIX)}")
|
||||
@@ -107,15 +114,15 @@ class CacheUpdater(
|
||||
val nameToKotlinLibrary = libraries.associateBy { it.moduleName }
|
||||
|
||||
libraries.associateWith {
|
||||
it.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true).map { depName ->
|
||||
it.manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true).memoryOptimizedMap { depName ->
|
||||
nameToKotlinLibrary[depName] ?: notFoundIcError("library $depName")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val mainModuleFriendLibraries = libraryDependencies.keys.let { libs ->
|
||||
val friendPaths = mainModuleFriends.mapTo(HashSet(mainModuleFriends.size)) { File(it).canonicalPath }
|
||||
libs.filter { it.libraryFile.canonicalPath in friendPaths }
|
||||
val friendPaths = mainModuleFriends.mapTo(newHashSetWithExpectedSize(mainModuleFriends.size)) { File(it).canonicalPath }
|
||||
libs.memoryOptimizedFilter { it.libraryFile.canonicalPath in friendPaths }
|
||||
}
|
||||
|
||||
private val klibCacheDirs = libraryDependencies.keys.map { lib ->
|
||||
@@ -139,12 +146,12 @@ class CacheUpdater(
|
||||
}
|
||||
|
||||
private val incrementalCaches = libraryDependencies.keys.zip(klibCacheDirs).associate { (lib, libraryCacheDir) ->
|
||||
KotlinLibraryFile(lib) to IncrementalCache(KotlinLoadedLibraryHeader(lib), libraryCacheDir)
|
||||
KotlinLibraryFile(lib) to IncrementalCache(KotlinLoadedLibraryHeader(lib, internationService), libraryCacheDir)
|
||||
}
|
||||
|
||||
private val removedIncrementalCaches = buildList {
|
||||
if (cacheRootDir.isDirectory) {
|
||||
val availableCaches = incrementalCaches.values.mapTo(HashSet(incrementalCaches.size)) { it.cacheDir }
|
||||
val availableCaches = incrementalCaches.values.mapTo(newHashSetWithExpectedSize(incrementalCaches.size)) { it.cacheDir }
|
||||
val allDirs = Files.walk(cacheRootDir.toPath(), 1).map { it.toFile() }
|
||||
allDirs.filter { it != cacheRootDir && it !in availableCaches }.forEach { removedCacheDir ->
|
||||
add(IncrementalCache(KotlinRemovedLibraryHeader(removedCacheDir), removedCacheDir))
|
||||
@@ -445,7 +452,7 @@ class CacheUpdater(
|
||||
// if imports have been modified, metadata for the file will be rebuilt later,
|
||||
// so if the imports haven't been modified, update the metadata manually
|
||||
if (newMetadata.importedSignaturesState == ImportedSignaturesState.NON_MODIFIED) {
|
||||
val newDirectDependencies = newSignatures.associateWithTo(HashMap(newSignatures.size)) {
|
||||
val newDirectDependencies = newSignatures.associateWithTo(newHashMapWithExpectedSize(newSignatures.size)) {
|
||||
signatureHashCalculator[it] ?: notFoundIcError("signature $it hash", libFile, srcFile)
|
||||
}
|
||||
newMetadata.directDependencies[libFile, srcFile] = newDirectDependencies
|
||||
@@ -690,7 +697,7 @@ class CacheUpdater(
|
||||
// Load declarations referenced during `context` initialization
|
||||
loadedIr.loadUnboundSymbols()
|
||||
|
||||
val dirtyFiles = dirtyFileExports.entries.associateTo(HashMap(dirtyFileExports.size)) { it.key to HashSet(it.value.keys) }
|
||||
val dirtyFiles = dirtyFileExports.entries.associateTo(newHashMapWithExpectedSize(dirtyFileExports.size)) { it.key to HashSet(it.value.keys) }
|
||||
|
||||
stopwatch.startNext("Processing IR - updating intrinsics and builtins dependencies")
|
||||
updater.updateStdlibIntrinsicDependencies(loadedIr, mainModuleFragment, dirtyFiles)
|
||||
@@ -752,12 +759,13 @@ fun rebuildCacheForDirtyFiles(
|
||||
mainArguments: List<String>?,
|
||||
es6mode: Boolean
|
||||
): Pair<IrModuleFragment, List<Pair<IrFile, JsIrProgramFragment>>> {
|
||||
val internationService = IrInterningService()
|
||||
val emptyMetadata = object : KotlinSourceFileExports() {
|
||||
override val inverseDependencies = KotlinSourceFileMap<Set<IdSignature>>(emptyMap())
|
||||
}
|
||||
|
||||
val libFile = KotlinLibraryFile(library)
|
||||
val dirtySrcFiles = dirtyFiles?.map { KotlinSourceFile(it) } ?: KotlinLoadedLibraryHeader(library).sourceFileFingerprints.keys
|
||||
val dirtySrcFiles = dirtyFiles?.memoryOptimizedMap { KotlinSourceFile(it) } ?: KotlinLoadedLibraryHeader(library, internationService).sourceFileFingerprints.keys
|
||||
|
||||
val modifiedFiles = mapOf(libFile to dirtySrcFiles.associateWith { emptyMetadata })
|
||||
|
||||
@@ -767,7 +775,7 @@ fun rebuildCacheForDirtyFiles(
|
||||
val currentIrModule = loadedIr.loadedFragments[libFile] ?: notFoundIcError("loaded fragment", libFile)
|
||||
val dirtyIrFiles = dirtyFiles?.let {
|
||||
val files = it.toSet()
|
||||
currentIrModule.files.filter { irFile -> irFile.fileEntry.name in files }
|
||||
currentIrModule.files.memoryOptimizedFilter { irFile -> irFile.fileEntry.name in files }
|
||||
} ?: currentIrModule.files
|
||||
|
||||
val compilerWithIC = JsIrCompilerWithIC(
|
||||
@@ -781,8 +789,9 @@ fun rebuildCacheForDirtyFiles(
|
||||
|
||||
// Load declarations referenced during `context` initialization
|
||||
loadedIr.loadUnboundSymbols()
|
||||
internationService.clear()
|
||||
|
||||
val fragments = compilerWithIC.compile(loadedIr.loadedFragments.values, dirtyIrFiles, mainArguments).map { it() }
|
||||
val fragments = compilerWithIC.compile(loadedIr.loadedFragments.values, dirtyIrFiles, mainArguments).memoryOptimizedMap { it() }
|
||||
|
||||
return currentIrModule to dirtyIrFiles.zip(fragments)
|
||||
}
|
||||
|
||||
+3
-3
@@ -32,13 +32,13 @@ internal class IncrementalCache(private val library: KotlinLibraryHeader, val ca
|
||||
|
||||
private val signatureToIndexMappingFromMetadata = hashMapOf<KotlinSourceFile, MutableMap<IdSignature, Int>>()
|
||||
|
||||
private val cacheHeaderFromDisk by lazy {
|
||||
private val cacheHeaderFromDisk by lazy(LazyThreadSafetyMode.NONE) {
|
||||
cacheHeaderFile.useCodedInputIfExists {
|
||||
CacheHeader.fromProtoStream(this)
|
||||
}
|
||||
}
|
||||
|
||||
val libraryFileFromHeader by lazy { cacheHeaderFromDisk?.libraryFile }
|
||||
val libraryFileFromHeader by lazy(LazyThreadSafetyMode.NONE) { cacheHeaderFromDisk?.libraryFile }
|
||||
|
||||
private class CacheHeader(
|
||||
val libraryFile: KotlinLibraryFile,
|
||||
@@ -149,7 +149,7 @@ internal class IncrementalCache(private val library: KotlinLibraryHeader, val ca
|
||||
private fun fetchSourceFileMetadata(srcFile: KotlinSourceFile, loadSignatures: Boolean) =
|
||||
kotlinLibrarySourceFileMetadata.getOrPut(srcFile) {
|
||||
val signatureToIndexMapping = signatureToIndexMappingFromMetadata.getOrPut(srcFile) { hashMapOf() }
|
||||
val deserializer: IdSignatureDeserializer by lazy {
|
||||
val deserializer: IdSignatureDeserializer by lazy(LazyThreadSafetyMode.NONE) {
|
||||
library.sourceFileDeserializers[srcFile] ?: notFoundIcError("signature deserializer", library.libraryFile, srcFile)
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.serialization.serializeTo
|
||||
import org.jetbrains.kotlin.konan.file.use
|
||||
import org.jetbrains.kotlin.utils.newHashSetWithExpectedSize
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
|
||||
@@ -54,7 +55,7 @@ internal class IncrementalCacheArtifact(
|
||||
private val srcCacheActions: List<SourceFileCacheArtifact>,
|
||||
private val externalModuleName: String?
|
||||
) {
|
||||
fun getSourceFiles() = srcCacheActions.mapTo(HashSet(srcCacheActions.size)) { it.srcFile }
|
||||
fun getSourceFiles() = srcCacheActions.mapTo(newHashSetWithExpectedSize(srcCacheActions.size)) { it.srcFile }
|
||||
|
||||
fun buildModuleArtifactAndCommitCache(
|
||||
moduleName: String,
|
||||
|
||||
@@ -73,6 +73,7 @@ internal data class LoadedJsIr(
|
||||
ExternalDependenciesGenerator(linker.symbolTable, listOf(linker)).generateUnboundSymbolsAsDependencies()
|
||||
linker.postProcess(inOrAfterLinkageStep = true)
|
||||
linker.checkNoUnboundSymbols(linker.symbolTable, "at the end of IR linkage process")
|
||||
linker.clear()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+9
-6
@@ -23,7 +23,10 @@ internal interface KotlinLibraryHeader {
|
||||
val jsOutputName: String?
|
||||
}
|
||||
|
||||
internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : KotlinLibraryHeader {
|
||||
internal class KotlinLoadedLibraryHeader(
|
||||
private val library: KotlinLibrary,
|
||||
private val internationService: IrInterningService
|
||||
) : KotlinLibraryHeader {
|
||||
private fun parseFingerprintsFromManifest(): Map<KotlinSourceFile, FingerprintHash>? {
|
||||
val manifestFingerprints = library.serializedIrFileFingerprints?.takeIf { it.size == sourceFiles.size } ?: return null
|
||||
return sourceFiles.withIndex().associate { it.value to manifestFingerprints[it.index].fileFingerprint }
|
||||
@@ -31,12 +34,12 @@ internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : K
|
||||
|
||||
override val libraryFile: KotlinLibraryFile = KotlinLibraryFile(library)
|
||||
|
||||
override val libraryFingerprint: FingerprintHash by lazy {
|
||||
override val libraryFingerprint: FingerprintHash by lazy(LazyThreadSafetyMode.NONE) {
|
||||
val serializedKlib = library.serializedKlibFingerprint ?: SerializedKlibFingerprint(File(libraryFile.path))
|
||||
serializedKlib.klibFingerprint
|
||||
}
|
||||
|
||||
override val sourceFileDeserializers: Map<KotlinSourceFile, IdSignatureDeserializer> by lazy {
|
||||
override val sourceFileDeserializers: Map<KotlinSourceFile, IdSignatureDeserializer> by lazy(LazyThreadSafetyMode.NONE) {
|
||||
buildMapUntil(sourceFiles.size) {
|
||||
val deserializer = IdSignatureDeserializer(IrLibraryFileFromBytes(object : IrLibraryBytesSource() {
|
||||
private fun err(): Nothing = icError("Not supported")
|
||||
@@ -46,13 +49,13 @@ internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : K
|
||||
override fun string(index: Int): ByteArray = library.string(index, it)
|
||||
override fun body(index: Int): ByteArray = err()
|
||||
override fun debugInfo(index: Int): ByteArray? = null
|
||||
}), null)
|
||||
}), null, internationService)
|
||||
|
||||
put(sourceFiles[it], deserializer)
|
||||
}
|
||||
}
|
||||
|
||||
override val sourceFileFingerprints: Map<KotlinSourceFile, FingerprintHash> by lazy {
|
||||
override val sourceFileFingerprints: Map<KotlinSourceFile, FingerprintHash> by lazy(LazyThreadSafetyMode.NONE) {
|
||||
parseFingerprintsFromManifest() ?: buildMapUntil(sourceFiles.size) {
|
||||
put(sourceFiles[it], SerializedIrFileFingerprint(library, it).fileFingerprint)
|
||||
}
|
||||
@@ -61,7 +64,7 @@ internal class KotlinLoadedLibraryHeader(private val library: KotlinLibrary) : K
|
||||
override val jsOutputName: String?
|
||||
get() = library.jsOutputName
|
||||
|
||||
private val sourceFiles by lazy {
|
||||
private val sourceFiles by lazy(LazyThreadSafetyMode.NONE) {
|
||||
val extReg = ExtensionRegistryLite.newInstance()
|
||||
Array(library.fileCount()) {
|
||||
val fileProto = IrFile.parseFrom(library.file(it).codedInputStream, extReg)
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ internal enum class ImportedSignaturesState { UNKNOWN, MODIFIED, NON_MODIFIED }
|
||||
|
||||
internal class UpdatedDependenciesMetadata(oldMetadata: KotlinSourceFileMetadata) : KotlinSourceFileMetadata() {
|
||||
private val oldInverseDependencies = oldMetadata.inverseDependencies
|
||||
private val newExportedSignatures: Set<IdSignature> by lazy { inverseDependencies.flatSignatures() }
|
||||
private val newExportedSignatures: Set<IdSignature> by lazy(LazyThreadSafetyMode.NONE) { inverseDependencies.flatSignatures() }
|
||||
|
||||
var importedSignaturesState = ImportedSignaturesState.UNKNOWN
|
||||
|
||||
|
||||
+6
-5
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.transformStatement
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.isElseBranch
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
@@ -399,7 +400,7 @@ class BlockDecomposerTransformer(
|
||||
}
|
||||
|
||||
if (compositeCount == 0) {
|
||||
val branches = results.map { (cond, res, orig) ->
|
||||
val branches = results.memoryOptimizedMap { (cond, res, orig) ->
|
||||
when {
|
||||
isElseBranch(orig) -> IrElseBranchImpl(orig.startOffset, orig.endOffset, cond, res)
|
||||
else /* IrBranch */ -> IrBranchImpl(orig.startOffset, orig.endOffset, cond, res)
|
||||
@@ -509,7 +510,7 @@ class BlockDecomposerTransformer(
|
||||
val newStatements = mutableListOf<IrStatement>()
|
||||
val arguments = mapArguments(expression.arguments, compositeCount, newStatements)
|
||||
|
||||
newStatements += expression.run { IrStringConcatenationImpl(startOffset, endOffset, type, arguments.map { it!! }) }
|
||||
newStatements += expression.run { IrStringConcatenationImpl(startOffset, endOffset, type, arguments.memoryOptimizedMap { it!! }) }
|
||||
return JsIrBuilder.buildComposite(expression.type, newStatements)
|
||||
}
|
||||
|
||||
@@ -710,7 +711,7 @@ class BlockDecomposerTransformer(
|
||||
val irVar = makeTempVar(aTry.type)
|
||||
|
||||
val newTryResult = wrap(aTry.tryResult, irVar)
|
||||
val newCatches = aTry.catches.map {
|
||||
val newCatches = aTry.catches.memoryOptimizedMap {
|
||||
val newCatchBody = wrap(it.result, irVar)
|
||||
IrCatchImpl(it.startOffset, it.endOffset, it.catchParameter, newCatchBody)
|
||||
}
|
||||
@@ -757,7 +758,7 @@ class BlockDecomposerTransformer(
|
||||
if (hasComposites) {
|
||||
val irVar = makeTempVar(expression.type)
|
||||
|
||||
val newBranches = decomposedResults.map { (branch, condition, result) ->
|
||||
val newBranches = decomposedResults.memoryOptimizedMap { (branch, condition, result) ->
|
||||
val newResult = wrap(result, irVar)
|
||||
when {
|
||||
isElseBranch(branch) -> IrElseBranchImpl(branch.startOffset, branch.endOffset, condition, newResult)
|
||||
@@ -771,7 +772,7 @@ class BlockDecomposerTransformer(
|
||||
|
||||
return JsIrBuilder.buildComposite(expression.type, listOf(irVar, newWhen, JsIrBuilder.buildGetValue(irVar.symbol)))
|
||||
} else {
|
||||
val newBranches = decomposedResults.map { (branch, condition, result) ->
|
||||
val newBranches = decomposedResults.memoryOptimizedMap { (branch, condition, result) ->
|
||||
when {
|
||||
isElseBranch(branch) -> IrElseBranchImpl(branch.startOffset, branch.endOffset, condition, result)
|
||||
else /* IrBranch */ -> IrBranchImpl(branch.startOffset, branch.endOffset, condition, result)
|
||||
|
||||
+5
-6
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle
|
||||
import org.jetbrains.kotlin.backend.common.bridges.generateBridges
|
||||
import org.jetbrains.kotlin.backend.common.ir.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
@@ -23,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
/**
|
||||
* Constructs bridges for inherited generic functions
|
||||
@@ -145,11 +145,10 @@ abstract class BridgesConstruction<T : JsCommonBackendContext>(val context: T) :
|
||||
val substitutionMap = makeTypeParameterSubstitutionMap(bridge, this)
|
||||
copyReceiverParametersFrom(bridge, substitutionMap)
|
||||
copyValueParametersFrom(bridge, substitutionMap)
|
||||
annotations += bridge.annotations
|
||||
annotations = annotations memoryOptimizedPlus bridge.annotations
|
||||
// the js function signature building process (jsFunctionSignature()) uses dfs throught overriddenSymbols for getting js name,
|
||||
// therefore it is very important to put bridge symbol at the beginning, it allows to get correct js function name
|
||||
overriddenSymbols += bridge.symbol
|
||||
overriddenSymbols += delegateTo.overriddenSymbols
|
||||
overriddenSymbols = overriddenSymbols memoryOptimizedPlus bridge.symbol memoryOptimizedPlus delegateTo.overriddenSymbols
|
||||
}
|
||||
|
||||
irFunction.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
|
||||
@@ -179,7 +178,7 @@ abstract class BridgesConstruction<T : JsCommonBackendContext>(val context: T) :
|
||||
|
||||
val toTake = valueParameters.size - if (call.isSuspend xor irFunction.isSuspend) 1 else 0
|
||||
|
||||
valueParameters.subList(0, toTake).mapIndexed { i, valueParameter ->
|
||||
valueParameters.subList(0, toTake).forEachIndexed { i, valueParameter ->
|
||||
call.putValueArgument(i, irCastIfNeeded(irGet(valueParameter), delegateTo.valueParameters[i].type))
|
||||
}
|
||||
|
||||
@@ -203,7 +202,7 @@ abstract class BridgesConstruction<T : JsCommonBackendContext>(val context: T) :
|
||||
valueParametersToCopy = bridge.valueParameters.take(varargIndex)
|
||||
}
|
||||
}
|
||||
valueParameters += valueParametersToCopy.map { p -> p.copyTo(this, type = p.type.substitute(substitutionMap)) }
|
||||
valueParameters = valueParameters memoryOptimizedPlus valueParametersToCopy.map { p -> p.copyTo(this, type = p.type.substitute(substitutionMap)) }
|
||||
}
|
||||
|
||||
abstract fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin
|
||||
|
||||
+9
-5
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.SpecialNames
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
class CallableReferenceLowering(private val context: CommonBackendContext) : BodyLoweringPass {
|
||||
|
||||
@@ -270,9 +272,11 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
|
||||
|
||||
private fun IrSimpleFunction.createLambdaInvokeMethod() {
|
||||
annotations = function.annotations
|
||||
val valueParameterMap = function.explicitParameters.withIndex().associate { (index, param) ->
|
||||
param to param.copyTo(this, index = index)
|
||||
}
|
||||
val valueParameterMap = function.explicitParameters
|
||||
.withIndex()
|
||||
.associate { (index, param) ->
|
||||
param to param.copyTo(this, index = index)
|
||||
}
|
||||
valueParameters = valueParameterMap.values.toList()
|
||||
body = function.moveBodyTo(this, valueParameterMap)
|
||||
}
|
||||
@@ -389,7 +393,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
|
||||
val parameterTypes = (reference.type as IrSimpleType).arguments.map { (it as IrTypeProjection).type }
|
||||
val argumentTypes = parameterTypes.dropLast(1)
|
||||
|
||||
valueParameters = argumentTypes.mapIndexed { i, t ->
|
||||
valueParameters = argumentTypes.memoryOptimizedMapIndexed { i, t ->
|
||||
buildValueParameter(this) {
|
||||
name = Name.identifier("p$i")
|
||||
type = t
|
||||
@@ -432,7 +436,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod
|
||||
val getter = nameProperty.addGetter() {
|
||||
returnType = stringType
|
||||
}
|
||||
getter.overriddenSymbols += supperGetter.symbol
|
||||
getter.overriddenSymbols = getter.overriddenSymbols memoryOptimizedPlus supperGetter.symbol
|
||||
getter.dispatchReceiverParameter = buildValueParameter(getter) {
|
||||
name = SpecialNames.THIS
|
||||
type = clazz.defaultType
|
||||
|
||||
+11
-11
@@ -19,8 +19,8 @@ import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.isFunction
|
||||
import org.jetbrains.kotlin.ir.util.isThrowable
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -29,22 +29,22 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
|
||||
private val reflectionSymbols get() = context.reflectionSymbols
|
||||
|
||||
private val primitiveClassProperties by lazy {
|
||||
private val primitiveClassProperties by lazy(LazyThreadSafetyMode.NONE) {
|
||||
reflectionSymbols.primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
||||
}
|
||||
|
||||
private val primitiveClassFunctionClass by lazy {
|
||||
private val primitiveClassFunctionClass by lazy(LazyThreadSafetyMode.NONE) {
|
||||
reflectionSymbols.primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.find { it.name == Name.identifier("functionClass") }!!
|
||||
.findIsInstanceAnd<IrSimpleFunction> { it.name == Name.identifier("functionClass") }!!
|
||||
}
|
||||
|
||||
private fun primitiveClassProperty(name: String) =
|
||||
primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter
|
||||
?: reflectionSymbols.primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.single { it.name == Name.special("<get-$name>") }
|
||||
|
||||
private val finalPrimitiveClasses by lazy {
|
||||
private val finalPrimitiveClasses by lazy(LazyThreadSafetyMode.NONE) {
|
||||
mapOf(
|
||||
IrType::isBoolean to "booleanClass",
|
||||
IrType::isByte to "byteClass",
|
||||
@@ -67,7 +67,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
}
|
||||
}
|
||||
|
||||
private val openPrimitiveClasses by lazy {
|
||||
private val openPrimitiveClasses by lazy(LazyThreadSafetyMode.NONE) {
|
||||
mapOf(
|
||||
IrType::isAny to "anyClass",
|
||||
IrType::isNumber to "numberClass",
|
||||
@@ -179,7 +179,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
arrayElementType = context.reflectionSymbols.kTypeClass.defaultType,
|
||||
arrayElements = type.arguments.map { createKTypeProjection(it, visitedTypeParams) }
|
||||
arrayElements = type.arguments.memoryOptimizedMap { createKTypeProjection(it, visitedTypeParams) }
|
||||
)
|
||||
|
||||
val isMarkedNullable = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, type.isMarkedNullable())
|
||||
@@ -225,7 +225,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
arrayElementType = context.reflectionSymbols.kTypeClass.defaultType,
|
||||
arrayElements = typeParameter.superTypes.map { createKType(it, visitedTypeParams) }
|
||||
arrayElements = typeParameter.superTypes.memoryOptimizedMap { createKType(it, visitedTypeParams) }
|
||||
)
|
||||
|
||||
val variance = when (typeParameter.variance) {
|
||||
|
||||
+5
-3
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
|
||||
private object SCRIPT_FUNCTION : IrDeclarationOriginImpl("SCRIPT_FUNCTION")
|
||||
|
||||
@@ -37,12 +38,13 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri
|
||||
val (startOffset, endOffset) = getFunctionBodyOffsets(irScript)
|
||||
|
||||
val initializeStatements = irScript.statements
|
||||
.asSequence()
|
||||
.filterIsInstance<IrProperty>()
|
||||
.mapNotNull { it.backingField }
|
||||
.filter { it.initializer != null }
|
||||
.map { Pair(it, it.initializer!!.expression) }
|
||||
|
||||
initializeStatements.forEach { it.first.initializer = null }
|
||||
.onEach { it.first.initializer = null }
|
||||
.toList()
|
||||
|
||||
val initializeScriptFunction = createFunction(irScript, "\$initializeScript\$", context.irBuiltIns.unitType).also {
|
||||
it.body = it.factory.createBlockBody(
|
||||
@@ -51,7 +53,7 @@ class CreateScriptFunctionsPhase(val context: CommonBackendContext) : FileLoweri
|
||||
initializeStatements.let {
|
||||
if (irScript.resultProperty == null || initializeStatements.lastOrNull()?.first?.correspondingPropertySymbol != irScript.resultProperty) it
|
||||
else it.dropLast(1)
|
||||
}.map { (field, expression) -> createIrSetField(field, expression) }
|
||||
}.memoryOptimizedMap { (field, expression) -> createIrSetField(field, expression) }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+14
-7
@@ -7,21 +7,28 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.ir.ValueRemapper
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getVoid
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.hasStrictSignature
|
||||
import org.jetbrains.kotlin.ir.builders.irEqeqeqWithoutBox
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irIfThen
|
||||
import org.jetbrains.kotlin.ir.builders.irSet
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isLocal
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.util.superClass
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
object ES6_BOX_PARAMETER : IrDeclarationOriginImpl("ES6_BOX_PARAMETER")
|
||||
object ES6_BOX_PARAMETER_DEFAULT_RESOLUTION : IrStatementOriginImpl("ES6_BOX_PARAMETER_DEFAULT_RESOLUTION")
|
||||
@@ -52,7 +59,7 @@ class ES6AddBoxParameterToConstructorsLowering(val context: JsIrBackendContext)
|
||||
|
||||
private fun IrConstructor.addBoxParameter() {
|
||||
val irClass = parentAsClass
|
||||
val boxParameter = generateBoxParameter(irClass).also { valueParameters += it }
|
||||
val boxParameter = generateBoxParameter(irClass).also { valueParameters = valueParameters memoryOptimizedPlus it }
|
||||
|
||||
val body = body as? IrBlockBody ?: return
|
||||
val isBoxUsed = body.replaceThisWithBoxBeforeSuperCall(irClass, boxParameter.symbol)
|
||||
|
||||
+3
-2
@@ -22,7 +22,8 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot
|
||||
|
||||
class ES6ConstructorBoxParameterOptimizationLowering(private val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
private val IrClass.needsOfBoxParameter by context.mapping.esClassWhichNeedBoxParameters
|
||||
@@ -36,7 +37,7 @@ class ES6ConstructorBoxParameterOptimizationLowering(private val context: JsIrBa
|
||||
containerFunction?.isEs6ConstructorReplacement == true && !containerFunction.parentAsClass.requiredToHaveBoxParameter()
|
||||
|
||||
if (containerFunction != null && shouldRemoveBoxRelatedDeclarationsAndStatements && irBody is IrBlockBody) {
|
||||
containerFunction.valueParameters = containerFunction.valueParameters.filter { !it.isBoxParameter }
|
||||
containerFunction.valueParameters = containerFunction.valueParameters.memoryOptimizedFilterNot { it.isBoxParameter }
|
||||
}
|
||||
|
||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
|
||||
+10
-6
@@ -23,6 +23,10 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
|
||||
|
||||
object ES6_INIT_CALL : IrStatementOriginImpl("ES6_INIT_CALL")
|
||||
object ES6_CONSTRUCTOR_REPLACEMENT : IrDeclarationOriginImpl("ES6_CONSTRUCTOR_REPLACEMENT")
|
||||
@@ -62,7 +66,7 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
private fun IrConstructor.generateExportedConstructorIfNeed(factoryFunction: IrSimpleFunction): IrConstructor? {
|
||||
return runIf(isExported(context) && isPrimary) {
|
||||
apply {
|
||||
valueParameters = valueParameters.filterNot { it.isBoxParameter }
|
||||
valueParameters = valueParameters.memoryOptimizedFilterNot { it.isBoxParameter }
|
||||
(body as? IrBlockBody)?.let {
|
||||
val selfReplacedConstructorCall = JsIrBuilder.buildCall(factoryFunction.symbol).apply {
|
||||
valueParameters.forEachIndexed { i, it -> putValueArgument(i, JsIrBuilder.buildGetValue(it.symbol)) }
|
||||
@@ -170,9 +174,9 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
|
||||
transformChildrenVoid(object : ValueRemapper(emptyMap()) {
|
||||
override val map: MutableMap<IrValueSymbol, IrValueSymbol> = currentConstructor.valueParameters
|
||||
.zip(constructorReplacement.valueParameters)
|
||||
.associate { it.first.symbol to it.second.symbol }
|
||||
.toMutableMap()
|
||||
.asSequence()
|
||||
.zip(constructorReplacement.valueParameters.asSequence())
|
||||
.associateTo(newHashMapWithExpectedSize(currentConstructor.valueParameters.size)) { it.first.symbol to it.second.symbol }
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
return if (expression.returnTargetSymbol == currentConstructor.symbol) {
|
||||
@@ -208,7 +212,7 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
.apply {
|
||||
putValueArgument(0, irClass.getCurrentConstructorReference(constructorReplacement))
|
||||
putValueArgument(1, expression.symbol.owner.parentAsClass.jsConstructorReference(context))
|
||||
putValueArgument(2, irAnyArray(expression.valueArguments.map { it ?: context.getVoid() }))
|
||||
putValueArgument(2, irAnyArray(expression.valueArguments.memoryOptimizedMap { it ?: context.getVoid() }))
|
||||
putValueArgument(3, boxParameterGetter)
|
||||
}
|
||||
constructor.parentAsClass.symbol == context.irBuiltIns.anyClass ->
|
||||
@@ -252,6 +256,6 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
private fun IrDeclaration.excludeFromExport() {
|
||||
val jsExportIgnoreClass = context.intrinsics.jsExportIgnoreAnnotationSymbol.owner
|
||||
val jsExportIgnoreCtor = jsExportIgnoreClass.primaryConstructor ?: return
|
||||
annotations += JsIrBuilder.buildConstructorCall(jsExportIgnoreCtor.symbol)
|
||||
annotations = annotations memoryOptimizedPlus JsIrBuilder.buildConstructorCall(jsExportIgnoreCtor.symbol)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -23,7 +23,8 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
|
||||
|
||||
const val CREATE_EXTERNAL_THIS_CONSTRUCTOR_PARAMETERS = 2
|
||||
|
||||
@@ -67,8 +68,7 @@ class ES6PrimaryConstructorOptimizationLowering(private val context: JsIrBackend
|
||||
|
||||
body.transformChildrenVoid(object : ValueRemapper(emptyMap()) {
|
||||
override val map = original.valueParameters.zip(constructor.valueParameters)
|
||||
.associate { it.first.symbol to it.second.symbol }
|
||||
.toMutableMap<IrValueSymbol, IrValueSymbol>()
|
||||
.associateTo(newHashMapWithExpectedSize<IrValueSymbol, IrValueSymbol>(original.valueParameters.size)) { it.first.symbol to it.second.symbol }
|
||||
|
||||
override fun visitReturn(expression: IrReturn): IrExpression {
|
||||
return if (expression.returnTargetSymbol == original.symbol) {
|
||||
|
||||
+9
-9
@@ -12,14 +12,11 @@ import org.jetbrains.kotlin.backend.common.ir.isExpect
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.common.lower.irIfThen
|
||||
import org.jetbrains.kotlin.backend.common.lower.parents
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PRIVATE
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsCommonBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isInstantiableEnum
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.parentEnumClassOrNull
|
||||
@@ -36,6 +33,9 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.findIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
class EnumUsageLowering(val context: JsCommonBackendContext) : BodyLoweringPass {
|
||||
private var IrEnumEntry.getInstanceFun by context.mapping.enumEntryToGetInstanceFun
|
||||
@@ -99,7 +99,7 @@ class EnumClassConstructorLowering(val context: JsCommonBackendContext) : Declar
|
||||
}.apply {
|
||||
parent = enumClass
|
||||
additionalParameters.forEachIndexed { index, (name, type) ->
|
||||
valueParameters += JsIrBuilder.buildValueParameter(this, name, index, type)
|
||||
valueParameters = valueParameters memoryOptimizedPlus JsIrBuilder.buildValueParameter(this, name, index, type)
|
||||
}
|
||||
copyParameterDeclarationsFrom(enumConstructor)
|
||||
|
||||
@@ -334,7 +334,7 @@ class EnumEntryInstancesBodyLowering(val context: JsCommonBackendContext) : Body
|
||||
val entryClass = container.constructedClass
|
||||
val enum = entryClass.parentAsClass
|
||||
if (enum.isInstantiableEnum) {
|
||||
val entry = enum.declarations.filterIsInstance<IrEnumEntry>().find { it.correspondingClass === entryClass }!!
|
||||
val entry = enum.declarations.findIsInstanceAnd<IrEnumEntry> { it.correspondingClass === entryClass }!!
|
||||
|
||||
//In ES6 using `this` before superCall is unavailable, so
|
||||
//need to find superCall and put `instance = this` after it
|
||||
@@ -476,7 +476,7 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
|
||||
declaration.body = context.irFactory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
|
||||
statements += context.createIrBuilder(declaration.symbol).irBlockBody {
|
||||
+irCall(enumClass.initEntryInstancesFun!!.symbol)
|
||||
}.statements + originalBody.statements
|
||||
}.statements memoryOptimizedPlus originalBody.statements
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -546,7 +546,7 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
|
||||
irBranch(
|
||||
irEquals(irGet(nameParameter), irString(it.name.identifier)), irReturn(irCall(it.getInstanceFun!!))
|
||||
)
|
||||
} + irElseBranch(irBlock {
|
||||
} memoryOptimizedPlus irElseBranch(irBlock {
|
||||
+irCall(irClass.initEntryInstancesFun!!)
|
||||
+irCall(throwISESymbol)
|
||||
})
|
||||
@@ -561,8 +561,8 @@ class EnumSyntheticFunctionsAndPropertiesLowering(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.arrayOfEnumEntriesOf(enumClass: IrClass) =
|
||||
irVararg(enumClass.defaultType, enumClass.enumEntries.map { irCall(it.getInstanceFun!!) })
|
||||
private fun IrBuilderWithScope.arrayOfEnumEntriesOf(enumClass: IrClass) =
|
||||
irVararg(enumClass.defaultType, enumClass.enumEntries.memoryOptimizedMap { irCall(it.getInstanceFun!!) })
|
||||
}
|
||||
|
||||
private val IrClass.enumEntries: List<IrEnumEntry>
|
||||
|
||||
+11
-5
@@ -10,7 +10,10 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isJsImplicitExport
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
@@ -18,6 +21,7 @@ import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
|
||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
class ImplicitlyExportedDeclarationsMarkingLowering(private val context: JsIrBackendContext) : DeclarationTransformer {
|
||||
private val strictImplicitExport = context.configuration.getBoolean(JSConfigurationKeys.GENERATE_STRICT_IMPLICIT_EXPORT)
|
||||
@@ -38,9 +42,11 @@ class ImplicitlyExportedDeclarationsMarkingLowering(private val context: JsIrBac
|
||||
}
|
||||
|
||||
private fun IrClass.collectImplicitlyExportedDeclarations(): Set<IrDeclaration> {
|
||||
return typeParameters
|
||||
.flatMap { it.superTypes }.toSet()
|
||||
.flatMap { it.collectImplicitlyExportedDeclarations() }.toSet()
|
||||
return typeParameters.asSequence()
|
||||
.flatMap { it.superTypes }
|
||||
.distinct()
|
||||
.flatMap { it.collectImplicitlyExportedDeclarations() }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -85,7 +91,7 @@ class ImplicitlyExportedDeclarationsMarkingLowering(private val context: JsIrBac
|
||||
|
||||
private fun IrDeclaration.markWithJsImplicitExport() {
|
||||
val jsImplicitExportCtor = context.intrinsics.jsImplicitExportAnnotationSymbol.constructors.single()
|
||||
annotations += JsIrBuilder.buildConstructorCall(jsImplicitExportCtor)
|
||||
annotations = annotations memoryOptimizedPlus JsIrBuilder.buildConstructorCall(jsImplicitExportCtor)
|
||||
|
||||
parentClassOrNull?.takeIf { it.shouldBeMarkedWithImplicitExport() }?.markWithJsImplicitExport()
|
||||
}
|
||||
|
||||
+11
-8
@@ -32,6 +32,9 @@ import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
|
||||
@@ -112,16 +115,16 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
|
||||
override fun lower(irFile: IrFile) {
|
||||
|
||||
// Regular contextless lambdas are always transformed to function references
|
||||
val ctorToFreeFunctionMap = mutableMapOf<IrConstructorSymbol, IrSimpleFunctionSymbol>()
|
||||
val ctorToFreeFunctionMap = hashMapOf<IrConstructorSymbol, IrSimpleFunctionSymbol>()
|
||||
|
||||
// Regular lambdas with captured variables are transformed to function expressions whenever possible.
|
||||
// However, we don't do that if the lambda captures a variable declared in a loop, at least when variable
|
||||
// declarations are lowered into 'var' statements in JS. See the CapturedVariablesDeclaredInLoops class.
|
||||
// We also don't do that if there is more than one constructor call for a single lambda.
|
||||
val ctorToFunctionExpressionMap = mutableMapOf<IrConstructorSymbol, FunctionExpressionFactory>()
|
||||
val ctorToFunctionExpressionMap = hashMapOf<IrConstructorSymbol, FunctionExpressionFactory>()
|
||||
|
||||
// Suspend lambdas are transformed to factory calls
|
||||
val ctorToFactoryMap = mutableMapOf<IrConstructorSymbol, IrSimpleFunctionSymbol>()
|
||||
val ctorToFactoryMap = hashMapOf<IrConstructorSymbol, IrSimpleFunctionSymbol>()
|
||||
|
||||
val closureUsageAnalyser = ClosureUsageAnalyser()
|
||||
|
||||
@@ -502,7 +505,7 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
|
||||
val isSuspendLambda = invokeFun.overriddenSymbols.any { it.owner.isSuspend }
|
||||
|
||||
fun createOldToNewInvokeParametersMapping(lambdaDeclaration: IrSimpleFunction) =
|
||||
invokeFun.valueParameters.associateBy({ it.symbol }, { lambdaDeclaration.valueParameters[it.index].symbol })
|
||||
invokeFun.valueParameters.associateBy({ it.symbol }) { lambdaDeclaration.valueParameters[it.index].symbol }
|
||||
|
||||
fun lambdaInnerClasses() =
|
||||
lambdaClass.declarations.filter { it is IrClass || (it is IrSimpleFunction && it.dispatchReceiverParameter == null) }
|
||||
@@ -620,7 +623,7 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
|
||||
|
||||
lambdaDeclaration.parent = parent
|
||||
|
||||
lambdaDeclaration.valueParameters = superInvokeFun.valueParameters.mapIndexed { id, vp ->
|
||||
lambdaDeclaration.valueParameters = superInvokeFun.valueParameters.memoryOptimizedMapIndexed { id, vp ->
|
||||
val originalValueParameter = invokeFun.valueParameters[id]
|
||||
vp.copyTo(
|
||||
irFunction = lambdaDeclaration,
|
||||
@@ -652,11 +655,11 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
|
||||
}
|
||||
}
|
||||
|
||||
factoryDeclaration.valueParameters = constructor.valueParameters.map { it.copyTo(factoryDeclaration) }
|
||||
factoryDeclaration.typeParameters = constructor.typeParameters.map {
|
||||
factoryDeclaration.valueParameters = constructor.valueParameters.memoryOptimizedMap { it.copyTo(factoryDeclaration) }
|
||||
factoryDeclaration.typeParameters = constructor.typeParameters.memoryOptimizedMap {
|
||||
it.copyToWithoutSuperTypes(factoryDeclaration).also { tp ->
|
||||
// TODO: make sure it is done well
|
||||
tp.superTypes += it.superTypes
|
||||
tp.superTypes = tp.superTypes memoryOptimizedPlus it.superTypes
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction<J
|
||||
type = context.irBuiltIns.intType
|
||||
}
|
||||
|
||||
val firstTrailingParameterIndexVar = lazy {
|
||||
val firstTrailingParameterIndexVar = lazy(LazyThreadSafetyMode.NONE) {
|
||||
irTemporary(
|
||||
if (numberOfTrailingParameters == 0)
|
||||
getTotalNumberOfArguments
|
||||
|
||||
+10
-6
@@ -5,7 +5,9 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.DefaultArgumentStubGenerator
|
||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
@@ -24,6 +26,8 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
||||
DefaultArgumentStubGenerator(
|
||||
@@ -62,9 +66,9 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
||||
private fun IrFunction.introduceDefaultResolution(): IrFunction {
|
||||
val irBuilder = context.createIrBuilder(symbol, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||
|
||||
val variables = mutableMapOf<IrValueParameter, IrValueParameter>()
|
||||
val variables = hashMapOf<IrValueParameter, IrValueParameter>()
|
||||
|
||||
valueParameters = valueParameters.map { param ->
|
||||
valueParameters = valueParameters.memoryOptimizedMap { param ->
|
||||
param.takeIf { it.defaultValue != null }
|
||||
?.copyTo(this, isAssignable = true, origin = JsLoweredDeclarationOrigin.JS_SHADOWED_DEFAULT_PARAMETER)
|
||||
?.also { new -> variables[param] = new } ?: param
|
||||
@@ -112,7 +116,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
||||
context.additionalExportedDeclarations.add(defaultFunStub)
|
||||
|
||||
if (!originalFun.hasAnnotation(JsAnnotations.jsNameFqn)) {
|
||||
annotations += originalFun.generateJsNameAnnotationCall()
|
||||
annotations = annotations memoryOptimizedPlus originalFun.generateJsNameAnnotationCall()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,7 +129,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
||||
}
|
||||
|
||||
originalFun.annotations = irrelevantAnnotations
|
||||
defaultFunStub.annotations += exportAnnotations
|
||||
defaultFunStub.annotations = defaultFunStub.annotations memoryOptimizedPlus exportAnnotations
|
||||
originalFun.origin = JsLoweredDeclarationOrigin.JS_SHADOWED_EXPORT
|
||||
|
||||
return listOf(originalFun, defaultFunStub)
|
||||
@@ -135,7 +139,7 @@ class JsDefaultArgumentStubGenerator(override val context: JsIrBackendContext) :
|
||||
val ctx = context
|
||||
val irBuilder = context.createIrBuilder(symbol, UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||
|
||||
val variables = mutableMapOf<IrValueParameter, IrValueDeclaration>().apply {
|
||||
val variables = hashMapOf<IrValueParameter, IrValueDeclaration>().apply {
|
||||
originalDeclaration.dispatchReceiverParameter?.let {
|
||||
set(it, dispatchReceiverParameter!!)
|
||||
}
|
||||
|
||||
+2
-2
@@ -11,12 +11,12 @@ import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsMapping
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder.SYNTHESIZED_DECLARATION
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildConstructor
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.buildValueParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
import org.jetbrains.kotlin.ir.util.copyTo
|
||||
import org.jetbrains.kotlin.ir.util.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
@@ -98,7 +98,7 @@ class JsInnerClassesSupport(mapping: JsMapping, private val irFactory: IrFactory
|
||||
newValueParameters += p.copyTo(newConstructor, index = p.index + 1)
|
||||
}
|
||||
|
||||
newConstructor.valueParameters += newValueParameters
|
||||
newConstructor.valueParameters = newConstructor.valueParameters memoryOptimizedPlus newValueParameters
|
||||
|
||||
return newConstructor
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ class JsReturnableBlockLowering(val context: CommonBackendContext) : BodyLowerin
|
||||
|
||||
class JsReturnableBlockTransformer(val context: CommonBackendContext) : IrElementTransformerVoidWithContext() {
|
||||
private var labelCnt = 0
|
||||
private var map = mutableMapOf<IrReturnableBlockSymbol, IrVariable>()
|
||||
private var map = hashMapOf<IrReturnableBlockSymbol, IrVariable>()
|
||||
|
||||
private val unitType = context.irBuiltIns.unitType
|
||||
private val unitValue get() = IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, unitType, context.irBuiltIns.unitClass)
|
||||
|
||||
+3
-5
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.DeclarationTransformer
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
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
|
||||
@@ -15,10 +14,9 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.isChildOf
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
private val BODILESS_BUILTIN_CLASSES = listOf(
|
||||
"kotlin.String",
|
||||
@@ -73,10 +71,10 @@ class MoveBodilessDeclarationsToSeparatePlaceLowering(private val context: JsIrB
|
||||
override fun transformFlat(declaration: IrDeclaration): List<IrDeclaration>? {
|
||||
val irFile = declaration.parent as? IrFile ?: return null
|
||||
|
||||
val externalPackageFragment by lazy {
|
||||
val externalPackageFragment by lazy(LazyThreadSafetyMode.NONE) {
|
||||
context.externalPackageFragment.getOrPut(irFile.symbol) {
|
||||
IrFileImpl(fileEntry = irFile.fileEntry, fqName = irFile.fqName, symbol = IrFileSymbolImpl(), module = irFile.module).also {
|
||||
it.annotations += irFile.annotations
|
||||
it.annotations = it.annotations memoryOptimizedPlus irFile.annotations
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -14,13 +14,14 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
import org.jetbrains.kotlin.ir.util.transformDeclarationsFlat
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
|
||||
fun moveOpenClassesToSeparateFiles(moduleFragment: IrModuleFragment) {
|
||||
fun createFile(file: IrFile, klass: IrClass): IrFile =
|
||||
IrFileImpl(fileEntry = file.fileEntry, fqName = file.fqName, symbol = IrFileSymbolImpl(), module = file.module).also {
|
||||
it.annotations += file.annotations
|
||||
it.annotations = it.annotations memoryOptimizedPlus file.annotations
|
||||
it.declarations += klass
|
||||
klass.parent = it
|
||||
}
|
||||
@@ -55,7 +56,7 @@ fun moveOpenClassesToSeparateFiles(moduleFragment: IrModuleFragment) {
|
||||
return@transformFlat if (openClasses.isEmpty())
|
||||
null
|
||||
else
|
||||
listOf(file) + openClasses.map { createFile(file, it) }
|
||||
openClasses.mapTo(mutableListOf(file)) { createFile(file, it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.isLocal
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
private val STATIC_THIS_PARAMETER = object : IrDeclarationOriginImpl("STATIC_THIS_PARAMETER") {}
|
||||
|
||||
@@ -61,10 +62,11 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
it.parent = function.parent
|
||||
}
|
||||
|
||||
staticFunction.typeParameters += function.typeParameters.map { it.deepCopyWithSymbols(staticFunction) }
|
||||
staticFunction.typeParameters =
|
||||
staticFunction.typeParameters memoryOptimizedPlus function.typeParameters.map { it.deepCopyWithSymbols(staticFunction) }
|
||||
|
||||
staticFunction.extensionReceiverParameter = function.extensionReceiverParameter?.copyTo(staticFunction)
|
||||
staticFunction.valueParameters += buildValueParameter(staticFunction) {
|
||||
staticFunction.valueParameters = staticFunction.valueParameters memoryOptimizedPlus buildValueParameter(staticFunction) {
|
||||
origin = STATIC_THIS_PARAMETER
|
||||
name = Name.identifier("\$this")
|
||||
index = 0
|
||||
@@ -73,7 +75,7 @@ class PrivateMembersLowering(val context: JsIrBackendContext) : DeclarationTrans
|
||||
|
||||
function.correspondingStatic = staticFunction
|
||||
|
||||
staticFunction.valueParameters += function.valueParameters.map {
|
||||
staticFunction.valueParameters = staticFunction.valueParameters memoryOptimizedPlus function.valueParameters.map {
|
||||
// TODO better way to avoid copying default value
|
||||
it.copyTo(staticFunction, index = it.index + 1, defaultValue = null)
|
||||
}
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
|
||||
class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
|
||||
@@ -144,7 +145,7 @@ class PropertyReferenceLowering(private val context: JsIrBackendContext) : BodyL
|
||||
|
||||
function.parent = factory
|
||||
|
||||
val unboundValueParameters = supperAccessor.valueParameters.map { it.copyTo(function) }
|
||||
val unboundValueParameters = supperAccessor.valueParameters.memoryOptimizedMap { it.copyTo(function) }
|
||||
function.valueParameters = unboundValueParameters
|
||||
val arity = unboundValueParameters.size
|
||||
val total = arity + boundValueParameters.size
|
||||
|
||||
+3
-3
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
@@ -17,6 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedFilterNot
|
||||
import org.jetbrains.kotlin.ir.util.transformFlat
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -66,7 +66,7 @@ class ScriptRemoveReceiverLowering(val context: CommonBackendContext) : FileLowe
|
||||
|
||||
val result = with(super.visitFunctionReference(expression) as IrFunctionReference) {
|
||||
// TODO do we really need to fix type or removing dispatchReceiver is enough?
|
||||
val arguments = (type as IrSimpleType).arguments.filterNot(::isScript)
|
||||
val arguments = (type as IrSimpleType).arguments.memoryOptimizedFilterNot(::isScript)
|
||||
val newN = arguments.size - 1
|
||||
|
||||
IrFunctionReferenceImpl(
|
||||
@@ -103,7 +103,7 @@ class ScriptRemoveReceiverLowering(val context: CommonBackendContext) : FileLowe
|
||||
|
||||
val result = with(super.visitPropertyReference(expression) as IrPropertyReference) {
|
||||
// TODO do we really need to fix type or removing dispatchReceiver is enough?
|
||||
val arguments = (type as IrSimpleType).arguments.filterNot(::isScript)
|
||||
val arguments = (type as IrSimpleType).arguments.memoryOptimizedFilterNot(::isScript)
|
||||
val newN = arguments.size - 1
|
||||
|
||||
IrPropertyReferenceImpl(
|
||||
|
||||
+8
-5
@@ -32,7 +32,8 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
class SecondaryConstructorLowering(val context: JsIrBackendContext) : DeclarationTransformer {
|
||||
|
||||
@@ -143,7 +144,9 @@ class SecondaryConstructorLowering(val context: JsIrBackendContext) : Declaratio
|
||||
ThisUsageReplaceTransformer(
|
||||
constructor.symbol,
|
||||
delegate.symbol,
|
||||
oldValueParameters.zip(delegate.valueParameters).associate { (old, new) -> old.symbol to new.symbol }
|
||||
oldValueParameters
|
||||
.zip(delegate.valueParameters)
|
||||
.associate { (old, new) -> old.symbol to new.symbol }
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -192,8 +195,8 @@ private fun JsIrBackendContext.buildInitDeclaration(constructor: IrConstructor,
|
||||
it.parent = constructor.parent
|
||||
it.copyTypeParametersFrom(constructor.parentAsClass)
|
||||
|
||||
it.valueParameters = constructor.valueParameters.map { p -> p.copyTo(it) }
|
||||
it.valueParameters += JsIrBuilder.buildValueParameter(it, "\$this", constructor.valueParameters.size, type)
|
||||
it.valueParameters = constructor.valueParameters.memoryOptimizedMap { p -> p.copyTo(it) }
|
||||
it.valueParameters = it.valueParameters memoryOptimizedPlus JsIrBuilder.buildValueParameter(it, "\$this", constructor.valueParameters.size, type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +217,7 @@ private fun JsIrBackendContext.buildFactoryDeclaration(constructor: IrConstructo
|
||||
}.also { factory ->
|
||||
factory.parent = constructor.parent
|
||||
factory.copyTypeParametersFrom(constructor.parentAsClass)
|
||||
factory.valueParameters += constructor.valueParameters.map { p -> p.copyTo(factory) }
|
||||
factory.valueParameters = factory.valueParameters memoryOptimizedPlus constructor.valueParameters.map { p -> p.copyTo(factory) }
|
||||
factory.annotations = constructor.annotations
|
||||
}
|
||||
}
|
||||
|
||||
+10
-9
@@ -27,6 +27,9 @@ import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.findIsInstanceAnd
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
|
||||
fun generateJsTests(context: JsIrBackendContext, moduleFragment: IrModuleFragment) {
|
||||
val generator = TestGenerator(context, false)
|
||||
@@ -40,6 +43,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
// Additional copy to prevent ConcurrentModificationException
|
||||
if (irFile.declarations.isEmpty()) return
|
||||
ArrayList(irFile.declarations).forEach {
|
||||
if (it is IrClass) {
|
||||
generateTestCalls(it) { if (groupByPackage) suiteForPackage(irFile) else context.createTestContainerFun(irFile) }
|
||||
@@ -49,7 +53,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo
|
||||
}
|
||||
}
|
||||
|
||||
private val packageSuites = mutableMapOf<FqName, IrSimpleFunction>()
|
||||
private val packageSuites = hashMapOf<FqName, IrSimpleFunction>()
|
||||
|
||||
private fun suiteForPackage(irFile: IrFile) = packageSuites.getOrPut(irFile.fqName) {
|
||||
context.suiteFun!!.createInvocation(irFile.fqName.asString(), context.createTestContainerFun(irFile))
|
||||
@@ -84,12 +88,12 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo
|
||||
private fun generateTestCalls(irClass: IrClass, parentFunction: () -> IrSimpleFunction) {
|
||||
if (irClass.modality == Modality.ABSTRACT || irClass.isEffectivelyExternal() || irClass.isExpect) return
|
||||
|
||||
val suiteFunBody by lazy {
|
||||
val suiteFunBody by lazy(LazyThreadSafetyMode.NONE) {
|
||||
context.suiteFun!!.createInvocation(irClass.name.asString(), parentFunction(), irClass.isIgnored)
|
||||
}
|
||||
|
||||
val beforeFunctions = irClass.declarations.filterIsInstance<IrSimpleFunction>().filter { it.isBefore }
|
||||
val afterFunctions = irClass.declarations.filterIsInstance<IrSimpleFunction>().filter { it.isAfter }
|
||||
val beforeFunctions = irClass.declarations.filterIsInstanceAnd<IrSimpleFunction> { it.isBefore }
|
||||
val afterFunctions = irClass.declarations.filterIsInstanceAnd<IrSimpleFunction> { it.isAfter }
|
||||
|
||||
irClass.declarations.forEach {
|
||||
when {
|
||||
@@ -174,10 +178,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo
|
||||
|
||||
if (context is JsIrBackendContext && (testFun.returnType as? IrSimpleType)?.classifier == context.intrinsics.promiseClassSymbol) {
|
||||
val finally = context.intrinsics.promiseClassSymbol.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.first {
|
||||
it.name.asString() == "finally"
|
||||
}
|
||||
.findIsInstanceAnd<IrSimpleFunction> { it.name.asString() == "finally" }!!
|
||||
|
||||
val refType = IrSimpleTypeImpl(context.ir.symbols.functionN(0), false, emptyList(), emptyList())
|
||||
|
||||
@@ -190,7 +191,7 @@ class TestGenerator(val context: JsCommonBackendContext, val groupByPackage: Boo
|
||||
this.body = context.irFactory.createBlockBody(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
afterFuns.map {
|
||||
afterFuns.memoryOptimizedMap {
|
||||
JsIrBuilder.buildCall(it.symbol).apply {
|
||||
dispatchReceiver = JsIrBuilder.buildGetValue(classVal.symbol)
|
||||
}
|
||||
|
||||
+4
-4
@@ -17,13 +17,14 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.atMostOne
|
||||
|
||||
class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : CallsTransformer {
|
||||
private val intrinsics = context.intrinsics
|
||||
private val irBuiltIns = context.irBuiltIns
|
||||
private val icUtils = context.inlineClassesUtils
|
||||
|
||||
private val symbolToTransformer: SymbolToTransformer = mutableMapOf()
|
||||
private val symbolToTransformer: SymbolToTransformer = hashMapOf()
|
||||
|
||||
init {
|
||||
symbolToTransformer.run {
|
||||
@@ -178,11 +179,10 @@ class EqualityAndComparisonCallsTransformer(context: JsIrBackendContext) : Calls
|
||||
private fun IrType.findEqualsMethod(): IrSimpleFunction? {
|
||||
val klass = getClass() ?: return null
|
||||
if (klass.isEnumClass && klass.isExternal) return null
|
||||
return klass.declarations
|
||||
return klass.declarations.asSequence()
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.filter { it.isEqualsInheritedFromAny() && !it.isFakeOverriddenFromAny() }
|
||||
.also { assert(it.size <= 1) }
|
||||
.singleOrNull()
|
||||
.atMostOne()
|
||||
}
|
||||
|
||||
private fun IrFunction.isMethodOfPrimitiveJSType() =
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ class MethodsOfAnyCallsTransformer(context: JsIrBackendContext) : CallsTransform
|
||||
private val nameToTransformer: Map<Name, (IrFunctionAccessExpression) -> IrExpression>
|
||||
|
||||
init {
|
||||
nameToTransformer = mutableMapOf()
|
||||
nameToTransformer = hashMapOf()
|
||||
nameToTransformer.run {
|
||||
put(Name.identifier("toString")) { call ->
|
||||
if (shouldReplaceToStringWithRuntimeCall(call)) {
|
||||
|
||||
-1
@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.irCall
|
||||
|
||||
+2
-2
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.ir.util.getSimpleFunction
|
||||
class PrimitiveContainerMemberCallTransformer(private val context: JsIrBackendContext) : CallsTransformer {
|
||||
private val intrinsics = context.intrinsics
|
||||
|
||||
private val symbolToTransformer: SymbolToTransformer = mutableMapOf()
|
||||
private val symbolToTransformer: SymbolToTransformer = hashMapOf()
|
||||
|
||||
init {
|
||||
symbolToTransformer.run {
|
||||
@@ -82,7 +82,7 @@ private val IrClassSymbol.iterator
|
||||
get() = getSimpleFunction("iterator")!!
|
||||
|
||||
private val IrClassSymbol.sizeConstructor
|
||||
get() = owner.declarations.filterIsInstance<IrConstructor>().first { it.valueParameters.size == 1 }.symbol
|
||||
get() = owner.declarations.asSequence().filterIsInstance<IrConstructor>().first { it.valueParameters.size == 1 }.symbol
|
||||
|
||||
private val IrClassSymbol.lengthProperty
|
||||
get() = getPropertyGetter("length")!!
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
|
||||
}
|
||||
|
||||
init {
|
||||
nameToTransformer = mutableMapOf()
|
||||
nameToTransformer = hashMapOf()
|
||||
nameToTransformer.run {
|
||||
addWithPredicate(
|
||||
Name.special(Namer.KCALLABLE_GET_NAME),
|
||||
|
||||
+4
-8
@@ -63,20 +63,16 @@ private class CodeCleaner : IrElementVisitorVoid {
|
||||
private fun IrStatementContainer.cleanUpStatements() {
|
||||
var unreachable = false
|
||||
|
||||
val newStatements = statements.filter {
|
||||
statements.removeIf {
|
||||
when {
|
||||
unreachable -> false
|
||||
it is IrExpression && it.isPure(true) -> false
|
||||
unreachable -> true
|
||||
it is IrExpression && it.isPure(true) -> true
|
||||
else -> {
|
||||
unreachable = it.doesNotReturn()
|
||||
true
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statements.clear()
|
||||
|
||||
statements += newStatements
|
||||
}
|
||||
|
||||
// Checks if it is safe to assume the statement doesn't return (e.g. throws an exception or loops infinitely)
|
||||
|
||||
+24
-17
@@ -33,6 +33,9 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMapIndexed
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val context: C) : BodyLoweringPass {
|
||||
|
||||
@@ -61,7 +64,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
protected open fun IrBuilderWithScope.generateDelegatedCall(expectedType: IrType, delegatingCall: IrExpression): IrExpression =
|
||||
delegatingCall
|
||||
|
||||
private val builtCoroutines = mutableMapOf<IrFunction, BuiltCoroutine>()
|
||||
private val builtCoroutines = hashMapOf<IrFunction, BuiltCoroutine>()
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
if (container is IrSimpleFunction && container.isSuspend) {
|
||||
@@ -153,7 +156,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
|
||||
private fun IrBlockBodyBuilder.createCoroutineInstance(function: IrSimpleFunction, parameters: Collection<IrValueParameter>, coroutine: BuiltCoroutine): IrExpression {
|
||||
val constructor = coroutine.coroutineConstructor
|
||||
val coroutineTypeArgs = function.typeParameters.map {
|
||||
val coroutineTypeArgs = function.typeParameters.memoryOptimizedMap {
|
||||
IrSimpleTypeImpl(it.symbol, true, emptyList(), emptyList())
|
||||
}
|
||||
|
||||
@@ -207,7 +210,8 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
private val continuationType = continuationClassSymbol.typeWith(function.returnType)
|
||||
|
||||
// Save all arguments to fields.
|
||||
private val argumentToPropertiesMap = functionParameters.associateWith { coroutineClass.addField(it.name, it.type, false) }
|
||||
private val argumentToPropertiesMap = functionParameters
|
||||
.associateWith { coroutineClass.addField(it.name, it.type, false) }
|
||||
|
||||
private val coroutineBaseClass = getCoroutineBaseClass(function)
|
||||
private val coroutineBaseClassConstructor = coroutineBaseClass.owner.constructors.single { it.valueParameters.size == 1 }
|
||||
@@ -228,17 +232,20 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
}.apply {
|
||||
parent = function.parent
|
||||
createParameterDeclarations()
|
||||
typeParameters = function.typeParameters.map { typeParam ->
|
||||
typeParameters = function.typeParameters.memoryOptimizedMap { typeParam ->
|
||||
// TODO: remap types
|
||||
typeParam.copyToWithoutSuperTypes(this).apply { superTypes += typeParam.superTypes }
|
||||
typeParam.copyToWithoutSuperTypes(this).apply { superTypes = superTypes memoryOptimizedPlus typeParam.superTypes }
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildConstructor(): IrConstructor {
|
||||
if (isSuspendLambda) {
|
||||
return coroutineClass.declarations.filterIsInstance<IrConstructor>().single().let {
|
||||
context.mapping.capturedConstructors[it] ?: it
|
||||
}
|
||||
return coroutineClass.declarations
|
||||
.filterIsInstance<IrConstructor>()
|
||||
.single()
|
||||
.let {
|
||||
context.mapping.capturedConstructors[it] ?: it
|
||||
}
|
||||
}
|
||||
|
||||
return context.irFactory.buildConstructor {
|
||||
@@ -251,11 +258,11 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
parent = coroutineClass
|
||||
coroutineClass.addChild(this)
|
||||
|
||||
valueParameters = functionParameters.mapIndexed { index, parameter ->
|
||||
valueParameters = functionParameters.memoryOptimizedMapIndexed { index, parameter ->
|
||||
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index, defaultValue = null)
|
||||
}
|
||||
val continuationParameter = coroutineBaseClassConstructor.valueParameters[0]
|
||||
valueParameters += continuationParameter.copyTo(
|
||||
valueParameters = valueParameters memoryOptimizedPlus continuationParameter.copyTo(
|
||||
this, DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||
index = valueParameters.size,
|
||||
startOffset = function.startOffset,
|
||||
@@ -303,12 +310,12 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
parent = coroutineClass
|
||||
coroutineClass.addChild(this)
|
||||
|
||||
typeParameters = stateMachineFunction.typeParameters.map { parameter ->
|
||||
typeParameters = stateMachineFunction.typeParameters.memoryOptimizedMap { parameter ->
|
||||
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
|
||||
.apply { superTypes += parameter.superTypes }
|
||||
.apply { superTypes = superTypes memoryOptimizedPlus parameter.superTypes }
|
||||
}
|
||||
|
||||
valueParameters = stateMachineFunction.valueParameters.mapIndexed { index, parameter ->
|
||||
valueParameters = stateMachineFunction.valueParameters.memoryOptimizedMapIndexed { index, parameter ->
|
||||
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
|
||||
}
|
||||
|
||||
@@ -338,14 +345,14 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
parent = coroutineClass
|
||||
coroutineClass.addChild(this)
|
||||
|
||||
typeParameters = function.typeParameters.map { parameter ->
|
||||
typeParameters = function.typeParameters.memoryOptimizedMap { parameter ->
|
||||
parameter.copyToWithoutSuperTypes(this, origin = DECLARATION_ORIGIN_COROUTINE_IMPL)
|
||||
.apply { superTypes += parameter.superTypes }
|
||||
.apply { superTypes = superTypes memoryOptimizedPlus parameter.superTypes }
|
||||
}
|
||||
|
||||
val unboundArgs = function.valueParameters
|
||||
|
||||
val createValueParameters = (unboundArgs + create1CompletionParameter).mapIndexed { index, parameter ->
|
||||
val createValueParameters = (unboundArgs + create1CompletionParameter).memoryOptimizedMapIndexed { index, parameter ->
|
||||
parameter.copyTo(this, DECLARATION_ORIGIN_COROUTINE_IMPL, index)
|
||||
}
|
||||
|
||||
@@ -441,7 +448,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
|
||||
transformInvokeMethod(createMethod, invokeSuspendMethod)
|
||||
} else {
|
||||
coroutineClass.superTypes += coroutineBaseClass.defaultType
|
||||
coroutineClass.superTypes = coroutineClass.superTypes memoryOptimizedPlus coroutineBaseClass.defaultType
|
||||
}
|
||||
|
||||
coroutineClass.addFakeOverrides(context.typeSystem, implementedMembers)
|
||||
|
||||
+3
-5
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.utils.filterIsInstanceAnd
|
||||
|
||||
class JsSuspendArityStoreLowering(context: JsIrBackendContext) : DeclarationTransformer {
|
||||
|
||||
@@ -19,11 +20,8 @@ class JsSuspendArityStoreLowering(context: JsIrBackendContext) : DeclarationTran
|
||||
if (declaration !is IrClass) return null
|
||||
|
||||
declaration.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.filter { it.isSuspend }
|
||||
.let {
|
||||
declaration.suspendArityStore = it
|
||||
}
|
||||
.filterIsInstanceAnd<IrSimpleFunction> { it.isSuspend }
|
||||
.let { declaration.suspendArityStore = it }
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
+1
-1
@@ -179,7 +179,7 @@ class JsSuspendFunctionsLowering(ctx: JsCommonBackendContext) : AbstractSuspendF
|
||||
|
||||
val liveLocals = computeLivenessAtSuspensionPoints(functionBody).values.flatten().toSet()
|
||||
|
||||
val localToPropertyMap = mutableMapOf<IrValueSymbol, IrFieldSymbol>()
|
||||
val localToPropertyMap = hashMapOf<IrValueSymbol, IrFieldSymbol>()
|
||||
var localCounter = 0
|
||||
// TODO: optimize by using the same property for different locals.
|
||||
liveLocals.forEach {
|
||||
|
||||
+2
-2
@@ -78,7 +78,7 @@ class StateMachineBuilder(
|
||||
private val setSuspendResultValue: (IrExpression) -> IrStatement
|
||||
) : IrElementVisitorVoid {
|
||||
|
||||
private val loopMap = mutableMapOf<IrLoop, LoopBounds>()
|
||||
private val loopMap = hashMapOf<IrLoop, LoopBounds>()
|
||||
private val unit = context.irBuiltIns.unitType
|
||||
private val anyN = context.irBuiltIns.anyNType
|
||||
private val nothing = context.irBuiltIns.nothingType
|
||||
@@ -154,7 +154,7 @@ class StateMachineBuilder(
|
||||
private var currentBlock = entryState.entryBlock
|
||||
|
||||
private val catchBlockStack = mutableListOf(rootExceptionTrap)
|
||||
private val tryStateMap = mutableMapOf<IrExpression, TryState>()
|
||||
private val tryStateMap = hashMapOf<IrExpression, TryState>()
|
||||
private val tryLoopStack = mutableListOf<IrExpression>()
|
||||
|
||||
private fun buildExceptionTrapState(): SuspendState {
|
||||
|
||||
+6
-3
@@ -21,6 +21,9 @@ import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.SideEffectKind
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.sideEffects
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
import org.jetbrains.kotlin.utils.toSmartList
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsExpression, JsGenerationContext> {
|
||||
@@ -48,7 +51,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
|
||||
override fun visitVararg(expression: IrVararg, context: JsGenerationContext): JsExpression {
|
||||
assert(expression.elements.none { it is IrSpreadElement })
|
||||
return JsArrayLiteral(expression.elements.map { it.accept(this, context) }).withSource(expression, context)
|
||||
return JsArrayLiteral(expression.elements.map { it.accept(this, context) }.toSmartList()).withSource(expression, context)
|
||||
}
|
||||
|
||||
override fun visitExpressionBody(body: IrExpressionBody, context: JsGenerationContext): JsExpression =
|
||||
@@ -179,7 +182,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
return if (context.staticContext.backendContext.es6mode) {
|
||||
JsInvocation(JsSuperRef(), arguments)
|
||||
} else {
|
||||
JsInvocation(callFuncRef, listOf(thisRef) + arguments)
|
||||
JsInvocation(callFuncRef, listOf(thisRef) memoryOptimizedPlus arguments)
|
||||
}.withSource(expression, context)
|
||||
}
|
||||
|
||||
@@ -301,7 +304,7 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
IrDynamicOperator.INVOKE ->
|
||||
JsInvocation(
|
||||
expression.receiver.accept(this, data),
|
||||
expression.arguments.map { it.accept(this, data) }
|
||||
expression.arguments.memoryOptimizedMap { it.accept(this, data) }
|
||||
)
|
||||
|
||||
else -> compilationException(
|
||||
|
||||
+4
-7
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.inlineFunction
|
||||
import org.jetbrains.kotlin.backend.common.ir.innerInlinedBlockOrThis
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.emptyScope
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isTheLastReturnStatementIn
|
||||
@@ -17,9 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isAny
|
||||
import org.jetbrains.kotlin.ir.util.constructedClassType
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
@@ -27,6 +24,7 @@ import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.synthetic
|
||||
import org.jetbrains.kotlin.utils.toSmartList
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsStatement, JsGenerationContext> {
|
||||
@@ -36,7 +34,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
}
|
||||
|
||||
override fun visitBlockBody(body: IrBlockBody, context: JsGenerationContext): JsStatement {
|
||||
return JsBlock(body.statements.map { it.accept(this, context) }).withSource(body, context, container = context.currentFunction)
|
||||
return JsBlock(body.statements.map { it.accept(this, context) }.toSmartList()).withSource(body, context, container = context.currentFunction)
|
||||
}
|
||||
|
||||
override fun visitBlock(expression: IrBlock, context: JsGenerationContext): JsStatement {
|
||||
@@ -45,7 +43,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
} ?: context
|
||||
|
||||
val container = expression.innerInlinedBlockOrThis.statements
|
||||
val statements = container.map { it.accept(this, newContext) }
|
||||
val statements = container.map { it.accept(this, newContext) }.toSmartList()
|
||||
|
||||
return if (expression is IrReturnableBlock) {
|
||||
val label = context.getNameForReturnableBlock(expression)
|
||||
@@ -73,7 +71,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
return if (expression.statements.isEmpty()) {
|
||||
JsEmpty
|
||||
} else {
|
||||
JsBlock(expression.statements.map { it.accept(this, context) }).withSource(expression, context)
|
||||
JsBlock(expression.statements.map { it.accept(this, context) }.toSmartList()).withSource(expression, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,7 +195,6 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
}
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, context: JsGenerationContext): JsStatement {
|
||||
|
||||
// TODO: implement
|
||||
return JsEmpty
|
||||
}
|
||||
|
||||
+7
-12
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.js.sourceMap.SourceMap3Builder
|
||||
import org.jetbrains.kotlin.js.sourceMap.SourceMapBuilderConsumer
|
||||
import org.jetbrains.kotlin.js.util.TextOutputImpl
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
|
||||
import java.io.File
|
||||
@@ -128,18 +129,14 @@ class IrModuleToJsTransformer(
|
||||
private fun doStaticMembersLowering(modules: Iterable<IrModuleFragment>) {
|
||||
modules.forEach { module ->
|
||||
module.files.forEach {
|
||||
it.accept(
|
||||
backendContext.keeper,
|
||||
Keeper.KeepData(
|
||||
classInKeep = false,
|
||||
classShouldBeKept = false
|
||||
)
|
||||
)
|
||||
it.accept(backendContext.keeper, Keeper.KeepData(classInKeep = false, classShouldBeKept = false))
|
||||
}
|
||||
}
|
||||
|
||||
modules.forEach { module ->
|
||||
module.files.forEach { StaticMembersLowering(backendContext).lower(it) }
|
||||
module.files.forEach {
|
||||
StaticMembersLowering(backendContext).lower(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,9 +210,7 @@ class IrModuleToJsTransformer(
|
||||
JsIrModule(
|
||||
data.fragment.safeName,
|
||||
data.fragment.externalModuleName(),
|
||||
data.files.map {
|
||||
generateProgramFragment(it, mode.minimizedMemberNames)
|
||||
}
|
||||
data.files.map { generateProgramFragment(it, mode.minimizedMemberNames) }
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -289,7 +284,7 @@ class IrModuleToJsTransformer(
|
||||
|
||||
staticContext.classModels.entries.forEach { (symbol, model) ->
|
||||
result.classes[nameGenerator.getNameForClass(symbol.owner)] =
|
||||
JsIrIcClassModel(model.superClasses.map { staticContext.getNameForClass(it.owner) }).also {
|
||||
JsIrIcClassModel(model.superClasses.memoryOptimizedMap { staticContext.getNameForClass(it.owner) }).also {
|
||||
it.preDeclarationBlock.statements += model.preDeclarationBlock.statements
|
||||
it.postDeclarationBlock.statements += model.postDeclarationBlock.statements
|
||||
}
|
||||
|
||||
+9
-7
@@ -22,14 +22,16 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.common.isValidES5Identifier
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.toSmartList
|
||||
|
||||
class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationContext) {
|
||||
private val className = context.getNameForClass(irClass)
|
||||
private val classNameRef = className.makeRef()
|
||||
private val baseClass: IrType? = irClass.superTypes.firstOrNull { !it.classifierOrFail.isInterface }
|
||||
|
||||
private val classPrototypeRef by lazy { prototypeOf(classNameRef, context.staticContext) }
|
||||
private val baseClassRef by lazy { // Lazy in case was not collected by namer during JsClassGenerator construction
|
||||
private val classPrototypeRef by lazy(LazyThreadSafetyMode.NONE) { prototypeOf(classNameRef, context.staticContext) }
|
||||
private val baseClassRef by lazy(LazyThreadSafetyMode.NONE) { // Lazy in case was not collected by namer during JsClassGenerator construction
|
||||
if (baseClass != null && !baseClass.isAny()) baseClass.getClassRef(context) else null
|
||||
}
|
||||
private val classBlock = JsCompositeBlock()
|
||||
@@ -337,7 +339,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
JsNameRef(context.getNameForStaticFunction(setMetadataFor)),
|
||||
listOf(ctor, name, metadataConstructor, parent, interfaces, associatedObjectKey, associatedObjects, suspendArity)
|
||||
.dropLastWhile { it == null }
|
||||
.map { it ?: undefined }
|
||||
.memoryOptimizedMap { it ?: undefined }
|
||||
).makeStmt()
|
||||
|
||||
}
|
||||
@@ -375,7 +377,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
.takeIf { it.size > 1 || it.singleOrNull() != baseClass }
|
||||
?.mapNotNull { it.asConstructorRef() }
|
||||
?.takeIf { it.isNotEmpty() } ?: return null
|
||||
return JsArrayLiteral(listRef)
|
||||
return JsArrayLiteral(listRef.toSmartList())
|
||||
}
|
||||
|
||||
private fun generateSuspendArity(): JsArrayLiteral? {
|
||||
@@ -385,7 +387,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
.distinct()
|
||||
.map { JsIntLiteral(it) }
|
||||
|
||||
return JsArrayLiteral(arity).takeIf { arity.isNotEmpty() }
|
||||
return JsArrayLiteral(arity.toSmartList()).takeIf { arity.isNotEmpty() }
|
||||
}
|
||||
|
||||
private fun generateAssociatedObjectKey(): JsIntLiteral? {
|
||||
@@ -402,7 +404,7 @@ class JsClassGenerator(private val irClass: IrClass, val context: JsGenerationCo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toSmartList()
|
||||
|
||||
return associatedObjects
|
||||
.takeIf { it.isNotEmpty() }
|
||||
@@ -466,7 +468,7 @@ private fun IrOverridableDeclaration<*>.overridesExternal(): Boolean {
|
||||
private val IrClassifierSymbol.isInterface get() = (owner as? IrClass)?.isInterface == true
|
||||
|
||||
class JsIrClassModel(val klass: IrClass) {
|
||||
val superClasses = klass.superTypes.map { it.classifierOrNull as IrClassSymbol }
|
||||
val superClasses = klass.superTypes.memoryOptimizedMap { it.classifierOrNull as IrClassSymbol }
|
||||
|
||||
val preDeclarationBlock = JsCompositeBlock()
|
||||
val postDeclarationBlock = JsCompositeBlock()
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class JsIntrinsicTransformers(backendContext: JsIrBackendContext) {
|
||||
init {
|
||||
val intrinsics = backendContext.intrinsics
|
||||
|
||||
transformers = mutableMapOf()
|
||||
transformers = hashMapOf()
|
||||
|
||||
transformers.apply {
|
||||
binOp(intrinsics.jsEqeqeq, JsBinaryOperator.REF_EQ)
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ class JsIrModuleHeader(
|
||||
val hasJsExports: Boolean,
|
||||
var associatedModule: JsIrModule?
|
||||
) {
|
||||
val externalNames: Set<String> by lazy { nameBindings.keys - definitions }
|
||||
val externalNames: Set<String> by lazy(LazyThreadSafetyMode.NONE) { nameBindings.keys - definitions }
|
||||
}
|
||||
|
||||
class JsIrProgram(private var modules: List<JsIrModule>) {
|
||||
|
||||
+6
-6
@@ -154,14 +154,14 @@ class SwitchOptimizer(
|
||||
lastStatement
|
||||
} else {
|
||||
val jsBody = case.body.accept(stmtTransformer, context).asBlock()
|
||||
var lastStatement = jsBody.statements.lastOrNull()
|
||||
|
||||
if (lastStatement != null) {
|
||||
lastStatement = lastStatementTransformer { lastStatement!! }
|
||||
jsBody.statements[jsBody.statements.lastIndex] = lastStatement
|
||||
}
|
||||
val lastStatement = jsBody.statements.lastOrNull()?.let { lastStatementTransformer { it } }
|
||||
|
||||
jsCase.statements += jsBody.statements
|
||||
|
||||
if (lastStatement != null) {
|
||||
jsCase.statements[jsCase.statements.lastIndex] = lastStatement
|
||||
}
|
||||
|
||||
lastStatement
|
||||
}
|
||||
|
||||
|
||||
+32
-31
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.js.config.SourceMapNamesPolicy
|
||||
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedMap
|
||||
import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
@@ -85,18 +87,18 @@ fun objectCreate(prototype: JsExpression, context: JsStaticContext) =
|
||||
prototype
|
||||
)
|
||||
|
||||
fun defineProperty(obj: JsExpression, name: String, getter: JsExpression?, setter: JsExpression?, context: JsStaticContext) =
|
||||
JsInvocation(
|
||||
fun defineProperty(obj: JsExpression, name: String, getter: JsExpression?, setter: JsExpression?, context: JsStaticContext): JsExpression {
|
||||
val undefined by lazy(LazyThreadSafetyMode.NONE) { jsUndefined(context, context.backendContext) }
|
||||
return JsInvocation(
|
||||
context
|
||||
.getNameForStaticFunction(context.backendContext.intrinsics.jsDefinePropertySymbol.owner)
|
||||
.makeRef(),
|
||||
obj,
|
||||
JsStringLiteral(name),
|
||||
*listOf(getter, setter)
|
||||
.dropLastWhile { it == null }
|
||||
.map { it ?: jsUndefined(context, context.backendContext) }
|
||||
.toTypedArray()
|
||||
getter ?: undefined,
|
||||
setter ?: undefined
|
||||
)
|
||||
}
|
||||
|
||||
fun translateFunction(declaration: IrFunction, name: JsName?, context: JsGenerationContext): JsFunction {
|
||||
context.staticContext.backendContext.getJsCodeForFunction(declaration.symbol)?.let { function ->
|
||||
@@ -212,7 +214,7 @@ fun translateCall(
|
||||
JsNameRef(Namer.CALL_FUNCTION, qPrototype)
|
||||
}
|
||||
|
||||
return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) + arguments } ?: arguments)
|
||||
return JsInvocation(callRef, jsDispatchReceiver?.let { receiver -> listOf(receiver) memoryOptimizedPlus arguments } ?: arguments)
|
||||
}
|
||||
|
||||
val varargParameterIndex = function.varargParameterIndex()
|
||||
@@ -291,7 +293,7 @@ fun translateCall(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JsInvocation(ref, listOfNotNull(jsExtensionReceiver) + arguments).pureIfPossible(function, context)
|
||||
JsInvocation(ref, listOfNotNull(jsExtensionReceiver) memoryOptimizedPlus arguments).pureIfPossible(function, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,37 +394,36 @@ fun translateCallArguments(
|
||||
val varargParameterIndex = function.realOverrideTarget.varargParameterIndex()
|
||||
|
||||
val validWithNullArgs = expression.validWithNullArgs()
|
||||
val arguments = (0 until size)
|
||||
.mapTo(ArrayList(size)) { index ->
|
||||
expression.getValueArgument(index).checkOnNullability(
|
||||
validWithNullArgs || function.valueParameters[index].isBoxParameter
|
||||
)
|
||||
}
|
||||
.dropLastWhile {
|
||||
allowDropTailVoids &&
|
||||
it is IrGetField &&
|
||||
it.symbol.owner.correspondingPropertySymbol == context.staticContext.backendContext.intrinsics.void
|
||||
}
|
||||
.map {
|
||||
it?.accept(transformer, context)
|
||||
}
|
||||
.mapIndexed { index, result ->
|
||||
val isEmptyExternalVararg = validWithNullArgs &&
|
||||
varargParameterIndex == index &&
|
||||
result is JsArrayLiteral &&
|
||||
result.expressions.isEmpty()
|
||||
val jsUndefined by lazy(LazyThreadSafetyMode.NONE) { jsUndefined(context, context.staticContext.backendContext) }
|
||||
|
||||
if (isEmptyExternalVararg && index == size - 1) {
|
||||
null
|
||||
} else result
|
||||
val arguments = (0 until size)
|
||||
.mapIndexedTo(ArrayList(size)) { i, _ ->
|
||||
expression.getValueArgument(i).checkOnNullability(validWithNullArgs || function.valueParameters[i].isBoxParameter)
|
||||
}
|
||||
.mapIndexed { i, it ->
|
||||
val jsArgument = when {
|
||||
allowDropTailVoids && (it == null || it.isVoidGetter(context)) -> null
|
||||
else -> it?.accept(transformer, context)
|
||||
}
|
||||
|
||||
val isEmptyExternalVararg = validWithNullArgs &&
|
||||
varargParameterIndex == i &&
|
||||
jsArgument is JsArrayLiteral &&
|
||||
jsArgument.expressions.isEmpty()
|
||||
|
||||
jsArgument.takeIf { !isEmptyExternalVararg || i != size - 1 }
|
||||
}
|
||||
.dropLastWhile { it == null }
|
||||
.map { it ?: jsUndefined(context, context.staticContext.backendContext) }
|
||||
.memoryOptimizedMap { it ?: jsUndefined }
|
||||
|
||||
check(!expression.symbol.isSuspend) { "Suspend functions should be lowered" }
|
||||
return arguments
|
||||
}
|
||||
|
||||
private fun IrExpression.isVoidGetter(context: JsGenerationContext): Boolean = this is IrGetField &&
|
||||
symbol.owner.correspondingPropertySymbol == context.staticContext.backendContext.intrinsics.void
|
||||
|
||||
|
||||
private fun IrExpression?.checkOnNullability(validWithNullArgs: Boolean) =
|
||||
also {
|
||||
if (it == null) {
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ fun JsNode.resolveTemporaryNames() {
|
||||
|
||||
private fun JsNode.resolveNames(): Map<JsName, JsName> {
|
||||
val rootScope = computeScopes().liftUsedNames()
|
||||
val replacements = mutableMapOf<JsName, JsName>()
|
||||
val replacements = hashMapOf<JsName, JsName>()
|
||||
fun traverse(scope: Scope) {
|
||||
// Don't clash with non-temporary names declared in current scope. It's for rare cases like `_` or `Kotlin` names,
|
||||
// since most of local declarations are temporary.
|
||||
@@ -37,7 +37,7 @@ private fun JsNode.resolveNames(): Map<JsName, JsName> {
|
||||
// Outer `foo` resolves first, so when traversing inner scope, we should take it into account.
|
||||
occupiedNames += scope.usedNames.asSequence().mapNotNull { if (!it.isTemporary) it.ident else replacements[it]?.ident }
|
||||
|
||||
val nextSuffix = mutableMapOf<String, Int>()
|
||||
val nextSuffix = hashMapOf<String, Int>()
|
||||
for (temporaryName in scope.declaredNames.asSequence().filter { it.isTemporary }) {
|
||||
var resolvedName = temporaryName.ident
|
||||
var suffix = nextSuffix.getOrDefault(temporaryName.ident, 0)
|
||||
|
||||
@@ -74,7 +74,7 @@ abstract class IrNamerBase : IrNamer {
|
||||
}
|
||||
}
|
||||
|
||||
private val associatedObjectKeyMap = mutableMapOf<IrClass, Int>()
|
||||
private val associatedObjectKeyMap = hashMapOf<IrClass, Int>()
|
||||
|
||||
override fun getAssociatedObjectKey(irClass: IrClass): Int? {
|
||||
if (irClass.isAssociatedObjectAnnotatedAnnotation) {
|
||||
|
||||
+3
-3
@@ -31,11 +31,11 @@ class JsGenerationContext(
|
||||
val currentFunction: IrFunction?,
|
||||
val staticContext: JsStaticContext,
|
||||
val localNames: LocalNameGenerator? = null,
|
||||
private val nameCache: MutableMap<IrElement, JsName> = mutableMapOf(),
|
||||
private val nameCache: MutableMap<IrElement, JsName> = hashMapOf(),
|
||||
private val useBareParameterNames: Boolean = false,
|
||||
) : IrNamer by staticContext {
|
||||
private val startLocationCache = mutableMapOf<Int, JsLocation>()
|
||||
private val endLocationCache = mutableMapOf<Int, JsLocation>()
|
||||
private val startLocationCache = hashMapOf<Int, JsLocation>()
|
||||
private val endLocationCache = hashMapOf<Int, JsLocation>()
|
||||
|
||||
fun newFile(file: IrFile, func: IrFunction? = null, localNames: LocalNameGenerator? = null): JsGenerationContext {
|
||||
return JsGenerationContext(
|
||||
|
||||
@@ -54,7 +54,7 @@ abstract class NameScope {
|
||||
class NameTable<T>(
|
||||
val parent: NameScope = EmptyScope,
|
||||
val reserved: MutableSet<String> = mutableSetOf(),
|
||||
val mappedNames: MutableMap<String, String>? = null
|
||||
val mappedNames: MutableMap<String, String>? = null,
|
||||
) : NameScope() {
|
||||
val names = mutableMapOf<T, String>()
|
||||
|
||||
@@ -153,13 +153,10 @@ fun calculateJsFunctionSignature(declaration: IrFunction, context: JsIrBackendCo
|
||||
|
||||
// TODO: Use better hashCode
|
||||
val sanitizedName = sanitizeName(declarationName, withHash = false)
|
||||
return "${sanitizedName}_$signature$RESERVED_MEMBER_NAME_SUFFIX".intern()
|
||||
return context.globalInternationService.string("${sanitizedName}_$signature$RESERVED_MEMBER_NAME_SUFFIX")
|
||||
}
|
||||
|
||||
fun jsFunctionSignature(
|
||||
declaration: IrFunction,
|
||||
context: JsIrBackendContext
|
||||
): String {
|
||||
fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String {
|
||||
require(!declaration.isStaticMethodOfClass)
|
||||
require(declaration.dispatchReceiverParameter != null)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user