There's no native
keyword anymore, there's @native
annotation. Currently, it's working solution and you can use it with 1.0.x branch of Kotlin compiler. However, we are going do deprecate this annotation in favour of extern
annotations, so be prepared to rewrite your code eventually for 1.1.x branch.
When you put @native
annotation on a class or on a top-level function, two things happen:
- Its body is not compiled to JavaScript.
- Compiler references this class or function directly, without package name and mangling.
I think it's easier to explain by providing example of a JavaScript library:
function A(x) {
this.x = x;
this.y = 0;
}
A.prototype.foo = function(z) {
return this.x + this.y + z;
}
function min(a, b) {
return a < b ? a : b;
}
and a corresponding Kotlin declaration
@native class A(val x: Int) {
var y: Int = noImpl
fun foo(z: Int): Int = noImpl
}
@native fun min(a: Int, b: Int): Int = noImpl
Note that noImpl
is a special placeholder that's required because of non-abstract functions required bodies and non-abstract properties require initializers. BTW, when we replace @native
with extern
, we'll get rid of this noImpl
.
Another aspect of interoperation with JS libraries is including libraries via module system. Sorry, we don't have any solution right now (but are going to release it soon). See proposal. You can use the following workaround for node.js/CommonJS:
@native interface ExternalModule {
fun foo(x: Int)
}
@native fun require(name: String): dynamic = noImpl
fun main(args: Array<String>) {
val module: ExternalModule = require("externalModule")
module.foo(123)
}
where external module is declared like this
function foo(x) {
return x + 1;
}
module.exports = { foo : foo };