From 2bc768d9cf0003f29d547532cf17e38947ddd064 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Mon, 23 Jan 2012 19:29:35 +0400 Subject: [PATCH] builder example working --- .idea/workspace.xml | 571 ++++++++-------- .../reference/ArrayAccessTranslator.java | 37 +- .../k2js/test/RhinoSystemOutputChecker.java | 4 +- translator/testFiles/kotlin_lib.js | 628 +++++++++--------- 4 files changed, 644 insertions(+), 596 deletions(-) diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 0da00cdbd16..b0d2c0318d3 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -14,14 +14,11 @@ - + - - - - - - + + + @@ -170,19 +167,6 @@ - + - + - - - + + + - - - - - - - - - - + @@ -276,6 +251,24 @@ + + + + + + + + + + + + + + + + + + @@ -303,28 +296,10 @@ - - - - - - - - - - - - - - - - - - - + - + @@ -343,73 +318,46 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -435,6 +383,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -459,10 +434,6 @@ @@ -596,6 +571,68 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1219,6 +1168,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1547,9 +1586,37 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1561,106 +1628,72 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java index 5f55464bb03..542286cfbd2 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/ArrayAccessTranslator.java @@ -1,16 +1,15 @@ package org.jetbrains.k2js.translate.reference; import com.google.dart.compiler.backend.js.ast.JsExpression; -import com.google.dart.compiler.backend.js.ast.JsInvocation; -import com.google.dart.compiler.backend.js.ast.JsNameRef; -import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.JetArrayAccessExpression; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.intrinsic.array.ArrayGetIntrinsic; import org.jetbrains.k2js.translate.intrinsic.array.ArraySetIntrinsic; +import org.jetbrains.k2js.translate.utils.BindingUtils; import org.jetbrains.k2js.translate.utils.TranslationUtils; import java.util.List; @@ -30,13 +29,14 @@ public final class ArrayAccessTranslator extends AccessTranslator { @NotNull private final JetArrayAccessExpression expression; @NotNull - private final DeclarationDescriptor methodDescriptor; + private final FunctionDescriptor methodDescriptor; private ArrayAccessTranslator(@NotNull JetArrayAccessExpression expression, @NotNull TranslationContext context) { super(context); this.expression = expression; - this.methodDescriptor = getDescriptorForReferenceExpression(context.bindingContext(), expression); + this.methodDescriptor = (FunctionDescriptor) + getDescriptorForReferenceExpression(context.bindingContext(), expression); } @Override @@ -52,6 +52,7 @@ public final class ArrayAccessTranslator extends AccessTranslator { return context().intrinsics().isIntrinsic(methodDescriptor); } + //TODO: hide direct access to intrinsics @NotNull private JsExpression intrinsicGet() { return ArrayGetIntrinsic.INSTANCE.apply(translateArrayExpression(), translateIndexExpressions(), context()); @@ -74,17 +75,20 @@ public final class ArrayAccessTranslator extends AccessTranslator { } @NotNull - private JsExpression overloadedSet(@NotNull JsExpression expression) { - JsInvocation setCall = translateAsAccessMethodCall(); - setCall.getArguments().add(expression); - return setCall; + private JsExpression overloadedSet(@NotNull JsExpression expressionToSetTo) { + ResolvedCall resolvedCall = BindingUtils.getResolvedCall(context().bindingContext(), expression); + List arguments = translateIndexExpressions(); + arguments.add(expressionToSetTo); + return CallTranslator.translate(translateArrayExpression(), arguments, resolvedCall, + methodDescriptor, context()); } @NotNull - private JsInvocation translateAsAccessMethodCall() { - JsNameRef accessMethodReference = getAccessMethodReference(); - AstUtil.setQualifier(accessMethodReference, translateArrayExpression()); - return AstUtil.newInvocation(accessMethodReference, translateIndexExpressions()); + private JsExpression translateAsAccessMethodCall() { + ResolvedCall resolvedCall = BindingUtils.getResolvedCall(context().bindingContext(), expression); + List arguments = translateIndexExpressions(); + return CallTranslator.translate(translateArrayExpression(), arguments, resolvedCall, + methodDescriptor, context()); } @NotNull @@ -92,11 +96,6 @@ public final class ArrayAccessTranslator extends AccessTranslator { return TranslationUtils.translateExpressionList(context(), expression.getIndexExpressions()); } - @NotNull - private JsNameRef getAccessMethodReference() { - return context().getNameForDescriptor(methodDescriptor).makeRef(); - } - @NotNull private JsExpression translateArrayExpression() { return Translation.translateAsExpression(expression.getArrayExpression(), context()); diff --git a/translator/test/org/jetbrains/k2js/test/RhinoSystemOutputChecker.java b/translator/test/org/jetbrains/k2js/test/RhinoSystemOutputChecker.java index 4bc44bf1cc5..86c2e3c0d36 100644 --- a/translator/test/org/jetbrains/k2js/test/RhinoSystemOutputChecker.java +++ b/translator/test/org/jetbrains/k2js/test/RhinoSystemOutputChecker.java @@ -29,8 +29,8 @@ public final class RhinoSystemOutputChecker implements RhinoResultChecker { String result = getSystemOutput(context, scope); String trimmedExpected = trimSpace(expectedResult); String trimmedActual = trimSpace(result); - System.out.println(trimmedActual); - System.out.println(trimmedExpected); + // System.out.println(trimmedActual); + // System.out.println(trimmedExpected); assertTrue("Returned:\n" + trimmedActual + "END_OF_RETURNED\nExpected:\n" + trimmedExpected + "END_OF_EXPECTED\n", trimmedExpected.equals(trimmedActual)); } diff --git a/translator/testFiles/kotlin_lib.js b/translator/testFiles/kotlin_lib.js index 74e7ac0893c..51e532642b0 100644 --- a/translator/testFiles/kotlin_lib.js +++ b/translator/testFiles/kotlin_lib.js @@ -373,7 +373,11 @@ Kotlin.System = function () { var print = function (obj) { if (obj !== undefined) { - output += obj; + if (obj == null || typeof obj != "object") { + output += obj; + } else { + output += obj.toString(); + } } }; var println = function (obj) { @@ -494,7 +498,6 @@ Kotlin.NumberRange = Kotlin.Class.create({initialize:function (start, size, reve }); - /** * Copyright 2010 Tim Down. * @@ -523,347 +526,347 @@ Kotlin.NumberRange = Kotlin.Class.create({initialize:function (start, size, reve * Website: http://www.timdown.co.uk/jshashtable */ -(function() { - var FUNCTION = "function"; +(function () { + var FUNCTION = "function"; - var arrayRemoveAt = (typeof Array.prototype.splice == FUNCTION) ? - function(arr, idx) { - arr.splice(idx, 1); - } : + 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 (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 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_fixedValueHasEquals(fixedValue, variableValue) { + return fixedValue.equals(variableValue); + } - function equals_fixedValueNoEquals(fixedValue, variableValue) { - return (typeof variableValue.equals == FUNCTION) ? - variableValue.equals(fixedValue) : (fixedValue === 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"); - } - }; - } + 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"); + var checkKey = createKeyValCheck("key"), checkValue = createKeyValCheck("value"); - /*----------------------------------------------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------------------------------------------*/ - function Bucket(hash, firstKey, firstValue, equalityFunction) { + function Bucket(hash, firstKey, firstValue, equalityFunction) { this[0] = hash; - this.entries = []; - this.addEntry(firstKey, firstValue); + this.entries = []; + this.addEntry(firstKey, firstValue); - if (equalityFunction !== null) { - this.getEqualityFunction = function() { - return equalityFunction; - }; - } - } + if (equalityFunction !== null) { + this.getEqualityFunction = function () { + return equalityFunction; + }; + } + } - var EXISTENCE = 0, ENTRY = 1, ENTRY_INDEX_AND_VALUE = 2; + 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 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]; - } - }; - } + 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; - }, + Bucket.prototype = { + getEqualityFunction:function (searchValue) { + return (typeof searchValue.equals == FUNCTION) ? equals_fixedValueHasEquals : equals_fixedValueNoEquals; + }, - getEntryForKey: createBucketSearcher(ENTRY), + getEntryForKey:createBucketSearcher(ENTRY), - getEntryAndIndexForKey: createBucketSearcher(ENTRY_INDEX_AND_VALUE), + 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; - }, + 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]; - }, + addEntry:function (key, value) { + this.entries[this.entries.length] = [key, value]; + }, - keys: createBucketLister(0), + keys:createBucketLister(0), - values: createBucketLister(1), + 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); - } - }, + 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), + containsKey:createBucketSearcher(EXISTENCE), - containsValue: function(value) { - var i = this.entries.length; - while (i--) { - if ( value === this.entries[i][1] ) { - return true; - } - } - return false; - } - }; + 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 + // 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 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]; + 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; - } + // 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 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; + 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; + 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; - }; + // 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); + this.get = function (key) { + checkKey(key); - var hash = hashingFunction(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; - }; + // 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); + this.containsKey = function (key) { + checkKey(key); + var bucketKey = hashingFunction(key); - // Check if a bucket exists for the bucket key - var bucket = getBucketForHash(bucketsByHash, bucketKey); + // Check if a bucket exists for the bucket key + var bucket = getBucketForHash(bucketsByHash, bucketKey); - return bucket ? bucket.containsKey(key) : false; - }; + 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.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.clear = function () { + buckets.length = 0; + bucketsByHash = {}; + }; - this.isEmpty = function() { - return !buckets.length; - }; + 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; - }; - }; + 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.keys = createBucketAggregator("keys"); + this.values = createBucketAggregator("values"); + this.entries = createBucketAggregator("getEntries"); - this.remove = function(key) { - checkKey(key); + this.remove = function (key) { + checkKey(key); - var hash = hashingFunction(key), bucketIndex, oldValue = null; + var hash = hashingFunction(key), bucketIndex, oldValue = null; - // Check if a bucket exists for the bucket key - var bucket = getBucketForHash(bucketsByHash, hash); + // 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; - }; + 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.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.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]; + 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); - } - }; + // 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.clone = function () { + var clone = new Hashtable(hashingFunctionParam, equalityFunctionParam); + clone.putAll(that); + return clone; + }; - this.keySet = function() { + this.keySet = function () { var res = new Kotlin.HashSet(); var keys = this.keys(); var i = keys.length; @@ -872,14 +875,14 @@ Kotlin.NumberRange = Kotlin.Class.create({initialize:function (start, size, reve } return res; } - }; + }; Kotlin.HashTable = Hashtable; })(); Kotlin.HashMap = Kotlin.Class.create( { - initialize : function() { + initialize:function () { Kotlin.HashTable.call(this); } } @@ -887,11 +890,14 @@ Kotlin.HashMap = Kotlin.Class.create( Kotlin.StringBuilder = Kotlin.Class.create( { - initialize : function() { + initialize:function () { this.string = ""; }, - append : function(obj) { + append:function (obj) { this.string = this.string + obj.toString(); + }, + toString:function () { + return this.string; } } ); @@ -925,52 +931,62 @@ Kotlin.StringBuilder = Kotlin.Class.create( * Build date: 27 March 2010 * Website: http://www.timdown.co.uk/jshashtable/ */ -(function() { +(function () { function HashSet(hashingFunction, equalityFunction) { - var hashTable = new Hashtable(hashingFunction, equalityFunction); + var hashTable = new Kotlin.HashTable(hashingFunction, equalityFunction); - this.add = function(o) { + this.add = function (o) { hashTable.put(o, true); }; - this.addAll = function(arr) { + this.addAll = function (arr) { var i = arr.length; while (i--) { hashTable.put(arr[i], true); } }; - this.values = function() { + this.values = function () { return hashTable.keys(); }; - this.remove = function(o) { + this.iterator = function () { + var list = new Kotlin.ArrayList(); + var values = this.values(); + var i = values.length; + while (i--) { + list.add(values[i]); + } + return list.iterator(); + }; + + this.remove = function (o) { return hashTable.remove(o) ? o : null; }; - this.contains = function(o) { + this.contains = function (o) { return hashTable.containsKey(o); }; - this.clear = function() { + this.clear = function () { hashTable.clear(); }; - this.size = function() { + this.size = function () { return hashTable.size(); }; - this.isEmpty = function() { + this.isEmpty = function () { return hashTable.isEmpty(); }; - this.clone = function() { + this.clone = function () { var h = new HashSet(hashingFunction, equalityFunction); h.addAll(hashTable.keys()); return h; }; - this.intersection = function(hashSet) { + this.intersection = function (hashSet) { var intersection = new HashSet(hashingFunction, equalityFunction); var values = hashSet.values(), i = values.length, val; while (i--) { @@ -982,7 +998,7 @@ Kotlin.StringBuilder = Kotlin.Class.create( return intersection; }; - this.union = function(hashSet) { + this.union = function (hashSet) { var union = this.clone(); var values = hashSet.values(), i = values.length, val; while (i--) { @@ -994,7 +1010,7 @@ Kotlin.StringBuilder = Kotlin.Class.create( return union; }; - this.isSubsetOf = function(hashSet) { + this.isSubsetOf = function (hashSet) { var values = hashTable.keys(), i = values.length; while (i--) { if (!hashSet.contains(values[i])) { @@ -1007,7 +1023,7 @@ Kotlin.StringBuilder = Kotlin.Class.create( Kotlin.HashSet = Kotlin.Class.create( { - initialize : function() { + initialize:function () { HashSet.call(this); } }