rra/ilgonmic/reducing-size
[JS IR] Fix review remarks - Fix translation mode from flags calculation - comment why not top level could be safely inlined [JS IR] Add test on exportness of internal val Revert "[Gradle, JS] Disable minimizing names in production by default" This reverts commit 700ff8634a73f155a2f0eaf963778216d6877075. [JS IR] Adopt reserved names Revert "[JS IR] Reserve interop names" This reverts commit 63f30becaf1a45750ff85aea3753aae9a85985f4. Revert "[JS IR] Clear minimized namer states" This reverts commit ef7f19fa8a928021e8bdfbee7fbb5285fc74b7ab. [JS IR] Clear minimized namer states [JS IR] Reserve interop names [JS IR] Separate arguments for users [JS IR] Minimized member names in tests [Gradle, JS] Disable minimizing names in production by default [JS IR] Fix extra helps [JS IR] Move mangling of signatures to linking namer [JS IR] Add key and minimized name generator [JS IR] cross module dependencies minimized [JS IR] Minimize names [JS IR] Cross module by index [JS IR] Fix warning [JS IR] Fix inlining accessors [JS IR] Bridges for property accessors [JS IR] Special case of jsFunctionSignature with property accessors [JS IR] Inline property accessor for non top level properties [JS IR] Reduce crossModule size Merge-request: KT-MR-5785 Merged-by: Ilya Goncharov <Ilya.Goncharov@jetbrains.com> ^KT-51735 fixed ^KT-50504 fixed
This commit is contained in:
+3
@@ -137,6 +137,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(value = "-Xir-property-lazy-initialization", description = "Perform lazy initialization for properties")
|
||||
var irPropertyLazyInitialization: Boolean by FreezableVar(true)
|
||||
|
||||
@Argument(value = "-Xir-minimized-member-names", description = "Perform minimization for names of members")
|
||||
var irMinimizedMemberNames: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(value = "-Xir-only", description = "Disables pre-IR backend")
|
||||
var irOnly: Boolean by FreezableVar(false)
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
|
||||
val moduleKind = configurationJs[JSConfigurationKeys.MODULE_KIND]!!
|
||||
|
||||
val translationMode = TranslationMode.fromFlags(false, arguments.irPerModule)
|
||||
val translationMode = TranslationMode.fromFlags(false, arguments.irPerModule, false)
|
||||
|
||||
val compiledModule = generateJsFromAst(
|
||||
moduleName,
|
||||
@@ -410,7 +410,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
moduleToName = ir.moduleFragmentToUniqueName
|
||||
)
|
||||
|
||||
transformer.generateModule(ir.allModules, setOf(TranslationMode.fromFlags(arguments.irDce, arguments.irPerModule)))
|
||||
transformer.generateModule(
|
||||
ir.allModules,
|
||||
setOf(TranslationMode.fromFlags(arguments.irDce, arguments.irPerModule, arguments.irMinimizedMemberNames))
|
||||
)
|
||||
} else {
|
||||
val transformer = IrModuleToJsTransformer(
|
||||
ir.context,
|
||||
|
||||
@@ -13,6 +13,7 @@ object JsLoweredDeclarationOrigin : IrDeclarationOrigin {
|
||||
object JS_CLOSURE_BOX_CLASS_DECLARATION : IrDeclarationOriginImpl("JS_CLOSURE_BOX_CLASS_DECLARATION")
|
||||
object BRIDGE_WITH_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITH_STABLE_NAME")
|
||||
object BRIDGE_WITHOUT_STABLE_NAME : IrDeclarationOriginImpl("BRIDGE_WITHOUT_STABLE_NAME")
|
||||
object BRIDGE_PROPERTY_ACCESSOR : IrDeclarationOriginImpl("BRIDGE_PROPERTY_ACCESSOR")
|
||||
object OBJECT_GET_INSTANCE_FUNCTION : IrDeclarationOriginImpl("OBJECT_GET_INSTANCE_FUNCTION")
|
||||
object JS_SHADOWED_EXPORT : IrDeclarationOriginImpl("JS_SHADOWED_EXPORT")
|
||||
object JS_SHADOWED_DEFAULT_PARAMETER : IrDeclarationOriginImpl("JS_SHADOWED_DEFAULT_PARAMETER")
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.JsInnerClassesSupport
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsPolyfills
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsInlineClassesUtils
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.MinimizedNameGenerator
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.OperatorNames
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -72,6 +73,11 @@ class JsIrBackendContext(
|
||||
val localClassNames: MutableMap<IrClass, String> = mutableMapOf()
|
||||
val extractedLocalClasses: MutableSet<IrClass> = hashSetOf()
|
||||
|
||||
val minimizedNameGenerator: MinimizedNameGenerator =
|
||||
MinimizedNameGenerator()
|
||||
|
||||
val fieldDataCache = mutableMapOf<IrClass, Map<IrField, String>>()
|
||||
|
||||
override val builtIns = module.builtIns
|
||||
|
||||
override val typeSystem: IrTypeSystemContext = IrTypeSystemContextImpl(irBuiltIns)
|
||||
|
||||
+1
@@ -549,6 +549,7 @@ class ExportModelGenerator(
|
||||
if (function.isFakeOverride && !function.isAllowedFakeOverriddenDeclaration(context))
|
||||
return Exportability.NotNeeded
|
||||
if (function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME ||
|
||||
function.origin == JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR ||
|
||||
function.origin == JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME ||
|
||||
function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||
function.origin == JsLoweredDeclarationOrigin.OBJECT_GET_INSTANCE_FUNCTION ||
|
||||
|
||||
+5
-4
@@ -52,10 +52,11 @@ class JsBridgesConstruction(context: JsIrBackendContext) : BridgesConstruction<J
|
||||
}
|
||||
|
||||
override fun getBridgeOrigin(bridge: IrSimpleFunction): IrDeclarationOrigin =
|
||||
if (bridge.hasStableJsName(context))
|
||||
JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME
|
||||
else
|
||||
JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME
|
||||
when {
|
||||
bridge.hasStableJsName(context) -> JsLoweredDeclarationOrigin.BRIDGE_WITH_STABLE_NAME
|
||||
bridge.correspondingPropertySymbol != null -> JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR
|
||||
else -> JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME
|
||||
}
|
||||
|
||||
override fun extractValueParameters(
|
||||
blockBodyBuilder: IrBlockBodyBuilder,
|
||||
|
||||
+4
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.codegen.JsGenerationGranularity
|
||||
@@ -19,6 +20,9 @@ class JsPropertyAccessorInlineLowering(
|
||||
if (!isSafeToInlineInClosedWorld())
|
||||
return false
|
||||
|
||||
// Member properties could be safely inlined, because initialization processed via parent declaration
|
||||
if (!isTopLevel) return true
|
||||
|
||||
// TODO: teach the deserializer to load constant property initializers
|
||||
if (context.icCompatibleIr2Js) {
|
||||
val accessFile = accessContainer.fileOrNull ?: return false
|
||||
|
||||
+2
-2
@@ -68,7 +68,7 @@ class IrModuleToJsTransformer(
|
||||
|
||||
val code = EnumMap<TranslationMode, CompilationOutputs>(TranslationMode::class.java)
|
||||
|
||||
if (fullJs) code[TranslationMode.fromFlags(false, multiModule)] = generateWrappedModuleBody(modules, exportedModule, namer)
|
||||
if (fullJs) code[TranslationMode.fromFlags(false, multiModule, false)] = generateWrappedModuleBody(modules, exportedModule, namer)
|
||||
|
||||
if (dceJs) {
|
||||
eliminateDeadDeclarations(modules, backendContext, removeUnusedAssociatedObjects)
|
||||
@@ -76,7 +76,7 @@ class IrModuleToJsTransformer(
|
||||
// TODO: is this mode relevant for scripting? If yes, refactor so that the external name tables are used here when needed.
|
||||
val namer = NameTables(emptyList(), context = backendContext)
|
||||
namer.merge(modules.flatMap { it.files }, additionalPackages)
|
||||
code[TranslationMode.fromFlags(true, multiModule)] = generateWrappedModuleBody(modules, exportedModule, namer)
|
||||
code[TranslationMode.fromFlags(true, multiModule, false)] = generateWrappedModuleBody(modules, exportedModule, namer)
|
||||
}
|
||||
|
||||
return CompilerResult(code, dts)
|
||||
|
||||
+37
-16
@@ -33,18 +33,30 @@ import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
enum class TranslationMode(val dce: Boolean, val perModule: Boolean) {
|
||||
FULL(dce = false, perModule = false),
|
||||
FULL_DCE(dce = true, perModule = false),
|
||||
PER_MODULE(dce = false, perModule = true),
|
||||
PER_MODULE_DCE(dce = true, perModule = true);
|
||||
enum class TranslationMode(
|
||||
val dce: Boolean,
|
||||
val perModule: Boolean,
|
||||
val minimizedMemberNames: Boolean,
|
||||
) {
|
||||
FULL(dce = false, perModule = false, minimizedMemberNames = false),
|
||||
FULL_DCE(dce = true, perModule = false, minimizedMemberNames = false),
|
||||
FULL_DCE_MINIMIZED_NAMES(dce = true, perModule = false, minimizedMemberNames = true),
|
||||
PER_MODULE(dce = false, perModule = true, minimizedMemberNames = false),
|
||||
PER_MODULE_DCE(dce = true, perModule = true, minimizedMemberNames = false),
|
||||
PER_MODULE_DCE_MINIMIZED_NAMES(dce = true, perModule = true, minimizedMemberNames = true);
|
||||
|
||||
companion object {
|
||||
fun fromFlags(dce: Boolean, perModule: Boolean): TranslationMode {
|
||||
fun fromFlags(dce: Boolean, perModule: Boolean, minimizedMemberNames: Boolean): TranslationMode {
|
||||
return if (perModule) {
|
||||
if (dce) PER_MODULE_DCE else PER_MODULE
|
||||
if (dce) {
|
||||
if (minimizedMemberNames) PER_MODULE_DCE_MINIMIZED_NAMES
|
||||
else PER_MODULE_DCE
|
||||
} else PER_MODULE
|
||||
} else {
|
||||
if (dce) FULL_DCE else FULL
|
||||
if (dce) {
|
||||
if (minimizedMemberNames) FULL_DCE_MINIMIZED_NAMES
|
||||
else FULL_DCE
|
||||
} else FULL
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,11 +90,11 @@ class IrModuleToJsTransformerTmp(
|
||||
module.files.forEach { StaticMembersLowering(backendContext).lower(it) }
|
||||
}
|
||||
|
||||
fun compilationOutput(multiModule: Boolean) = generateWrappedModuleBody(
|
||||
fun compilationOutput(multiModule: Boolean, minimizedMemberNames: Boolean) = generateWrappedModuleBody(
|
||||
multiModule,
|
||||
mainModuleName,
|
||||
moduleKind,
|
||||
generateProgramFragments(modules, exportData),
|
||||
generateProgramFragments(modules, exportData, minimizedMemberNames),
|
||||
SourceMapsInfo.from(backendContext.configuration),
|
||||
relativeRequirePath,
|
||||
generateScriptModule,
|
||||
@@ -91,7 +103,11 @@ class IrModuleToJsTransformerTmp(
|
||||
val result = EnumMap<TranslationMode, CompilationOutputs>(TranslationMode::class.java)
|
||||
|
||||
modes.filter { !it.dce }.forEach {
|
||||
result[it] = compilationOutput(it.perModule)
|
||||
if (it.minimizedMemberNames) {
|
||||
backendContext.fieldDataCache.clear()
|
||||
backendContext.minimizedNameGenerator.clear()
|
||||
}
|
||||
result[it] = compilationOutput(it.perModule, it.minimizedMemberNames)
|
||||
}
|
||||
|
||||
if (modes.any { it.dce }) {
|
||||
@@ -99,7 +115,11 @@ class IrModuleToJsTransformerTmp(
|
||||
}
|
||||
|
||||
modes.filter { it.dce }.forEach {
|
||||
result[it] = compilationOutput(it.perModule)
|
||||
if (it.minimizedMemberNames) {
|
||||
backendContext.fieldDataCache.clear()
|
||||
backendContext.minimizedNameGenerator.clear()
|
||||
}
|
||||
result[it] = compilationOutput(it.perModule, it.minimizedMemberNames)
|
||||
}
|
||||
|
||||
return CompilerResult(result, dts)
|
||||
@@ -123,7 +143,7 @@ class IrModuleToJsTransformerTmp(
|
||||
val result = mutableMapOf<String, ByteArray>()
|
||||
files.forEach { f ->
|
||||
val exports = exportData[f]!! // TODO
|
||||
val fragment = generateProgramFragment(f, exports)
|
||||
val fragment = generateProgramFragment(f, exports, minimizedMemberNames = false)
|
||||
val output = ByteArrayOutputStream()
|
||||
serializer.serialize(fragment, output)
|
||||
val binaryAst = output.toByteArray()
|
||||
@@ -146,6 +166,7 @@ class IrModuleToJsTransformerTmp(
|
||||
private fun generateProgramFragments(
|
||||
modules: Iterable<IrModuleFragment>,
|
||||
exportData: Map<IrModuleFragment, Map<IrFile, List<ExportedDeclaration>>>,
|
||||
minimizedMemberNames: Boolean
|
||||
): JsIrProgram {
|
||||
return JsIrProgram(
|
||||
modules.map { m ->
|
||||
@@ -154,7 +175,7 @@ class IrModuleToJsTransformerTmp(
|
||||
m.externalModuleName(),
|
||||
m.files.map {
|
||||
val exports = exportData[m]!![it]!!
|
||||
generateProgramFragment(it, exports)
|
||||
generateProgramFragment(it, exports, minimizedMemberNames)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -164,8 +185,8 @@ class IrModuleToJsTransformerTmp(
|
||||
private val generateFilePaths = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_COMMENTS_WITH_FILE_PATH)
|
||||
private val pathPrefixMap = backendContext.configuration.getMap(JSConfigurationKeys.FILE_PATHS_PREFIX_MAP)
|
||||
|
||||
private fun generateProgramFragment(file: IrFile, exports: List<ExportedDeclaration>): JsIrProgramFragment {
|
||||
val nameGenerator = JsNameLinkingNamer(backendContext)
|
||||
private fun generateProgramFragment(file: IrFile, exports: List<ExportedDeclaration>, minimizedMemberNames: Boolean): JsIrProgramFragment {
|
||||
val nameGenerator = JsNameLinkingNamer(backendContext, minimizedMemberNames)
|
||||
|
||||
val globalNameScope = NameTable<IrDeclaration>()
|
||||
|
||||
|
||||
+6
-10
@@ -5,7 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.toJsIdentifier
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
|
||||
class JsIrProgramFragment(val packageFqn: String) {
|
||||
@@ -75,19 +75,15 @@ private class JsIrModuleCrossModuleReferecenceBuilder(val module: JsIrModule, va
|
||||
val exports = mutableSetOf<String>()
|
||||
var transitiveJsExportFrom = emptyList<JsIrModule>()
|
||||
|
||||
private lateinit var exportNames: Map<String, String> // tag -> name
|
||||
private lateinit var exportNames: Map<String, String> // tag -> index
|
||||
|
||||
private fun buildUniqueNames() {
|
||||
val names = module.fragments.flatMap { it.nameBindings.entries }.associate { it.key to sanitizeName(it.value.ident) }
|
||||
val nameToCnt = mutableMapOf<String, Int>()
|
||||
|
||||
val result = mutableMapOf<String, String>()
|
||||
|
||||
var index = 0
|
||||
|
||||
exports.sorted().forEach { tag ->
|
||||
val suggestedName = names[tag] ?: error("Name not found for tag $tag")
|
||||
val suffix = nameToCnt[suggestedName]?.let { "_$it" } ?: ""
|
||||
nameToCnt[suggestedName] = nameToCnt.getOrDefault(suggestedName, 0) + 1
|
||||
result[tag] = suggestedName + suffix
|
||||
result[tag] = index++.toJsIdentifier()
|
||||
}
|
||||
|
||||
exportNames = result
|
||||
@@ -132,7 +128,7 @@ private class JsIrModuleCrossModuleReferecenceBuilder(val module: JsIrModule, va
|
||||
class CrossModuleReferences(
|
||||
val importedModules: List<JsImportedModule>, // additional Kotlin imported modules
|
||||
val imports: Map<String, JsVars.JsVar>, // tag -> import statement
|
||||
val exports: Map<String, String>, // tag -> name
|
||||
val exports: Map<String, String>, // tag -> index
|
||||
val transitiveJsExportFrom: List<JsName> // the list of modules which provide their js exports for transitive export
|
||||
) {
|
||||
companion object {
|
||||
|
||||
+39
-8
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
@@ -17,13 +18,15 @@ import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.utils.DFS
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase() {
|
||||
class JsNameLinkingNamer(private val context: JsIrBackendContext, private val minimizedMemberNames: Boolean) : IrNamerBase() {
|
||||
|
||||
val nameMap = mutableMapOf<IrDeclaration, JsName>()
|
||||
|
||||
private fun IrDeclarationWithName.getName(prefix: String = ""): JsName {
|
||||
return nameMap.getOrPut(this) {
|
||||
val name = (this as? IrClass)?.let { context.localClassNames[this] } ?: getJsNameOrKotlinName().asString()
|
||||
val name = (this as? IrClass)?.let { context.localClassNames[this] } ?: let {
|
||||
this.nameIfPropertyAccessor() ?: getJsNameOrKotlinName().asString()
|
||||
}
|
||||
JsName(sanitizeName(prefix + name), true)
|
||||
}
|
||||
}
|
||||
@@ -82,7 +85,11 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
|
||||
override fun getNameForMemberFunction(function: IrSimpleFunction): JsName {
|
||||
require(function.dispatchReceiverParameter != null)
|
||||
val signature = jsFunctionSignature(function, context)
|
||||
return signature.toJsName()
|
||||
val result = if (minimizedMemberNames && !function.hasStableJsName(context)) {
|
||||
function.parentAsClass.fieldData()
|
||||
context.minimizedNameGenerator.nameBySignature(signature)
|
||||
} else signature
|
||||
return result.toJsName()
|
||||
}
|
||||
|
||||
override fun getNameForMemberField(field: IrField): JsName {
|
||||
@@ -91,10 +98,8 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
|
||||
return JsName(field.parentAsClass.fieldData()[field]!!, false)
|
||||
}
|
||||
|
||||
private val fieldDataCache = mutableMapOf<IrClass, Map<IrField, String>>()
|
||||
|
||||
private fun IrClass.fieldData(): Map<IrField, String> {
|
||||
return fieldDataCache.getOrPut(this) {
|
||||
return context.fieldDataCache.getOrPut(this) {
|
||||
val nameCnt = mutableMapOf<String, Int>()
|
||||
|
||||
val allClasses = DFS.topologicalOrder(listOf(this)) { node ->
|
||||
@@ -105,11 +110,37 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
|
||||
|
||||
val result = mutableMapOf<IrField, String>()
|
||||
|
||||
if (minimizedMemberNames) {
|
||||
allClasses.reversed().forEach {
|
||||
it.declarations.forEach { declaration ->
|
||||
when {
|
||||
declaration is IrFunction && declaration.dispatchReceiverParameter != null -> {
|
||||
val property = (declaration as? IrSimpleFunction)?.correspondingPropertySymbol?.owner
|
||||
if (property?.isExported(context) == true || property?.isEffectivelyExternal() == true) {
|
||||
context.minimizedNameGenerator.reserveName(property.name.asString())
|
||||
}
|
||||
if (declaration.hasStableJsName(context)) {
|
||||
val signature = jsFunctionSignature(declaration, context)
|
||||
context.minimizedNameGenerator.reserveName(signature)
|
||||
}
|
||||
}
|
||||
declaration is IrProperty -> {
|
||||
if (declaration.isExported(context)) {
|
||||
context.minimizedNameGenerator.reserveName(declaration.name.asString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allClasses.reversed().forEach {
|
||||
it.declarations.forEach {
|
||||
when {
|
||||
it is IrField -> {
|
||||
val safeName = it.safeName()
|
||||
val safeName = if (minimizedMemberNames) {
|
||||
context.minimizedNameGenerator.generateNextName()
|
||||
} else it.safeName()
|
||||
val suffix = nameCnt.getOrDefault(safeName, 0) + 1
|
||||
nameCnt[safeName] = suffix
|
||||
result[it] = safeName + "_$suffix"
|
||||
@@ -121,7 +152,7 @@ class JsNameLinkingNamer(private val context: JsIrBackendContext) : IrNamerBase(
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -71,10 +71,10 @@ class Merger(
|
||||
).makeStmt()
|
||||
additionalExports += createExportBlock
|
||||
|
||||
crossModuleReferences.exports.entries.forEach { (tag, name) ->
|
||||
crossModuleReferences.exports.entries.forEach { (tag, hash) ->
|
||||
val internalName = nameMap[tag] ?: error("Missing name for declaration '$tag'")
|
||||
val crossModuleRef = ReservedJsNames.makeCrossModuleNameRef(ReservedJsNames.makeInternalModuleName())
|
||||
additionalExports += jsAssignment(JsNameRef(name, crossModuleRef), JsNameRef(internalName)).makeStmt()
|
||||
additionalExports += jsAssignment(JsNameRef(hash, crossModuleRef), JsNameRef(internalName)).makeStmt()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,6 +12,6 @@ class ReservedJsNames {
|
||||
companion object {
|
||||
fun makeInternalModuleName() = JsName("_", false)
|
||||
fun makeJsExporterName() = JsName("\$jsExportAll\$", false)
|
||||
fun makeCrossModuleNameRef(moduleName: JsName) = JsNameRef("\$crossModule\$", moduleName.makeRef())
|
||||
fun makeCrossModuleNameRef(moduleName: JsName) = JsNameRef("\$_\$", moduleName.makeRef())
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.utils
|
||||
|
||||
class MinimizedNameGenerator {
|
||||
private var index = 0
|
||||
private val functionSignatureToName = mutableMapOf<String, String>()
|
||||
private val reservedNames = mutableSetOf<String>()
|
||||
|
||||
fun generateNextName(): String {
|
||||
var candidate = index++.toJsIdentifier()
|
||||
while (candidate in reservedNames) {
|
||||
candidate = index++.toJsIdentifier()
|
||||
}
|
||||
return candidate
|
||||
}
|
||||
|
||||
fun nameBySignature(signature: String): String {
|
||||
return functionSignatureToName.getOrPut(signature) {
|
||||
generateNextName()
|
||||
}
|
||||
}
|
||||
|
||||
fun reserveName(signature: String) {
|
||||
reservedNames.add(signature)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
index = 0
|
||||
functionSignatureToName.clear()
|
||||
reservedNames.clear()
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
||||
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -105,11 +106,21 @@ fun NameTable<IrDeclaration>.dump(): String =
|
||||
|
||||
private const val RESERVED_MEMBER_NAME_SUFFIX = "_k$"
|
||||
|
||||
fun Int.toJsIdentifier(): String {
|
||||
val first = ('a'.code + (this % 26)).toChar().toString()
|
||||
val other = this / 26
|
||||
return if (other == 0) {
|
||||
first
|
||||
} else {
|
||||
first + other.toString(Character.MAX_RADIX)
|
||||
}
|
||||
}
|
||||
|
||||
fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): String {
|
||||
require(!declaration.isStaticMethodOfClass)
|
||||
require(declaration.dispatchReceiverParameter != null)
|
||||
|
||||
val declarationName = declaration.getJsNameOrKotlinName().asString()
|
||||
var declarationName = declaration.getJsNameOrKotlinName().asString()
|
||||
|
||||
if (declaration.hasStableJsName(context)) {
|
||||
// TODO: Handle reserved suffix in FE
|
||||
@@ -119,6 +130,10 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): S
|
||||
return declarationName
|
||||
}
|
||||
|
||||
declaration.nameIfPropertyAccessor()?.let {
|
||||
declarationName = it
|
||||
}
|
||||
|
||||
val nameBuilder = StringBuilder()
|
||||
nameBuilder.append(declarationName)
|
||||
|
||||
@@ -139,7 +154,10 @@ fun jsFunctionSignature(declaration: IrFunction, context: JsIrBackendContext): S
|
||||
val signature = nameBuilder.toString()
|
||||
|
||||
// TODO: Use better hashCode
|
||||
return sanitizeName(declarationName) + "_" + abs(signature.hashCode()).toString(Character.MAX_RADIX) + RESERVED_MEMBER_NAME_SUFFIX
|
||||
return sanitizeName(
|
||||
declarationName,
|
||||
withHash = false
|
||||
) + "_" + abs(signature.hashCode()).toString(Character.MAX_RADIX) + RESERVED_MEMBER_NAME_SUFFIX
|
||||
}
|
||||
|
||||
class NameTables(
|
||||
@@ -295,8 +313,10 @@ class NameTables(
|
||||
}
|
||||
}
|
||||
|
||||
else ->
|
||||
globalNames.declareFreshName(declaration, declaration.name.asString())
|
||||
else -> {
|
||||
val name = declaration.nameIfPropertyAccessor() ?: declaration.name.asString()
|
||||
globalNames.declareFreshName(declaration, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -393,12 +413,38 @@ fun sanitizeName(name: String, withHash: Boolean = true): String {
|
||||
}
|
||||
|
||||
return if (withHash) {
|
||||
"${builder}_${name.hashCode().toUInt()}"
|
||||
"${builder}_${abs(name.hashCode()).toString(Character.MAX_RADIX)}"
|
||||
} else {
|
||||
builder.toString()
|
||||
}
|
||||
}
|
||||
|
||||
fun IrDeclarationWithName.nameIfPropertyAccessor(): String? {
|
||||
if (this is IrSimpleFunction) {
|
||||
return when {
|
||||
this.correspondingPropertySymbol != null -> {
|
||||
val property = this.correspondingPropertySymbol!!.owner
|
||||
val name = property.getJsNameOrKotlinName().asString()
|
||||
val prefix = when (this) {
|
||||
property.getter -> "get_"
|
||||
property.setter -> "set_"
|
||||
else -> error("")
|
||||
}
|
||||
prefix + name
|
||||
}
|
||||
this.origin == JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR -> {
|
||||
this.getJsNameOrKotlinName().asString()
|
||||
.removePrefix("<")
|
||||
.removeSuffix(">")
|
||||
.replaceFirst("get-", "get_")
|
||||
.replaceFirst("set-", "set_")
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private inline fun Char.mangleIfNot(predicate: Char.() -> Boolean) =
|
||||
if (predicate()) this else '_'
|
||||
|
||||
|
||||
@@ -157,7 +157,8 @@ class NewNamerImpl(
|
||||
|
||||
|
||||
} else { // Non-external declaration
|
||||
staticNames.declareFreshName(declaration, declaration.name.asString())
|
||||
val name = declaration.nameIfPropertyAccessor() ?: declaration.name.asString()
|
||||
staticNames.declareFreshName(declaration, name)
|
||||
val unitReference = unit.referenceCodegenUnitOfDeclaration(declaration)
|
||||
if (unitReference is IrToJs.OtherUnitReference) {
|
||||
registerImport(unitReference.importPath, exportId(declaration))
|
||||
|
||||
@@ -8,17 +8,16 @@ package org.jetbrains.kotlin.ir.backend.js.utils
|
||||
import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny
|
||||
import org.jetbrains.kotlin.backend.common.ir.isTopLevel
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
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.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.util.isEffectivelyExternal
|
||||
@@ -38,7 +37,8 @@ fun IrFunction.hasStableJsName(context: JsIrBackendContext): Boolean {
|
||||
if (
|
||||
origin == JsLoweredDeclarationOrigin.JS_SHADOWED_EXPORT ||
|
||||
origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||
origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME
|
||||
origin == JsLoweredDeclarationOrigin.BRIDGE_WITHOUT_STABLE_NAME ||
|
||||
origin == JsLoweredDeclarationOrigin.BRIDGE_PROPERTY_ACCESSOR
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
+1
@@ -17,6 +17,7 @@ where advanced options include:
|
||||
Print declarations' reachability info to stdout during performing DCE
|
||||
-Xir-dce-runtime-diagnostic={log|exception}
|
||||
Enable runtime diagnostics when performing DCE instead of removing declarations
|
||||
-Xir-minimized-member-names Perform minimization for names of members
|
||||
-Xir-module-name=<name> Specify a compilation module name for IR backend
|
||||
-Xir-new-ir2js New fragment-based ir2js
|
||||
-Xir-only Disables pre-IR backend
|
||||
|
||||
+2
-2
@@ -56,9 +56,9 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu
|
||||
// Keep names short to keep path lengths under 255 for Windows
|
||||
private val outputDirByMode = mapOf(
|
||||
TranslationMode.FULL to "out",
|
||||
TranslationMode.FULL_DCE to "outMin",
|
||||
TranslationMode.FULL_DCE_MINIMIZED_NAMES to "outMin",
|
||||
TranslationMode.PER_MODULE to "outPm",
|
||||
TranslationMode.PER_MODULE_DCE to "outPmMin"
|
||||
TranslationMode.PER_MODULE_DCE_MINIMIZED_NAMES to "outPmMin"
|
||||
)
|
||||
|
||||
private const val OUTPUT_KLIB_DIR_NAME = "outputKlibDir"
|
||||
|
||||
@@ -76,9 +76,9 @@ abstract class AbstractJsKLibABITestCase : AbstractKlibABITestCase() {
|
||||
relativeRequirePath = false
|
||||
)
|
||||
|
||||
val compiledResult = transformer.generateModule(ir.allModules, setOf(TranslationMode.FULL_DCE))
|
||||
val compiledResult = transformer.generateModule(ir.allModules, setOf(TranslationMode.FULL_DCE_MINIMIZED_NAMES))
|
||||
|
||||
val dceOutput = compiledResult.outputs[TranslationMode.FULL_DCE] ?: error("No DCE output")
|
||||
val dceOutput = compiledResult.outputs[TranslationMode.FULL_DCE_MINIMIZED_NAMES] ?: error("No DCE output")
|
||||
|
||||
val binariesDir = File(buildDir, BIN_DIR_NAME).also { it.mkdirs() }
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ class JsIrBackendFacade(
|
||||
val perModuleOnly = JsEnvironmentConfigurationDirectives.SPLIT_PER_MODULE in module.directives
|
||||
|
||||
val outputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name, TranslationMode.FULL) + ".js")
|
||||
val dceOutputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name, TranslationMode.FULL_DCE) + ".js")
|
||||
val dceOutputFile = File(JsEnvironmentConfigurator.getJsModuleArtifactPath(testServices, module.name, TranslationMode.FULL_DCE_MINIMIZED_NAMES) + ".js")
|
||||
if (!esModules) {
|
||||
if (runNewIr2Js) {
|
||||
val transformer = IrModuleToJsTransformerTmp(
|
||||
@@ -172,7 +172,10 @@ class JsIrBackendFacade(
|
||||
// If runIrDce then include DCE results
|
||||
// If perModuleOnly then skip whole program
|
||||
// (it.dce => runIrDce) && (perModuleOnly => it.perModule)
|
||||
val translationModes = TranslationMode.values().filter { (!it.dce || runIrDce) && (!perModuleOnly || it.perModule) }.toSet()
|
||||
val translationModes = TranslationMode.values()
|
||||
.filter { (!it.dce || runIrDce) && (!perModuleOnly || it.perModule) }
|
||||
.filter { it.dce == it.minimizedMemberNames }
|
||||
.toSet()
|
||||
return BinaryArtifacts.Js.JsIrArtifact(outputFile, transformer.generateModule(loweredIr.allModules, translationModes)).dump(module)
|
||||
} else {
|
||||
val transformer = IrModuleToJsTransformer(
|
||||
|
||||
@@ -39,9 +39,9 @@ class JsArtifactsDumpHandler(testServices: TestServices) : AfterAnalysisChecker(
|
||||
val minOutputDir = File(dceOutputDir, originalFile.nameWithoutExtension)
|
||||
|
||||
copy(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices), outputDir)
|
||||
copy(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE), dceOutputDir)
|
||||
copy(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE_MINIMIZED_NAMES), dceOutputDir)
|
||||
copy(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.PER_MODULE), perModuleOutputDir)
|
||||
copy(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.PER_MODULE_DCE), preModuleDceOutputDir)
|
||||
copy(JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.PER_MODULE_DCE_MINIMIZED_NAMES), preModuleDceOutputDir)
|
||||
copy(JsEnvironmentConfigurator.getMinificationJsArtifactsOutputDir(testServices), minOutputDir)
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ class JsBoxRunner(testServices: TestServices) : AbstractJsArtifactsCollector(tes
|
||||
val globalDirectives = testServices.moduleStructure.allDirectives
|
||||
|
||||
val esmOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices).esModulesSubDir
|
||||
val esmDceOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE).esModulesSubDir
|
||||
val esmDceOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE_MINIMIZED_NAMES).esModulesSubDir
|
||||
|
||||
val dontSkipRegularMode = JsEnvironmentConfigurationDirectives.SKIP_REGULAR_MODE !in globalDirectives
|
||||
val runIrDce = JsEnvironmentConfigurationDirectives.RUN_IR_DCE in globalDirectives
|
||||
|
||||
@@ -129,7 +129,7 @@ fun getAllFilesForRunner(
|
||||
} else {
|
||||
// Old BE and ES modules
|
||||
val outputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices)
|
||||
val dceOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE)
|
||||
val dceOutputDir = JsEnvironmentConfigurator.getJsArtifactsOutputDir(testServices, TranslationMode.FULL_DCE_MINIMIZED_NAMES)
|
||||
|
||||
val artifactsPaths = modulesToArtifact.values.map { it.outputFile.absolutePath }.filter { !File(it).isDirectory }
|
||||
val allJsFiles = additionalFiles + inputJsFilesBefore +artifactsPaths + commonFiles + additionalMainFiles + inputJsFilesAfter
|
||||
@@ -141,7 +141,7 @@ fun getAllFilesForRunner(
|
||||
if (runIrDce) {
|
||||
val dceJsFiles = artifactsPaths.map { it.replace(outputDir.absolutePath, dceOutputDir.absolutePath) }
|
||||
val dceAllJsFiles = additionalFiles + inputJsFilesBefore + dceJsFiles + commonFiles + additionalMainFiles + inputJsFilesAfter
|
||||
result[TranslationMode.FULL_DCE] = dceAllJsFiles
|
||||
result[TranslationMode.FULL_DCE_MINIMIZED_NAMES] = dceAllJsFiles
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -2088,6 +2088,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/export/exportAllFile.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exportClassWithInternal.kt")
|
||||
public void testExportClassWithInternal() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/exportClassWithInternal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exportEnumClass.kt")
|
||||
public void testExportEnumClass() throws Exception {
|
||||
|
||||
+6
@@ -2484,6 +2484,12 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/export/exportAllFile.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exportClassWithInternal.kt")
|
||||
public void testExportClassWithInternal() throws Exception {
|
||||
runTest("js/js.translator/testData/box/export/exportClassWithInternal.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exportEnumClass.kt")
|
||||
public void testExportEnumClass() throws Exception {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// FILE: lib.kt
|
||||
@JsExport
|
||||
class Foo(internal val constructorParameter: String)
|
||||
|
||||
// FILE: main.kt
|
||||
fun box():String {
|
||||
val foo = Foo("foo")
|
||||
if (foo.constructorParameter != "foo") return "fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+44
-63
@@ -3,100 +3,74 @@ package test
|
||||
|
||||
var a = 0
|
||||
|
||||
// CHECK_FUNCTION_EXISTS: get_p1 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p1 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p1 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p1 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _get_p1__1413126122 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p1_ scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p1__3473235702 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p1__3473235702 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: get_p1
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p1 scope=box
|
||||
// CHECK_FUNCTION_EXISTS: set_p1
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p1 scope=box
|
||||
private inline var p1: Int
|
||||
get() = a + 10000
|
||||
set(v) {
|
||||
a = v + 100
|
||||
}
|
||||
|
||||
// CHECK_FUNCTION_EXISTS: get_p2 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p2 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p2 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _get_p2__1413126153 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p2__1413126153 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_set_p2__3473235733 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: get_p2
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p2 scope=box
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p2 scope=box
|
||||
private var p2: Int
|
||||
inline get() = a + 20000
|
||||
set(v) {
|
||||
a = v + 200
|
||||
}
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p3 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p3 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p3 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_get_p3__1413126184 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p3__3473235764 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p3__3473235764 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p3 scope=box
|
||||
// CHECK_FUNCTION_EXISTS: set_p3
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p3 scope=box
|
||||
var p3: Int
|
||||
get() = a + 30000
|
||||
private inline set(v) {
|
||||
a = v + 300
|
||||
}
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p4 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p4 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p4 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_get_p4__1413126215 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p4__3473235795 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p4__3473235795 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p4 scope=box
|
||||
// CHECK_FUNCTION_EXISTS: set_p4
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p4 scope=box
|
||||
private var p4: Int
|
||||
get() = a + 40000
|
||||
inline set(v) {
|
||||
a = v + 400
|
||||
}
|
||||
|
||||
// CHECK_FUNCTION_EXISTS: get_p5 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p5 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p5 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p5 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _get_p5__1413126246 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p5__1413126246 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p5__3473235826 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p5__3473235826 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: get_p5
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p5 scope=box
|
||||
// CHECK_FUNCTION_EXISTS: set_p5
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p5 scope=box
|
||||
private inline var Int.p5: Int
|
||||
get() = this * 100 + a + 50000
|
||||
set(v) {
|
||||
a = this + v + 500
|
||||
}
|
||||
|
||||
// CHECK_FUNCTION_EXISTS: get_p6 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p6 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p6 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _get_p6__1413126277 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p6__1413126277 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_set_p6__3473235857 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: get_p6
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p6 scope=box
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p6 scope=box
|
||||
private var Int.p6: Int
|
||||
inline get() = this * 100 + a + 60000
|
||||
set(v) {
|
||||
a = this + v + 600
|
||||
}
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p7 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p7 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p7 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_get_p7__1413126308 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p7__3473235888 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p7__3473235888 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p7 scope=box
|
||||
// CHECK_FUNCTION_EXISTS: set_p7
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p7 scope=box
|
||||
var Int.p7: Int
|
||||
get() = this * 100 + a + 70000
|
||||
private inline set(v) {
|
||||
a = this + v + 700
|
||||
}
|
||||
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p8 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p8 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p8 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_get_p8__1413126339 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p8__3473235919 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p8__3473235919 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p8 scope=box
|
||||
// CHECK_FUNCTION_EXISTS: set_p8
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p8 scope=box
|
||||
private var Int.p8: Int
|
||||
get() = this * 100 + a + 80000
|
||||
inline set(v) {
|
||||
@@ -130,7 +104,8 @@ private class A {
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p12_s8ev3n$ scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p12_dqglrj$ TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p12_dqglrj$ scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p12__quadv7_k$ scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p12_jvqn3p_k$ scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p12_na24b5_k$ scope=box IGNORED_BACKENDS=JS
|
||||
inline var Int.p12: Int
|
||||
get() = this * 100 + a + 120000
|
||||
set(v) {
|
||||
@@ -140,6 +115,9 @@ private class A {
|
||||
// CHECK_FUNCTION_EXISTS: get_p13_s8ev3n$ TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p13_s8ev3n$ scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p13_dqglrj$ scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: get_p13_s8qimu_k$ IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p13_s8qimu_k$ scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p13_8qdsq6_k$ scope=box IGNORED_BACKENDS=JS
|
||||
var Int.p13: Int
|
||||
inline get() = this * 100 + a + 130000
|
||||
set(v) {
|
||||
@@ -149,6 +127,9 @@ private class A {
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p14_s8ev3n$ scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p14_dqglrj$ TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p14_dqglrj$ scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p14_yfdnt5_k$ scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p14_uaac7n_k$ IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p14_uaac7n_k$ scope=box IGNORED_BACKENDS=JS
|
||||
var Int.p14: Int
|
||||
get() = this * 100 + a + 140000
|
||||
inline set(v) {
|
||||
@@ -160,10 +141,10 @@ private class A {
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p15 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p15 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p15 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _get_p15__857236605 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p15__857236605 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p15__296124145 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p15__296124145 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: get_p15 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p15 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p15 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p15 scope=box IGNORED_BACKENDS=JS
|
||||
private inline var A.p15: Int
|
||||
get() = a + 150000
|
||||
set(v) {
|
||||
@@ -173,9 +154,9 @@ private inline var A.p15: Int
|
||||
// CHECK_FUNCTION_EXISTS: get_p16 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p16 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p16 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _get_p16__857236636 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_get_p16__857236636 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_set_p16__296124176 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p16 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=get_p16 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=set_p16 scope=box IGNORED_BACKENDS=JS
|
||||
private var A.p16: Int
|
||||
inline get() = a + 160000
|
||||
set(v) {
|
||||
@@ -185,9 +166,9 @@ private var A.p16: Int
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p17 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p17 TARGET_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p17 scope=box TARGET_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=_get_p17__857236667 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: _set_p17__296124207 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=_set_p17__296124207 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_CALLED_IN_SCOPE: function=get_p17 scope=box IGNORED_BACKENDS=JS
|
||||
// CHECK_FUNCTION_EXISTS: set_p17 IGNORED_BACKENDS=JS
|
||||
// CHECK_NOT_CALLED_IN_SCOPE: function=set_p17 scope=box IGNORED_BACKENDS=JS
|
||||
private var A.p17: Int
|
||||
get() = a + 170000
|
||||
inline set(v) {
|
||||
|
||||
+2
@@ -22,6 +22,8 @@ internal const val PRODUCE_JS = "-Xir-produce-js"
|
||||
internal const val PRODUCE_UNZIPPED_KLIB = "-Xir-produce-klib-dir"
|
||||
internal const val PRODUCE_ZIPPED_KLIB = "-Xir-produce-klib-file"
|
||||
|
||||
internal const val MINIMIZED_MEMBER_NAMES = "-Xir-minimized-member-names"
|
||||
|
||||
internal const val MODULE_NAME = "-Xir-module-name"
|
||||
|
||||
internal const val PER_MODULE = "-Xir-per-module"
|
||||
|
||||
+1
-1
@@ -171,7 +171,7 @@ abstract class KotlinJsIrLink @Inject constructor(
|
||||
override fun setupCompilerArgs(args: K2JSCompilerArguments, defaultsOnly: Boolean, ignoreClasspathResolutionErrors: Boolean) {
|
||||
when (mode) {
|
||||
PRODUCTION -> {
|
||||
kotlinOptions.configureOptions(ENABLE_DCE, GENERATE_D_TS)
|
||||
kotlinOptions.configureOptions(ENABLE_DCE, GENERATE_D_TS, MINIMIZED_MEMBER_NAMES)
|
||||
}
|
||||
DEVELOPMENT -> {
|
||||
kotlinOptions.configureOptions(GENERATE_D_TS)
|
||||
|
||||
Reference in New Issue
Block a user