[JS IR] Extract adding of function call to another function
[JS IR] Add option for dce mode [JS IR] Add logging to non useful declarations if appropriate dce mode [JS IR] Add mode with throwing exception [JS IR] unreachableDeclaration method is in rootDeclarations [JS IR] Add js extra help arg with dce mode and include debug.kt to compile unreachableMethod [JS IR] unreachableDeclaration as internal to not reproduce stdlib api [JS IR] Fix description of dce mode argument - Use console.error instead of console.log - Use JsError instead Kotlin exception for lightweight [JS IR] Remove body for throwing exception [JS IR] Remove default parameter in unreachableDeclaration [JS IR] Process without removing fields and declaration containers [JS IR] Rename dce mode on dce runtime diagnostic [JS IR] Use console.trace instead of console.error [JS IR] Extract JsError - Fix naming in prependFunctionCall - Fix description on runtime diagnostic argument - Using message collector instead of throwing exception [JS IR] Distinguish unreachableMethods for log and exception [JS IR] Extract checking of Kotlin packages of IrField ^KT-45059 fixed
This commit is contained in:
+8
-2
@@ -5,8 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.cli.common.arguments
|
package org.jetbrains.kotlin.cli.common.arguments
|
||||||
|
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.CALL
|
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.*
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.NO_CALL
|
|
||||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
import org.jetbrains.kotlin.config.ApiVersion
|
import org.jetbrains.kotlin.config.ApiVersion
|
||||||
@@ -126,6 +125,13 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-Xir-dce", description = "Perform experimental dead code elimination")
|
@Argument(value = "-Xir-dce", description = "Perform experimental dead code elimination")
|
||||||
var irDce: Boolean by FreezableVar(false)
|
var irDce: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xir-dce-runtime-diagnostic",
|
||||||
|
valueDescription = "{$DCE_RUNTIME_DIAGNOSTIC_LOG|$DCE_RUNTIME_DIAGNOSTIC_EXCEPTION}",
|
||||||
|
description = "Enable runtime diagnostics when performing DCE instead of removing declarations"
|
||||||
|
)
|
||||||
|
var irDceRuntimeDiagnostic: String? by NullableStringFreezableVar(null)
|
||||||
|
|
||||||
@Argument(value = "-Xir-dce-driven", description = "Perform a more experimental faster dead code elimination")
|
@Argument(value = "-Xir-dce-driven", description = "Perform a more experimental faster dead code elimination")
|
||||||
var irDceDriven: Boolean by FreezableVar(false)
|
var irDceDriven: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
|||||||
+3
@@ -28,4 +28,7 @@ public interface K2JsArgumentConstants {
|
|||||||
String SOURCE_MAP_SOURCE_CONTENT_ALWAYS = "always";
|
String SOURCE_MAP_SOURCE_CONTENT_ALWAYS = "always";
|
||||||
String SOURCE_MAP_SOURCE_CONTENT_NEVER = "never";
|
String SOURCE_MAP_SOURCE_CONTENT_NEVER = "never";
|
||||||
String SOURCE_MAP_SOURCE_CONTENT_INLINING = "inlining";
|
String SOURCE_MAP_SOURCE_CONTENT_INLINING = "inlining";
|
||||||
|
|
||||||
|
String DCE_RUNTIME_DIAGNOSTIC_LOG = "log";
|
||||||
|
String DCE_RUNTIME_DIAGNOSTIC_EXCEPTION = "exception";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR
|
|||||||
import org.jetbrains.kotlin.cli.common.ExitCode.OK
|
import org.jetbrains.kotlin.cli.common.ExitCode.OK
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
||||||
|
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants.*
|
||||||
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
|
import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
|
||||||
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
|
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
|
||||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||||
@@ -259,12 +260,17 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
mainArguments = mainCallArguments,
|
mainArguments = mainCallArguments,
|
||||||
generateFullJs = !arguments.irDce,
|
generateFullJs = !arguments.irDce,
|
||||||
generateDceJs = arguments.irDce,
|
generateDceJs = arguments.irDce,
|
||||||
|
dceRuntimeDiagnostic = DceRuntimeDiagnostic.resolve(
|
||||||
|
arguments.irDceRuntimeDiagnostic,
|
||||||
|
messageCollector
|
||||||
|
),
|
||||||
dceDriven = arguments.irDceDriven,
|
dceDriven = arguments.irDceDriven,
|
||||||
multiModule = arguments.irPerModule,
|
multiModule = arguments.irPerModule,
|
||||||
relativeRequirePath = true,
|
relativeRequirePath = true,
|
||||||
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
val jsCode = if (arguments.irDce && !arguments.irDceDriven) compiledModule.dceJsCode!! else compiledModule.jsCode!!
|
val jsCode = if (arguments.irDce && !arguments.irDceDriven) compiledModule.dceJsCode!! else compiledModule.jsCode!!
|
||||||
outputFile.writeText(jsCode.mainModule)
|
outputFile.writeText(jsCode.mainModule)
|
||||||
jsCode.dependencies.forEach { (name, content) ->
|
jsCode.dependencies.forEach { (name, content) ->
|
||||||
@@ -422,6 +428,19 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DceRuntimeDiagnostic.Companion.resolve(
|
||||||
|
value: String?,
|
||||||
|
messageCollector: MessageCollector
|
||||||
|
): DceRuntimeDiagnostic? = when (value?.toLowerCase()) {
|
||||||
|
DCE_RUNTIME_DIAGNOSTIC_LOG -> DceRuntimeDiagnostic.LOG
|
||||||
|
DCE_RUNTIME_DIAGNOSTIC_EXCEPTION -> DceRuntimeDiagnostic.EXCEPTION
|
||||||
|
null -> null
|
||||||
|
else -> {
|
||||||
|
messageCollector.report(STRONG_WARNING, "Unknown DCE runtime diagnostic '$value'")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun messageCollectorLogger(collector: MessageCollector) = object : Logger {
|
fun messageCollectorLogger(collector: MessageCollector) = object : Logger {
|
||||||
override fun warning(message: String) = collector.report(STRONG_WARNING, message)
|
override fun warning(message: String) = collector.report(STRONG_WARNING, message)
|
||||||
override fun error(message: String) = collector.report(ERROR, message)
|
override fun error(message: String) = collector.report(ERROR, message)
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.ir.backend.js
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.ir.isMemberOfOpenClass
|
import org.jetbrains.kotlin.backend.common.ir.isMemberOfOpenClass
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
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.*
|
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -20,7 +22,9 @@ import org.jetbrains.kotlin.ir.util.*
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
import org.jetbrains.kotlin.js.config.DceRuntimeDiagnostic
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.js.config.removingBody
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -34,7 +38,11 @@ fun eliminateDeadDeclarations(
|
|||||||
val usefulDeclarations = usefulDeclarations(allRoots, context)
|
val usefulDeclarations = usefulDeclarations(allRoots, context)
|
||||||
|
|
||||||
context.irFactory.stageController.unrestrictDeclarationListsAccess {
|
context.irFactory.stageController.unrestrictDeclarationListsAccess {
|
||||||
removeUselessDeclarations(modules, usefulDeclarations)
|
processUselessDeclarations(
|
||||||
|
modules,
|
||||||
|
usefulDeclarations,
|
||||||
|
context
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +55,7 @@ private fun buildRoots(modules: Iterable<IrModuleFragment>, context: JsIrBackend
|
|||||||
(modules.flatMap { it.files } + context.packageLevelJsModules + context.externalPackageFragment.values).flatMapTo(mutableListOf()) { file ->
|
(modules.flatMap { it.files } + context.packageLevelJsModules + context.externalPackageFragment.values).flatMapTo(mutableListOf()) { file ->
|
||||||
file.declarations.flatMap { if (it is IrProperty) listOfNotNull(it.backingField, it.getter, it.setter) else listOf(it) }
|
file.declarations.flatMap { if (it is IrProperty) listOfNotNull(it.backingField, it.getter, it.setter) else listOf(it) }
|
||||||
.filter {
|
.filter {
|
||||||
it is IrField && it.initializer != null && it.fqNameWhenAvailable?.asString()?.startsWith("kotlin") != true
|
it is IrField && it.initializer != null && !it.isKotlinPackage()
|
||||||
|| it.isExported(context)
|
|| it.isExported(context)
|
||||||
|| it.isEffectivelyExternal()
|
|| it.isEffectivelyExternal()
|
||||||
|| it is IrField && it.correspondingPropertySymbol?.owner?.isExported(context) == true
|
|| it is IrField && it.correspondingPropertySymbol?.owner?.isExported(context) == true
|
||||||
@@ -57,6 +65,11 @@ private fun buildRoots(modules: Iterable<IrModuleFragment>, context: JsIrBackend
|
|||||||
|
|
||||||
rootDeclarations += context.testRoots.values
|
rootDeclarations += context.testRoots.values
|
||||||
|
|
||||||
|
val dceRuntimeDiagnostic = context.dceRuntimeDiagnostic
|
||||||
|
if (dceRuntimeDiagnostic != null) {
|
||||||
|
rootDeclarations += dceRuntimeDiagnostic.unreachableDeclarationMethod(context).owner
|
||||||
|
}
|
||||||
|
|
||||||
JsMainFunctionDetector.getMainFunctionOrNull(modules.last())?.let { mainFunction ->
|
JsMainFunctionDetector.getMainFunctionOrNull(modules.last())?.let { mainFunction ->
|
||||||
rootDeclarations += mainFunction
|
rootDeclarations += mainFunction
|
||||||
if (mainFunction.isSuspend) {
|
if (mainFunction.isSuspend) {
|
||||||
@@ -67,7 +80,17 @@ private fun buildRoots(modules: Iterable<IrModuleFragment>, context: JsIrBackend
|
|||||||
return rootDeclarations
|
return rootDeclarations
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun removeUselessDeclarations(modules: Iterable<IrModuleFragment>, usefulDeclarations: Set<IrDeclaration>) {
|
private fun DceRuntimeDiagnostic.unreachableDeclarationMethod(context: JsIrBackendContext) =
|
||||||
|
when (this) {
|
||||||
|
DceRuntimeDiagnostic.LOG -> context.intrinsics.jsUnreachableDeclarationLog
|
||||||
|
DceRuntimeDiagnostic.EXCEPTION -> context.intrinsics.jsUnreachableDeclarationException
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processUselessDeclarations(
|
||||||
|
modules: Iterable<IrModuleFragment>,
|
||||||
|
usefulDeclarations: Set<IrDeclaration>,
|
||||||
|
context: JsIrBackendContext
|
||||||
|
) {
|
||||||
modules.forEach { module ->
|
modules.forEach { module ->
|
||||||
module.files.forEach {
|
module.files.forEach {
|
||||||
it.acceptVoid(object : IrElementVisitorVoid {
|
it.acceptVoid(object : IrElementVisitorVoid {
|
||||||
@@ -99,7 +122,7 @@ private fun removeUselessDeclarations(modules: Iterable<IrModuleFragment>, usefu
|
|||||||
private fun process(container: IrDeclarationContainer) {
|
private fun process(container: IrDeclarationContainer) {
|
||||||
container.declarations.transformFlat { member ->
|
container.declarations.transformFlat { member ->
|
||||||
if (member !in usefulDeclarations) {
|
if (member !in usefulDeclarations) {
|
||||||
emptyList()
|
member.processUselessDeclaration(context)
|
||||||
} else {
|
} else {
|
||||||
member.acceptVoid(this)
|
member.acceptVoid(this)
|
||||||
null
|
null
|
||||||
@@ -111,6 +134,53 @@ private fun removeUselessDeclarations(modules: Iterable<IrModuleFragment>, usefu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrDeclaration.processUselessDeclaration(context: JsIrBackendContext): List<IrDeclaration>? {
|
||||||
|
return when {
|
||||||
|
context.dceRuntimeDiagnostic != null -> {
|
||||||
|
processWithDiagnostic(context)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
else -> emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrDeclaration.processWithDiagnostic(context: JsIrBackendContext) {
|
||||||
|
when (this) {
|
||||||
|
is IrFunction -> processFunctionWithDiagnostic(context)
|
||||||
|
is IrField -> processFieldWithDiagnostic()
|
||||||
|
is IrDeclarationContainer -> declarations.forEach { it.processWithDiagnostic(context) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrFunction.processFunctionWithDiagnostic(context: JsIrBackendContext) {
|
||||||
|
val dceRuntimeDiagnostic = context.dceRuntimeDiagnostic!!
|
||||||
|
|
||||||
|
val isRemovingBody = dceRuntimeDiagnostic.removingBody()
|
||||||
|
val targetMethod = dceRuntimeDiagnostic.unreachableDeclarationMethod(context)
|
||||||
|
val call = JsIrBuilder.buildCall(
|
||||||
|
target = targetMethod,
|
||||||
|
type = targetMethod.owner.returnType
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isRemovingBody) {
|
||||||
|
body = context.irFactory.createBlockBody(
|
||||||
|
UNDEFINED_OFFSET,
|
||||||
|
UNDEFINED_OFFSET
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
body?.prependFunctionCall(call)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrField.processFieldWithDiagnostic() {
|
||||||
|
if (initializer != null && isKotlinPackage()) {
|
||||||
|
initializer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrField.isKotlinPackage() =
|
||||||
|
fqNameWhenAvailable?.asString()?.startsWith("kotlin") == true
|
||||||
|
|
||||||
// TODO refactor it, the function became too big. Please contact me (Zalim) before doing it.
|
// TODO refactor it, the function became too big. Please contact me (Zalim) before doing it.
|
||||||
fun usefulDeclarations(roots: Iterable<IrDeclaration>, context: JsIrBackendContext): Set<IrDeclaration> {
|
fun usefulDeclarations(roots: Iterable<IrDeclaration>, context: JsIrBackendContext): Set<IrDeclaration> {
|
||||||
val printReachabilityInfo =
|
val printReachabilityInfo =
|
||||||
|
|||||||
@@ -162,6 +162,9 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
|||||||
|
|
||||||
val jsImul = getInternalFunction("imul")
|
val jsImul = getInternalFunction("imul")
|
||||||
|
|
||||||
|
val jsUnreachableDeclarationLog = getInternalFunction("unreachableDeclarationLog")
|
||||||
|
val jsUnreachableDeclarationException = getInternalFunction("unreachableDeclarationException")
|
||||||
|
|
||||||
// Coroutines
|
// Coroutines
|
||||||
|
|
||||||
val jsCoroutineContext
|
val jsCoroutineContext
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmen
|
|||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrDynamicTypeImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
|
import org.jetbrains.kotlin.js.config.DceRuntimeDiagnostic
|
||||||
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy
|
||||||
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
import org.jetbrains.kotlin.js.config.JSConfigurationKeys
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -44,6 +45,7 @@ class JsIrBackendContext(
|
|||||||
override val configuration: CompilerConfiguration, // TODO: remove configuration from backend context
|
override val configuration: CompilerConfiguration, // TODO: remove configuration from backend context
|
||||||
override val scriptMode: Boolean = false,
|
override val scriptMode: Boolean = false,
|
||||||
override val es6mode: Boolean = false,
|
override val es6mode: Boolean = false,
|
||||||
|
val dceRuntimeDiagnostic: DceRuntimeDiagnostic? = null,
|
||||||
val propertyLazyInitialization: Boolean = false,
|
val propertyLazyInitialization: Boolean = false,
|
||||||
override val irFactory: IrFactory = IrFactoryImpl
|
override val irFactory: IrFactory = IrFactoryImpl
|
||||||
) : JsCommonBackendContext {
|
) : JsCommonBackendContext {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
|||||||
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
|
||||||
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
|
||||||
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
import org.jetbrains.kotlin.ir.util.noUnboundLeft
|
||||||
|
import org.jetbrains.kotlin.js.config.DceRuntimeDiagnostic
|
||||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||||
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
import org.jetbrains.kotlin.library.resolver.KotlinLibraryResolveResult
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -45,6 +46,7 @@ fun compile(
|
|||||||
generateFullJs: Boolean = true,
|
generateFullJs: Boolean = true,
|
||||||
generateDceJs: Boolean = false,
|
generateDceJs: Boolean = false,
|
||||||
dceDriven: Boolean = false,
|
dceDriven: Boolean = false,
|
||||||
|
dceRuntimeDiagnostic: DceRuntimeDiagnostic? = null,
|
||||||
es6mode: Boolean = false,
|
es6mode: Boolean = false,
|
||||||
multiModule: Boolean = false,
|
multiModule: Boolean = false,
|
||||||
relativeRequirePath: Boolean = false,
|
relativeRequirePath: Boolean = false,
|
||||||
@@ -70,6 +72,7 @@ fun compile(
|
|||||||
exportedDeclarations,
|
exportedDeclarations,
|
||||||
configuration,
|
configuration,
|
||||||
es6mode = es6mode,
|
es6mode = es6mode,
|
||||||
|
dceRuntimeDiagnostic = dceRuntimeDiagnostic,
|
||||||
propertyLazyInitialization = propertyLazyInitialization,
|
propertyLazyInitialization = propertyLazyInitialization,
|
||||||
irFactory = irFactory
|
irFactory = irFactory
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-25
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder
|
||||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||||
|
import org.jetbrains.kotlin.ir.backend.js.utils.prependFunctionCall
|
||||||
import org.jetbrains.kotlin.ir.util.isPure
|
import org.jetbrains.kotlin.ir.util.isPure
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
import org.jetbrains.kotlin.ir.builders.declarations.buildField
|
||||||
@@ -74,7 +75,7 @@ class PropertyLazyInitLowering(
|
|||||||
|
|
||||||
when (container) {
|
when (container) {
|
||||||
is IrSimpleFunction ->
|
is IrSimpleFunction ->
|
||||||
irBody.addInitialization(initializationCall, container)
|
irBody.prependFunctionCall(initializationCall)
|
||||||
is IrField -> {
|
is IrField -> {
|
||||||
container
|
container
|
||||||
.correspondingProperty
|
.correspondingProperty
|
||||||
@@ -83,7 +84,7 @@ class PropertyLazyInitLowering(
|
|||||||
?.let { listOf(it.getter, it.setter) }
|
?.let { listOf(it.getter, it.setter) }
|
||||||
?.filterNotNull()
|
?.filterNotNull()
|
||||||
?.forEach {
|
?.forEach {
|
||||||
irBody.addInitialization(initializationCall, it)
|
irBody.prependFunctionCall(initializationCall)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,29 +173,6 @@ class PropertyLazyInitLowering(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrBody.addInitialization(
|
|
||||||
initCall: IrCall,
|
|
||||||
container: IrSimpleFunction
|
|
||||||
) {
|
|
||||||
when (this) {
|
|
||||||
is IrExpressionBody -> {
|
|
||||||
expression = JsIrBuilder.buildComposite(
|
|
||||||
type = container.returnType,
|
|
||||||
statements = listOf(
|
|
||||||
initCall,
|
|
||||||
expression
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is IrBlockBody -> {
|
|
||||||
statements.add(
|
|
||||||
0,
|
|
||||||
initCall
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createIrGetField(field: IrField): IrGetField {
|
private fun createIrGetField(field: IrField): IrGetField {
|
||||||
return JsIrBuilder.buildGetField(
|
return JsIrBuilder.buildGetField(
|
||||||
symbol = field.symbol,
|
symbol = field.symbol,
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|||||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
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.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
@@ -88,4 +89,26 @@ val IrValueDeclaration.isDispatchReceiver: Boolean
|
|||||||
if (parent is IrFunction && parent.dispatchReceiverParameter == this)
|
if (parent is IrFunction && parent.dispatchReceiverParameter == this)
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun IrBody.prependFunctionCall(
|
||||||
|
call: IrCall
|
||||||
|
) {
|
||||||
|
when (this) {
|
||||||
|
is IrExpressionBody -> {
|
||||||
|
expression = JsIrBuilder.buildComposite(
|
||||||
|
type = expression.type,
|
||||||
|
statements = listOf(
|
||||||
|
call,
|
||||||
|
expression
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is IrBlockBody -> {
|
||||||
|
statements.add(
|
||||||
|
0,
|
||||||
|
call
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -11,6 +11,8 @@ where advanced options include:
|
|||||||
-Xir-dce-driven Perform a more experimental faster dead code elimination
|
-Xir-dce-driven Perform a more experimental faster dead code elimination
|
||||||
-Xir-dce-print-reachability-info
|
-Xir-dce-print-reachability-info
|
||||||
Print declarations' reachability info to stdout during performing DCE
|
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-module-name=<name> Specify a compilation module name for IR backend
|
-Xir-module-name=<name> Specify a compilation module name for IR backend
|
||||||
-Xir-only Disables pre-IR backend
|
-Xir-only Disables pre-IR backend
|
||||||
-Xir-per-module Splits generated .js per-module
|
-Xir-per-module Splits generated .js per-module
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.js.config
|
||||||
|
|
||||||
|
enum class DceRuntimeDiagnostic {
|
||||||
|
LOG,
|
||||||
|
EXCEPTION;
|
||||||
|
|
||||||
|
companion object
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DceRuntimeDiagnostic.removingBody(): Boolean {
|
||||||
|
return this != DceRuntimeDiagnostic.LOG
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DceRuntimeDiagnostic.dceRuntimeDiagnosticToArgumentOfUnreachableMethod(): Int {
|
||||||
|
return when (this) {
|
||||||
|
DceRuntimeDiagnostic.LOG -> 0
|
||||||
|
DceRuntimeDiagnostic.EXCEPTION -> 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -71,7 +71,6 @@ val jsMainSources by task<Sync> {
|
|||||||
"libraries/stdlib/js/src/kotlin/console.kt",
|
"libraries/stdlib/js/src/kotlin/console.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/coreDeprecated.kt",
|
"libraries/stdlib/js/src/kotlin/coreDeprecated.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/date.kt",
|
"libraries/stdlib/js/src/kotlin/date.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/debug.kt",
|
|
||||||
"libraries/stdlib/js/src/kotlin/grouping.kt",
|
"libraries/stdlib/js/src/kotlin/grouping.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/json.kt",
|
"libraries/stdlib/js/src/kotlin/json.kt",
|
||||||
"libraries/stdlib/js/src/kotlin/promise.kt",
|
"libraries/stdlib/js/src/kotlin/promise.kt",
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@JsName("Error")
|
||||||
|
internal open external class JsError(message: String) : Throwable
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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 kotlin.js
|
||||||
|
|
||||||
|
import JsError
|
||||||
|
|
||||||
|
internal fun unreachableDeclarationLog() {
|
||||||
|
console.asDynamic().trace("Unreachable declaration")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun unreachableDeclarationException() {
|
||||||
|
throw JsError("Unreachable declaration")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user