JS: decomposition of ternary operator
This commit is contained in:
@@ -97,6 +97,35 @@ class ExpressionDecomposer private (
|
|||||||
index = accept(index)
|
index = accept(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visit(x: JsConditional, ctx: JsContext<*>): Boolean {
|
||||||
|
x.process(ctx)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun JsConditional.process(ctx: JsContext<*>) {
|
||||||
|
test = accept(test)
|
||||||
|
if (then !in containsExtractable && otherwise !in containsExtractable) return
|
||||||
|
|
||||||
|
val tmp = Temporary()
|
||||||
|
addStatement(tmp.variable)
|
||||||
|
|
||||||
|
val thenBlock = withNewAdditionalStatements {
|
||||||
|
then = accept(then)
|
||||||
|
addStatement(tmp.assign(then))
|
||||||
|
additionalStatements.toStatement()
|
||||||
|
}
|
||||||
|
|
||||||
|
val elseBlock = withNewAdditionalStatements {
|
||||||
|
otherwise = accept(otherwise)
|
||||||
|
addStatement(tmp.assign(otherwise))
|
||||||
|
additionalStatements.toStatement()
|
||||||
|
}
|
||||||
|
|
||||||
|
val lazyEval = JsIf(test, thenBlock, elseBlock)
|
||||||
|
addStatement(lazyEval)
|
||||||
|
ctx.replaceMe(tmp.nameRef)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visit(x: JsInvocation, ctx: JsContext<*>): Boolean {
|
override fun visit(x: JsInvocation, ctx: JsContext<*>): Boolean {
|
||||||
CallableInvocationAdapter(x).process()
|
CallableInvocationAdapter(x).process()
|
||||||
return false
|
return false
|
||||||
@@ -153,9 +182,21 @@ class ExpressionDecomposer private (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
private fun withNewAdditionalStatements<T>(fn: ()->T): T {
|
||||||
|
val backup = additionalStatements
|
||||||
|
additionalStatements = SmartList<JsStatement>()
|
||||||
|
val result = fn()
|
||||||
|
additionalStatements = backup
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
private fun addStatement(statement: JsStatement) =
|
private fun addStatement(statement: JsStatement) =
|
||||||
additionalStatements.add(statement)
|
additionalStatements.add(statement)
|
||||||
|
|
||||||
|
private fun addStatements(statements: List<JsStatement>) =
|
||||||
|
additionalStatements.addAll(statements)
|
||||||
|
|
||||||
private fun JsExpression.extractToTemporary(): JsExpression {
|
private fun JsExpression.extractToTemporary(): JsExpression {
|
||||||
val tmp = Temporary(this)
|
val tmp = Temporary(this)
|
||||||
addStatement(tmp.variable)
|
addStatement(tmp.variable)
|
||||||
@@ -294,3 +335,10 @@ private fun JsNode.withParentsOfNodes(nodes: Set<JsNode>): Set<JsNode> {
|
|||||||
visitor.accept(this)
|
visitor.accept(this)
|
||||||
return visitor.matched
|
return visitor.matched
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun List<JsStatement>.toStatement(): JsStatement =
|
||||||
|
when (size()) {
|
||||||
|
0 -> JsEmpty
|
||||||
|
1 -> get(0)
|
||||||
|
else -> JsBlock(this)
|
||||||
|
}
|
||||||
|
|||||||
@@ -63,3 +63,15 @@ public var JsArrayAccess.index: JsExpression
|
|||||||
public var JsArrayAccess.array: JsExpression
|
public var JsArrayAccess.array: JsExpression
|
||||||
get() = getArrayExpression()
|
get() = getArrayExpression()
|
||||||
set(value) = setArrayExpression(value)
|
set(value) = setArrayExpression(value)
|
||||||
|
|
||||||
|
public var JsConditional.test: JsExpression
|
||||||
|
get() = getTestExpression()
|
||||||
|
set(value) = setTestExpression(value)
|
||||||
|
|
||||||
|
public var JsConditional.then: JsExpression
|
||||||
|
get() = getThenExpression()
|
||||||
|
set(value) = setThenExpression(value)
|
||||||
|
|
||||||
|
public var JsConditional.otherwise: JsExpression
|
||||||
|
get() = getElseExpression()
|
||||||
|
set(value) = setElseExpression(value)
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun test(x: Boolean): Boolean =
|
||||||
|
if (fizz(x)) buzz(true) else buzz(false)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(true, test(true))
|
||||||
|
assertEquals("fizz(true);buzz(true);", pullLog())
|
||||||
|
assertEquals(false, test(false))
|
||||||
|
assertEquals("fizz(false);buzz(false);", pullLog())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun test(x: Boolean?): Boolean = fizz(x) ?: buzz(true)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(true, test(null))
|
||||||
|
assertEquals("fizz(null);buzz(true);", pullLog())
|
||||||
|
assertEquals(false, test(false))
|
||||||
|
assertEquals("fizz(false);", pullLog())
|
||||||
|
assertEquals(true, test(true))
|
||||||
|
assertEquals("fizz(true);", pullLog())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun test(x: Boolean, y: Boolean): Int =
|
||||||
|
if (fizz(x))
|
||||||
|
if (fizz(y)) buzz(1) else buzz(2)
|
||||||
|
else
|
||||||
|
if (fizz(y)) buzz(3) else buzz(4)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(1, test(true, true))
|
||||||
|
assertEquals("fizz(true);fizz(true);buzz(1);", pullLog())
|
||||||
|
|
||||||
|
assertEquals(2, test(true, false))
|
||||||
|
assertEquals("fizz(true);fizz(false);buzz(2);", pullLog())
|
||||||
|
|
||||||
|
assertEquals(3, test(false, true))
|
||||||
|
assertEquals("fizz(false);fizz(true);buzz(3);", pullLog())
|
||||||
|
|
||||||
|
assertEquals(4, test(false, false))
|
||||||
|
assertEquals("fizz(false);fizz(false);buzz(4);", pullLog())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun test(x: Boolean): Boolean =
|
||||||
|
if (buzz(x)) buzz(true) else fizz(false)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(true, test(true))
|
||||||
|
assertEquals("buzz(true);buzz(true);", pullLog())
|
||||||
|
assertEquals(false, test(false))
|
||||||
|
assertEquals("buzz(false);fizz(false);", pullLog())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package foo
|
||||||
|
|
||||||
|
fun test(x: Boolean?): Boolean = buzz(x) ?: fizz(true)
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(true, test(null))
|
||||||
|
assertEquals("buzz(null);fizz(true);", pullLog())
|
||||||
|
assertEquals(false, test(false))
|
||||||
|
assertEquals("buzz(false);", pullLog())
|
||||||
|
assertEquals(true, test(true))
|
||||||
|
assertEquals("buzz(true);", pullLog())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user