JS inline refactor: splitted Renaming.kt
This commit is contained in:
committed by
Zalim Bashorov
parent
17a78dd522
commit
6018b103cc
+8
-68
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.k2js.inline
|
||||
package org.jetbrains.k2js.inline.util
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.*
|
||||
import com.google.dart.compiler.backend.js.ast.JsVars.JsVar
|
||||
@@ -25,9 +25,11 @@ import java.util.HashMap
|
||||
import java.util.IdentityHashMap
|
||||
|
||||
import kotlin.test.assertTrue
|
||||
import org.jetbrains.k2js.inline.context.NamingContext
|
||||
import org.jetbrains.k2js.inline.util.needToAlias
|
||||
|
||||
fun aliasArgumentsIfNeeded(
|
||||
context: RenamingContext<*>,
|
||||
public fun aliasArgumentsIfNeeded(
|
||||
context: NamingContext,
|
||||
arguments: List<JsExpression>,
|
||||
parameters: List<JsParameter>
|
||||
) {
|
||||
@@ -60,74 +62,12 @@ fun aliasArgumentsIfNeeded(
|
||||
/**
|
||||
* Makes function local names fresh in context
|
||||
*/
|
||||
fun renameLocalNames(
|
||||
context: RenamingContext<*>,
|
||||
public fun renameLocalNames(
|
||||
context: NamingContext,
|
||||
function: JsFunction
|
||||
) {
|
||||
for (name in collectLocalNames(function)) {
|
||||
val freshName = context.getFreshName(name)
|
||||
context.replaceName(name, freshName.makeRef())
|
||||
}
|
||||
}
|
||||
|
||||
private fun isLambdaConstructor(x: JsInvocation): Boolean {
|
||||
val staticRef = (x.getQualifier() as? HasName)?.getName()?.getStaticRef()
|
||||
return when (staticRef) {
|
||||
is JsFunction -> isLambdaConstructor(staticRef)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
private fun isLambdaConstructor(x: JsFunction): Boolean {
|
||||
return InvocationUtil.getInnerFunction(x) != null;
|
||||
}
|
||||
|
||||
private fun needToAlias(x: JsExpression): Boolean {
|
||||
val visitor = ShouldBeAliasedVisitor()
|
||||
visitor.accept(x)
|
||||
return visitor.shouldBeAliased
|
||||
}
|
||||
|
||||
private class ShouldBeAliasedVisitor(): RecursiveJsVisitor() {
|
||||
public var shouldBeAliased: Boolean = false
|
||||
private set
|
||||
|
||||
override fun visitElement(node: JsNode?) {
|
||||
if (!shouldBeAliased) {
|
||||
super<RecursiveJsVisitor>.visitElement(node)
|
||||
}
|
||||
}
|
||||
override fun visitBinaryExpression(x: JsBinaryOperation?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
|
||||
override fun visitInvocation(invocation: JsInvocation?) {
|
||||
if (invocation != null && !isLambdaConstructor(invocation)) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPostfixOperation(x: JsPostfixOperation?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
|
||||
override fun visitPrefixOperation(x: JsPrefixOperation?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
|
||||
override fun visitObjectLiteral(x: JsObjectLiteral?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
|
||||
override fun visitNew(x: JsNew?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
|
||||
override fun visitThis(x: JsLiteral.JsThisRef?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
|
||||
override fun visitArray(x: JsArrayLiteral?) {
|
||||
shouldBeAliased = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,48 +16,69 @@
|
||||
|
||||
package org.jetbrains.k2js.inline.util
|
||||
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||
import com.google.dart.compiler.backend.js.ast.RecursiveJsVisitor
|
||||
import com.google.dart.compiler.backend.js.ast.JsNode
|
||||
import com.google.dart.compiler.backend.js.ast.JsArrayAccess
|
||||
import com.google.dart.compiler.backend.js.ast.JsArrayLiteral
|
||||
import com.google.dart.compiler.backend.js.ast.JsBinaryOperation
|
||||
import com.google.dart.compiler.backend.js.ast.JsConditional
|
||||
import com.google.dart.compiler.backend.js.ast.JsExpression
|
||||
import com.google.dart.compiler.backend.js.ast.JsInvocation
|
||||
import com.google.dart.compiler.backend.js.ast.JsLiteral
|
||||
import com.google.dart.compiler.backend.js.ast.JsLiteral.JsThisRef
|
||||
import com.google.dart.compiler.backend.js.ast.JsLiteral.JsValueLiteral
|
||||
import com.google.dart.compiler.backend.js.ast.JsNameRef
|
||||
import com.google.dart.compiler.backend.js.ast.JsNew
|
||||
import com.google.dart.compiler.backend.js.ast.JsNode
|
||||
import com.google.dart.compiler.backend.js.ast.JsObjectLiteral
|
||||
import com.google.dart.compiler.backend.js.ast.JsPostfixOperation
|
||||
import com.google.dart.compiler.backend.js.ast.JsPrefixOperation
|
||||
import com.google.dart.compiler.backend.js.ast.JsNew
|
||||
import com.google.dart.compiler.backend.js.ast.JsInvocation
|
||||
import com.google.dart.compiler.backend.js.ast.RecursiveJsVisitor
|
||||
|
||||
public fun canHaveSideEffect(expression: JsExpression): Boolean {
|
||||
val visitor = SideEffectExpessionVisitor()
|
||||
visitor.accept(expression)
|
||||
return visitor.canHaveSideEffect
|
||||
public fun canHaveSideEffect(x: JsExpression): Boolean {
|
||||
return with(SideEffectVisitor()) {
|
||||
accept(x)
|
||||
!sideEffectFree
|
||||
}
|
||||
}
|
||||
|
||||
private class SideEffectExpessionVisitor() : RecursiveJsVisitor() {
|
||||
public var canHaveSideEffect: Boolean = false
|
||||
private set
|
||||
public fun needToAlias(x: JsExpression): Boolean {
|
||||
return with(NeedToAliasVisitor()) {
|
||||
accept(x)
|
||||
!sideEffectFree
|
||||
}
|
||||
}
|
||||
|
||||
private open class SideEffectVisitor() : RecursiveJsVisitor() {
|
||||
public var sideEffectFree: Boolean = true
|
||||
protected set
|
||||
|
||||
override fun visitElement(node: JsNode?) {
|
||||
if (!canHaveSideEffect) {
|
||||
super<RecursiveJsVisitor>.visitElement(node)
|
||||
sideEffectFree = sideEffectFree && isSideEffectFree(node)
|
||||
|
||||
if (sideEffectFree) {
|
||||
super.visitElement(node)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitBinaryExpression(x: JsBinaryOperation?) {
|
||||
canHaveSideEffect = true
|
||||
}
|
||||
protected open fun isSideEffectFree(node: JsNode?): Boolean =
|
||||
when (node) {
|
||||
is JsValueLiteral,
|
||||
is JsConditional,
|
||||
is JsBinaryOperation,
|
||||
is JsArrayAccess,
|
||||
is JsArrayLiteral,
|
||||
is JsNameRef -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitPostfixOperation(x: JsPostfixOperation?) {
|
||||
canHaveSideEffect = true
|
||||
}
|
||||
|
||||
override fun visitPrefixOperation(x: JsPrefixOperation?) {
|
||||
canHaveSideEffect = true
|
||||
}
|
||||
|
||||
override fun visitNew(x: JsNew?) {
|
||||
canHaveSideEffect = true
|
||||
}
|
||||
|
||||
override fun visitInvocation(invocation: JsInvocation?) {
|
||||
canHaveSideEffect = true
|
||||
}
|
||||
private class NeedToAliasVisitor() : SideEffectVisitor() {
|
||||
override fun isSideEffectFree(node: JsNode?): Boolean =
|
||||
when (node) {
|
||||
is JsThisRef,
|
||||
is JsConditional,
|
||||
is JsBinaryOperation,
|
||||
is JsArrayLiteral -> false
|
||||
is JsInvocation -> isFunctionCreatorInvocation(node)
|
||||
else -> super.isSideEffectFree(node)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user