Implement inlining of default parameters in JS BE
Fix KT-17910
This commit is contained in:
+21
-7
@@ -18,18 +18,16 @@ package org.jetbrains.kotlin.js.inline.clean
|
||||
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.hasDefaultValue
|
||||
|
||||
import org.jetbrains.kotlin.js.inline.util.toIdentitySet
|
||||
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
|
||||
import org.jetbrains.kotlin.js.inline.util.zipWithDefault
|
||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.decomposeAssignmentToVariable
|
||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.flattenStatement
|
||||
|
||||
/**
|
||||
* Removes initializers for default parameters with defined arguments given
|
||||
* Expands initializers for default parameters with undefined arguments given
|
||||
*
|
||||
* @see isInitializer
|
||||
*/
|
||||
fun removeDefaultInitializers(arguments: List<JsExpression>, parameters: List<JsParameter>, body: JsBlock) {
|
||||
val toRemove = getDefaultParamsNames(arguments, parameters, initialized = true)
|
||||
@@ -45,8 +43,11 @@ fun removeDefaultInitializers(arguments: List<JsExpression>, parameters: List<Js
|
||||
when {
|
||||
name != null && name in toRemove ->
|
||||
listOf<JsStatement>()
|
||||
name != null && name in toExpand ->
|
||||
flattenStatement((it as JsIf).thenStatement)
|
||||
name != null && name in toExpand -> {
|
||||
val thenStatement = (it as JsIf).thenStatement
|
||||
markAssignmentAsStaticRef(name, thenStatement)
|
||||
flattenStatement(thenStatement)
|
||||
}
|
||||
else ->
|
||||
listOf(it)
|
||||
}
|
||||
@@ -56,6 +57,19 @@ fun removeDefaultInitializers(arguments: List<JsExpression>, parameters: List<Js
|
||||
statements.addAll(newStatements)
|
||||
}
|
||||
|
||||
private fun markAssignmentAsStaticRef(name: JsName, node: JsNode) {
|
||||
node.accept(object : RecursiveJsVisitor() {
|
||||
override fun visitBinaryExpression(x: JsBinaryOperation) {
|
||||
decomposeAssignmentToVariable(x)?.let { (assignmentTarget, assignmentExpr) ->
|
||||
if (assignmentTarget == name) {
|
||||
assignmentTarget.staticRef = assignmentExpr
|
||||
}
|
||||
}
|
||||
super.visitBinaryExpression(x)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun getNameFromInitializer(statement: JsStatement): JsName? {
|
||||
val ifStmt = (statement as? JsIf)
|
||||
val testExpr = ifStmt?.ifExpression
|
||||
@@ -118,6 +132,6 @@ private fun getDefaultParamsNames(
|
||||
.filter { initialized == !JsAstUtils.isUndefinedExpression(it.first) }
|
||||
|
||||
val names = relevantParams.map { it.second.name }
|
||||
return names.toIdentitySet()
|
||||
return names.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ fun aliasArgumentsIfNeeded(
|
||||
for (defaultParam in defaultParams) {
|
||||
val paramName = defaultParam.name
|
||||
val freshName = JsScope.declareTemporaryName(paramName.ident)
|
||||
freshName.copyMetadataFrom(paramName)
|
||||
context.newVar(freshName)
|
||||
|
||||
context.replaceName(paramName, freshName.makeRef())
|
||||
|
||||
Reference in New Issue
Block a user