Skip to content

Commit

Permalink
Some fragilities of JS transformer fixed (+ fixed JS local testing)
Browse files Browse the repository at this point in the history
Fixes #25
  • Loading branch information
SokolovaMaria authored and elizarov committed Oct 17, 2018
1 parent 259c431 commit 633560e
Showing 1 changed file with 58 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ private const val SCOPE = "scope"
private const val FACTORY = "factory"
private const val REQUIRE = "require"
private const val KOTLINX_ATOMICFU = "'kotlinx-atomicfu'"
private const val MODULE_KOTLINX_ATOMICFU = "\$module\$kotlinx_atomicfu"

class AtomicFUTransformerJS(
inputDir: File,
Expand Down Expand Up @@ -51,9 +52,13 @@ class AtomicFUTransformerJS(
private fun isAtomicfuDependency(node: AstNode) =
(node.type == Token.STRING && node.toSource() == KOTLINX_ATOMICFU)

private fun isAtomicfuModule(node: AstNode) =
(node.type == Token.NAME && node.toSource() == MODULE_KOTLINX_ATOMICFU)

override fun visit(node: AstNode): Boolean {
when (node.type) {
Token.ARRAYLIT -> {
// erasing 'kotlinx-atomicfu' from the list of defined dependencies
val elements = (node as ArrayLiteral).elements as MutableList
val it = elements.listIterator()
while (it.hasNext()) {
Expand All @@ -63,20 +68,33 @@ class AtomicFUTransformerJS(
}
}
}
Token.FUNCTION -> {
// erasing 'kotlinx-atomicfu' module passed as parameter
if (node is FunctionNode) {
val it = node.params.listIterator()
while (it.hasNext()) {
if (isAtomicfuModule(it.next()) && !requireKotlinxAtomicfu) {
it.remove()
}
}
}
}
Token.CALL -> {
if (node is FunctionCall && node.target.toSource() == FACTORY) {
val it = node.arguments.listIterator()
while (it.hasNext()) {
val arg = it.next()
when (arg.type) {
Token.GETELEM -> {
// erasing 'kotlinx-atomicfu' dependency as factory argument
if (isAtomicfuDependency((arg as ElementGet).element)) {
it.remove()
}
}
Token.CALL -> {
if ((arg as FunctionCall).target.toSource() == REQUIRE && !requireKotlinxAtomicfu) {
if (isAtomicfuDependency(arg.arguments[0])) {
// erasing require of 'kotlinx-atomicfu' dependency
if ((arg as FunctionCall).target.toSource() == REQUIRE) {
if (isAtomicfuDependency(arg.arguments[0]) && !requireKotlinxAtomicfu) {
it.remove()
}
}
Expand All @@ -88,10 +106,30 @@ class AtomicFUTransformerJS(
Token.GETELEM -> {
if (isAtomicfuDependency((node as ElementGet).element)) {
val enclosingNode = node.parent
if (node.parent.type == Token.TYPEOF) {
// erasing the check whether 'kotlinx-atomicfu' is defined
if (enclosingNode.type == Token.TYPEOF) {
if (enclosingNode.parent.parent.type == Token.IF) {
val ifStatement = enclosingNode.parent.parent as IfStatement
ifStatement.thenPart = Block()
val falseKeyword = KeywordLiteral()
falseKeyword.type = Token.FALSE
ifStatement.condition = falseKeyword
val oneLineBlock = Block()
oneLineBlock.addStatement(EmptyLine())
ifStatement.thenPart = oneLineBlock
}
}

}
}
Token.BLOCK -> {
// erasing importsForInline for 'kotlinx-atomicfu'
for (stmt in node) {
if (stmt is ExpressionStatement) {
val expr = stmt.expression
if (expr is Assignment && expr.left is ElementGet) {
if (isAtomicfuDependency((expr.left as ElementGet).element)) {
node.replaceChild(stmt, EmptyLine())
}
}
}
}
Expand All @@ -103,12 +141,18 @@ class AtomicFUTransformerJS(

inner class AtomicConstructorDetector : NodeVisitor {
override fun visit(node: AstNode?): Boolean {
if (node is VariableInitializer && node.initializer is PropertyGet) {
if ((node.initializer as PropertyGet).property.toSource().matches(Regex(ATOMIC_CONSTRUCTOR))) {
atomicConstructors.add(node.target.toSource())
node.initializer = null
if (node is Block) {
for (stmt in node) {
if (stmt is VariableDeclaration) {
val varInit = stmt.variables[0] as VariableInitializer
if (varInit.initializer is PropertyGet) {
if ((varInit.initializer as PropertyGet).property.toSource().matches(Regex(ATOMIC_CONSTRUCTOR))) {
atomicConstructors.add(varInit.target.toSource())
node.replaceChild(stmt, EmptyLine())
}
}
}
}
return false
}
return true
}
Expand Down Expand Up @@ -362,14 +406,18 @@ private class FunctionNodeDerived(val fn: FunctionNode) : FunctionNode() {
}
}

private class EmptyLine: EmptyExpression() {
override fun toSource(depth: Int) = "\n"
}

fun main(args: Array<String>) {
if (args.size !in 1..3) {
println("Usage: AtomicFUTransformerKt <dir> [<output>]")
return
}
val t = AtomicFUTransformerJS(File(args[0]), File(args[1]))
if (args.size > 2) {
t.requireKotlinxAtomicfu = true
t.requireKotlinxAtomicfu = args[2].toBoolean()
}
t.transform()
}

0 comments on commit 633560e

Please sign in to comment.