From 77320e07f21d057751681e45ea935b61ce28a365 Mon Sep 17 00:00:00 2001 From: develar Date: Thu, 28 Jun 2012 11:13:48 +0400 Subject: [PATCH] ArrayList improvements: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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" --- js/js.libraries/src/core/javautil.kt | 169 +++------ .../k2js/test/semantics/ArrayListTest.java | 4 + .../testFiles/java/arrayList/cases/toArray.kt | 13 + js/js.translator/testFiles/kotlin_lib.js | 342 ++++++++---------- .../testFiles/kotlin_lib_ecma5.js | 139 ++++--- 5 files changed, 291 insertions(+), 376 deletions(-) create mode 100644 js/js.translator/testFiles/java/arrayList/cases/toArray.kt diff --git a/js/js.libraries/src/core/javautil.kt b/js/js.libraries/src/core/javautil.kt index 9633f527eb8..9a64ea25e65 100644 --- a/js/js.libraries/src/core/javautil.kt +++ b/js/js.libraries/src/core/javautil.kt @@ -55,125 +55,77 @@ val Collections = object { list[i2] = tmp } } - - } library -public open class ArrayList() : java.util.List { - 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 iterator() : Iterator = js.noImpl - // public override fun indexOf(o : Any?) : Int = js.noImpl - // public override fun lastIndexOf(o : Any?) : Int = js.noImpl - // public override fun toArray() : Array = js.noImpl - // public override fun toArray(a : Array) : Array = 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(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) : Boolean = js.noImpl - // public override fun addAll(index : Int, c : java.util.Collection) : Boolean = js.noImpl -} - -library -public trait Collection : java.lang.Iterable { - open fun size() : Int - open fun isEmpty() : Boolean - open fun contains(o : Any?) : Boolean - override fun iterator() : java.util.Iterator - // open fun toArray() : Array - // open fun toArray(a : Array) : Array - open fun add(e : E) : Boolean - open fun remove(o : Any?) : Boolean +public trait Collection: Iterable { + open fun size(): Int + open fun isEmpty(): Boolean + open fun contains(o: Any?): Boolean + override fun iterator(): Iterator + fun toArray(): Array + // open fun toArray(a : Array) : Array + open fun add(e: E): Boolean + open fun remove(o: Any?): Boolean //open fun containsAll(c : java.util.Collection<*>) : Boolean - open fun addAll(c : java.util.Collection) : Boolean + open fun addAll(c: Collection): Boolean //open fun removeAll(c : java.util.Collection<*>) : Boolean //open fun retainAll(c : java.util.Collection<*>) : Boolean - open fun clear() : Unit + open fun clear(): Unit } library -public abstract open class AbstractCollection() : Collection { +public abstract class AbstractCollection() : Collection { + override fun toArray(): Array = js.noImpl + + override fun isEmpty(): Boolean = js.noImpl + override fun contains(o: Any?): Boolean = js.noImpl + override fun iterator(): Iterator = js.noImpl + + override fun add(e: E): Boolean = js.noImpl + override fun remove(o: Any?): Boolean = js.noImpl + + override fun addAll(c: Collection): Boolean = js.noImpl + + override fun clear(): Unit = js.noImpl + override fun size(): Int = js.noImpl } library -public abstract open class AbstractList() : AbstractCollection(), List { - public override fun isEmpty() : Boolean = js.noImpl - public override fun contains(o : Any?) : Boolean = js.noImpl - public override fun iterator() : Iterator = js.noImpl - // public override fun indexOf(o : Any?) : Int = js.noImpl - // public override fun lastIndexOf(o : Any?) : Int = js.noImpl - // public override fun toArray() : Array = js.noImpl - // public override fun toArray(a : Array) : Array = 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) : Boolean = js.noImpl - // public override fun addAll(index : Int, c : java.util.Collection) : Boolean = js.noImpl +public trait List: Collection { + fun get(index: Int): E + fun set(index: Int, element: E): E + + fun add(index: Int, element: E): Unit + fun remove(index: Int): E + + fun indexOf(o: E?): Int } library -public trait List : Collection { - override fun size() : Int - override fun isEmpty() : Boolean - override fun contains(o : Any?) : Boolean - override fun iterator() : java.util.Iterator - // override fun toArray() : Array - // Simulate Java's array covariance - // override fun toArray(a : Array) : Array - 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) : Boolean - // open fun addAll(index : Int, c : java.util.Collection) : Boolean - // override fun removeAll(c : java.util.Collection<*>) : Boolean - // override fun retainAll(c : java.util.Collection<*>) : Boolean - 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 +public abstract class AbstractList(): AbstractCollection(), List { + override fun get(index: Int): E = js.noImpl + override fun set(index: Int, element: E): E = js.noImpl + + library("addAt") + override fun add(index: Int, element: E): Unit = js.noImpl + + library("removeAt") + override fun remove(index: Int): E = js.noImpl + + override fun indexOf(o: E?): Int = js.noImpl +} + +library +public open class ArrayList() : AbstractList() { } library public trait Set : Collection { - override fun size() : Int - override fun isEmpty() : Boolean - override fun contains(o : Any?) : Boolean - override fun iterator() : java.util.Iterator - // override fun toArray() : Array - // override fun toArray(a : Array) : Array - 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) : Boolean - //override fun retainAll(c : java.util.Collection<*>) : Boolean - //override fun removeAll(c : java.util.Collection<*>) : Boolean - override fun clear() : Unit } library -public open class HashSet() : java.util.Set { - public override fun iterator() : java.util.Iterator = 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) : Boolean = js.noImpl +public open class HashSet(): AbstractCollection(), java.util.Set { } library @@ -220,22 +172,13 @@ public open class HashMap() : java.util.Map { } library -public open class LinkedList() : List { - public override fun iterator() : java.util.Iterator = js.noImpl - public override fun isEmpty() : Boolean = js.noImpl - public override fun contains(o : Any?) : Boolean = js.noImpl - public override fun size() : Int = js.noImpl - public override fun add(e : E) : Boolean = js.noImpl - public override fun remove(o : Any?) : Boolean = js.noImpl - public override fun addAll(c : java.util.Collection) : 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 +public open class LinkedList(): AbstractList() { + 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 fun poll(): E? = js.noImpl + public fun peek(): E? = js.noImpl + public fun offer(e: E): Boolean = js.noImpl } library diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java index 4a2f0b6ff1f..8f8551acee7 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ArrayListTest.java @@ -51,6 +51,10 @@ public final class ArrayListTest extends JavaClassesTest { fooBoxTest(); } + public void testToArray() throws Exception { + fooBoxTest(); + } + public void testIndexOOB() throws Exception { try { fooBoxTest(); diff --git a/js/js.translator/testFiles/java/arrayList/cases/toArray.kt b/js/js.translator/testFiles/java/arrayList/cases/toArray.kt new file mode 100644 index 00000000000..65da1d0d93f --- /dev/null +++ b/js/js.translator/testFiles/java/arrayList/cases/toArray.kt @@ -0,0 +1,13 @@ +package foo + +import java.util.ArrayList + +fun box() : Boolean { + var i = 0 + val list = ArrayList() + while (i++ < 3) { + list.add(i) + } + val array = list.toArray() + return array[0] == 1 && array[1] == 2 && array[2] == 3 +} \ No newline at end of file diff --git a/js/js.translator/testFiles/kotlin_lib.js b/js/js.translator/testFiles/kotlin_lib.js index 48a25bcf9fb..2722a7e4201 100644 --- a/js/js.translator/testFiles/kotlin_lib.js +++ b/js/js.translator/testFiles/kotlin_lib.js @@ -28,7 +28,7 @@ var kotlin = {set:function (receiver, key, value) { return obj1.equals(obj2); } } - return (obj1 === obj2); + return obj1 === obj2; }; Kotlin.modules = {}; @@ -48,117 +48,122 @@ var kotlin = {set:function (receiver, key, value) { throw Kotlin.$new(Kotlin.Exceptions.NullPointerException)(); }; - Kotlin.AbstractList = Kotlin.$createClass({ - set:function (index, value) { - 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; - } - }); + function throwAbstractFunctionInvocationError() { + throw new TypeError("Function is abstract"); + } - Kotlin.ArrayList = Kotlin.$createClass({ - initialize:function () { - this.array = []; - this.$size = 0; + Kotlin.Iterator = Kotlin.$createClass({ + initialize: function () { }, - get:function (index) { - if ((index < 0) || (index >= this.$size)) { - throw Kotlin.Exceptions.IndexOutOfBounds; - } - return (this.array)[index]; + next: throwAbstractFunctionInvocationError, + get_hasNext: throwAbstractFunctionInvocationError + }); + + var ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, { + initialize: function (array) { + this.array = array; + this.size = array.length; + this.index = 0; }, - set:function (index, value) { - if ((index < 0) || (index >= this.$size)) { - throw Kotlin.Exceptions.IndexOutOfBounds; - } - (this.array)[index] = value; + next: function () { + return this.array[this.index++]; }, - size:function () { - return this.$size; + get_hasNext: function () { + 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 () { - return Kotlin.$new(Kotlin.ArrayIterator)(this); + next: function () { + return this.list.get(this.index++); }, - isEmpty:function () { - return (this.$size === 0); + get_hasNext: function () { + return this.index < this.size; + } + }); + + Kotlin.AbstractList = Kotlin.$createClass({ + iterator: function () { + return Kotlin.$new(ListIterator)(this); }, - add:function (element) { - this.array[this.$size++] = element; + isEmpty: function () { + return this.size() == 0; }, - addAll:function (collection) { + 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; - } + remove: function (o) { + var index = this.indexOf(o); + if (index != -1) { + this.removeAt(index); } }, - removeByIndex:function (index) { - for (var i = index; i < this.$size - 1; ++i) { - 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; + contains: function (o) { + return this.indexOf(o) != -1; } }); + 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) { return parseInt(str, 10); - } - ; + }; Kotlin.safeParseInt = function(str) { var r = parseInt(str, 10); @@ -212,51 +217,32 @@ var kotlin = {set:function (receiver, key, value) { 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, { - initialize:function (start, count, reversed) { + initialize: function (start, count, reversed) { this.$start = start; this.$count = count; this.$reversed = reversed; this.$i = this.get_start(); - }, get_start:function () { + }, + get_start: function () { return this.$start; - }, get_count:function () { + }, + get_count: function () { return this.$count; - }, set_count:function (tmp$0) { + }, + set_count: function (tmp$0) { this.$count = tmp$0; - }, get_reversed:function () { + }, + get_reversed: function () { return this.$reversed; - }, get_i:function () { + }, + get_i: function () { return this.$i; - }, set_i:function (tmp$0) { + }, + set_i: function (tmp$0) { this.$i = tmp$0; - }, next:function () { + }, + next: function () { this.set_count(this.get_count() - 1); if (this.get_reversed()) { 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) { - this.$start = start; - this.$size = size; - this.$reversed = reversed; - }, get_start:function () { - return this.$start; - }, get_size:function () { - return this.$size; - }, get_reversed:function () { - return this.$reversed; - }, 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(); + Kotlin.NumberRange = Kotlin.$createClass({ + initialize: function (start, size, reversed) { + this.$start = start; + this.$size = size; + this.$reversed = reversed; + }, + get_start: function () { + return this.$start; + }, + get_size: function () { + return this.$size; + }, + get_reversed: function () { + return this.$reversed; + }, + 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( - { - initialize: function () { - }, - compare: function (el1, el2) { - throw Kotlin.$new(Kotlin.AbstractFunctionInvocationError)(); - } - } - ); + Kotlin.Comparator = Kotlin.$createClass({ + initialize: function () { + }, + compare: throwAbstractFunctionInvocationError + }); var ComparatorImpl = Kotlin.$createClass(Kotlin.Comparator, { - initialize: function (comparator) { - this.compare = comparator; - } - } - ); + initialize: function (comparator) { + this.compare = comparator; + } + }); Kotlin.comparator = function (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); }; - var intrinsicArrayIterator = Kotlin.$createClass( - Kotlin.Iterator, - { - 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.arrayIterator = function (array) { + return Kotlin.$new(ArrayIterator)(array); }; Kotlin.toString = function (obj) { @@ -800,14 +771,11 @@ var kotlin = {set:function (receiver, key, value) { Kotlin.HashTable = Hashtable; })(); - Kotlin.HashMap = Kotlin.$createClass( - { - initialize:function () { - Kotlin.HashTable.call(this); - } - } - ); - + Kotlin.HashMap = Kotlin.$createClass({ + initialize: function () { + Kotlin.HashTable.call(this); + } + }); (function () { function HashSet(hashingFunction, equalityFunction) { diff --git a/js/js.translator/testFiles/kotlin_lib_ecma5.js b/js/js.translator/testFiles/kotlin_lib_ecma5.js index 221727bfe2c..324a79a5c00 100644 --- a/js/js.translator/testFiles/kotlin_lib_ecma5.js +++ b/js/js.translator/testFiles/kotlin_lib_ecma5.js @@ -20,88 +20,75 @@ var Kotlin = {}; 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) - Kotlin.createClass = (function () { - function create(bases, initializer, properties) { - var proto; - var baseInitializer = null; - var isTrait = initializer == null; - if (!bases) { - proto = !properties && isTrait ? null : Object.create(null, properties || undefined); + Kotlin.createClass = function (bases, initializer, properties) { + var proto; + var baseInitializer = null; + var isTrait = initializer == null; + if (!bases) { + 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 - function createConstructor(proto, initializer) { - return function () { - var o = Object.create(proto); - if (initializer != null) { - initializer.apply(o, arguments); - } + 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.seal(o); - return o; - }; + Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer}); + Object.freeze(initializer); } - 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; - } - - // 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; - })(); + Object.freeze(constructor); + return constructor; + }; Kotlin.createObject = function (initializer, properties) { var o = Object.create(null, properties || undefined); @@ -128,7 +115,7 @@ var Kotlin = {}; }; Kotlin.$createClass = function (parent, properties) { - if (typeof (parent) != "function") { + if (parent !== null && typeof (parent) != "function") { properties = parent; parent = null; }