I might be able to make that work with interfaces (although I then run into the complication of such interfaces not supporting implemented methods, which I would have to work around by using extension functions, which are their own hassle when interfacing with Javascript code because Javascript doesn't support extensions and Kotlin doesn't modify class prototypes automatically) but I don't think that technique can be made to work with open classes. Example:
open class BaseArgless {
open fun soMuchFun() {}
}
class SubArgless: BaseArgless() {
override fun soMuchFun() {}
}
open class BaseArgful {
open fun noFun(erpret: Int) {}
}
class SubArgful: BaseArgful() {
override fun noFun(erpret: Int) {}
}
The output of the above is:
(function (Kotlin) {
'use strict';
var _ = Kotlin.defineRootPackage(null, /** @lends _ */ {
BaseArgless: Kotlin.createClass(null, null, /** @lends _.BaseArgless.prototype */ {
soMuchFun: function () {
}
}),
SubArgless: Kotlin.createClass(function () {
return [_.BaseArgless];
}, function $fun() {
$fun.baseInitializer.call(this);
}, /** @lends _.SubArgless.prototype */ {
soMuchFun: function () {
}
}),
BaseArgful: Kotlin.createClass(null, null, /** @lends _.BaseArgful.prototype */ {
noFun_za3lpa$: function (erpret) {
}
}),
SubArgful: Kotlin.createClass(function () {
return [_.BaseArgful];
}, function $fun() {
$fun.baseInitializer.call(this);
}, /** @lends _.SubArgful.prototype */ {
noFun_za3lpa$: function (erpret) {
}
})
});
Kotlin.defineModule('kotlin-js-name-mangling', _);
}(Kotlin));
Notice how the function `noFun(Int)` is renamed to support possible overloading even though I'm not actually overloading it. It's alright when an entire project is written in Kotlin but my use case is to write a library that can be used by web and Node projects that aren't written in pure Kotlin. If I declare the base classes to be native then the generated subclasses don't change - they keep their references to the identifiers of the missing superclasses - thus yielding code that will not execute. The best solution I've found so far is to write the following workaround:
(function() {
'use strict'
var baseCreateClass = Kotlin.createClass
Kotlin.createClass = function(/varargs/) {
var base = baseCreateClass.apply(this, arguments)
var wrapper = function(/varargs/) {
var result = base.apply(this, arguments)
Object.keys(result.prototype).forEach(function(key) {
var groups = /(w*)_(w*$)/.exec(key)
if(groups)
result.prototype[groups[1]] = result.prototype[key]
})
return result
}
wrapper.type = base.type
Object.defineProperty(wrapper, ‘className’, {set: function(a) { base.className = a }})
return wrapper
}
})();
With that workaround, the output of my code can be used the way you would expect from Javascript. It won’t work when you overload an open function but no one expects an overloaded function written in Kotlin to interface cleanly with Javascript because Javascript only does parametric polymorphism. What I do expect is for a function that isn’t overloaded to interface cleanly. Obviously Kotlin can only be developed so fast but given enough time, it doesn’t make much sense to me that I seem to have to defeat one of your “features” in order to write a reasonable Javascript library in a language that targets Javascript.