Files
kotlin-fork/js/js.translator/testData/maps.js
T

875 lines
27 KiB
JavaScript

/*
* Copyright 2010-2013 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.
*/
(function () {
"use strict";
/**
* @class
* @constructor
* @param {K} key
* @param {V} value
* @template K, V
*/
function Entry(key, value) {
this.key = key;
this.value = value;
}
Entry.prototype.getKey = function () {
return this.key;
};
Entry.prototype.getValue = function () {
return this.value;
};
function hashMapPutAll (fromMap) {
var entries = fromMap.entrySet();
var it = entries.iterator();
while (it.hasNext()) {
var e = it.next();
this.put_wn2jw4$(e.getKey(), e.getValue());
}
}
/** @const */
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) {
if (obj == null) return "";
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_za3rmp$(variableValue);
}
function equals_fixedValueNoEquals(fixedValue, variableValue) {
return (variableValue != null && typeof variableValue.equals_za3rmp$ == FUNCTION) ?
// TODO: test this case
variableValue.equals_za3rmp$(fixedValue) : (fixedValue === variableValue);
}
/**
* @constructor
* @param {string} hash
* @param {Key} firstKey
* @param {Value} firstValue
* @param {(function(Key, Key): boolean)|null|undefined} equalityFunction
* @template Key, 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 (searchValue != null && typeof searchValue.equals_za3rmp$ == 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;
}
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_za3rmp$: createBucketSearcher(EXISTENCE),
containsValue_za3rmp$: 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;
}
/*----------------------------------------------------------------------------------------------------------------*/
/**
* @class
*
* @constructor
* @param {(function(Key): string)=} hashingFunctionParam
* @param {(function(Key, Key): boolean)=} equalityFunctionParam
* @template Key, Value
*/
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_wn2jw4$ = function (key, 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_za3rmp$ = function (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_za3rmp$ = function (key) {
var bucketKey = hashingFunction(key);
// Check if a bucket exists for the bucket key
var bucket = getBucketForHash(bucketsByHash, bucketKey);
return bucket ? bucket.containsKey_za3rmp$(key) : false;
};
this.containsValue_za3rmp$ = function (value) {
var i = buckets.length;
while (i--) {
if (buckets[i].containsValue_za3rmp$(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 = new Kotlin.ArrayList();
while (i--) {
result.add_za3rmp$(values[i]);
}
return result;
};
this.remove_za3rmp$ = function (key) {
var hash = hashingFunction(key), bucketIndex, oldValue = null, result = 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
result = bucket.removeEntryForKey(key);
if (result !== null) {
oldValue = result[1];
// 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]);
}
};
/**
* @param {Hashtable.<Key, Value>} hashtable
*/
this.putAll_za3j1t$ = hashMapPutAll;
this.clone = function () {
var clone = new Hashtable(hashingFunctionParam, equalityFunctionParam);
clone.putAll_za3j1t$(that);
return clone;
};
this.keySet = function () {
var res = new Kotlin.ComplexHashSet();
var keys = this._keys();
var i = keys.length;
while (i--) {
res.add_za3rmp$(keys[i]);
}
return res;
};
this.entrySet = function () {
var result = new Kotlin.ComplexHashSet();
var entries = this._entries();
var i = entries.length;
while (i--) {
var entry = entries[i];
result.add_za3rmp$(new Entry(entry[0], entry[1]));
}
return result;
}
};
Kotlin.HashTable = Hashtable;
/**
* @interface
* @template Key, Value
*/
Kotlin.Map = Kotlin.createClassNow();
Kotlin.HashMap = Kotlin.createClassNow(Kotlin.Map,
function () {
Kotlin.HashTable.call(this);
}
);
Kotlin.ComplexHashMap = Kotlin.HashMap;
/**
* @class
* @implements Kotlin.Iterator.<Value>
*
* @constructor
* @param {Kotlin.Map.<Key, Value>} map
* @param {Array.<Value>} keys
* @template Key, Value
*/
var PrimitiveHashMapValuesIterator = Kotlin.createClassNow(Kotlin.Iterator,
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++]];
},
hasNext: function () {
return this.index < this.size;
}
});
/**
* @class
* @implements Kotlin.Collection.<Value>
*
* @constructor
* @param {Kotlin.PrimitiveHashMap.<Key, Value>} map
* @template Key, Value
*/
var PrimitiveHashMapValues = Kotlin.createClassNow(Kotlin.Collection,
function (map) {
this.map = map;
}, {
iterator: function () {
return new PrimitiveHashMapValuesIterator(this.map.map, Object.keys(this.map.map));
},
isEmpty: function () {
return this.map.$size === 0;
},
// TODO: test it
contains: function (o) {
return this.map.containsValue_za3rmp$(o);
}
});
/**
* @class
* @implements Kotlin.Map.<Key, Value>
* @constructor
* @template Key, Value
*/
Kotlin.PrimitiveHashMap = Kotlin.createClassNow(Kotlin.Map,
function () {
this.$size = 0;
this.map = Object.create(null);
}, {
size: function () {
return this.$size;
},
isEmpty: function () {
return this.$size === 0;
},
containsKey_za3rmp$: function (key) {
// TODO: should process "__proto__" separately?
return this.map[key] !== undefined;
},
containsValue_za3rmp$: function (value) {
var map = this.map;
for (var key in map) {
//noinspection JSUnfilteredForInLoop
if (map[key] === value) {
return true;
}
}
return false;
},
get_za3rmp$: function (key) {
return this.map[key];
},
put_wn2jw4$: function (key, value) {
var prevValue = this.map[key];
this.map[key] = value === undefined ? null : value;
if (prevValue === undefined) {
this.$size++;
}
return prevValue;
},
remove_za3rmp$: 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_za3j1t$: hashMapPutAll,
entrySet: function () {
var result = new Kotlin.ComplexHashSet();
var map = this.map;
for (var key in map) {
//noinspection JSUnfilteredForInLoop
result.add_za3rmp$(new Entry(key, map[key]));
}
return result;
},
keySet: function () {
var result = new Kotlin.PrimitiveHashSet();
var map = this.map;
for (var key in map) {
//noinspection JSUnfilteredForInLoop
result.add_za3rmp$(key);
}
return result;
},
values: function () {
return new PrimitiveHashMapValues(this);
},
toJSON: function () {
return this.map;
}
});
function LinkedHashMap() {
Kotlin.ComplexHashMap.call(this);
this.orderedKeys = [];
this.super_put_wn2jw4$ = this.put_wn2jw4$;
this.put_wn2jw4$ = function(key, value) {
if (!this.containsKey_za3rmp$(key)) {
this.orderedKeys.push(key);
}
return this.super_put_wn2jw4$(key, value);
};
this.super_remove_za3rmp$ = this.remove_za3rmp$;
this.remove_za3rmp$ = function(key) {
var i = this.orderedKeys.indexOf(key);
if (i != -1) {
this.orderedKeys.splice(i, 1);
}
return this.super_remove_za3rmp$(key);
};
this.super_clear = this.clear;
this.clear = function() {
this.super_clear();
this.orderedKeys = [];
};
this.keySet = function() {
// TODO return special Set which unsupported adding
var set = new Kotlin.LinkedHashSet();
set.map = this;
return set;
};
this.values = function() {
var set = new Kotlin.LinkedHashSet();
for (var i = 0, c = this.orderedKeys, l = c.length; i < l; i++) {
set.add_za3rmp$(this.get_za3rmp$(c[i]));
}
return set;
};
this.entrySet = function() {
var set = new Kotlin.LinkedHashSet();
for (var i = 0, c = this.orderedKeys, l = c.length; i < l; i++) {
set.add_za3rmp$(new Entry(c[i], this.get_za3rmp$(c[i])));
}
return set;
};
}
LinkedHashMap.prototype = Object.create(Kotlin.ComplexHashMap);
Kotlin.LinkedHashMap = LinkedHashMap;
Kotlin.LinkedHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
/** @constructs */
function () {
this.map = new Kotlin.LinkedHashMap();
},
/** @lends {Kotlin.LinkedHashSet.prototype} */
{
size: function () {
return this.map.size()
},
contains_za3rmp$: function (element) {
return this.map.containsKey_za3rmp$(element);
},
iterator: function () {
return new SetIterator(this);
},
add_za3rmp$: function (element) {
return this.map.put_wn2jw4$(element, true) == null;
},
remove_za3rmp$: function (element) {
return this.map.remove_za3rmp$(element) != null;
},
clear: function () {
this.map.clear();
},
toArray: function () {
return this.map.orderedKeys.slice();
}
});
}());
/**
* @interface
*/
Kotlin.Set = Kotlin.createClassNow(Kotlin.Collection);
/**
* @class
* @constructor
* @param {Kotlin.Set} set
*/
var SetIterator = Kotlin.createClassNow(Kotlin.Iterator,
function (set) {
this.set = set;
this.keys = set.toArray();
this.index = 0;
},
/** @lends SetIterator.prototype */
{
next: function () {
return this.keys[this.index++];
},
hasNext: function () {
return this.index < this.keys.length;
},
remove: function () {
this.set.remove_za3rmp$(this.keys[this.index - 1]);
}
});
/**
* @class
* @constructor
* @extends {Kotlin.Collection.<T>}
* @template T
*/
Kotlin.PrimitiveHashSet = Kotlin.createClassNow(Kotlin.AbstractCollection,
/** @constructs */
function () {
this.$size = 0;
this.map = {};
},
/** @lends {Kotlin.PrimitiveHashSet.prototype} */
{
size: function () {
return this.$size;
},
contains_za3rmp$: function (key) {
return this.map[key] === true;
},
iterator: function () {
return new SetIterator(this);
},
add_za3rmp$: function (element) {
var prevElement = this.map[element];
this.map[element] = true;
if (prevElement === true) {
return false;
}
else {
this.$size++;
return true;
}
},
remove_za3rmp$: function (element) {
if (this.map[element] === true) {
delete this.map[element];
this.$size--;
return true;
}
else {
return false;
}
},
clear: function () {
this.$size = 0;
this.map = {};
},
toArray: function () {
return Object.keys(this.map);
}
});
(function () {
/**
* @class
* @constructor
* @param {(function(Key): string)=} hashingFunction
* @param {(function(Key, Key): boolean)=} equalityFunction
* @template Key, Value
*/
function HashSet(hashingFunction, equalityFunction) {
var hashTable = new Kotlin.HashTable(hashingFunction, equalityFunction);
this.addAll_xeylzf$ = Kotlin.AbstractCollection.prototype.addAll_xeylzf$;
this.removeAll_xeylzf$ = Kotlin.AbstractCollection.prototype.removeAll_xeylzf$;
this.retainAll_xeylzf$ = Kotlin.AbstractCollection.prototype.retainAll_xeylzf$;
this.containsAll_xeylzf$ = Kotlin.AbstractCollection.prototype.containsAll_xeylzf$;
this.add_za3rmp$ = function (o) {
return !hashTable.put_wn2jw4$(o, true);
};
this.toArray = function () {
return hashTable._keys();
};
/** @suppress {checkTypes} */
this.iterator = function () {
return new SetIterator(this);
};
this.remove_za3rmp$ = function (o) {
return hashTable.remove_za3rmp$(o) != null;
};
this.contains_za3rmp$ = function (o) {
return hashTable.containsKey_za3rmp$(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_xeylzf$(hashTable.keys());
return h;
};
this.equals_za3rmp$ = 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.hasNext();
var hn2 = iter2.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.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_za3rmp$(val)) {
intersection.add_za3rmp$(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_za3rmp$(val)) {
union.add_za3rmp$(val);
}
}
return union;
};
this.isSubsetOf = function (hashSet) {
var values = hashTable.keys(), i = values.length;
while (i--) {
if (!hashSet.contains_za3rmp$(values[i])) {
return false;
}
}
return true;
};
}
Kotlin.HashSet = Kotlin.createClassNow(Kotlin.Set,
function () {
HashSet.call(this);
}
);
Kotlin.ComplexHashSet = Kotlin.HashSet;
}());