ArrayList improvements:

1) remove must compare object using Kotlin.equals (the same as in contains)
2) use ArrayIterator instead of ListIterator (perfomance)
3) remove duplicated code (refactor)
4) toArray
5) fix "add((index, item)" — correct translation to JavaScript "addAt"
This commit is contained in:
develar
2012-06-28 11:13:48 +04:00
parent 07ae3afc95
commit 77320e07f2
5 changed files with 291 additions and 376 deletions
+56 -113
View File
@@ -55,125 +55,77 @@ val Collections = object {
list[i2] = tmp list[i2] = tmp
} }
} }
} }
library library
public open class ArrayList<E>() : java.util.List<E> { public trait Collection<E>: Iterable<E> {
public override fun size() : Int = js.noImpl open fun size(): Int
public override fun isEmpty() : Boolean = js.noImpl open fun isEmpty(): Boolean
public override fun contains(o : Any?) : Boolean = js.noImpl open fun contains(o: Any?): Boolean
public override fun iterator() : Iterator<E> = js.noImpl override fun iterator(): Iterator<E>
// public override fun indexOf(o : Any?) : Int = js.noImpl fun toArray(): Array<E>
// public override fun lastIndexOf(o : Any?) : Int = js.noImpl // open fun toArray<T>(a : Array<out T>) : Array<T>
// public override fun toArray() : Array<Any?> = js.noImpl open fun add(e: E): Boolean
// public override fun toArray<T>(a : Array<out T>) : Array<T> = js.noImpl open fun remove(o: Any?): Boolean
public override fun get(index : Int) : E = js.noImpl
public override fun set(index : Int, element : E) : E = js.noImpl
public override fun add(e : E) : Boolean = js.noImpl
public override fun add(index : Int, element : E) : Unit = js.noImpl
library("removeByIndex")
public override fun remove(index : Int) : E = js.noImpl
public override fun remove(o : Any?) : Boolean = js.noImpl
public override fun clear() : Unit = js.noImpl
public override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
// public override fun addAll(index : Int, c : java.util.Collection<out E>) : Boolean = js.noImpl
}
library
public trait Collection<E> : java.lang.Iterable<E> {
open fun size() : Int
open fun isEmpty() : Boolean
open fun contains(o : Any?) : Boolean
override fun iterator() : java.util.Iterator<E>
// open fun toArray() : Array<Any?>
// open fun toArray<T>(a : Array<out T>) : Array<T>
open fun add(e : E) : Boolean
open fun remove(o : Any?) : Boolean
//open fun containsAll(c : java.util.Collection<*>) : Boolean //open fun containsAll(c : java.util.Collection<*>) : Boolean
open fun addAll(c : java.util.Collection<out E>) : Boolean open fun addAll(c: Collection<out E>): Boolean
//open fun removeAll(c : java.util.Collection<*>) : Boolean //open fun removeAll(c : java.util.Collection<*>) : Boolean
//open fun retainAll(c : java.util.Collection<*>) : Boolean //open fun retainAll(c : java.util.Collection<*>) : Boolean
open fun clear() : Unit open fun clear(): Unit
} }
library library
public abstract open class AbstractCollection<E>() : Collection<E> { public abstract class AbstractCollection<E>() : Collection<E> {
override fun toArray(): Array<E> = js.noImpl
override fun isEmpty(): Boolean = js.noImpl
override fun contains(o: Any?): Boolean = js.noImpl
override fun iterator(): Iterator<E> = js.noImpl
override fun add(e: E): Boolean = js.noImpl
override fun remove(o: Any?): Boolean = js.noImpl
override fun addAll(c: Collection<out E>): Boolean = js.noImpl
override fun clear(): Unit = js.noImpl
override fun size(): Int = js.noImpl
} }
library library
public abstract open class AbstractList<E>() : AbstractCollection<E>(), List<E> { public trait List<E>: Collection<E> {
public override fun isEmpty() : Boolean = js.noImpl fun get(index: Int): E
public override fun contains(o : Any?) : Boolean = js.noImpl fun set(index: Int, element: E): E
public override fun iterator() : Iterator<E> = js.noImpl
// public override fun indexOf(o : Any?) : Int = js.noImpl fun add(index: Int, element: E): Unit
// public override fun lastIndexOf(o : Any?) : Int = js.noImpl fun remove(index: Int): E
// public override fun toArray() : Array<Any?> = js.noImpl
// public override fun toArray<T>(a : Array<out T>) : Array<T> = js.noImpl fun indexOf(o: E?): Int
public override fun set(index : Int, element : E) : E = js.noImpl
public override fun add(e : E) : Boolean = js.noImpl
public override fun add(index : Int, element : E) : Unit = js.noImpl
library("removeByIndex")
public override fun remove(index : Int) : E = js.noImpl
public override fun remove(o : Any?) : Boolean = js.noImpl
public override fun clear() : Unit = js.noImpl
public override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
// public override fun addAll(index : Int, c : java.util.Collection<out E>) : Boolean = js.noImpl
} }
library library
public trait List<E> : Collection<E> { public abstract class AbstractList<E>(): AbstractCollection<E>(), List<E> {
override fun size() : Int override fun get(index: Int): E = js.noImpl
override fun isEmpty() : Boolean override fun set(index: Int, element: E): E = js.noImpl
override fun contains(o : Any?) : Boolean
override fun iterator() : java.util.Iterator<E> library("addAt")
// override fun toArray() : Array<Any?> override fun add(index: Int, element: E): Unit = js.noImpl
// Simulate Java's array covariance
// override fun toArray<T>(a : Array<out T>) : Array<T> library("removeAt")
override fun add(e : E) : Boolean override fun remove(index: Int): E = js.noImpl
override fun remove(o : Any?) : Boolean
// override fun containsAll(c : java.util.Collection<*>) : Boolean override fun indexOf(o: E?): Int = js.noImpl
override fun addAll(c : java.util.Collection<out E>) : Boolean }
// open fun addAll(index : Int, c : java.util.Collection<out E>) : Boolean
// override fun removeAll(c : java.util.Collection<*>) : Boolean library
// override fun retainAll(c : java.util.Collection<*>) : Boolean public open class ArrayList<E>() : AbstractList<E>() {
override fun clear() : Unit
open fun get(index : Int) : E
open fun set(index : Int, element : E) : E
open fun add(index : Int, element : E) : Unit
open fun remove(index : Int) : E
// open fun indexOf(o : Any?) : Int
// open fun lastIndexOf(o : Any?) : Int
} }
library library
public trait Set<E> : Collection<E> { public trait Set<E> : Collection<E> {
override fun size() : Int
override fun isEmpty() : Boolean
override fun contains(o : Any?) : Boolean
override fun iterator() : java.util.Iterator<E>
// override fun toArray() : Array<Any?>
// override fun toArray<T>(a : Array<out T>) : Array<T>
override fun add(e : E) : Boolean
override fun remove(o : Any?) : Boolean
//override fun containsAll(c : java.util.Collection<*>) : Boolean
override fun addAll(c : java.util.Collection<out E>) : Boolean
//override fun retainAll(c : java.util.Collection<*>) : Boolean
//override fun removeAll(c : java.util.Collection<*>) : Boolean
override fun clear() : Unit
} }
library library
public open class HashSet<E>() : java.util.Set<E> { public open class HashSet<E>(): AbstractCollection<E>(), java.util.Set<E> {
public override fun iterator() : java.util.Iterator<E> = js.noImpl
public override fun size() : Int = js.noImpl
public override fun isEmpty() : Boolean = js.noImpl
public override fun contains(o : Any?) : Boolean = js.noImpl
public override fun add(e : E) : Boolean = js.noImpl
public override fun remove(o : Any?) : Boolean = js.noImpl
public override fun clear() : Unit = js.noImpl
override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
} }
library library
@@ -220,22 +172,13 @@ public open class HashMap<K, V>() : java.util.Map<K, V> {
} }
library library
public open class LinkedList<E>() : List<E> { public open class LinkedList<E>(): AbstractList<E>() {
public override fun iterator() : java.util.Iterator<E> = js.noImpl public override fun get(index: Int): E = js.noImpl
public override fun isEmpty() : Boolean = js.noImpl public override fun set(index: Int, element: E): E = js.noImpl
public override fun contains(o : Any?) : Boolean = js.noImpl public override fun add(index: Int, element: E): Unit = js.noImpl
public override fun size() : Int = js.noImpl public fun poll(): E? = js.noImpl
public override fun add(e : E) : Boolean = js.noImpl public fun peek(): E? = js.noImpl
public override fun remove(o : Any?) : Boolean = js.noImpl public fun offer(e: E): Boolean = js.noImpl
public override fun addAll(c : java.util.Collection<out E>) : Boolean = js.noImpl
public override fun clear() : Unit = js.noImpl
public override fun get(index : Int) : E = js.noImpl
public override fun set(index : Int, element : E) : E = js.noImpl
public override fun add(index : Int, element : E) : Unit = js.noImpl
public override fun remove(index : Int) : E = js.noImpl
public fun poll() : E? = js.noImpl
public fun peek() : E? = js.noImpl
public fun offer(e : E) : Boolean = js.noImpl
} }
library library
@@ -51,6 +51,10 @@ public final class ArrayListTest extends JavaClassesTest {
fooBoxTest(); fooBoxTest();
} }
public void testToArray() throws Exception {
fooBoxTest();
}
public void testIndexOOB() throws Exception { public void testIndexOOB() throws Exception {
try { try {
fooBoxTest(); fooBoxTest();
@@ -0,0 +1,13 @@
package foo
import java.util.ArrayList
fun box() : Boolean {
var i = 0
val list = ArrayList<Int>()
while (i++ < 3) {
list.add(i)
}
val array = list.toArray()
return array[0] == 1 && array[1] == 2 && array[2] == 3
}
+155 -187
View File
@@ -28,7 +28,7 @@ var kotlin = {set:function (receiver, key, value) {
return obj1.equals(obj2); return obj1.equals(obj2);
} }
} }
return (obj1 === obj2); return obj1 === obj2;
}; };
Kotlin.modules = {}; Kotlin.modules = {};
@@ -48,117 +48,122 @@ var kotlin = {set:function (receiver, key, value) {
throw Kotlin.$new(Kotlin.Exceptions.NullPointerException)(); throw Kotlin.$new(Kotlin.Exceptions.NullPointerException)();
}; };
Kotlin.AbstractList = Kotlin.$createClass({ function throwAbstractFunctionInvocationError() {
set:function (index, value) { throw new TypeError("Function is abstract");
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)(); }
},
iterator:function () {
return Kotlin.$new(Kotlin.ArrayIterator)(this);
},
isEmpty:function () {
return (this.size() === 0);
},
add:function (element) {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
addAll:function (collection) {
var it = collection.iterator();
while (it.get_hasNext()) {
this.add(it.next());
}
},
remove:function(value) {
for (var i = 0; i < this.$size; ++i) {
if (this.array[i] == value) {
this.removeByIndex(i);
return;
}
}
},
removeByIndex:function (index) {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
clear:function () {
throw Kotlin.$new(Kotlin.Exceptions.UnsupportedOperationException)();
},
contains:function (obj) {
for (var i = 0; i < this.$size; ++i) {
if (Kotlin.equals(this.array[i], obj)) {
return true;
}
}
return false;
}
});
Kotlin.ArrayList = Kotlin.$createClass({ Kotlin.Iterator = Kotlin.$createClass({
initialize:function () { initialize: function () {
this.array = [];
this.$size = 0;
}, },
get:function (index) { next: throwAbstractFunctionInvocationError,
if ((index < 0) || (index >= this.$size)) { get_hasNext: throwAbstractFunctionInvocationError
throw Kotlin.Exceptions.IndexOutOfBounds; });
}
return (this.array)[index]; var ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
initialize: function (array) {
this.array = array;
this.size = array.length;
this.index = 0;
}, },
set:function (index, value) { next: function () {
if ((index < 0) || (index >= this.$size)) { return this.array[this.index++];
throw Kotlin.Exceptions.IndexOutOfBounds;
}
(this.array)[index] = value;
}, },
size:function () { get_hasNext: function () {
return this.$size; return this.index < this.size;
}
});
var ListIterator = Kotlin.$createClass(ArrayIterator, {
initialize: function (list) {
this.list = list;
this.size = list.size();
this.index = 0;
}, },
iterator:function () { next: function () {
return Kotlin.$new(Kotlin.ArrayIterator)(this); return this.list.get(this.index++);
}, },
isEmpty:function () { get_hasNext: function () {
return (this.$size === 0); return this.index < this.size;
}
});
Kotlin.AbstractList = Kotlin.$createClass({
iterator: function () {
return Kotlin.$new(ListIterator)(this);
}, },
add:function (element) { isEmpty: function () {
this.array[this.$size++] = element; return this.size() == 0;
}, },
addAll:function (collection) { addAll: function (collection) {
var it = collection.iterator(); var it = collection.iterator();
while (it.get_hasNext()) { while (it.get_hasNext()) {
this.add(it.next()); this.add(it.next());
} }
}, },
remove:function(value) { remove: function (o) {
for (var i = 0; i < this.$size; ++i) { var index = this.indexOf(o);
if (this.array[i] == value) { if (index != -1) {
this.removeByIndex(i); this.removeAt(index);
return;
}
} }
}, },
removeByIndex:function (index) { contains: function (o) {
for (var i = index; i < this.$size - 1; ++i) { return this.indexOf(o) != -1;
this.array[i] = this.array[i + 1];
}
this.$size--;
},
clear:function () {
this.array = [];
this.$size = 0;
},
contains:function (obj) {
for (var i = 0; i < this.$size; ++i) {
if (Kotlin.equals(this.array[i], obj)) {
return true;
}
}
return false;
} }
}); });
Kotlin.ArrayList = Kotlin.$createClass(Kotlin.AbstractList, {
initialize: function () {
this.array = [];
this.$size = 0;
},
get: function (index) {
if (index < 0 || index >= this.$size) {
throw Kotlin.Exceptions.IndexOutOfBounds;
}
return this.array[index];
},
set: function (index, value) {
if (index < 0 || index >= this.$size) {
throw Kotlin.Exceptions.IndexOutOfBounds;
}
this.array[index] = value;
},
toArray: function () {
return this.array.slice(0, this.$size);
},
size: function () {
return this.$size;
},
iterator: function () {
return Kotlin.arrayIterator(this.array);
},
add: function (element) {
this.array[this.$size++] = element;
},
addAt: function (index, element) {
this.array.splice(index, 0, element);
},
removeAt: function (index) {
this.array.splice(index, 1);
this.$size--;
},
clear: function () {
this.array.length = 0;
this.$size = 0;
},
indexOf: function (o) {
for (var i = 0, n = this.$size; i < n; ++i) {
if (Kotlin.equals(this.array[i], o)) {
return i;
}
}
return -1;
}
});
Kotlin.parseInt = function (str) { Kotlin.parseInt = function (str) {
return parseInt(str, 10); return parseInt(str, 10);
} };
;
Kotlin.safeParseInt = function(str) { Kotlin.safeParseInt = function(str) {
var r = parseInt(str, 10); var r = parseInt(str, 10);
@@ -212,51 +217,32 @@ var kotlin = {set:function (receiver, key, value) {
Kotlin.System.out().print(s); Kotlin.System.out().print(s);
}; };
Kotlin.AbstractFunctionInvocationError = Kotlin.$createClass();
Kotlin.Iterator = Kotlin.$createClass({
initialize:function () {
},
next:function () {
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
},
get_hasNext:function () {
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
}
});
Kotlin.ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
initialize: function (array) {
this.array = array;
this.index = 0;
},
next: function () {
return this.array.get(this.index++);
},
get_hasNext: function () {
return this.array.size() > this.index;
}
});
Kotlin.RangeIterator = Kotlin.$createClass(Kotlin.Iterator, { Kotlin.RangeIterator = Kotlin.$createClass(Kotlin.Iterator, {
initialize:function (start, count, reversed) { initialize: function (start, count, reversed) {
this.$start = start; this.$start = start;
this.$count = count; this.$count = count;
this.$reversed = reversed; this.$reversed = reversed;
this.$i = this.get_start(); this.$i = this.get_start();
}, get_start:function () { },
get_start: function () {
return this.$start; return this.$start;
}, get_count:function () { },
get_count: function () {
return this.$count; return this.$count;
}, set_count:function (tmp$0) { },
set_count: function (tmp$0) {
this.$count = tmp$0; this.$count = tmp$0;
}, get_reversed:function () { },
get_reversed: function () {
return this.$reversed; return this.$reversed;
}, get_i:function () { },
get_i: function () {
return this.$i; return this.$i;
}, set_i:function (tmp$0) { },
set_i: function (tmp$0) {
this.$i = tmp$0; this.$i = tmp$0;
}, next:function () { },
next: function () {
this.set_count(this.get_count() - 1); this.set_count(this.get_count() - 1);
if (this.get_reversed()) { if (this.get_reversed()) {
this.set_i(this.get_i() - 1); this.set_i(this.get_i() - 1);
@@ -272,46 +258,48 @@ var kotlin = {set:function (receiver, key, value) {
} }
}); });
Kotlin.NumberRange = Kotlin.$createClass({initialize:function (start, size, reversed) { Kotlin.NumberRange = Kotlin.$createClass({
this.$start = start; initialize: function (start, size, reversed) {
this.$size = size; this.$start = start;
this.$reversed = reversed; this.$size = size;
}, get_start:function () { this.$reversed = reversed;
return this.$start; },
}, get_size:function () { get_start: function () {
return this.$size; return this.$start;
}, get_reversed:function () { },
return this.$reversed; get_size: function () {
}, get_end:function () { return this.$size;
return this.get_reversed() ? this.get_start() - this.get_size() + 1 : this.get_start() + this.get_size() - 1; },
}, contains:function (number) { get_reversed: function () {
if (this.get_reversed()) { return this.$reversed;
return number <= this.get_start() && number > this.get_start() - this.get_size(); },
get_end: function () {
return this.get_reversed() ? this.get_start() - this.get_size() + 1 : this.get_start() + this.get_size() - 1;
},
contains: function (number) {
if (this.get_reversed()) {
return number <= this.get_start() && number > this.get_start() - this.get_size();
}
else {
return number >= this.get_start() && number < this.get_start() + this.get_size();
}
},
iterator: function () {
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_size(), this.get_reversed());
} }
else {
return number >= this.get_start() && number < this.get_start() + this.get_size();
}
}, iterator:function () {
return Kotlin.$new(Kotlin.RangeIterator)(this.get_start(), this.get_size(), this.get_reversed());
}
}); });
Kotlin.Comparator = Kotlin.$createClass( Kotlin.Comparator = Kotlin.$createClass({
{ initialize: function () {
initialize: function () { },
}, compare: throwAbstractFunctionInvocationError
compare: function (el1, el2) { });
throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)();
}
}
);
var ComparatorImpl = Kotlin.$createClass(Kotlin.Comparator, { var ComparatorImpl = Kotlin.$createClass(Kotlin.Comparator, {
initialize: function (comparator) { initialize: function (comparator) {
this.compare = comparator; this.compare = comparator;
} }
} });
);
Kotlin.comparator = function (f) { Kotlin.comparator = function (f) {
return Kotlin.$new(ComparatorImpl)(f); return Kotlin.$new(ComparatorImpl)(f);
@@ -373,25 +361,8 @@ var kotlin = {set:function (receiver, key, value) {
return Kotlin.$new(Kotlin.NumberRange)(0, arr.length); return Kotlin.$new(Kotlin.NumberRange)(0, arr.length);
}; };
var intrinsicArrayIterator = Kotlin.$createClass( Kotlin.arrayIterator = function (array) {
Kotlin.Iterator, return Kotlin.$new(ArrayIterator)(array);
{
initialize: function (arr) {
this.arr = arr;
this.len = arr.length;
this.i = 0;
},
next: function () {
return this.arr[this.i++];
},
get_hasNext: function () {
return this.i < this.len;
}
}
);
Kotlin.arrayIterator = function (arr) {
return Kotlin.$new(intrinsicArrayIterator)(arr);
}; };
Kotlin.toString = function (obj) { Kotlin.toString = function (obj) {
@@ -800,14 +771,11 @@ var kotlin = {set:function (receiver, key, value) {
Kotlin.HashTable = Hashtable; Kotlin.HashTable = Hashtable;
})(); })();
Kotlin.HashMap = Kotlin.$createClass( Kotlin.HashMap = Kotlin.$createClass({
{ initialize: function () {
initialize:function () { Kotlin.HashTable.call(this);
Kotlin.HashTable.call(this); }
} });
}
);
(function () { (function () {
function HashSet(hashingFunction, equalityFunction) { function HashSet(hashingFunction, equalityFunction) {
+63 -76
View File
@@ -20,88 +20,75 @@ var Kotlin = {};
return false; return false;
}; };
// todo compatibility for opera https://raw.github.com/gist/1000718/es5compat-gs.js // as separated function to reduce scope
function createConstructor(proto, initializer) {
return function () {
var o = Object.create(proto);
if (initializer != null) {
initializer.apply(o, arguments);
}
Object.seal(o);
return o;
};
}
function computeProto(bases, properties) {
var proto = null;
for (var i = 0, n = bases.length; i < n; i++) {
var base = bases[i];
var baseProto = base.proto;
if (baseProto == null || base.properties == null) {
continue;
}
if (!proto) {
proto = Object.create(baseProto, properties || undefined);
continue;
}
Object.defineProperties(proto, base.properties);
// todo test A -> B, C(->D) *properties from D is not yet added to proto*
}
return proto;
}
// proto must be created for class even if it is not needed (requires for is operator) // proto must be created for class even if it is not needed (requires for is operator)
Kotlin.createClass = (function () { Kotlin.createClass = function (bases, initializer, properties) {
function create(bases, initializer, properties) { var proto;
var proto; var baseInitializer = null;
var baseInitializer = null; var isTrait = initializer == null;
var isTrait = initializer == null; if (!bases) {
if (!bases) { proto = !properties && isTrait ? null : Object.create(null, properties || undefined);
proto = !properties && isTrait ? null : Object.create(null, properties || undefined); }
else if (!Array.isArray(bases)) {
baseInitializer = bases.initializer;
proto = !properties && isTrait ? bases.proto : Object.create(bases.proto, properties || undefined);
}
else {
proto = computeProto(bases, properties);
// first is superclass, other are traits
baseInitializer = bases[0].initializer;
// all bases are traits without properties
if (proto == null && !isTrait) {
proto = Object.create(null, properties || undefined);
} }
else if (!Array.isArray(bases)) {
baseInitializer = bases.initializer;
proto = !properties && isTrait ? bases.proto : Object.create(bases.proto, properties || undefined);
}
else {
proto = computeProto(bases, properties);
// first is superclass, other are traits
baseInitializer = bases[0].initializer;
// all bases are traits without properties
if (proto == null && !isTrait) {
proto = Object.create(null, properties || undefined);
}
}
var constructor = createConstructor(proto, initializer);
Object.defineProperty(constructor, "proto", {value: proto});
Object.defineProperty(constructor, "properties", {value: properties || null});
// null for trait
if (!isTrait) {
Object.defineProperty(constructor, "initializer", {value: initializer});
Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
Object.seal(initializer);
}
Object.seal(constructor);
return constructor;
} }
// as separate function to reduce scope var constructor = createConstructor(proto, initializer);
function createConstructor(proto, initializer) { Object.defineProperty(constructor, "proto", {value: proto});
return function () { Object.defineProperty(constructor, "properties", {value: properties || null});
var o = Object.create(proto); // null for trait
if (initializer != null) { if (!isTrait) {
initializer.apply(o, arguments); Object.defineProperty(constructor, "initializer", {value: initializer});
}
Object.seal(o); Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
return o; Object.freeze(initializer);
};
} }
function computeProto(bases, properties) { Object.freeze(constructor);
var proto = null; return constructor;
for (var i = 0, n = bases.length; i < n; i++) { };
var base = bases[i];
var baseProto = base.proto;
if (baseProto == null || base.properties == null) {
continue;
}
if (!proto) {
proto = Object.create(baseProto, properties || undefined);
continue;
}
// chrome bug related to getOwnPropertyDescriptor (sometimes returns undefined), so, we keep properties
//var names = Object.getOwnPropertyNames(baseProto);
//for (var j = 0, k = names.length; j < k; j++) {
// var descriptor = Object.getOwnPropertyDescriptor(baseProto, names[i]);
// Object.defineProperty(proto, names[i], descriptor);
//}
Object.defineProperties(proto, base.properties);
// todo test A -> B, C(->D) *properties from D is not yet added to proto*
}
return proto;
}
return create;
})();
Kotlin.createObject = function (initializer, properties) { Kotlin.createObject = function (initializer, properties) {
var o = Object.create(null, properties || undefined); var o = Object.create(null, properties || undefined);
@@ -128,7 +115,7 @@ var Kotlin = {};
}; };
Kotlin.$createClass = function (parent, properties) { Kotlin.$createClass = function (parent, properties) {
if (typeof (parent) != "function") { if (parent !== null && typeof (parent) != "function") {
properties = parent; properties = parent;
parent = null; parent = null;
} }