Changes to js_libs.js:
Extract maps into separate file. Straight forward solution for "JS_TESTS" hack. Numerous optimizations.
This commit is contained in:
@@ -36,8 +36,6 @@ import java.util.List;
|
|||||||
* Base class representing a configuration of translator.
|
* Base class representing a configuration of translator.
|
||||||
*/
|
*/
|
||||||
public abstract class Config {
|
public abstract class Config {
|
||||||
|
|
||||||
//NOTE: hard-coded in kotlin-lib files
|
|
||||||
//NOTE: a hacky solution to be able to rerun code samples with lib loaded only once: used by tests and web demo
|
//NOTE: a hacky solution to be able to rerun code samples with lib loaded only once: used by tests and web demo
|
||||||
@NotNull
|
@NotNull
|
||||||
public static final String REWRITABLE_MODULE_NAME = "JS_TESTS";
|
public static final String REWRITABLE_MODULE_NAME = "JS_TESTS";
|
||||||
|
|||||||
@@ -14,19 +14,36 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// todo inlined
|
||||||
|
String.prototype.startsWith = function (s) {
|
||||||
|
return this.indexOf(s) === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.endsWith = function (s) {
|
||||||
|
return this.indexOf(s, this.length - s.length) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
String.prototype.contains = function (s) {
|
||||||
|
return this.indexOf(s) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
// todo org.jetbrains.k2js.test.semantics.WebDemoExamples2Test#testBuilder
|
// todo org.jetbrains.k2js.test.semantics.WebDemoExamples2Test#testBuilder
|
||||||
var kotlin = {set:function (receiver, key, value) {
|
var kotlin = {set:function (receiver, key, value) {
|
||||||
return receiver.put(key, value);
|
return receiver.put(key, value);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
|
||||||
|
|
||||||
Kotlin.equals = function (obj1, obj2) {
|
Kotlin.equals = function (obj1, obj2) {
|
||||||
if ((obj1 === null) || (obj1 === undefined)) return obj2 === null;
|
if (obj1 === null || obj1 === undefined) {
|
||||||
|
return obj2 === null;
|
||||||
|
}
|
||||||
|
|
||||||
if (obj1 instanceof Array) {
|
if (obj1 instanceof Array) {
|
||||||
if (!(obj2 instanceof Array)) return false;
|
if (!(obj2 instanceof Array) || obj1.length != obj2.length) {
|
||||||
if (obj1.length != obj2.length) return false;
|
return false;
|
||||||
|
}
|
||||||
for (var i = 0; i < obj1.length; i++) {
|
for (var i = 0; i < obj1.length; i++) {
|
||||||
if (!Kotlin.equals(obj1[i], obj2[i])) {
|
if (!Kotlin.equals(obj1[i], obj2[i])) {
|
||||||
return false;
|
return false;
|
||||||
@@ -34,22 +51,16 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (typeof obj1 == "object") {
|
|
||||||
if (obj1.equals !== undefined) {
|
if (typeof obj1 == "object" && obj1.equals !== undefined) {
|
||||||
return obj1.equals(obj2);
|
return obj1.equals(obj2);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj1 === obj2;
|
return obj1 === obj2;
|
||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.array = function (args) {
|
Kotlin.array = function (args) {
|
||||||
var answer = [];
|
return args === null || args === undefined ? [] : args.slice();
|
||||||
if (args !== null && args !== undefined) {
|
|
||||||
for (var i = 0, n = args.length; i < n; ++i) {
|
|
||||||
answer[i] = args[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return answer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.intUpto = function (from, limit) {
|
Kotlin.intUpto = function (from, limit) {
|
||||||
@@ -61,20 +72,20 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.modules = {};
|
Kotlin.modules = {};
|
||||||
Kotlin.Exceptions = {};
|
|
||||||
Kotlin.Exception = Kotlin.$createClass();
|
Kotlin.Exception = Kotlin.$createClass();
|
||||||
Kotlin.RuntimeException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.RuntimeException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.IndexOutOfBounds = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.IndexOutOfBounds = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.NullPointerException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.NullPointerException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.NoSuchElementException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.NoSuchElementException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.IllegalArgumentException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.IllegalArgumentException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.IllegalStateException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.IllegalStateException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.IndexOutOfBoundsException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.IndexOutOfBoundsException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.UnsupportedOperationException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.UnsupportedOperationException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
Kotlin.Exceptions.IOException = Kotlin.$createClass(Kotlin.Exception);
|
Kotlin.IOException = Kotlin.$createClass(Kotlin.Exception);
|
||||||
|
|
||||||
Kotlin.throwNPE = function () {
|
Kotlin.throwNPE = function () {
|
||||||
throw Kotlin.$new(Kotlin.Exceptions.NullPointerException)();
|
throw Kotlin.$new(Kotlin.NullPointerException)();
|
||||||
};
|
};
|
||||||
|
|
||||||
function throwAbstractFunctionInvocationError(funName) {
|
function throwAbstractFunctionInvocationError(funName) {
|
||||||
@@ -93,7 +104,8 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
initialize: function () {
|
initialize: function () {
|
||||||
},
|
},
|
||||||
next: throwAbstractFunctionInvocationError("Iterator#next"),
|
next: throwAbstractFunctionInvocationError("Iterator#next"),
|
||||||
get_hasNext: throwAbstractFunctionInvocationError("Iterator#get_hasNext")
|
get_hasNext: throwAbstractFunctionInvocationError("Iterator#get_hasNext"),
|
||||||
|
hasNext: throwAbstractFunctionInvocationError("Iterator#hasNext")
|
||||||
});
|
});
|
||||||
|
|
||||||
var ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
var ArrayIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
||||||
@@ -107,6 +119,9 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
},
|
},
|
||||||
get_hasNext: function () {
|
get_hasNext: function () {
|
||||||
return this.index < this.size;
|
return this.index < this.size;
|
||||||
|
},
|
||||||
|
hasNext: function () {
|
||||||
|
return this.index < this.size;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -124,52 +139,6 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Kotlin.AbstractCollection = Kotlin.$createClass({
|
|
||||||
isEmpty: function () {
|
|
||||||
return this.size() == 0;
|
|
||||||
},
|
|
||||||
addAll: function (collection) {
|
|
||||||
var it = collection.iterator();
|
|
||||||
while (it.get_hasNext()) {
|
|
||||||
this.add(it.next());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
equals: function (o) {
|
|
||||||
if (o === null || o === undefined) return false;
|
|
||||||
if (this.size() === o.size()) {
|
|
||||||
var iter1 = this.iterator();
|
|
||||||
var iter2 = o.iterator();
|
|
||||||
while (true) {
|
|
||||||
var hn1 = iter1.get_hasNext();
|
|
||||||
var hn2 = iter2.get_hasNext();
|
|
||||||
if (hn1 != hn2) return false;
|
|
||||||
if (!hn2)
|
|
||||||
return true;
|
|
||||||
else {
|
|
||||||
var o1 = iter1.next();
|
|
||||||
var o2 = iter2.next();
|
|
||||||
if (!Kotlin.equals(o1, o2)) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
toString: function() {
|
|
||||||
var builder = "[";
|
|
||||||
var iter = this.iterator();
|
|
||||||
var first = true;
|
|
||||||
while (iter.get_hasNext()) {
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
builder += ", ";
|
|
||||||
builder += iter.next();
|
|
||||||
}
|
|
||||||
builder += "]";
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Kotlin.Collection = Kotlin.$createClass();
|
Kotlin.Collection = Kotlin.$createClass();
|
||||||
|
|
||||||
Kotlin.AbstractList = Kotlin.$createClass(Kotlin.Collection, {
|
Kotlin.AbstractList = Kotlin.$createClass(Kotlin.Collection, {
|
||||||
@@ -229,6 +198,7 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
return this.toArray();
|
return this.toArray();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Kotlin.ArrayList = Kotlin.$createClass(Kotlin.AbstractList, {
|
Kotlin.ArrayList = Kotlin.$createClass(Kotlin.AbstractList, {
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
this.array = [];
|
this.array = [];
|
||||||
@@ -328,7 +298,7 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.safeParseDouble = function(str) {
|
Kotlin.safeParseDouble = function(str) {
|
||||||
var r = parseFloat(str, 10);
|
var r = parseFloat(str);
|
||||||
return isNaN(r) ? null : r;
|
return isNaN(r) ? null : r;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -351,16 +321,16 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
out:function () {
|
out: function () {
|
||||||
return {
|
return {
|
||||||
print:print,
|
print: print,
|
||||||
println:println
|
println: println
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
output:function () {
|
output: function () {
|
||||||
return output;
|
return output;
|
||||||
},
|
},
|
||||||
flush:function () {
|
flush: function () {
|
||||||
output = "";
|
output = "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -506,12 +476,11 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.arrayFromFun = function (size, initFun) {
|
Kotlin.arrayFromFun = function (size, initFun) {
|
||||||
var res = [];
|
var result = new Array(size);
|
||||||
var i = size;
|
for (var i = 0; i < size; i++) {
|
||||||
while (i > 0) {
|
result[i] = initFun(i);
|
||||||
res[--i] = initFun(i);
|
|
||||||
}
|
}
|
||||||
return res;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.arrayIndices = function (arr) {
|
Kotlin.arrayIndices = function (arr) {
|
||||||
@@ -560,502 +529,51 @@ var kotlin = {set:function (receiver, key, value) {
|
|||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
(function () {
|
// native concat doesn't work for arguments
|
||||||
var FUNCTION = "function";
|
Kotlin.concat = function (a, b) {
|
||||||
|
var r = new Array(a.length + b.length);
|
||||||
var arrayRemoveAt = (typeof Array.prototype.splice == FUNCTION) ?
|
var i = 0;
|
||||||
function (arr, idx) {
|
var n = a.length;
|
||||||
arr.splice(idx, 1);
|
for (; i < n; i++) {
|
||||||
} :
|
r[i] = a[i];
|
||||||
|
|
||||||
function (arr, idx) {
|
|
||||||
var itemsAfterDeleted, i, len;
|
|
||||||
if (idx === arr.length - 1) {
|
|
||||||
arr.length = idx;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
itemsAfterDeleted = arr.slice(idx + 1);
|
|
||||||
arr.length = idx;
|
|
||||||
for (i = 0, len = itemsAfterDeleted.length; i < len; ++i) {
|
|
||||||
arr[idx + i] = itemsAfterDeleted[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function hashObject(obj) {
|
|
||||||
var hashCode;
|
|
||||||
if (typeof obj == "string") {
|
|
||||||
return obj;
|
|
||||||
} else if (typeof obj.hashCode == FUNCTION) {
|
|
||||||
// Check the hashCode method really has returned a string
|
|
||||||
hashCode = obj.hashCode();
|
|
||||||
return (typeof hashCode == "string") ? hashCode : hashObject(hashCode);
|
|
||||||
} else if (typeof obj.toString == FUNCTION) {
|
|
||||||
return obj.toString();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
return String(obj);
|
|
||||||
} catch (ex) {
|
|
||||||
// For host objects (such as ActiveObjects in IE) that have no toString() method and throw an error when
|
|
||||||
// passed to String()
|
|
||||||
return Object.prototype.toString.call(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
n = b.length;
|
||||||
function equals_fixedValueHasEquals(fixedValue, variableValue) {
|
for (var j = 0; j < n;) {
|
||||||
return fixedValue.equals(variableValue);
|
r[i++] = b[j++];
|
||||||
}
|
}
|
||||||
|
return r;
|
||||||
function equals_fixedValueNoEquals(fixedValue, variableValue) {
|
}
|
||||||
return (typeof variableValue.equals == FUNCTION) ?
|
|
||||||
variableValue.equals(fixedValue) : (fixedValue === variableValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createKeyValCheck(kvStr) {
|
|
||||||
return function (kv) {
|
|
||||||
if (kv === null) {
|
|
||||||
throw new Error("null is not a valid " + kvStr);
|
|
||||||
} else if (typeof kv == "undefined") {
|
|
||||||
throw new Error(kvStr + " must not be undefined");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
var checkKey = createKeyValCheck("key"), checkValue = createKeyValCheck("value");
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
function Bucket(hash, firstKey, firstValue, equalityFunction) {
|
|
||||||
this[0] = hash;
|
|
||||||
this.entries = [];
|
|
||||||
this.addEntry(firstKey, firstValue);
|
|
||||||
|
|
||||||
if (equalityFunction !== null) {
|
|
||||||
this.getEqualityFunction = function () {
|
|
||||||
return equalityFunction;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var EXISTENCE = 0, ENTRY = 1, ENTRY_INDEX_AND_VALUE = 2;
|
|
||||||
|
|
||||||
function createBucketSearcher(mode) {
|
|
||||||
return function (key) {
|
|
||||||
var i = this.entries.length, entry, equals = this.getEqualityFunction(key);
|
|
||||||
while (i--) {
|
|
||||||
entry = this.entries[i];
|
|
||||||
if (equals(key, entry[0])) {
|
|
||||||
switch (mode) {
|
|
||||||
case EXISTENCE:
|
|
||||||
return true;
|
|
||||||
case ENTRY:
|
|
||||||
return entry;
|
|
||||||
case ENTRY_INDEX_AND_VALUE:
|
|
||||||
return [ i, entry[1] ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createBucketLister(entryProperty) {
|
|
||||||
return function (aggregatedArr) {
|
|
||||||
var startIndex = aggregatedArr.length;
|
|
||||||
for (var i = 0, len = this.entries.length; i < len; ++i) {
|
|
||||||
aggregatedArr[startIndex + i] = this.entries[i][entryProperty];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Bucket.prototype = {
|
|
||||||
getEqualityFunction:function (searchValue) {
|
|
||||||
return (typeof searchValue.equals == FUNCTION) ? equals_fixedValueHasEquals : equals_fixedValueNoEquals;
|
|
||||||
},
|
|
||||||
|
|
||||||
getEntryForKey:createBucketSearcher(ENTRY),
|
|
||||||
|
|
||||||
getEntryAndIndexForKey:createBucketSearcher(ENTRY_INDEX_AND_VALUE),
|
|
||||||
|
|
||||||
removeEntryForKey:function (key) {
|
|
||||||
var result = this.getEntryAndIndexForKey(key);
|
|
||||||
if (result) {
|
|
||||||
arrayRemoveAt(this.entries, result[0]);
|
|
||||||
return result[1];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
|
|
||||||
addEntry:function (key, value) {
|
|
||||||
this.entries[this.entries.length] = [key, value];
|
|
||||||
},
|
|
||||||
|
|
||||||
keys:createBucketLister(0),
|
|
||||||
|
|
||||||
values:createBucketLister(1),
|
|
||||||
|
|
||||||
getEntries:function (entries) {
|
|
||||||
var startIndex = entries.length;
|
|
||||||
for (var i = 0, len = this.entries.length; i < len; ++i) {
|
|
||||||
// Clone the entry stored in the bucket before adding to array
|
|
||||||
entries[startIndex + i] = this.entries[i].slice(0);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
containsKey:createBucketSearcher(EXISTENCE),
|
|
||||||
|
|
||||||
containsValue:function (value) {
|
|
||||||
var i = this.entries.length;
|
|
||||||
while (i--) {
|
|
||||||
if (value === this.entries[i][1]) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// Supporting functions for searching hashtable buckets
|
|
||||||
|
|
||||||
function searchBuckets(buckets, hash) {
|
|
||||||
var i = buckets.length, bucket;
|
|
||||||
while (i--) {
|
|
||||||
bucket = buckets[i];
|
|
||||||
if (hash === bucket[0]) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBucketForHash(bucketsByHash, hash) {
|
|
||||||
var bucket = bucketsByHash[hash];
|
|
||||||
|
|
||||||
// Check that this is a genuine bucket and not something inherited from the bucketsByHash's prototype
|
|
||||||
return ( bucket && (bucket instanceof Bucket) ) ? bucket : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
var Hashtable = function (hashingFunctionParam, equalityFunctionParam) {
|
|
||||||
var that = this;
|
|
||||||
var buckets = [];
|
|
||||||
var bucketsByHash = {};
|
|
||||||
|
|
||||||
var hashingFunction = (typeof hashingFunctionParam == FUNCTION) ? hashingFunctionParam : hashObject;
|
|
||||||
var equalityFunction = (typeof equalityFunctionParam == FUNCTION) ? equalityFunctionParam : null;
|
|
||||||
|
|
||||||
this.put = function (key, value) {
|
|
||||||
checkKey(key);
|
|
||||||
checkValue(value);
|
|
||||||
var hash = hashingFunction(key), bucket, bucketEntry, oldValue = null;
|
|
||||||
|
|
||||||
// Check if a bucket exists for the bucket key
|
|
||||||
bucket = getBucketForHash(bucketsByHash, hash);
|
|
||||||
if (bucket) {
|
|
||||||
// Check this bucket to see if it already contains this key
|
|
||||||
bucketEntry = bucket.getEntryForKey(key);
|
|
||||||
if (bucketEntry) {
|
|
||||||
// This bucket entry is the current mapping of key to value, so replace old value and we're done.
|
|
||||||
oldValue = bucketEntry[1];
|
|
||||||
bucketEntry[1] = value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The bucket does not contain an entry for this key, so add one
|
|
||||||
bucket.addEntry(key, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// No bucket exists for the key, so create one and put our key/value mapping in
|
|
||||||
bucket = new Bucket(hash, key, value, equalityFunction);
|
|
||||||
buckets[buckets.length] = bucket;
|
|
||||||
bucketsByHash[hash] = bucket;
|
|
||||||
}
|
|
||||||
return oldValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.get = function (key) {
|
|
||||||
checkKey(key);
|
|
||||||
|
|
||||||
var hash = hashingFunction(key);
|
|
||||||
|
|
||||||
// Check if a bucket exists for the bucket key
|
|
||||||
var bucket = getBucketForHash(bucketsByHash, hash);
|
|
||||||
if (bucket) {
|
|
||||||
// Check this bucket to see if it contains this key
|
|
||||||
var bucketEntry = bucket.getEntryForKey(key);
|
|
||||||
if (bucketEntry) {
|
|
||||||
// This bucket entry is the current mapping of key to value, so return the value.
|
|
||||||
return bucketEntry[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.containsKey = function (key) {
|
|
||||||
checkKey(key);
|
|
||||||
var bucketKey = hashingFunction(key);
|
|
||||||
|
|
||||||
// Check if a bucket exists for the bucket key
|
|
||||||
var bucket = getBucketForHash(bucketsByHash, bucketKey);
|
|
||||||
|
|
||||||
return bucket ? bucket.containsKey(key) : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.containsValue = function (value) {
|
|
||||||
checkValue(value);
|
|
||||||
var i = buckets.length;
|
|
||||||
while (i--) {
|
|
||||||
if (buckets[i].containsValue(value)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clear = function () {
|
|
||||||
buckets.length = 0;
|
|
||||||
bucketsByHash = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isEmpty = function () {
|
|
||||||
return !buckets.length;
|
|
||||||
};
|
|
||||||
|
|
||||||
var createBucketAggregator = function (bucketFuncName) {
|
|
||||||
return function () {
|
|
||||||
var aggregated = [], i = buckets.length;
|
|
||||||
while (i--) {
|
|
||||||
buckets[i][bucketFuncName](aggregated);
|
|
||||||
}
|
|
||||||
return aggregated;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
this._keys = createBucketAggregator("keys");
|
|
||||||
this._values = createBucketAggregator("values");
|
|
||||||
this._entries = createBucketAggregator("getEntries");
|
|
||||||
|
|
||||||
this.values = function() {
|
|
||||||
var values = this._values();
|
|
||||||
var i = values.length
|
|
||||||
var result = Kotlin.$new(Kotlin.ArrayList)();
|
|
||||||
while (--i) {
|
|
||||||
result.add(values[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.remove = function (key) {
|
|
||||||
checkKey(key);
|
|
||||||
|
|
||||||
var hash = hashingFunction(key), bucketIndex, oldValue = null;
|
|
||||||
|
|
||||||
// Check if a bucket exists for the bucket key
|
|
||||||
var bucket = getBucketForHash(bucketsByHash, hash);
|
|
||||||
|
|
||||||
if (bucket) {
|
|
||||||
// Remove entry from this bucket for this key
|
|
||||||
oldValue = bucket.removeEntryForKey(key);
|
|
||||||
if (oldValue !== null) {
|
|
||||||
// Entry was removed, so check if bucket is empty
|
|
||||||
if (!bucket.entries.length) {
|
|
||||||
// Bucket is empty, so remove it from the bucket collections
|
|
||||||
bucketIndex = searchBuckets(buckets, hash);
|
|
||||||
arrayRemoveAt(buckets, bucketIndex);
|
|
||||||
delete bucketsByHash[hash];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return oldValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.size = function () {
|
|
||||||
var total = 0, i = buckets.length;
|
|
||||||
while (i--) {
|
|
||||||
total += buckets[i].entries.length;
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.each = function (callback) {
|
|
||||||
var entries = that.entries(), i = entries.length, entry;
|
|
||||||
while (i--) {
|
|
||||||
entry = entries[i];
|
|
||||||
callback(entry[0], entry[1]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
this.putAll = function (hashtable, conflictCallback) {
|
|
||||||
var entries = hashtable.entries();
|
|
||||||
var entry, key, value, thisValue, i = entries.length;
|
|
||||||
var hasConflictCallback = (typeof conflictCallback == FUNCTION);
|
|
||||||
while (i--) {
|
|
||||||
entry = entries[i];
|
|
||||||
key = entry[0];
|
|
||||||
value = entry[1];
|
|
||||||
|
|
||||||
// Check for a conflict. The default behaviour is to overwrite the value for an existing key
|
|
||||||
if (hasConflictCallback && (thisValue = that.get(key))) {
|
|
||||||
value = conflictCallback(key, thisValue, value);
|
|
||||||
}
|
|
||||||
that.put(key, value);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clone = function () {
|
|
||||||
var clone = new Hashtable(hashingFunctionParam, equalityFunctionParam);
|
|
||||||
clone.putAll(that);
|
|
||||||
return clone;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.keySet = function () {
|
|
||||||
var res = Kotlin.$new(Kotlin.HashSet)();
|
|
||||||
var keys = this._keys();
|
|
||||||
var i = keys.length;
|
|
||||||
while (i--) {
|
|
||||||
res.add(keys[i]);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
Kotlin.HashTable = Hashtable;
|
|
||||||
})();
|
|
||||||
|
|
||||||
Kotlin.HashMap = Kotlin.$createClass({
|
|
||||||
initialize: function () {
|
|
||||||
Kotlin.HashTable.call(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
function HashSet(hashingFunction, equalityFunction) {
|
|
||||||
var hashTable = new Kotlin.HashTable(hashingFunction, equalityFunction);
|
|
||||||
|
|
||||||
this.add = function (o) {
|
|
||||||
hashTable.put(o, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.addAll = function (arr) {
|
|
||||||
var i = arr.length;
|
|
||||||
while (i--) {
|
|
||||||
hashTable.put(arr[i], true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.values = function () {
|
|
||||||
return hashTable._keys();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.iterator = function () {
|
|
||||||
return Kotlin.arrayIterator(this.values());
|
|
||||||
};
|
|
||||||
|
|
||||||
this.remove = function (o) {
|
|
||||||
return hashTable.remove(o) ? o : null;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.contains = function (o) {
|
|
||||||
return hashTable.containsKey(o);
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clear = function () {
|
|
||||||
hashTable.clear();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.size = function () {
|
|
||||||
return hashTable.size();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isEmpty = function () {
|
|
||||||
return hashTable.isEmpty();
|
|
||||||
};
|
|
||||||
|
|
||||||
this.clone = function () {
|
|
||||||
var h = new HashSet(hashingFunction, equalityFunction);
|
|
||||||
h.addAll(hashTable.keys());
|
|
||||||
return h;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.equals = function (o) {
|
|
||||||
if (o === null || o === undefined) return false;
|
|
||||||
if (this.size() === o.size()) {
|
|
||||||
var iter1 = this.iterator();
|
|
||||||
var iter2 = o.iterator();
|
|
||||||
while (true) {
|
|
||||||
var hn1 = iter1.get_hasNext();
|
|
||||||
var hn2 = iter2.get_hasNext();
|
|
||||||
if (hn1 != hn2) return false;
|
|
||||||
if (!hn2)
|
|
||||||
return true;
|
|
||||||
else {
|
|
||||||
var o1 = iter1.next();
|
|
||||||
var o2 = iter2.next();
|
|
||||||
if (!Kotlin.equals(o1, o2)) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.toString = function() {
|
|
||||||
var builder = "[";
|
|
||||||
var iter = this.iterator();
|
|
||||||
var first = true;
|
|
||||||
while (iter.get_hasNext()) {
|
|
||||||
if (first)
|
|
||||||
first = false;
|
|
||||||
else
|
|
||||||
builder += ", ";
|
|
||||||
builder += iter.next();
|
|
||||||
}
|
|
||||||
builder += "]";
|
|
||||||
return builder;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.intersection = function (hashSet) {
|
|
||||||
var intersection = new HashSet(hashingFunction, equalityFunction);
|
|
||||||
var values = hashSet.values(), i = values.length, val;
|
|
||||||
while (i--) {
|
|
||||||
val = values[i];
|
|
||||||
if (hashTable.containsKey(val)) {
|
|
||||||
intersection.add(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return intersection;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.union = function (hashSet) {
|
|
||||||
var union = this.clone();
|
|
||||||
var values = hashSet.values(), i = values.length, val;
|
|
||||||
while (i--) {
|
|
||||||
val = values[i];
|
|
||||||
if (!hashTable.containsKey(val)) {
|
|
||||||
union.add(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return union;
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isSubsetOf = function (hashSet) {
|
|
||||||
var values = hashTable.keys(), i = values.length;
|
|
||||||
while (i--) {
|
|
||||||
if (!hashSet.contains(values[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Kotlin.HashSet = Kotlin.$createClass({initialize: function () {
|
|
||||||
HashSet.call(this);
|
|
||||||
}});
|
|
||||||
}());
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
Kotlin.assignOwner = function(f, o) {
|
||||||
|
f.o = o;
|
||||||
|
return f;
|
||||||
|
};
|
||||||
|
|
||||||
|
// we cannot use Function.bind, because if we bind with null self, but call with not null — fun must receive passed not null self
|
||||||
|
// test case: WebDemoExamples2Test.testBuilder
|
||||||
|
Kotlin.b0 = function (f, self, value) {
|
||||||
|
return function () {
|
||||||
|
return f.call(self !== null ? self : this, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Kotlin.b1 = function (f, self, values) {
|
||||||
|
return function () {
|
||||||
|
return f.apply(self !== null ? self : this, values);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Kotlin.b2 = function (f, self, values) {
|
||||||
|
return function () {
|
||||||
|
return f.apply(self !== null ? self : this, Kotlin.concat(values, arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Kotlin.b3 = function (f, self) {
|
||||||
|
return function () {
|
||||||
|
return f.call(self)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Kotlin.b4 = function (f, self) {
|
||||||
|
return function () {
|
||||||
|
return f.apply(self, Kotlin.argumentsToArrayLike(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/* Prototype JavaScript framework, version 1.6.1
|
/* Prototype JavaScript framework, version 1.6.1
|
||||||
* (c) 2005-2009 Sam Stephenson
|
* (c) 2005-2009 Sam Stephenson
|
||||||
*
|
*
|
||||||
* Prototype is freely distributable under the terms of an MIT-style license.
|
* Prototype is freely distributable under the terms of an MIT-style license.
|
||||||
* For details, see the Prototype web site: http://www.prototypejs.org/
|
* For details, see the Prototype web site: http://www.prototypejs.org/
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
var Kotlin = {};
|
var Kotlin = {};
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
@@ -12,6 +12,17 @@ var Kotlin = {};
|
|||||||
var emptyFunction = function () {
|
var emptyFunction = function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Kotlin.keys = Object.keys || function (o) {
|
||||||
|
var result = [];
|
||||||
|
var i = 0;
|
||||||
|
for (var p in o) {
|
||||||
|
if (o.hasOwnProperty(p)) {
|
||||||
|
result[i++] = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
Kotlin.argumentsToArrayLike = function (args) {
|
Kotlin.argumentsToArrayLike = function (args) {
|
||||||
var n = args.length;
|
var n = args.length;
|
||||||
var result = new Array(n);
|
var result = new Array(n);
|
||||||
@@ -21,80 +32,16 @@ var Kotlin = {};
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
(function () {
|
function copyProperties(to, from) {
|
||||||
function extend(destination, source) {
|
for (var p in from) {
|
||||||
for (var property in source) {
|
if (from.hasOwnProperty(p)) {
|
||||||
destination[property] = source[property];
|
to[p] = from[p];
|
||||||
}
|
}
|
||||||
return destination;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
function keys(object) {
|
|
||||||
var results = [];
|
|
||||||
for (var property in object) {
|
|
||||||
if (object.hasOwnProperty(property)) {
|
|
||||||
results.push(property);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
function values(object) {
|
|
||||||
var results = [];
|
|
||||||
for (var property in object) {
|
|
||||||
results.push(object[property]);
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
extend(Object, {
|
|
||||||
extend: extend,
|
|
||||||
keys: Object.keys || keys,
|
|
||||||
values: values
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
|
|
||||||
Object.extend(Function.prototype, (function () {
|
|
||||||
var slice = Array.prototype.slice;
|
|
||||||
|
|
||||||
function update(array, args) {
|
|
||||||
var arrayLength = array.length, length = args.length;
|
|
||||||
while (length--) array[arrayLength + length] = args[length];
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
function argumentNames() {
|
|
||||||
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
|
|
||||||
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
|
|
||||||
.replace(/\s+/g, '').split(',');
|
|
||||||
return names.length == 1 && !names[0] ? [] : names;
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindAsEventListener(context) {
|
|
||||||
var __method = this, args = slice.call(arguments, 1);
|
|
||||||
return function (event) {
|
|
||||||
var a = update([event || window.event], args);
|
|
||||||
return __method.apply(context, a);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function wrap(wrapper) {
|
|
||||||
var __method = this;
|
|
||||||
return function () {
|
|
||||||
var a = update([__method.bind(this)], arguments);
|
|
||||||
return wrapper.apply(this, a);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
argumentNames: argumentNames,
|
|
||||||
bindAsEventListener: bindAsEventListener,
|
|
||||||
wrap: wrap
|
|
||||||
};
|
|
||||||
})());
|
|
||||||
|
|
||||||
Kotlin.isType = function (object, klass) {
|
Kotlin.isType = function (object, klass) {
|
||||||
if (object === null) {
|
if (object === null || object === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,28 +56,20 @@ var Kotlin = {};
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.createTrait = (function () {
|
Kotlin.createTrait = (function () {
|
||||||
function add(object, source) {
|
|
||||||
var properties = Object.keys(source);
|
|
||||||
for (var i = 0, length = properties.length; i < length; i++) {
|
|
||||||
var property = properties[i];
|
|
||||||
object[property] = source[property];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return function () {
|
return function () {
|
||||||
var result = arguments[0];
|
var result = arguments[0];
|
||||||
for (var i = 1, n = arguments.length; i < n; i++) {
|
for (var i = 1, n = arguments.length; i < n; i++) {
|
||||||
add(result, arguments[i]);
|
copyProperties(result, arguments[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
Kotlin.definePackage = Kotlin.createTrait;
|
Kotlin.definePackage = function (members) {
|
||||||
|
return members === null ? {} : members;
|
||||||
|
};
|
||||||
|
|
||||||
Kotlin.createClass = (function () {
|
Kotlin.createClass = (function () {
|
||||||
var METHODS = {addMethods: addMethods};
|
|
||||||
|
|
||||||
function subclass() {
|
function subclass() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +86,7 @@ var Kotlin = {};
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.extend(klass, METHODS);
|
klass.addMethods = addMethods;
|
||||||
klass.superclass = parent;
|
klass.superclass = parent;
|
||||||
klass.subclasses = [];
|
klass.subclasses = [];
|
||||||
|
|
||||||
@@ -157,21 +96,15 @@ var Kotlin = {};
|
|||||||
parent.subclasses.push(klass);
|
parent.subclasses.push(klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
klass.addMethods(
|
klass.addMethods({get_class: function () {
|
||||||
{
|
return klass;
|
||||||
get_class: function () {
|
}});
|
||||||
return klass;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (parent !== null) {
|
if (parent !== null) {
|
||||||
klass.addMethods(
|
klass.addMethods({super_init: function () {
|
||||||
{
|
this.initializing = this.initializing.superclass;
|
||||||
super_init: function () {
|
this.initializing.prototype.initialize.apply(this, arguments);
|
||||||
this.initializing = this.initializing.superclass;
|
}});
|
||||||
this.initializing.prototype.initialize.apply(this, arguments);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0, length = properties.length; i < length; i++) {
|
for (var i = 0, length = properties.length; i < length; i++) {
|
||||||
@@ -187,25 +120,7 @@ var Kotlin = {};
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addMethods(source) {
|
function addMethods(source) {
|
||||||
var ancestor = this.superclass && this.superclass.prototype,
|
copyProperties(this.prototype, source);
|
||||||
properties = Object.keys(source);
|
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0, length = properties.length; i < length; i++) {
|
|
||||||
var property = properties[i], value = source[property];
|
|
||||||
if (ancestor && (typeof (value) == "function") &&
|
|
||||||
value.argumentNames()[0] == "$super") {
|
|
||||||
var method = value;
|
|
||||||
value = (function (m) {
|
|
||||||
return function () {
|
|
||||||
return ancestor[m].apply(this, arguments);
|
|
||||||
};
|
|
||||||
})(property).wrap(method);
|
|
||||||
|
|
||||||
}
|
|
||||||
this.prototype[property] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,10 +143,10 @@ var Kotlin = {};
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.defineModule = function (id, module) {
|
Kotlin.defineModule = function (id, module) {
|
||||||
if ((id in Kotlin.modules) && (id !== "JS_TESTS")) {
|
if (id in Kotlin.modules) {
|
||||||
throw Kotlin.$new(Kotlin.Exceptions.IllegalArgumentException)();
|
throw Kotlin.$new(Kotlin.IllegalArgumentException)();
|
||||||
}
|
}
|
||||||
|
|
||||||
Kotlin.modules[id] = module;
|
Kotlin.modules[id] = module;
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
// Be aware — Google Chrome has serious issue — you can rewrite READ-ONLY property (if it is defined in prototype). Firefox and Safari work correct.
|
// Be aware — Google Chrome has serious issue — you can rewrite READ-ONLY property (if it is defined in prototype). Firefox and Safari work correct.
|
||||||
// Always test property access issues in Firefox, but not in Chrome.
|
// Always test property access issues in Firefox, but not in Chrome.
|
||||||
var Kotlin = {};
|
var Kotlin = Object.create(null);
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
Kotlin.isType = function (object, klass) {
|
// ecma5 is still sucks — concat doesn't accept arguments, but apply does, so, we just return arguments
|
||||||
if (object === null) {
|
Kotlin.argumentsToArrayLike = function (args) {
|
||||||
|
return args;
|
||||||
|
};
|
||||||
|
|
||||||
|
Kotlin.keys = Object.keys;
|
||||||
|
|
||||||
|
Kotlin.isType = function (object, type) {
|
||||||
|
if (object === null || object === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var proto = Object.getPrototypeOf(object);
|
var proto = Object.getPrototypeOf(object);
|
||||||
// todo test nested class
|
// todo test nested class
|
||||||
//noinspection RedundantIfStatementJS
|
//noinspection RedundantIfStatementJS
|
||||||
if (proto == klass.proto) {
|
if (proto == type.proto) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,11 +28,17 @@ var Kotlin = {};
|
|||||||
};
|
};
|
||||||
|
|
||||||
// as separated function to reduce scope
|
// as separated function to reduce scope
|
||||||
function createConstructor(proto, initializer) {
|
function createConstructor() {
|
||||||
return function () {
|
return function $fun() {
|
||||||
var o = Object.create(proto);
|
var o = Object.create($fun.proto);
|
||||||
|
var initializer = $fun.initializer;
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
initializer.apply(o, arguments);
|
if (initializer.length == 0) {
|
||||||
|
initializer.call(o);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
initializer.apply(o, arguments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.seal(o);
|
Object.seal(o);
|
||||||
@@ -38,11 +51,11 @@ var Kotlin = {};
|
|||||||
for (var i = 0, n = bases.length; i < n; i++) {
|
for (var i = 0, n = bases.length; i < n; i++) {
|
||||||
var base = bases[i];
|
var base = bases[i];
|
||||||
var baseProto = base.proto;
|
var baseProto = base.proto;
|
||||||
if (baseProto == null || base.properties == null) {
|
if (baseProto === null || base.properties === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proto) {
|
if (proto === null) {
|
||||||
proto = Object.create(baseProto, properties || undefined);
|
proto = Object.create(baseProto, properties || undefined);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -53,33 +66,59 @@ var Kotlin = {};
|
|||||||
return proto;
|
return proto;
|
||||||
}
|
}
|
||||||
|
|
||||||
// proto must be created for class even if it is not needed (requires for is operator)
|
Kotlin.createTrait = function (bases, properties) {
|
||||||
|
return createClass(bases, null, properties, false);
|
||||||
|
};
|
||||||
|
|
||||||
Kotlin.createClass = function (bases, initializer, properties) {
|
Kotlin.createClass = function (bases, initializer, properties) {
|
||||||
|
// proto must be created for class even if it is not needed (requires for is operator)
|
||||||
|
return createClass(bases, initializer === null ? function () {} : initializer, properties, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
function computeProto2(bases, properties) {
|
||||||
|
if (bases === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Array.isArray(bases) ? computeProto(bases, properties) : bases.proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
Kotlin.createObject = function (bases, initializer, properties) {
|
||||||
|
var o = Object.create(computeProto2(bases, properties), properties || undefined);
|
||||||
|
if (initializer !== null) {
|
||||||
|
if (bases !== null) {
|
||||||
|
Object.defineProperty(initializer, "baseInitializer", {value: Array.isArray(bases) ? bases[0].initializer : bases.initializer});
|
||||||
|
}
|
||||||
|
initializer.call(o);
|
||||||
|
}
|
||||||
|
Object.seal(o);
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
function createClass(bases, initializer, properties, isClass) {
|
||||||
var proto;
|
var proto;
|
||||||
var baseInitializer = null;
|
var baseInitializer;
|
||||||
var isTrait = initializer == null;
|
if (bases === null) {
|
||||||
if (!bases) {
|
baseInitializer = null;
|
||||||
proto = !properties && isTrait ? null : Object.create(null, properties || undefined);
|
proto = !isClass && properties === null ? null : Object.create(null, properties || undefined);
|
||||||
}
|
}
|
||||||
else if (!Array.isArray(bases)) {
|
else if (!Array.isArray(bases)) {
|
||||||
baseInitializer = bases.initializer;
|
baseInitializer = bases.initializer;
|
||||||
proto = !properties && isTrait ? bases.proto : Object.create(bases.proto, properties || undefined);
|
proto = !isClass && properties === null ? bases.proto : Object.create(bases.proto, properties || undefined);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
proto = computeProto(bases, properties);
|
|
||||||
// first is superclass, other are traits
|
// first is superclass, other are traits
|
||||||
baseInitializer = bases[0].initializer;
|
baseInitializer = bases[0].initializer;
|
||||||
|
proto = computeProto(bases, properties);
|
||||||
// all bases are traits without properties
|
// all bases are traits without properties
|
||||||
if (proto == null && !isTrait) {
|
if (proto === null && isClass) {
|
||||||
proto = Object.create(null, properties || undefined);
|
proto = Object.create(null, properties || undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var constructor = createConstructor(proto, initializer);
|
var constructor = createConstructor();
|
||||||
Object.defineProperty(constructor, "proto", {value: proto});
|
Object.defineProperty(constructor, "proto", {value: proto});
|
||||||
Object.defineProperty(constructor, "properties", {value: properties || null});
|
Object.defineProperty(constructor, "properties", {value: properties || null});
|
||||||
// null for trait
|
if (isClass) {
|
||||||
if (!isTrait) {
|
|
||||||
Object.defineProperty(constructor, "initializer", {value: initializer});
|
Object.defineProperty(constructor, "initializer", {value: initializer});
|
||||||
|
|
||||||
Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
|
Object.defineProperty(initializer, "baseInitializer", {value: baseInitializer});
|
||||||
@@ -88,28 +127,33 @@ var Kotlin = {};
|
|||||||
|
|
||||||
Object.freeze(constructor);
|
Object.freeze(constructor);
|
||||||
return constructor;
|
return constructor;
|
||||||
};
|
}
|
||||||
|
|
||||||
Kotlin.createObject = function (initializer, properties) {
|
Kotlin.definePackage = function (initializer, members) {
|
||||||
var o = Object.create(null, properties || undefined);
|
var definition = Object.create(null, members === null ? undefined : members);
|
||||||
initializer.call(o);
|
if (initializer === null) {
|
||||||
return o;
|
return {value: definition};
|
||||||
};
|
}
|
||||||
|
else {
|
||||||
|
var getter = createPackageGetter(definition, initializer);
|
||||||
Kotlin.definePackage = function (functionsAndClasses, nestedNamespaces) {
|
Object.freeze(getter);
|
||||||
var p = Object.create(null, functionsAndClasses || undefined);
|
return {get: getter};
|
||||||
if (nestedNamespaces) {
|
|
||||||
var keys = Object.keys(nestedNamespaces);
|
|
||||||
for (var i = 0, n = keys.length; i < n; i++) {
|
|
||||||
var name = keys[i];
|
|
||||||
Object.defineProperty(p, name, {value:nestedNamespaces[name]});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return p;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function createPackageGetter(instance, initializer) {
|
||||||
|
return function () {
|
||||||
|
if (initializer !== null) {
|
||||||
|
var tmp = initializer;
|
||||||
|
initializer = null;
|
||||||
|
tmp.call(instance);
|
||||||
|
Object.seal(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Kotlin.$new = function (f) {
|
Kotlin.$new = function (f) {
|
||||||
return f;
|
return f;
|
||||||
};
|
};
|
||||||
@@ -154,12 +198,11 @@ var Kotlin = {};
|
|||||||
};
|
};
|
||||||
|
|
||||||
Kotlin.defineModule = function (id, module) {
|
Kotlin.defineModule = function (id, module) {
|
||||||
var isTestMode = id === "JS_TESTS";
|
if (id in Kotlin.modules) {
|
||||||
if ((id in Kotlin.modules) && (!isTestMode)) {
|
throw Kotlin.$new(Kotlin.IllegalArgumentException)();
|
||||||
throw Kotlin.$new(Kotlin.Exceptions.IllegalArgumentException)();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.freeze(module);
|
Object.freeze(module);
|
||||||
Object.defineProperty(Kotlin.modules, id, {value: module, writable: isTestMode});
|
Object.defineProperty(Kotlin.modules, id, {value: module});
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -0,0 +1,620 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
(function () {
|
||||||
|
var FUNCTION = "function";
|
||||||
|
var arrayRemoveAt = (typeof Array.prototype.splice == FUNCTION) ?
|
||||||
|
function (arr, idx) {
|
||||||
|
arr.splice(idx, 1);
|
||||||
|
} :
|
||||||
|
|
||||||
|
function (arr, idx) {
|
||||||
|
var itemsAfterDeleted, i, len;
|
||||||
|
if (idx === arr.length - 1) {
|
||||||
|
arr.length = idx;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
itemsAfterDeleted = arr.slice(idx + 1);
|
||||||
|
arr.length = idx;
|
||||||
|
for (i = 0, len = itemsAfterDeleted.length; i < len; ++i) {
|
||||||
|
arr[idx + i] = itemsAfterDeleted[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function hashObject(obj) {
|
||||||
|
var hashCode;
|
||||||
|
if (typeof obj == "string") {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
else if (typeof obj.hashCode == FUNCTION) {
|
||||||
|
// Check the hashCode method really has returned a string
|
||||||
|
hashCode = obj.hashCode();
|
||||||
|
return (typeof hashCode == "string") ? hashCode : hashObject(hashCode);
|
||||||
|
}
|
||||||
|
else if (typeof obj.toString == FUNCTION) {
|
||||||
|
return obj.toString();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
return String(obj);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
// For host objects (such as ActiveObjects in IE) that have no toString() method and throw an error when
|
||||||
|
// passed to String()
|
||||||
|
return Object.prototype.toString.call(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function equals_fixedValueHasEquals(fixedValue, variableValue) {
|
||||||
|
return fixedValue.equals(variableValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function equals_fixedValueNoEquals(fixedValue, variableValue) {
|
||||||
|
return (typeof variableValue.equals == FUNCTION) ?
|
||||||
|
variableValue.equals(fixedValue) : (fixedValue === variableValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createKeyValCheck(kvStr) {
|
||||||
|
return function (kv) {
|
||||||
|
if (kv === null) {
|
||||||
|
throw new Error("null is not a valid " + kvStr);
|
||||||
|
}
|
||||||
|
else if (typeof kv == "undefined") {
|
||||||
|
throw new Error(kvStr + " must not be undefined");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var checkKey = createKeyValCheck("key"), checkValue = createKeyValCheck("value");
|
||||||
|
|
||||||
|
function Bucket(hash, firstKey, firstValue, equalityFunction) {
|
||||||
|
this[0] = hash;
|
||||||
|
this.entries = [];
|
||||||
|
this.addEntry(firstKey, firstValue);
|
||||||
|
|
||||||
|
if (equalityFunction !== null) {
|
||||||
|
this.getEqualityFunction = function () {
|
||||||
|
return equalityFunction;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var EXISTENCE = 0, ENTRY = 1, ENTRY_INDEX_AND_VALUE = 2;
|
||||||
|
|
||||||
|
function createBucketSearcher(mode) {
|
||||||
|
return function (key) {
|
||||||
|
var i = this.entries.length, entry, equals = this.getEqualityFunction(key);
|
||||||
|
while (i--) {
|
||||||
|
entry = this.entries[i];
|
||||||
|
if (equals(key, entry[0])) {
|
||||||
|
switch (mode) {
|
||||||
|
case EXISTENCE:
|
||||||
|
return true;
|
||||||
|
case ENTRY:
|
||||||
|
return entry;
|
||||||
|
case ENTRY_INDEX_AND_VALUE:
|
||||||
|
return [ i, entry[1] ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createBucketLister(entryProperty) {
|
||||||
|
return function (aggregatedArr) {
|
||||||
|
var startIndex = aggregatedArr.length;
|
||||||
|
for (var i = 0, len = this.entries.length; i < len; ++i) {
|
||||||
|
aggregatedArr[startIndex + i] = this.entries[i][entryProperty];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Bucket.prototype = {
|
||||||
|
getEqualityFunction: function (searchValue) {
|
||||||
|
return (typeof searchValue.equals == FUNCTION) ? equals_fixedValueHasEquals : equals_fixedValueNoEquals;
|
||||||
|
},
|
||||||
|
|
||||||
|
getEntryForKey: createBucketSearcher(ENTRY),
|
||||||
|
|
||||||
|
getEntryAndIndexForKey: createBucketSearcher(ENTRY_INDEX_AND_VALUE),
|
||||||
|
|
||||||
|
removeEntryForKey: function (key) {
|
||||||
|
var result = this.getEntryAndIndexForKey(key);
|
||||||
|
if (result) {
|
||||||
|
arrayRemoveAt(this.entries, result[0]);
|
||||||
|
return result[1];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
addEntry: function (key, value) {
|
||||||
|
this.entries[this.entries.length] = [key, value];
|
||||||
|
},
|
||||||
|
|
||||||
|
keys: createBucketLister(0),
|
||||||
|
|
||||||
|
values: createBucketLister(1),
|
||||||
|
|
||||||
|
getEntries: function (entries) {
|
||||||
|
var startIndex = entries.length;
|
||||||
|
for (var i = 0, len = this.entries.length; i < len; ++i) {
|
||||||
|
// Clone the entry stored in the bucket before adding to array
|
||||||
|
entries[startIndex + i] = this.entries[i].slice(0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
containsKey: createBucketSearcher(EXISTENCE),
|
||||||
|
|
||||||
|
containsValue: function (value) {
|
||||||
|
var i = this.entries.length;
|
||||||
|
while (i--) {
|
||||||
|
if (value === this.entries[i][1]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Supporting functions for searching hashtable buckets
|
||||||
|
|
||||||
|
function searchBuckets(buckets, hash) {
|
||||||
|
var i = buckets.length, bucket;
|
||||||
|
while (i--) {
|
||||||
|
bucket = buckets[i];
|
||||||
|
if (hash === bucket[0]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBucketForHash(bucketsByHash, hash) {
|
||||||
|
var bucket = bucketsByHash[hash];
|
||||||
|
|
||||||
|
// Check that this is a genuine bucket and not something inherited from the bucketsByHash's prototype
|
||||||
|
return ( bucket && (bucket instanceof Bucket) ) ? bucket : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
var Hashtable = function (hashingFunctionParam, equalityFunctionParam) {
|
||||||
|
var that = this;
|
||||||
|
var buckets = [];
|
||||||
|
var bucketsByHash = {};
|
||||||
|
|
||||||
|
var hashingFunction = (typeof hashingFunctionParam == FUNCTION) ? hashingFunctionParam : hashObject;
|
||||||
|
var equalityFunction = (typeof equalityFunctionParam == FUNCTION) ? equalityFunctionParam : null;
|
||||||
|
|
||||||
|
this.put = function (key, value) {
|
||||||
|
checkKey(key);
|
||||||
|
checkValue(value);
|
||||||
|
var hash = hashingFunction(key), bucket, bucketEntry, oldValue = null;
|
||||||
|
|
||||||
|
// Check if a bucket exists for the bucket key
|
||||||
|
bucket = getBucketForHash(bucketsByHash, hash);
|
||||||
|
if (bucket) {
|
||||||
|
// Check this bucket to see if it already contains this key
|
||||||
|
bucketEntry = bucket.getEntryForKey(key);
|
||||||
|
if (bucketEntry) {
|
||||||
|
// This bucket entry is the current mapping of key to value, so replace old value and we're done.
|
||||||
|
oldValue = bucketEntry[1];
|
||||||
|
bucketEntry[1] = value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The bucket does not contain an entry for this key, so add one
|
||||||
|
bucket.addEntry(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No bucket exists for the key, so create one and put our key/value mapping in
|
||||||
|
bucket = new Bucket(hash, key, value, equalityFunction);
|
||||||
|
buckets[buckets.length] = bucket;
|
||||||
|
bucketsByHash[hash] = bucket;
|
||||||
|
}
|
||||||
|
return oldValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.get = function (key) {
|
||||||
|
checkKey(key);
|
||||||
|
|
||||||
|
var hash = hashingFunction(key);
|
||||||
|
|
||||||
|
// Check if a bucket exists for the bucket key
|
||||||
|
var bucket = getBucketForHash(bucketsByHash, hash);
|
||||||
|
if (bucket) {
|
||||||
|
// Check this bucket to see if it contains this key
|
||||||
|
var bucketEntry = bucket.getEntryForKey(key);
|
||||||
|
if (bucketEntry) {
|
||||||
|
// This bucket entry is the current mapping of key to value, so return the value.
|
||||||
|
return bucketEntry[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.containsKey = function (key) {
|
||||||
|
checkKey(key);
|
||||||
|
var bucketKey = hashingFunction(key);
|
||||||
|
|
||||||
|
// Check if a bucket exists for the bucket key
|
||||||
|
var bucket = getBucketForHash(bucketsByHash, bucketKey);
|
||||||
|
|
||||||
|
return bucket ? bucket.containsKey(key) : false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.containsValue = function (value) {
|
||||||
|
checkValue(value);
|
||||||
|
var i = buckets.length;
|
||||||
|
while (i--) {
|
||||||
|
if (buckets[i].containsValue(value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clear = function () {
|
||||||
|
buckets.length = 0;
|
||||||
|
bucketsByHash = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isEmpty = function () {
|
||||||
|
return !buckets.length;
|
||||||
|
};
|
||||||
|
|
||||||
|
var createBucketAggregator = function (bucketFuncName) {
|
||||||
|
return function () {
|
||||||
|
var aggregated = [], i = buckets.length;
|
||||||
|
while (i--) {
|
||||||
|
buckets[i][bucketFuncName](aggregated);
|
||||||
|
}
|
||||||
|
return aggregated;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
this._keys = createBucketAggregator("keys");
|
||||||
|
this._values = createBucketAggregator("values");
|
||||||
|
this._entries = createBucketAggregator("getEntries");
|
||||||
|
|
||||||
|
this.values = function () {
|
||||||
|
var values = this._values();
|
||||||
|
var i = values.length
|
||||||
|
var result = Kotlin.$new(Kotlin.ArrayList)();
|
||||||
|
while (--i) {
|
||||||
|
result.add(values[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function (key) {
|
||||||
|
checkKey(key);
|
||||||
|
|
||||||
|
var hash = hashingFunction(key), bucketIndex, oldValue = null;
|
||||||
|
|
||||||
|
// Check if a bucket exists for the bucket key
|
||||||
|
var bucket = getBucketForHash(bucketsByHash, hash);
|
||||||
|
|
||||||
|
if (bucket) {
|
||||||
|
// Remove entry from this bucket for this key
|
||||||
|
oldValue = bucket.removeEntryForKey(key);
|
||||||
|
if (oldValue !== null) {
|
||||||
|
// Entry was removed, so check if bucket is empty
|
||||||
|
if (!bucket.entries.length) {
|
||||||
|
// Bucket is empty, so remove it from the bucket collections
|
||||||
|
bucketIndex = searchBuckets(buckets, hash);
|
||||||
|
arrayRemoveAt(buckets, bucketIndex);
|
||||||
|
delete bucketsByHash[hash];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oldValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.size = function () {
|
||||||
|
var total = 0, i = buckets.length;
|
||||||
|
while (i--) {
|
||||||
|
total += buckets[i].entries.length;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.each = function (callback) {
|
||||||
|
var entries = that.entries(), i = entries.length, entry;
|
||||||
|
while (i--) {
|
||||||
|
entry = entries[i];
|
||||||
|
callback(entry[0], entry[1]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.putAll = function (hashtable, conflictCallback) {
|
||||||
|
var entries = hashtable.entries();
|
||||||
|
var entry, key, value, thisValue, i = entries.length;
|
||||||
|
var hasConflictCallback = (typeof conflictCallback == FUNCTION);
|
||||||
|
while (i--) {
|
||||||
|
entry = entries[i];
|
||||||
|
key = entry[0];
|
||||||
|
value = entry[1];
|
||||||
|
|
||||||
|
// Check for a conflict. The default behaviour is to overwrite the value for an existing key
|
||||||
|
if (hasConflictCallback && (thisValue = that.get(key))) {
|
||||||
|
value = conflictCallback(key, thisValue, value);
|
||||||
|
}
|
||||||
|
that.put(key, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clone = function () {
|
||||||
|
var clone = new Hashtable(hashingFunctionParam, equalityFunctionParam);
|
||||||
|
clone.putAll(that);
|
||||||
|
return clone;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.keySet = function () {
|
||||||
|
var res = Kotlin.$new(Kotlin.HashSet)();
|
||||||
|
var keys = this._keys();
|
||||||
|
var i = keys.length;
|
||||||
|
while (i--) {
|
||||||
|
res.add(keys[i]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Kotlin.HashTable = Hashtable;
|
||||||
|
})();
|
||||||
|
|
||||||
|
Kotlin.Map = Kotlin.$createClass();
|
||||||
|
|
||||||
|
Kotlin.HashMap = Kotlin.$createClass(Kotlin.Map, {initialize: function () {
|
||||||
|
Kotlin.HashTable.call(this);
|
||||||
|
}});
|
||||||
|
|
||||||
|
Kotlin.ComplexHashMap = Kotlin.HashMap;
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var PrimitiveHashMapValuesIterator = Kotlin.$createClass(Kotlin.Iterator, {
|
||||||
|
initialize: function (map, keys) {
|
||||||
|
this.map = map;
|
||||||
|
this.keys = keys;
|
||||||
|
this.size = keys.length;
|
||||||
|
this.index = 0;
|
||||||
|
},
|
||||||
|
next: function () {
|
||||||
|
return this.map[this.keys[this.index++]];
|
||||||
|
},
|
||||||
|
get_hasNext: function () {
|
||||||
|
return this.index < this.size;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var PrimitiveHashMapValues = Kotlin.$createClass(Kotlin.Collection, {
|
||||||
|
initialize: function (map) {
|
||||||
|
this.map = map;
|
||||||
|
},
|
||||||
|
iterator: function () {
|
||||||
|
return Kotlin.$new(PrimitiveHashMapValuesIterator)(this.map.map, Kotlin.keys(this.map.map));
|
||||||
|
},
|
||||||
|
isEmpty: function () {
|
||||||
|
return this.map.$size === 0;
|
||||||
|
},
|
||||||
|
contains: function (o) {
|
||||||
|
return this.map.containsValue(o);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Kotlin.PrimitiveHashMap = Kotlin.$createClass(Kotlin.Map, {
|
||||||
|
initialize: function () {
|
||||||
|
this.$size = 0;
|
||||||
|
this.map = {};
|
||||||
|
},
|
||||||
|
size: function () {
|
||||||
|
return this.$size;
|
||||||
|
},
|
||||||
|
isEmpty: function () {
|
||||||
|
return this.$size === 0;
|
||||||
|
},
|
||||||
|
containsKey: function (key) {
|
||||||
|
return this.map[key] !== undefined;
|
||||||
|
},
|
||||||
|
containsValue: function (value) {
|
||||||
|
var map = this.map;
|
||||||
|
for (var key in map) {
|
||||||
|
if (map.hasOwnProperty(key) && map[key] === value) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
get: function (key) {
|
||||||
|
return this.map[key];
|
||||||
|
},
|
||||||
|
put: function (key, value) {
|
||||||
|
var prevValue = this.map[key];
|
||||||
|
this.map[key] = value === undefined ? null : value;
|
||||||
|
if (prevValue === undefined) {
|
||||||
|
this.$size++;
|
||||||
|
}
|
||||||
|
return prevValue;
|
||||||
|
},
|
||||||
|
remove: function (key) {
|
||||||
|
var prevValue = this.map[key];
|
||||||
|
if (prevValue !== undefined) {
|
||||||
|
delete this.map[key];
|
||||||
|
this.$size--;
|
||||||
|
}
|
||||||
|
return prevValue;
|
||||||
|
},
|
||||||
|
clear: function () {
|
||||||
|
this.$size = 0;
|
||||||
|
this.map = {};
|
||||||
|
},
|
||||||
|
putAll: function (fromMap) {
|
||||||
|
throw Kotlin.$new(Kotlin.UnsupportedOperationException)();
|
||||||
|
},
|
||||||
|
keySet: function () {
|
||||||
|
var result = Kotlin.$new(Kotlin.HashSet)();
|
||||||
|
var map = this.map;
|
||||||
|
for (var key in map) {
|
||||||
|
if (map.hasOwnProperty(key)) {
|
||||||
|
result.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
values: function () {
|
||||||
|
return Kotlin.$new(PrimitiveHashMapValues)(this);
|
||||||
|
},
|
||||||
|
toJSON: function () {
|
||||||
|
return this.map;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
function HashSet(hashingFunction, equalityFunction) {
|
||||||
|
var hashTable = new Kotlin.HashTable(hashingFunction, equalityFunction);
|
||||||
|
|
||||||
|
this.add = function (o) {
|
||||||
|
hashTable.put(o, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.addAll = function (arr) {
|
||||||
|
var i = arr.length;
|
||||||
|
while (i--) {
|
||||||
|
hashTable.put(arr[i], true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.values = function () {
|
||||||
|
return hashTable._keys();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.iterator = function () {
|
||||||
|
return Kotlin.arrayIterator(this.values());
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function (o) {
|
||||||
|
return hashTable.remove(o) ? o : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.contains = function (o) {
|
||||||
|
return hashTable.containsKey(o);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clear = function () {
|
||||||
|
hashTable.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.size = function () {
|
||||||
|
return hashTable.size();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isEmpty = function () {
|
||||||
|
return hashTable.isEmpty();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clone = function () {
|
||||||
|
var h = new HashSet(hashingFunction, equalityFunction);
|
||||||
|
h.addAll(hashTable.keys());
|
||||||
|
return h;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.equals = function (o) {
|
||||||
|
if (o === null || o === undefined) return false;
|
||||||
|
if (this.size() === o.size()) {
|
||||||
|
var iter1 = this.iterator();
|
||||||
|
var iter2 = o.iterator();
|
||||||
|
while (true) {
|
||||||
|
var hn1 = iter1.get_hasNext();
|
||||||
|
var hn2 = iter2.get_hasNext();
|
||||||
|
if (hn1 != hn2) return false;
|
||||||
|
if (!hn2)
|
||||||
|
return true;
|
||||||
|
else {
|
||||||
|
var o1 = iter1.next();
|
||||||
|
var o2 = iter2.next();
|
||||||
|
if (!Kotlin.equals(o1, o2)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
var builder = "[";
|
||||||
|
var iter = this.iterator();
|
||||||
|
var first = true;
|
||||||
|
while (iter.get_hasNext()) {
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
builder += ", ";
|
||||||
|
builder += iter.next();
|
||||||
|
}
|
||||||
|
builder += "]";
|
||||||
|
return builder;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.intersection = function (hashSet) {
|
||||||
|
var intersection = new HashSet(hashingFunction, equalityFunction);
|
||||||
|
var values = hashSet.values(), i = values.length, val;
|
||||||
|
while (i--) {
|
||||||
|
val = values[i];
|
||||||
|
if (hashTable.containsKey(val)) {
|
||||||
|
intersection.add(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return intersection;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.union = function (hashSet) {
|
||||||
|
var union = this.clone();
|
||||||
|
var values = hashSet.values(), i = values.length, val;
|
||||||
|
while (i--) {
|
||||||
|
val = values[i];
|
||||||
|
if (!hashTable.containsKey(val)) {
|
||||||
|
union.add(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return union;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.isSubsetOf = function (hashSet) {
|
||||||
|
var values = hashTable.keys(), i = values.length;
|
||||||
|
while (i--) {
|
||||||
|
if (!hashSet.contains(values[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Kotlin.HashSet = Kotlin.$createClass({initialize: function () {
|
||||||
|
HashSet.call(this);
|
||||||
|
}});
|
||||||
|
}());
|
||||||
Reference in New Issue
Block a user