So I tried to compile the Carballo Kotlin code to JS (as a NodeJS app) in the “js” branch: https://github.com/albertoruibal/karballo/tree/js, and I couldn’t make it work yet. I found some problems that I will detail in this post.
GWT includes a reduced version of the JRE, without some classes and methods, but Kotlin is much more radical: To compile a Kotlin code to JS, it cannot reference any java.* class, so forget about java.lang.*, java.util.* or java.io.*.
No basic java types
Integer, Character, Boolean… are a Java classes and they cannot be used, so a lot of common operations must be done the “Kotlin way”, i.e.:
Integer.parseInt(myString) -> myString.toInt() Character.toLowerCase(myChar) -> myChar.toLowerCase() Integer.MAX_VALUE -> Int.MAX_VALUE
Emulating Java classes: System, Math, Random, Arrays, Date
These classes are not available when building to JS. To avoid changing the original code and migrate seamless from JVM to JS, I created auxiliar classes with the methods used in the code:
- System: I implemented currentTimeMillis() (calling the JS Date object), exit(), arraycopy(), and an empty gc()
- Math: When building for JS, the java.lang.Math class must be replaced by kotlin.js.Math, using this class avoids to change a lot of code
- Random: Using kotlin.js.Math.random()
- Arrays: Implementing some variants of the fill() method
- Date: partial implementation to get the current date
- IntelliJ does not allow to mix the Java and the JS Kotlin stdlib in the same project, so I hat to create a different branch “js”
- No Threads nor Coroutines support in JS jet
- Kotlin’s readLine() (to read lines from stdin) is only available in the JVM stdlib
- String.toBoolean() is only available in the JVM stdlib, I fixed it defining a extension function in the same package:
inline fun String.toBoolean(): Boolean = "true".equals(this.toLowerCase())
- No support for asserts in the JS compiler
- Some annotations aren’t available @JvmOverloads, @Throws…
- No LinkedList
- No StringBuffer, but in this case it’s better to use Kotlin’s StringBuilder
- Missing StringBuilder.setLength() method (I sent a pull request to Kotlin implementing setLength() and substring())
- It does not allow returns into synchronized blocks
- No printStackTrace() on exceptions
- No JUnit tests in JS, so I removed the tests in the “js” branch
After solving all these problems, the Kotlin2JS compiler is introducing bugs that don’t allow the karballo engine to work.
Kotlin2JS isn’t production ready, and years behind GWT.