JS/Inlining: refactor TemporaryVariableElimination
This commit is contained in:
+19
-28
@@ -22,6 +22,7 @@ import com.google.dart.compiler.backend.js.ast.metadata.synthetic
|
|||||||
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
|
import org.jetbrains.kotlin.js.inline.util.collectFreeVariables
|
||||||
import org.jetbrains.kotlin.js.inline.util.collectLocalVariables
|
import org.jetbrains.kotlin.js.inline.util.collectLocalVariables
|
||||||
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
|
||||||
|
import org.jetbrains.kotlin.js.translate.utils.splitToRanges
|
||||||
|
|
||||||
internal class TemporaryVariableElimination(function: JsFunction) {
|
internal class TemporaryVariableElimination(function: JsFunction) {
|
||||||
private val root = function.body
|
private val root = function.body
|
||||||
@@ -440,38 +441,28 @@ internal class TemporaryVariableElimination(function: JsFunction) {
|
|||||||
private fun cleanUp() {
|
private fun cleanUp() {
|
||||||
object : JsVisitorWithContextImpl() {
|
object : JsVisitorWithContextImpl() {
|
||||||
override fun visit(x: JsVars, ctx: JsContext<JsNode>): Boolean {
|
override fun visit(x: JsVars, ctx: JsContext<JsNode>): Boolean {
|
||||||
x.vars.removeAll(statementsToRemove)
|
if (x.vars.removeAll(statementsToRemove)) {
|
||||||
|
hasChanges = true
|
||||||
|
}
|
||||||
|
|
||||||
var lastDroppedIndex = 0
|
val ranges = x.vars.splitToRanges { it.name in variablesToRemove }
|
||||||
for ((index, v) in x.vars.toList().withIndex()) {
|
if (ranges.size == 1 && !ranges[0].second) return super.visit(x, ctx)
|
||||||
val name = v.name
|
|
||||||
if (name in variablesToRemove) {
|
hasChanges = true
|
||||||
hasChanges = true
|
for ((subList, isRemoved) in ranges) {
|
||||||
if (index > lastDroppedIndex) {
|
val initializers = subList.mapNotNull { it.initExpression }
|
||||||
val droppedVars = JsVars(*x.vars.subList(lastDroppedIndex, index).toTypedArray())
|
initializers.forEach { accept(it) }
|
||||||
droppedVars.synthetic = x.synthetic
|
if (isRemoved) {
|
||||||
ctx.addPrevious(droppedVars)
|
for (initializer in initializers) {
|
||||||
|
ctx.addPrevious(JsExpressionStatement(initializer).apply { synthetic = x.synthetic })
|
||||||
}
|
}
|
||||||
val initExpression = v.initExpression
|
}
|
||||||
if (initExpression != null) {
|
else {
|
||||||
ctx.addPrevious(JsExpressionStatement(initExpression).run {
|
ctx.addPrevious(JsVars(*subList.toTypedArray()).apply { synthetic = x.synthetic })
|
||||||
synthetic = true
|
|
||||||
accept(this)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
lastDroppedIndex = index + 1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lastDroppedIndex > 0) {
|
ctx.removeMe()
|
||||||
x.vars.subList(0, lastDroppedIndex).clear()
|
return false
|
||||||
}
|
|
||||||
|
|
||||||
if (x.vars.isEmpty()) {
|
|
||||||
ctx.removeMe()
|
|
||||||
hasChanges = true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return super.visit(x, ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(x: JsExpressionStatement, ctx: JsContext<JsNode>): Boolean {
|
override fun visit(x: JsExpressionStatement, ctx: JsContext<JsNode>): Boolean {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.js.translate.utils
|
package org.jetbrains.kotlin.js.translate.utils
|
||||||
|
|
||||||
import com.google.dart.compiler.backend.js.ast.*
|
import com.google.dart.compiler.backend.js.ast.*
|
||||||
|
import com.google.dart.compiler.backend.js.ast.metadata.synthetic
|
||||||
import com.intellij.util.SmartList
|
import com.intellij.util.SmartList
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.js.translate.context.Namer
|
import org.jetbrains.kotlin.js.translate.context.Namer
|
||||||
@@ -55,3 +56,23 @@ fun generateDelegateCall(
|
|||||||
functionObject.parameters.addAll(parameters)
|
functionObject.parameters.addAll(parameters)
|
||||||
return JsPropertyInitializer(delegateMemberFunctionName.makeRef(), functionObject)
|
return JsPropertyInitializer(delegateMemberFunctionName.makeRef(), functionObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T, S> List<T>.splitToRanges(classifier: (T) -> S): List<Pair<List<T>, S>> {
|
||||||
|
if (isEmpty()) return emptyList()
|
||||||
|
|
||||||
|
var lastIndex = 0
|
||||||
|
var lastClass: S = classifier(this[0])
|
||||||
|
val result = mutableListOf<Pair<List<T>, S>>()
|
||||||
|
|
||||||
|
for ((index, e) in asSequence().withIndex().drop(1)) {
|
||||||
|
val cls = classifier(e)
|
||||||
|
if (cls != lastClass) {
|
||||||
|
result += Pair(subList(lastIndex, index), lastClass)
|
||||||
|
lastClass = cls
|
||||||
|
lastIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result += Pair(subList(lastIndex, size), lastClass)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user