Provide the ways to interact with native JavaScript.
TODO
Calls to functions annotated by nativeInvoke
will be translated to calls of receiver with the arguments provided for original call.
Applicable to:
- member functions of native declarations
- non-member extension functions
Example:
native
class A {
nativeInvoke
fun invoke(): String = noImpl
nativeInvoke
fun foo(a: Int): Int = noImpl
}
fun A.bar(a: String): Int = noImpl
fun test(baz: A) {
baz()
baz.invoke()
baz.foo(1)
baz.bar("str")
}
Function test
will be translated to:
...
test: function (baz) {
foo()
foo()
foo(1)
foo("str")
}
...
Calls to functions annotated by nativeGetter
will be translated to square/index operation on the receiver with the argument provided for original call.
Applicable to:
- member functions of native declarations
- non-member extension functions
Requirements:
- must have exactly one argument
- type of the argument must be
String
or subtype ofNumber
- default values are prohibited
- return type must be nullable
Example:
native
class A {
nativeGetter
fun get(a: String): String? = noImpl
nativeGetter
fun foo(a: Int): Int? = noImpl
}
class B
nativeGetter
fun B.get(a: String): Int? = noImpl
nativeGetter
fun B.bar(a: Int): Int? = noImpl
fun test(a: A, b: B) {
a["foo"]
a.get("bar")
a.foo(1)
b["foo"]
b.get("bar")
b.bar(1)
}
Function test
will be translated to:
...
test: function (a, b) {
a["foo"]
a["bar"]
a[1]
b["foo"]
b["bar"]
b[1]
}
...
Calls of functions annotated by nativeSetter
will be translated to assignment of the second argument to the receiver
indexed (with square/index operation) with the first argument.
Applicable to:
- member functions of native declarations
- non-member extension functions
Requirements:
- must have exactly two arguments
- type of the first argument must be
String
or subtype ofNumber
- default values are prohibited
- the return type is either
Unit
or a supertype of the second parameter's type
Example:
native
class A {
nativeSetter
fun set(a: String, v: Any) {}
nativeSetter
fun foo(a: Int, v: A) {}
}
class B
nativeSetter
fun B.set(a: String, v: B) {}
nativeSetter
fun B.bar(a: String, v: B?) {}
fun test(a: A, b: B) {
a["foo"] = "text"
a.set("bar", "value")
a.foo(1, A())
b["foo"] = B()
b.set("bar", b)
b.bar("a", null)
}
Function test
will be translated to:
...
test: function (a, b) {
a["foo"] = "text"
a["bar"] = "value"
a[1] = A()
b["foo"] = B()
b["bar"] = b
b["a"] = null
}
...
Argument of js
function is parsed as JavaScript code and injected directly into the JavaScript code generated by the compiler.
Requirements:
- the argument should be a compile time constant of type
String
Example:
fun test1() {
js("console.log('Hello')")
}
fun test2(a: String) = js("""
var r = foo(a);
return r;
""")
is translated to:
function test1() {
console.log('Hello')
}
function test2(a) {
var r = foo(a);
return r;
}
All dynamic calls with explicit names (regular and infix function calls, and property calls) are translated "as is", without mangling.
Additionally, many operations when applied to a receiver of type dynamic
are translated "as is", instead of by convention.
Operations translated "as is" to JavaScript:
- binary:
+
,-
,*
,/
,%
,>
,<
>=
,<=
,==
,!=
,===
,!==
,&&
,||
- unary
- prefix:
-
,+
,!
- prefix and postfix:
++
,--
- assignments:
+=
,-=
,*=
,/=
,%=
- indexed access:
- read:
d[a]
, more than one argument is an error - write:
d[a1] = a2
, more than one argument in[]
is an error in
and!in
are forbidden, an error is reported
Note:
..
is translated to a call torangeTo
~
,|
,&
and^
are not supported (there's no Kotlin code that translates to these operations)