[JS IR] Perform optimizations on the generated JS code
The patch adopts and reuses the optimizations from the legacy backend. The optimizations remove useless temporary variables, statements and simplify generated JS code. The optimizations can be disabled by `-Xoptimize-generated-js=false`. Related to KT-51139
This commit is contained in:
committed by
Space Team
parent
84b5af3c89
commit
79d378f2bd
+1
@@ -48,6 +48,7 @@ fun copyK2JSCompilerArguments(from: K2JSCompilerArguments, to: K2JSCompilerArgum
|
||||
to.moduleKind = from.moduleKind
|
||||
to.moduleName = from.moduleName
|
||||
to.noStdlib = from.noStdlib
|
||||
to.optimizeGeneratedJs = from.optimizeGeneratedJs
|
||||
to.outputDir = from.outputDir
|
||||
to.outputFile = from.outputFile
|
||||
to.outputPostfix = from.outputPostfix
|
||||
|
||||
+10
@@ -605,6 +605,16 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
||||
field = value
|
||||
}
|
||||
|
||||
@Argument(
|
||||
value = "-Xoptimize-generated-js",
|
||||
description = "Perform additional optimizations on the generated JS code"
|
||||
)
|
||||
var optimizeGeneratedJs = true
|
||||
set(value) {
|
||||
checkFrozen()
|
||||
field = value
|
||||
}
|
||||
|
||||
private fun MessageCollector.deprecationWarn(value: Boolean, defaultValue: Boolean, name: String) {
|
||||
if (value != defaultValue) {
|
||||
report(CompilerMessageSeverity.WARNING, "'$name' is deprecated and ignored, it will be removed in a future release")
|
||||
|
||||
@@ -175,6 +175,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
||||
configuration.put(JSConfigurationKeys.WASM_ENABLE_ARRAY_RANGE_CHECKS, arguments.wasmEnableArrayRangeChecks)
|
||||
configuration.put(JSConfigurationKeys.WASM_ENABLE_ASSERTS, arguments.wasmEnableAsserts)
|
||||
configuration.put(JSConfigurationKeys.WASM_GENERATE_WAT, arguments.wasmGenerateWat)
|
||||
configuration.put(JSConfigurationKeys.OPTIMIZE_GENERATED_JS, arguments.optimizeGeneratedJs)
|
||||
|
||||
val commonSourcesArray = arguments.commonSources
|
||||
val commonSources = commonSourcesArray?.toSet() ?: emptySet()
|
||||
|
||||
@@ -14,6 +14,7 @@ dependencies {
|
||||
api(project(":js:js.ast"))
|
||||
api(project(":js:js.frontend"))
|
||||
api(project(":js:js.sourcemap"))
|
||||
implementation(project(":js:js.translator"))
|
||||
|
||||
compileOnly(intellijCore())
|
||||
}
|
||||
|
||||
+2
-1
@@ -95,7 +95,8 @@ internal class ICHasher {
|
||||
val importantSettings = listOf(
|
||||
JSConfigurationKeys.GENERATE_DTS,
|
||||
JSConfigurationKeys.MODULE_KIND,
|
||||
JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION
|
||||
JSConfigurationKeys.PROPERTY_LAZY_INITIALIZATION,
|
||||
JSConfigurationKeys.OPTIMIZE_GENERATED_JS
|
||||
)
|
||||
hashCalculator.updateForEach(importantSettings) { key ->
|
||||
hashCalculator.update(key.toString())
|
||||
|
||||
@@ -8,7 +8,11 @@ package org.jetbrains.kotlin.ir.backend.js
|
||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.ir.backend.js.dce.eliminateDeadDeclarations
|
||||
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.JsIrProgramFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.js.backend.ast.JsFunction
|
||||
import org.jetbrains.kotlin.js.backend.ast.RecursiveJsVisitor
|
||||
import org.jetbrains.kotlin.js.inline.clean.FunctionPostProcessor
|
||||
|
||||
fun optimizeProgramByIr(
|
||||
modules: Iterable<IrModuleFragment>,
|
||||
@@ -17,4 +21,14 @@ fun optimizeProgramByIr(
|
||||
) {
|
||||
eliminateDeadDeclarations(modules, context, removeUnusedAssociatedObjects)
|
||||
jsOptimizationPhases.invokeToplevel(PhaseConfig(jsOptimizationPhases), context, modules)
|
||||
}
|
||||
}
|
||||
|
||||
fun optimizeFragmentByJsAst(fragment: JsIrProgramFragment) {
|
||||
fragment.declarations.statements.forEach {
|
||||
it.accept(object : RecursiveJsVisitor() {
|
||||
override fun visitFunction(x: JsFunction) {
|
||||
FunctionPostProcessor(x).apply()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -7,15 +7,20 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.compilationException
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsStatementOrigins
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.JsGenerationContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isUnitInstanceFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.isString
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
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
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsExpression, JsGenerationContext> {
|
||||
@@ -23,6 +28,12 @@ class IrElementToJsExpressionTransformer : BaseIrElementToJsNodeTransformer<JsEx
|
||||
private fun JsGenerationContext.isClassInlineLike(irClass: IrClass) =
|
||||
staticContext.backendContext.inlineClassesUtils.isClassInlineLike(irClass)
|
||||
|
||||
override fun visitMemberAccess(expression: IrMemberAccessExpression<*>, data: JsGenerationContext): JsExpression {
|
||||
return super.visitMemberAccess(expression, data).apply {
|
||||
synthetic = expression.origin == JsStatementOrigins.SYNTHESIZED_STATEMENT
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitComposite(expression: IrComposite, data: JsGenerationContext): JsExpression {
|
||||
val size = expression.statements.size
|
||||
if (size == 0) TODO("Empty IrComposite is not supported")
|
||||
|
||||
+17
-7
@@ -11,6 +11,8 @@ 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
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.isUnitInstanceFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
@@ -24,6 +26,7 @@ import org.jetbrains.kotlin.ir.util.file
|
||||
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
|
||||
|
||||
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
|
||||
class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsStatement, JsGenerationContext> {
|
||||
@@ -161,7 +164,19 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
}
|
||||
|
||||
val jsInitializer = value?.accept(IrElementToJsExpressionTransformer(), context)
|
||||
return JsVars(JsVars.JsVar(varName, jsInitializer).withSource(declaration, context, useNameOf = declaration))
|
||||
|
||||
val syntheticVariable = when (declaration.origin) {
|
||||
is IrDeclarationOrigin.IR_TEMPORARY_VARIABLE -> true
|
||||
is IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_PARAMETER -> true
|
||||
is IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_EXTENSION_RECEIVER -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
val variable = JsVars.JsVar(varName, jsInitializer).apply {
|
||||
withSource(declaration, context, useNameOf = declaration)
|
||||
synthetic = syntheticVariable
|
||||
}
|
||||
return JsVars(variable).apply { synthetic = syntheticVariable }
|
||||
}
|
||||
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall, context: JsGenerationContext): JsStatement {
|
||||
@@ -172,7 +187,7 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall, data: JsGenerationContext): JsStatement {
|
||||
if (expression.symbol.isUnitInstanceFunction(data)) {
|
||||
if (expression.symbol.isUnitInstanceFunction(data.staticContext.backendContext)) {
|
||||
return JsEmpty
|
||||
}
|
||||
if (data.checkIfJsCode(expression.symbol) || data.checkIfHasAssociatedJsCode(expression.symbol)) {
|
||||
@@ -181,11 +196,6 @@ class IrElementToJsStatementTransformer : BaseIrElementToJsNodeTransformer<JsSta
|
||||
return translateCall(expression, data, IrElementToJsExpressionTransformer()).withSource(expression, data).makeStmt()
|
||||
}
|
||||
|
||||
private fun IrFunctionSymbol.isUnitInstanceFunction(context: JsGenerationContext): Boolean {
|
||||
return owner.origin === JsLoweredDeclarationOrigin.OBJECT_GET_INSTANCE_FUNCTION &&
|
||||
owner.returnType.classifierOrNull === context.staticContext.backendContext.irBuiltIns.unitClass
|
||||
}
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall, context: JsGenerationContext): JsStatement {
|
||||
|
||||
// TODO: implement
|
||||
|
||||
+5
@@ -225,6 +225,7 @@ class IrModuleToJsTransformer(
|
||||
|
||||
private val generateFilePaths = backendContext.configuration.getBoolean(JSConfigurationKeys.GENERATE_COMMENTS_WITH_FILE_PATH)
|
||||
private val pathPrefixMap = backendContext.configuration.getMap(JSConfigurationKeys.FILE_PATHS_PREFIX_MAP)
|
||||
private val optimizeGeneratedJs = backendContext.configuration.get(JSConfigurationKeys.OPTIMIZE_GENERATED_JS, true)
|
||||
|
||||
private fun generateProgramFragment(fileExports: IrFileExports, minimizedMemberNames: Boolean): JsIrProgramFragment {
|
||||
val nameGenerator = JsNameLinkingNamer(backendContext, minimizedMemberNames)
|
||||
@@ -353,6 +354,10 @@ class IrModuleToJsTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
if (optimizeGeneratedJs) {
|
||||
optimizeFragmentByJsAst(result)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -23,6 +23,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.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.common.isValidES5Identifier
|
||||
import org.jetbrains.kotlin.js.config.SourceMapNamesPolicy
|
||||
import org.jetbrains.kotlin.js.config.SourceMapSourceEmbedding
|
||||
@@ -289,7 +291,14 @@ fun translateCall(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
JsInvocation(ref, listOfNotNull(jsExtensionReceiver) + arguments)
|
||||
JsInvocation(ref, listOfNotNull(jsExtensionReceiver) + arguments).pureIfPossible(function, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun JsInvocation.pureIfPossible(function: IrFunction, context: JsGenerationContext) = apply {
|
||||
if (function.symbol.isUnitInstanceFunction(context.staticContext.backendContext)) {
|
||||
sideEffects = SideEffectKind.PURE
|
||||
qualifier.sideEffects = SideEffectKind.PURE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.isClass
|
||||
import org.jetbrains.kotlin.descriptors.isInterface
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsStatementOrigins
|
||||
import org.jetbrains.kotlin.ir.backend.js.export.isExported
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
@@ -20,8 +21,10 @@ import org.jetbrains.kotlin.ir.expressions.IrInlinedFunctionBlock
|
||||
import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
@@ -85,6 +88,11 @@ val IrClass.isInstantiableEnum: Boolean
|
||||
val IrDeclaration.parentEnumClassOrNull: IrClass?
|
||||
get() = parents.filterIsInstance<IrClass>().firstOrNull { it.isInstantiableEnum }
|
||||
|
||||
fun IrFunctionSymbol.isUnitInstanceFunction(context: JsIrBackendContext): Boolean {
|
||||
return owner.origin === JsLoweredDeclarationOrigin.OBJECT_GET_INSTANCE_FUNCTION &&
|
||||
owner.returnType.classifierOrNull === context.irBuiltIns.unitClass
|
||||
}
|
||||
|
||||
// TODO: the code is written to pass Repl tests, so we should understand. why in Repl tests we don't have backingField
|
||||
fun JsIrBackendContext.getVoid(): IrExpression =
|
||||
intrinsics.void.owner.backingField?.let {
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ class JsGenerationContext(
|
||||
fun getNameForReturnableBlock(block: IrReturnableBlock): JsName? {
|
||||
return nameCache.getOrPut(block) {
|
||||
val name = localNames!!.localReturnableBlockNames.names[block] ?: return null
|
||||
return JsName(name, true)
|
||||
JsName(name, true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -40,6 +40,7 @@ where advanced options include:
|
||||
-Xir-safe-external-boolean-diagnostic={log|exception}
|
||||
Enable runtime diagnostics when access safely to boolean in external declarations
|
||||
-Xmetadata-only Generate *.meta.js and *.kjsm files only
|
||||
-Xoptimize-generated-js Perform additional optimizations on the generated JS code
|
||||
-Xpartial-linkage-loglevel={info|warning|error}
|
||||
Partial linkage compile-time log level
|
||||
-Xpartial-linkage={enable|disable}
|
||||
|
||||
+4
-5
@@ -1,15 +1,14 @@
|
||||
// CHECK_CASES_COUNT: function=test1 count=2 TARGET_BACKENDS=JS
|
||||
// CHECK_CASES_COUNT: function=test1 count=0 IGNORED_BACKENDS=JS
|
||||
// CHECK_IF_COUNT: function=test1 count=0 TARGET_BACKENDS=JS
|
||||
// CHECK_IF_COUNT: function=test1 count=1 IGNORED_BACKENDS=JS
|
||||
// CHECK_BREAKS_COUNT: function=test1 count=1 TARGET_BACKENDS=JS
|
||||
// CHECK_BREAKS_COUNT: function=test1 count=0 IGNORED_BACKENDS=JS
|
||||
// CHECK_IF_COUNT: function=test1 count=0
|
||||
|
||||
// CHECK_CASES_COUNT: function=test2 count=2 TARGET_BACKENDS=JS
|
||||
// CHECK_CASES_COUNT: function=test2 count=0 IGNORED_BACKENDS=JS
|
||||
// CHECK_IF_COUNT: function=test2 count=0 TARGET_BACKENDS=JS
|
||||
// CHECK_IF_COUNT: function=test2 count=1 IGNORED_BACKENDS=JS
|
||||
// CHECK_BREAKS_COUNT: function=test2 count=1
|
||||
// CHECK_BREAKS_COUNT: function=test2 count=1 TARGET_BACKENDS=JS
|
||||
// CHECK_BREAKS_COUNT: function=test2 count=0 IGNORED_BACKENDS=JS
|
||||
// CHECK_IF_COUNT: function=test2 count=0
|
||||
|
||||
fun test1(v: Int) {
|
||||
when (v) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_STDLIB
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
|
||||
@@ -22,7 +22,6 @@ fun box() {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:4 box:
|
||||
// test.kt:5 box: a=1:number
|
||||
// test.kt:5 box: a=1:number
|
||||
// test.kt:6 box: a=0:number
|
||||
// test.kt:7 box: a=0:number
|
||||
// test.kt:8 box: a=0:number
|
||||
|
||||
@@ -17,6 +17,5 @@ fun box(): String {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:5 box:
|
||||
// test.kt:7 box: p=kotlin.Pair
|
||||
// test.kt:7 box: p=kotlin.Pair
|
||||
// test.kt:7 box: p=kotlin.Pair, o="O":kotlin.String
|
||||
// test.kt:9 box: p=kotlin.Pair, o="O":kotlin.String, k="K":kotlin.String
|
||||
|
||||
-1
@@ -36,7 +36,6 @@ fun box(): String {
|
||||
// test.kt:2 <init>: x="X":kotlin.String, y="Y":kotlin.String
|
||||
// test.kt:2 <init>: x="X":kotlin.String, y="Y":kotlin.String
|
||||
// test.kt:14 box: p=MyPair
|
||||
// test.kt:14 box: p=MyPair
|
||||
// test.kt:4 component1:
|
||||
// test.kt:14 box: p=MyPair, o="O":kotlin.String
|
||||
// test.kt:8 component2:
|
||||
|
||||
Vendored
-1
@@ -44,7 +44,6 @@ fun box(): String {
|
||||
// test.kt:4 <init>: x="X":kotlin.String, y="Y":kotlin.String
|
||||
// test.kt:4 <init>: x="X":kotlin.String, y="Y":kotlin.String
|
||||
// test.kt:4 <init>: x="X":kotlin.String, y="Y":kotlin.String
|
||||
// test.kt:23 box: p=MyPair
|
||||
// test.kt:18 box: p=MyPair
|
||||
// test.kt:6 component1:
|
||||
// test.kt:20 box: p=MyPair, o="O":kotlin.String
|
||||
|
||||
@@ -30,7 +30,6 @@ fun box(): String {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:6 box:
|
||||
// test.kt:15 box: p=kotlin.Pair
|
||||
// test.kt:10 box: p=kotlin.Pair
|
||||
// test.kt:12 box: p=kotlin.Pair, o="O":kotlin.String
|
||||
// test.kt:17 box: p=kotlin.Pair, o="O":kotlin.String, k="K":kotlin.String
|
||||
|
||||
-1
@@ -17,6 +17,5 @@ fun box(): String {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:5 box:
|
||||
// test.kt:7 box: p=kotlin.Triple
|
||||
// test.kt:7 box: p=kotlin.Triple
|
||||
// test.kt:7 box: p=kotlin.Triple, o="O":kotlin.String
|
||||
// test.kt:9 box: p=kotlin.Triple, o="O":kotlin.String, k="K":kotlin.String
|
||||
|
||||
-1
@@ -32,7 +32,6 @@ fun box(): String {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:6 box:
|
||||
// test.kt:17 box: p=kotlin.Triple
|
||||
// test.kt:12 box: p=kotlin.Triple
|
||||
// test.kt:14 box: p=kotlin.Triple, o="O":kotlin.String
|
||||
// test.kt:19 box: p=kotlin.Triple, o="O":kotlin.String, k="K":kotlin.String
|
||||
|
||||
@@ -20,9 +20,6 @@ fun box() {
|
||||
// test.kt:5 box:
|
||||
// test.kt:6 box: map=kotlin.collections.HashMap
|
||||
// test.kt:6 box: map=kotlin.collections.HashMap
|
||||
// test.kt:6 box: map=kotlin.collections.HashMap
|
||||
// test.kt:6 box: map=kotlin.collections.HashMap
|
||||
// test.kt:6 box: map=kotlin.collections.HashMap, a="1":kotlin.String
|
||||
// test.kt:7 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
// test.kt:6 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
// test.kt:9 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
|
||||
@@ -43,9 +43,6 @@ fun box() {
|
||||
// test.kt:5 box:
|
||||
// test.kt:15 box: map=kotlin.collections.HashMap
|
||||
// test.kt:15 box: map=kotlin.collections.HashMap
|
||||
// test.kt:15 box: map=kotlin.collections.HashMap
|
||||
// test.kt:10 box: map=kotlin.collections.HashMap
|
||||
// test.kt:12 box: map=kotlin.collections.HashMap, a="1":kotlin.String
|
||||
// test.kt:18 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
// test.kt:15 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
// test.kt:20 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
// test.kt:20 box: map=kotlin.collections.HashMap, a="1":kotlin.String, b="23":kotlin.String
|
||||
|
||||
@@ -36,8 +36,7 @@ fun box() {
|
||||
// test.kt:5 box:
|
||||
// test.kt:11 box: map=kotlin.collections.HashMap
|
||||
// test.kt:11 box: map=kotlin.collections.HashMap
|
||||
// test.kt:11 box: map=kotlin.collections.HashMap
|
||||
// test.kt:14 box: map=kotlin.collections.HashMap, e=kotlin.collections.AbstractMutableMap.SimpleEntry
|
||||
// test.kt:14 box: map=kotlin.collections.HashMap, e=kotlin.collections.AbstractMutableMap.SimpleEntry
|
||||
// test.kt:11 box: map=kotlin.collections.HashMap, e=kotlin.collections.AbstractMutableMap.SimpleEntry
|
||||
// test.kt:16 box: map=kotlin.collections.HashMap, e=kotlin.collections.AbstractMutableMap.SimpleEntry
|
||||
// test.kt:16 box: map=kotlin.collections.HashMap, e=kotlin.collections.AbstractMutableMap.SimpleEntry
|
||||
|
||||
@@ -24,7 +24,5 @@ fun box() {
|
||||
// test.kt:8 box:
|
||||
// test.kt:2 <init>:
|
||||
// test.kt:4 box: a=A
|
||||
// test.kt:9 box: a=A
|
||||
// test.kt:10 box: a=A, y=1:number
|
||||
// test.kt:10 box: a=A, y=1:number
|
||||
// test.kt:11 box: a=A, y=2:number
|
||||
|
||||
+1
-2
@@ -81,8 +81,7 @@ fun box() {
|
||||
// a.kt:6 exclamate: s="Jesse":kotlin.String
|
||||
// test.kt:52 box: jesse="Jesse":kotlin.String, walter1="Walter!":kotlin.String, jesse1="Jesse!":kotlin.String
|
||||
// a.kt:6 exclamate: s="Jesse!":kotlin.String
|
||||
// a.kt:29 box: jesse="Jesse":kotlin.String, walter1="Walter!":kotlin.String, jesse1="Jesse!":kotlin.String
|
||||
// a.kt:22 value:
|
||||
// test.kt:63 box: jesse="Jesse":kotlin.String, walter1="Walter!":kotlin.String, jesse1="Jesse!":kotlin.String
|
||||
// test.kt:59 localFun: hello="hello":kotlin.String, world="world":kotlin.String
|
||||
// test.kt:64 box: jesse="Jesse":kotlin.String, walter1="Walter!":kotlin.String, jesse1="Jesse!":kotlin.String
|
||||
// test.kt:64 box: jesse="Jesse":kotlin.String, walter1="Walter!":kotlin.String, jesse1="Jesse!":kotlin.String
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ suspend fun box() {
|
||||
// test.kt:10 box: $completion:kotlin.coroutines.Continuation=Generated_Box_MainKt$main$1
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:9 box: $completion=EmptyContinuation
|
||||
// test.kt:10 box: $completion=EmptyContinuation
|
||||
// test.kt:4 <init>:
|
||||
// test.kt:9 box: $completion=EmptyContinuation
|
||||
// test.kt:5 foo: $completion=EmptyContinuation
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ suspend fun box() {
|
||||
// test.kt:15 box: $completion:kotlin.coroutines.Continuation=Generated_Box_MainKt$main$1
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
// test.kt:15 box: $completion=EmptyContinuation
|
||||
// test.kt:4 <init>:
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ suspend fun box() {
|
||||
// test.kt:10 box: $completion:kotlin.coroutines.Continuation=Generated_Box_MainKt$main$1
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:9 box: $completion=EmptyContinuation
|
||||
// test.kt:10 box: $completion=EmptyContinuation
|
||||
// test.kt:4 <init>:
|
||||
// test.kt:9 box: $completion=EmptyContinuation
|
||||
// test.kt:6 foo: <this>=A, $completion=EmptyContinuation
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ suspend fun box() {
|
||||
// test.kt:13 box: $completion:kotlin.coroutines.Continuation=Generated_Box_MainKt$main$1
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:12 box: $completion=EmptyContinuation
|
||||
// test.kt:13 box: $completion=EmptyContinuation
|
||||
// test.kt:12 box: $completion=EmptyContinuation
|
||||
// test.kt:6 doResume:
|
||||
// test.kt:4 foo: $completion=$foo1COROUTINE$0
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ suspend fun box() {
|
||||
// test.kt:15 box: $completion:kotlin.coroutines.Continuation=Generated_Box_MainKt$main$1
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
// test.kt:15 box: $completion=EmptyContinuation
|
||||
// test.kt:4 <init>:
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
|
||||
@@ -42,7 +42,7 @@ suspend fun box() = foo(A()) { (x_param, _, y_param) ->
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:12 box: $completion=EmptyContinuation
|
||||
// test.kt:4 <init>:
|
||||
// test.kt:12 box: $completion=EmptyContinuation
|
||||
// test.kt:14 box: $completion=EmptyContinuation
|
||||
// test.kt:12 box$slambda:
|
||||
// test.kt:12 box: $completion=EmptyContinuation
|
||||
// test.kt:10 foo: a=A, block=Function2, $completion=EmptyContinuation
|
||||
|
||||
@@ -66,7 +66,6 @@ fun box() {
|
||||
// test.kt:9 compute: y=42:number, i=0:number, z=32:number
|
||||
// test.kt:9 compute: y=42:number, i=0:number, z=32:number
|
||||
// test.kt:9 compute: y=42:number, i=0:number, z=32:number, j=0:number
|
||||
// test.kt:10 compute: y=42:number, i=0:number, z=32:number, j=0:number
|
||||
// test.kt:24 compute: y=42:number, i=0:number, z=32:number, j=0:number
|
||||
// test.kt:28 compute: y=42:number, i=0:number, z=32:number, j=0:number
|
||||
// test.kt:29 compute: y=42:number, i=0:number, z=32:number, j=0:number, s2="OK":kotlin.String
|
||||
|
||||
@@ -66,9 +66,6 @@ fun box() {
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:4 <init>: x=1:number
|
||||
// test.kt:4 <init>: x=1:number, y="":kotlin.String
|
||||
// test.kt:4 <init>: x=1:number, y="":kotlin.String, z=48:number
|
||||
@@ -78,7 +75,6 @@ fun box() {
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:8 <init properties test.kt>:
|
||||
// test.kt:12 box:
|
||||
// test.kt:4 <init>: x=1:number
|
||||
// test.kt:4 <init>: x=1:number, y="":kotlin.String
|
||||
|
||||
@@ -37,12 +37,9 @@ fun box() {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:19 box
|
||||
// test.kt:12 foo
|
||||
// test.kt:6 alternate
|
||||
// test.kt:7 alternate
|
||||
// test.kt:12 foo
|
||||
// test.kt:6 alternate
|
||||
// test.kt:7 alternate
|
||||
// test.kt:13 foo
|
||||
// test.kt:16 foo
|
||||
// test.kt:20 box
|
||||
// test.kt:20 box
|
||||
|
||||
+1
-2
@@ -32,5 +32,4 @@ fun box() {
|
||||
// test.kt:3 <init>
|
||||
// test.kt:11 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 box
|
||||
// test.kt:15 box
|
||||
// test.kt:15 box
|
||||
|
||||
+1
-4
@@ -36,7 +36,4 @@ fun box() {
|
||||
// test.kt:4 foo
|
||||
// test.kt:11 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 box
|
||||
// test.kt:13 box
|
||||
// test.kt:5 box
|
||||
// test.kt:15 box
|
||||
// test.kt:15 box
|
||||
|
||||
+1
-3
@@ -82,7 +82,6 @@ fun box() {
|
||||
// test.kt:16 box
|
||||
// test.kt:1 toString
|
||||
// test.kt:17 box
|
||||
// test.kt:17 box
|
||||
// test.kt:1 component1
|
||||
// test.kt:17 box
|
||||
// test.kt:1 component2
|
||||
@@ -108,7 +107,6 @@ fun box() {
|
||||
// test.kt:22 box
|
||||
// test.kt:6 toString
|
||||
// test.kt:23 box
|
||||
// test.kt:23 box
|
||||
// test.kt:1 component1
|
||||
// test.kt:23 box
|
||||
// test.kt:1 component2
|
||||
@@ -117,4 +115,4 @@ fun box() {
|
||||
// test.kt:5 <init>
|
||||
// test.kt:5 <init>
|
||||
// test.kt:5 <init>
|
||||
// test.kt:25 box
|
||||
// test.kt:25 box
|
||||
|
||||
+1
-2
@@ -25,7 +25,6 @@ inline fun getB(): Int {
|
||||
// test.kt:8 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:14 box
|
||||
// test.kt:4 box
|
||||
// test.kt:11 getA
|
||||
// test.kt:14 box
|
||||
// test.kt:8 box
|
||||
|
||||
+1
-7
@@ -40,13 +40,7 @@ fun box() {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:20 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:21 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:22 box
|
||||
// test.kt:22 box
|
||||
|
||||
@@ -56,23 +56,12 @@ fun nop() {}
|
||||
// test.kt:21 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:24 box
|
||||
// test.kt:3 box
|
||||
// test.kt:4 box
|
||||
// test.kt:30 nop
|
||||
// test.kt:24 box
|
||||
// test.kt:8 box
|
||||
// test.kt:28 box
|
||||
// test.kt:8 box
|
||||
// test.kt:24 box
|
||||
// test.kt:9 box
|
||||
// test.kt:7 box
|
||||
// test.kt:11 box
|
||||
// test.kt:30 nop
|
||||
// test.kt:24 box
|
||||
// test.kt:16 box
|
||||
// test.kt:27 box
|
||||
// test.kt:14 box
|
||||
// test.kt:19 box
|
||||
// test.kt:30 nop
|
||||
// test.kt:21 box
|
||||
|
||||
+1
-2
@@ -20,7 +20,6 @@ inline fun foo() = {
|
||||
// test.kt:6 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test1.kt:10 box
|
||||
// test.kt:5 box
|
||||
// test1.kt:9 box
|
||||
// test1.kt:7 box$lambda
|
||||
// test.kt:6 box
|
||||
|
||||
+1
-2
@@ -26,8 +26,7 @@ inline fun foo() = {
|
||||
// test.kt:7 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test1.kt:11 box
|
||||
// test.kt:5 box
|
||||
// test1.kt:10 box
|
||||
// test.kt:6 box
|
||||
// test1.kt:8 box$lambda
|
||||
// test.kt:7 box
|
||||
|
||||
+1
-2
@@ -44,8 +44,7 @@ fun baz(v:(() -> Unit)) {
|
||||
// test3.kt:15 baz
|
||||
// test1.kt:9 box$lambda
|
||||
// test3.kt:16 baz
|
||||
// test1.kt:12 box
|
||||
// test.kt:6 box
|
||||
// test1.kt:11 box
|
||||
// test.kt:7 box
|
||||
// test3.kt:15 baz
|
||||
// test1.kt:9 box$lambda
|
||||
|
||||
@@ -25,8 +25,4 @@ fun box(): String {
|
||||
// test.kt:13 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:8 box
|
||||
// test.kt:4 box
|
||||
// test.kt:10 box
|
||||
// test.kt:4 box
|
||||
// test.kt:13 box
|
||||
|
||||
@@ -30,8 +30,4 @@ fun box(): String {
|
||||
// test.kt:16 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:2 box
|
||||
// test.kt:3 box
|
||||
// test.kt:7 box
|
||||
// test.kt:10 box
|
||||
// test.kt:16 box
|
||||
|
||||
@@ -69,8 +69,5 @@ inline fun html(init: () -> Unit) {
|
||||
// 1.kt:33 box
|
||||
// 1.kt:36 box
|
||||
// 1.kt:37 box
|
||||
// 1.kt:37 box
|
||||
// 1.kt:41 box
|
||||
// test.kt:15 box
|
||||
// test.kt:19 box
|
||||
// test.kt:21 box
|
||||
|
||||
@@ -23,6 +23,5 @@ inline fun lookAtMe(f: () -> Int) {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:11 box
|
||||
// test.kt:6 box
|
||||
// test.kt:12 box
|
||||
// test.kt:8 box
|
||||
|
||||
@@ -26,5 +26,4 @@ fun box(): String {
|
||||
// test.kt:14 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:5 box
|
||||
// test.kt:14 box
|
||||
// test.kt:14 box
|
||||
|
||||
@@ -38,6 +38,4 @@ fun box(): String {
|
||||
// test.kt:10 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:3 box
|
||||
// test.kt:5 box
|
||||
// test.kt:6 box
|
||||
// test.kt:10 box
|
||||
|
||||
@@ -38,14 +38,12 @@ fun fail() : String {
|
||||
// test.kt:9 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:16 box
|
||||
// test.kt:4 box
|
||||
// test.kt:20 fail
|
||||
// test.kt:4 box
|
||||
// test.kt:13 checkEquals
|
||||
// test.kt:7 box
|
||||
// test.kt:20 fail
|
||||
// test.kt:16 box
|
||||
// test.kt:7 box
|
||||
// test.kt:13 checkEquals
|
||||
// test.kt:9 box
|
||||
|
||||
@@ -36,14 +36,12 @@ fun fail() : String {
|
||||
// test.kt:11 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:14 box
|
||||
// test.kt:6 box
|
||||
// test.kt:18 fail
|
||||
// test.kt:6 box
|
||||
// test.kt:3 execute
|
||||
// test.kt:9 box
|
||||
// test.kt:18 fail
|
||||
// test.kt:14 box
|
||||
// test.kt:9 box
|
||||
// test.kt:3 execute
|
||||
// test.kt:11 box
|
||||
|
||||
@@ -38,14 +38,8 @@ fun fail() : String {
|
||||
// test.kt:9 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:16 box
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:20 fail
|
||||
// test.kt:16 box
|
||||
// test.kt:7 box
|
||||
// test.kt:20 fail
|
||||
// test.kt:16 box
|
||||
// test.kt:8 box
|
||||
// test.kt:16 box
|
||||
// test.kt:9 box
|
||||
|
||||
@@ -38,10 +38,8 @@ fun fail() : String {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:12 box
|
||||
// test.kt:4 box
|
||||
// test.kt:16 fail
|
||||
// test.kt:7 box
|
||||
// test.kt:16 fail
|
||||
// test.kt:12 box
|
||||
// test.kt:7 box
|
||||
// test.kt:9 box
|
||||
|
||||
@@ -117,9 +117,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:12 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:21 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
@@ -127,9 +125,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:6 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:13 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:22 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
@@ -137,9 +133,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:7 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:14 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
@@ -147,9 +141,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:8 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:15 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:18 stringSwitch
|
||||
// test.kt:24 stringSwitch
|
||||
// test.kt:26 stringSwitch
|
||||
|
||||
@@ -100,9 +100,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:5 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:11 stringSwitch
|
||||
// test.kt:17 stringSwitch
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:19 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
@@ -110,9 +108,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:6 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:12 stringSwitch
|
||||
// test.kt:17 stringSwitch
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:20 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
@@ -120,9 +116,7 @@ fun box() {
|
||||
// test.kt:4 stringSwitch
|
||||
// test.kt:7 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:10 stringSwitch
|
||||
// test.kt:13 stringSwitch
|
||||
// test.kt:17 stringSwitch
|
||||
// test.kt:16 stringSwitch
|
||||
// test.kt:21 stringSwitch
|
||||
// test.kt:23 stringSwitch
|
||||
|
||||
@@ -26,7 +26,7 @@ suspend fun box() {
|
||||
// test.kt:9 doResume
|
||||
// test.kt:9 box$slambda
|
||||
// test.kt:9 doResume
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:10 doResume
|
||||
// test.kt:12 doResume
|
||||
|
||||
@@ -18,6 +18,4 @@ fun box(): String {
|
||||
// test.kt:8 box
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:4 box
|
||||
// test.kt:6 box
|
||||
// test.kt:8 box
|
||||
|
||||
@@ -52,18 +52,13 @@ fun box() {
|
||||
// test.kt:16 box
|
||||
// test.kt:5 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:17 box
|
||||
// test.kt:5 foo
|
||||
// test.kt:7 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:18 box
|
||||
// test.kt:5 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:19 box
|
||||
|
||||
@@ -24,5 +24,4 @@ fun box() {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:4 box
|
||||
// test.kt:4 box
|
||||
// test.kt:12 box
|
||||
|
||||
+1
-2
@@ -26,5 +26,4 @@ fun box() {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:5 box
|
||||
// test.kt:16 box
|
||||
// test.kt:16 box
|
||||
|
||||
@@ -39,15 +39,9 @@ fun box() {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:15 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:16 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:18 box
|
||||
|
||||
@@ -58,22 +58,16 @@ fun box() {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:26 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:27 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:22 foo
|
||||
// test.kt:28 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:22 foo
|
||||
|
||||
@@ -26,5 +26,4 @@ fun box() {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:4 box
|
||||
// test.kt:5 box
|
||||
// test.kt:5 box
|
||||
// test.kt:16 box
|
||||
|
||||
-14
@@ -73,24 +73,17 @@ fun box() {
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:18 box
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
@@ -98,24 +91,17 @@ fun box() {
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:11 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:6 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:10 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:10 foo
|
||||
|
||||
@@ -122,50 +122,36 @@ fun box() {
|
||||
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:22 box
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:7 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:16 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:15 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:8 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:19 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:16 foo
|
||||
// test.kt:5 foo
|
||||
// test.kt:4 foo
|
||||
// test.kt:13 foo
|
||||
// test.kt:12 foo
|
||||
// test.kt:17 foo
|
||||
// test.kt:12 foo
|
||||
|
||||
@@ -73,27 +73,15 @@ fun nop() {}
|
||||
// EXPECTATIONS JS_IR
|
||||
// test.kt:3 box
|
||||
// test.kt:19 value
|
||||
// test.kt:4 box
|
||||
// test.kt:20 box
|
||||
// test.kt:5 box
|
||||
// test.kt:21 box
|
||||
// test.kt:6 box
|
||||
// test.kt:22 box
|
||||
// test.kt:7 box
|
||||
// test.kt:7 box
|
||||
// test.kt:28 nop
|
||||
// test.kt:20 box
|
||||
// test.kt:12 box
|
||||
// test.kt:21 box
|
||||
// test.kt:12 box
|
||||
// test.kt:20 box
|
||||
// test.kt:13 box
|
||||
// test.kt:26 box
|
||||
// test.kt:13 box
|
||||
// test.kt:21 box
|
||||
// test.kt:14 box
|
||||
// test.kt:25 box
|
||||
// test.kt:14 box
|
||||
// test.kt:14 box
|
||||
// test.kt:28 nop
|
||||
// test.kt:17 box
|
||||
// test.kt:17 box
|
||||
|
||||
@@ -121,4 +121,6 @@ public class JSConfigurationKeys {
|
||||
public static final CompilerConfigurationKey<ZipFileSystemAccessor> ZIP_FILE_SYSTEM_ACCESSOR =
|
||||
CompilerConfigurationKey.create("zip file system accessor, used for klib reading");
|
||||
|
||||
public static final CompilerConfigurationKey<Boolean> OPTIMIZE_GENERATED_JS =
|
||||
CompilerConfigurationKey.create("perform additional optimizations on the generated JS code");
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ internal class DoWhileGuardElimination(private val root: JsStatement) {
|
||||
else -> null
|
||||
}
|
||||
|
||||
if (guard != null) {
|
||||
if (guard != null && guard.statement !is JsLoop) {
|
||||
|
||||
// When do..while loop has no label and we encounter `break guard` from nested loop, we can't
|
||||
// replace this break with continue. Example:
|
||||
|
||||
+36
-4
@@ -88,6 +88,16 @@ import org.jetbrains.kotlin.js.translate.utils.splitToRanges
|
||||
* foo(B, $a)
|
||||
*
|
||||
* we get `$a` eliminated.
|
||||
*
|
||||
* It is also worth taking care of the temporary variables captured into closure as they cannot be simply removed.
|
||||
*
|
||||
* function test(a) {
|
||||
* var tmp_a = a // removing this temporary variable changes function behaviour
|
||||
* var f = function() { console.log(tmp_a) }
|
||||
* a = []
|
||||
* return f
|
||||
* }
|
||||
*
|
||||
*/
|
||||
internal class TemporaryVariableElimination(private val function: JsFunction) {
|
||||
private val root = function.body
|
||||
@@ -95,6 +105,7 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
|
||||
private val usages = mutableMapOf<JsName, Int>()
|
||||
private val definedValues = mutableMapOf<JsName, JsExpression>()
|
||||
private val temporary = mutableSetOf<JsName>()
|
||||
private val capturedInClosure = mutableSetOf<JsName>()
|
||||
private var hasChanges = false
|
||||
private val localVariables = function.collectLocalVariables()
|
||||
|
||||
@@ -201,6 +212,7 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
|
||||
for (freeVar in x.collectFreeVariables()) {
|
||||
useVariable(freeVar)
|
||||
useVariable(freeVar)
|
||||
capturedInClosure += freeVar
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,9 +272,12 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
|
||||
namesWithSideEffects += name
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sideEffects) {
|
||||
invalidateTemporaries()
|
||||
} else {
|
||||
if (sideEffects) {
|
||||
invalidateTemporaries()
|
||||
} else {
|
||||
invalidateTemporariesUsingName(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -359,6 +374,21 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
|
||||
lastAssignedVars.clear()
|
||||
}
|
||||
|
||||
private fun invalidateTemporariesUsingName(name: JsName) {
|
||||
lastAssignedVars.removeAll { (_, expr) ->
|
||||
var nameUsed = false
|
||||
object : RecursiveJsVisitor() {
|
||||
override fun visitNameRef(nameRef: JsNameRef) {
|
||||
if (nameRef.name == name) {
|
||||
nameUsed = true
|
||||
}
|
||||
super.visitNameRef(nameRef)
|
||||
}
|
||||
}.accept(expr)
|
||||
nameUsed
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleExpression(expression: JsExpression): Boolean {
|
||||
val candidateFinder = SubstitutionCandidateFinder()
|
||||
candidateFinder.accept(expression)
|
||||
@@ -593,7 +623,9 @@ internal class TemporaryVariableElimination(private val function: JsFunction) {
|
||||
(definitions[name] ?: 0) > 0 && (usages[name] ?: 0) == 0 && name in temporary && !name.imported
|
||||
|
||||
private fun shouldConsiderTemporary(name: JsName): Boolean {
|
||||
if (definitions[name] != 1 || name !in temporary) return false
|
||||
if (definitions[name] != 1 || name !in temporary || name in capturedInClosure) {
|
||||
return false
|
||||
}
|
||||
|
||||
val expr = definedValues[name]
|
||||
// It's useful to copy trivial expressions when they are used more than once. Example are temporary variables
|
||||
|
||||
+1
-1
@@ -12,4 +12,4 @@ fun baz() = 1
|
||||
fun bar() = 2
|
||||
|
||||
// LINES(JS): 1 3 3 2 2 4 3 4 4 4 5 5 2 8 8 10 10 10 12 12 12
|
||||
// LINES(JS_IR): 1 2 8 * 3 4 5 * 8 8 10 10 10 10 12 12 12 12
|
||||
// LINES(JS_IR): 1 2 8 * 4 3 4 5 * 8 8 10 10 10 10 12 12 12 12
|
||||
|
||||
@@ -14,5 +14,5 @@ private inline fun foo(): Int {
|
||||
return 23
|
||||
}
|
||||
|
||||
// LINES(JS): 1 10 3 3 3 4 3 6 13 13 3 14 2 12 15 13 13 14 14
|
||||
// LINES(JS_IR): 1 1 * 3 4 6 * 8 * 13 13 14 14 8 2 12 12 13 13 14 14
|
||||
// LINES(JS): 1 10 3 3 3 4 3 6 13 13 3 14 2 12 15 13 13 14 14
|
||||
// LINES(JS_IR): 1 1 * 3 4 6 * 13 13 14 2 12 12 13 13 14 14
|
||||
|
||||
+1
-1
@@ -15,4 +15,4 @@ suspend fun bar(): Unit {
|
||||
}
|
||||
|
||||
// LINES(JS): 39 4 4 4 7 5 5 45 45 5 93 45 5 5 6 4 4 4 9 15 9 9 9 * 9 15 10 10 11 11 11 11 11 * 11 12 12 13 13 13 13 13 13 13 14 14 * 9 15 9 9 9 9
|
||||
// LINES(JS_IR): 4 4 * 19 * 5 * 45 * 93 93 45 45 45 6 6 19 7 7 9 9 * 9 * 9 * 10 10 * 11 * 11 12 12 * 13 * 13 14 14 15 15
|
||||
// LINES(JS_IR): 4 4 * 93 93 45 45 7 7 6 9 9 * 9 * 9 * 10 10 * 11 * 11 12 12 * 13 * 13 14 14 15 15
|
||||
|
||||
@@ -33,4 +33,4 @@ inline operator fun P.component1() = a
|
||||
inline operator fun P.component2() = b
|
||||
|
||||
// LINES(JS): 15 22 17 17 31 18 18 33 20 20 21 21 22 22 3 23 9 9 9 9 4 9 9 9 6 6 31 7 7 33 11 11 12 12 15 15 25 27 26 26 29 29 29 * 31 31 31 33 33 33 * 1 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 9 9 4 9 * 6 * 31 31 6 * 7 * 33 33 7 11 11 12 12 15 15 25 25 26 26 29 29 29 29 29 29 29 29 29 29 29 29 31 31 31 31 33 33 33 33 15 16 15 * 17 * 31 31 17 * 18 * 33 33 18 20 20 21 21 22 22 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 9 9 4 9 * 6 31 * 7 33 11 11 12 12 15 15 25 25 26 26 29 29 29 29 29 29 29 29 29 29 29 29 31 31 31 31 33 33 33 33 15 16 15 * 17 31 * 18 33 20 20 21 21 22 22 * 1
|
||||
|
||||
+1
-1
@@ -10,4 +10,4 @@ fun box(x: String?) {
|
||||
fun foo() = "bar"
|
||||
|
||||
// LINES(JS): 3 8 7 7 4 4 4 5 5 7 7 7 7 * 5 4 5 10 10 10 * 1 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 4 5 * 5 5 * 7 7 7 * 5 4 4 10 10 10 10 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 4 * 5 5 * 7 7 7 * 5 4 4 10 10 10 10 * 1
|
||||
|
||||
+2
-2
@@ -17,5 +17,5 @@ fun box() {
|
||||
}
|
||||
}
|
||||
|
||||
// LINES(JS): 1 18 2 2 10 2 2 2 2 2 2 3 3 6 6 6 6 7 7 10 10 10 10 10 10 11 11 14 14 15 15 15 15 16 16
|
||||
// LINES(JS_IR): 1 1 * 2 * 35 * 18 * 12 2 18 18 35 35 2 2 2 2 2 2 2 2 3 3 6 6 6 6 6 6 6 7 7 10 10 10 10 11 11 14 15 15 15 15 15 15 15 15 16 16
|
||||
// LINES(JS): 1 18 2 2 10 2 2 2 2 2 2 3 3 6 6 6 6 7 7 10 10 10 10 10 10 11 11 14 14 15 15 15 15 16 16
|
||||
// LINES(JS_IR): 1 1 * 2 2 2 2 2 2 2 2 3 3 6 6 6 6 6 6 6 7 7 10 10 10 10 11 11 14 15 15 15 15 15 15 15 15 16 16
|
||||
|
||||
+2
-2
@@ -8,5 +8,5 @@ fun foo(x: Int) {
|
||||
println(y)
|
||||
}
|
||||
|
||||
// LINES(JS): 1 9 2 2 3 3 4 4 5 5 6 6 7 7 8 8
|
||||
// LINES(JS_IR): 1 1 2 3 3 3 4 4 5 5 6 6 7 7 8 8
|
||||
// LINES(JS): 1 9 2 2 3 3 4 4 5 5 6 6 7 7 8 8
|
||||
// LINES(JS_IR): 1 1 2 3 3 4 4 5 5 6 6 7 7 8 8
|
||||
|
||||
@@ -12,4 +12,4 @@ inline fun foo(x: Int) {
|
||||
fun bar() = 23
|
||||
|
||||
// LINES(JS): 3 5 4 4 8 8 9 9 7 10 8 8 9 9 12 12 12 * 1 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 4 * 4 8 8 9 9 7 7 8 8 9 9 12 12 12 12 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 * 4 8 8 9 9 7 7 8 8 9 9 12 12 12 12 * 1
|
||||
|
||||
@@ -10,4 +10,4 @@ fun bar() {
|
||||
}
|
||||
|
||||
// LINES(JS): 1 1 1 1 1 6 2 2 3 3 4 4 8 10 2 2 9 2 3 3 4 4
|
||||
// LINES(JS_IR): 1 1 2 3 3 3 4 4 8 8 9 * 2 3 3 3 4 4
|
||||
// LINES(JS_IR): 1 1 2 3 3 3 4 4 8 8 * 2 3 3 3 4 4
|
||||
|
||||
@@ -22,5 +22,5 @@ fun box() {
|
||||
foo("42")
|
||||
}
|
||||
|
||||
// LINES(JS): 6 20 23 7 7 21 7 8 8 21 8 7 7 22 7 8 8 22 8
|
||||
// LINES(JS_IR): 20 20 21 * 7 7 8 8 22 * 7 7 8 8
|
||||
// LINES(JS): 6 20 23 7 7 21 7 8 8 21 8 7 7 22 7 8 8 22 8
|
||||
// LINES(JS_IR): 20 20 * 7 7 8 8 * 7 7 8 8
|
||||
|
||||
+2
-2
@@ -11,5 +11,5 @@ inline fun bar() {
|
||||
println("bar2")
|
||||
}
|
||||
|
||||
// LINES(JS): 1 7 2 2 10 10 11 11 4 4 10 10 11 11 6 6 9 9 9 9 9 12 10 10 11 11
|
||||
// LINES(JS_IR): 1 1 2 2 3 * 10 10 11 11 4 4 5 * 10 10 11 11 6 6 9 9 10 10 11 11
|
||||
// LINES(JS): 1 7 2 2 10 10 11 11 4 4 10 10 11 11 6 6 9 9 9 9 9 12 10 10 11 11
|
||||
// LINES(JS_IR): 1 1 2 2 * 10 10 11 11 4 4 * 10 10 11 11 6 6 9 9 10 10 11 11
|
||||
|
||||
@@ -16,5 +16,5 @@ inline fun foo(f: () -> Unit) {
|
||||
println("after")
|
||||
}
|
||||
|
||||
// LINES(JS): 1 11 2 2 14 14 4 4 16 16 6 6 14 14 8 8 16 16 10 10 13 13 13 13 13 17 14 14 15 15 16 16
|
||||
// LINES(JS_IR): 1 1 2 2 3 * 14 14 15 * 4 4 16 16 6 6 7 * 14 14 15 * 8 8 16 16 10 10 13 13 14 14 15 15 16 16
|
||||
// LINES(JS): 1 11 2 2 14 14 4 4 16 16 6 6 14 14 8 8 16 16 10 10 13 13 13 13 13 17 14 14 15 15 16 16
|
||||
// LINES(JS_IR): 1 1 2 2 * 14 14 * 4 4 16 16 6 6 * 14 14 * 8 8 16 16 10 10 13 13 14 14 15 15 16 16
|
||||
|
||||
+2
-2
@@ -11,5 +11,5 @@ inline fun foo(): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
// LINES(JS): 3 7 4 4 4 10 10 4 11 4 5 5 9 12 10 10 11 11 * 1 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 * 4 4 * 4 * 10 10 11 11 4 4 4 5 5 9 9 10 10 11 11 * 1
|
||||
// LINES(JS): 3 7 4 4 4 10 10 4 11 4 5 5 9 12 10 10 11 11 * 1 * 1
|
||||
// LINES(JS_IR): 1 1 1 1 1 1 1 1 * 3 3 * 4 4 * 10 10 11 4 4 4 5 5 9 9 10 10 11 11 * 1
|
||||
|
||||
@@ -24,5 +24,5 @@ fun baz() = "baz"
|
||||
|
||||
fun boo() = "boo"
|
||||
|
||||
// LINES(JS): 1 17 9 4 6 6 7 7 3 3 3 * 13 12 13 13 14 19 21 20 20 23 23 23 25 25 25
|
||||
// LINES(JS_IR): 1 1 * 2 * 20 * 4 * 6 7 * 3 20 20 * 11 * 20 * 12 12 13 14 20 20 19 19 20 20 23 23 23 23 25 25 25 25
|
||||
// LINES(JS): 1 17 9 4 6 6 7 7 3 3 3 * 13 12 13 13 14 19 21 20 20 23 23 23 25 25 25
|
||||
// LINES(JS_IR): 1 1 * 4 * 6 7 * 13 12 13 19 19 20 20 23 23 23 23 25 25 25 25
|
||||
|
||||
@@ -19,4 +19,4 @@ fun box(x: Int) {
|
||||
}
|
||||
|
||||
// LINES(JS): 1 19 4 4 3 3 4 6 9 9 6 11 13 13 11 16 16 3 2
|
||||
// LINES(JS_IR): 1 1 4 2 8 7 6 7 8 9 12 11 12 13 16
|
||||
// LINES(JS_IR): 1 1 2 8 7 6 4 6 7 4 7 8 4 8 9 12 11 4 11 12 4 12 13 16
|
||||
|
||||
+1
-1
@@ -29,4 +29,4 @@ fun four() = 4
|
||||
fun five() = 5
|
||||
|
||||
// LINES(JS): 1 19 4 4 3 6 4 6 4 7 4 8 9 9 11 4 11 4 12 13 13 16 16 2 21 21 21 23 23 23 25 25 25 27 27 27 29 29 29
|
||||
// LINES(JS_IR): 1 1 4 2 8 7 6 7 8 9 12 11 12 13 16 21 21 21 21 23 23 23 23 25 25 25 25 27 27 27 27 29 29 29 29
|
||||
// LINES(JS_IR): 1 1 2 8 7 6 4 6 7 4 7 8 4 8 9 12 11 4 11 12 4 12 13 16 21 21 21 21 23 23 23 23 25 25 25 25 27 27 27 27 29 29 29 29
|
||||
|
||||
Reference in New Issue
Block a user