From 3f59f11f1a446bd5681e67d69667eaa80a6105d9 Mon Sep 17 00:00:00 2001 From: Tobias Schlatter Date: Mon, 27 Jan 2014 13:59:58 +0100 Subject: [PATCH] Fix #149: Implement String.hashCode() --- corejslib/scalajsenv.js | 21 ++++++++++++++++++- .../scalajs/test/javalib/StringTest.scala | 12 ++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/corejslib/scalajsenv.js b/corejslib/scalajsenv.js index a82675a73a..42cb5f94f0 100644 --- a/corejslib/scalajsenv.js +++ b/corejslib/scalajsenv.js @@ -204,8 +204,27 @@ var ScalaJS = { objectHashCode: function(instance) { if (ScalaJS.isScalaJSObject(instance)) return instance.hashCode__I(); - else + else if (typeof(instance) === "string") { + // calculate hash of String as specified by JavaDoc + var n = instance.length; + var res = 0; + var mul = 1; // holds pow(31, n-i-1) + // multiplications with `mul` do never overflow the 52 bits of precision: + // - we truncate `mul` to 32 bits on each operation + // - 31 has 5 significant bits only + // - s[i] has 16 significant bits max + // 32 + max(5, 16) = 48 < 52 => no overflow + for (var i = n-1; i >= 0; --i) { + // calculate s[i] * pow(31, n-i-1) + res = res + (instance.charCodeAt(i) * mul | 0) | 0 + // update mul for next iteration + mul = mul * 31 | 0 + } + + return res; + } else { return 42; // TODO + } }, comparableCompareTo: function(instance, rhs) { diff --git a/test/src/test/scala/scala/scalajs/test/javalib/StringTest.scala b/test/src/test/scala/scala/scalajs/test/javalib/StringTest.scala index 9ba4801e12..ada379dfdf 100644 --- a/test/src/test/scala/scala/scalajs/test/javalib/StringTest.scala +++ b/test/src/test/scala/scala/scalajs/test/javalib/StringTest.scala @@ -113,17 +113,23 @@ object StringTest extends JasmineTest { it("should respond to `split`") { expect("Scala.js".split("a")).toEqual(js.Array("Sc", "l", ".js")) - + } - + it("should respond to `split` with char as argument") { expect("Scala.js".split('.')).toEqual(js.Array("Scala","js")) } - + it("should respond to `toCharArray`") { expect("Scala.js".toCharArray()(5)).toEqual('.') } + it("should respond to `hashCode`") { + expect("a`jkxzcbfaslkjfbkj,289oinkasdf".hashCode()).toEqual(-1395193631) + expect("-34".hashCode()).toEqual(44878) + expect("".hashCode()).toEqual(0) + } + it("should provide `format`") { expect(String.format("%d", new Integer(5))).toEqual("5") expect(String.format("%05d", new Integer(5))).toEqual("00005")