summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-09-22 06:24:34 +0000
committerPaul Phillips <paulp@improving.org>2009-09-22 06:24:34 +0000
commitefc9abd507efc4a1847459a3523dbd95d1e0acb3 (patch)
tree965a24814c8546972cddf718988e7ab41cce1cb4 /src/library
parentd094b4ac4dfc3822129562921d801a2ae7616605 (diff)
downloadscala-efc9abd507efc4a1847459a3523dbd95d1e0acb3.tar.gz
scala-efc9abd507efc4a1847459a3523dbd95d1e0acb3.tar.bz2
scala-efc9abd507efc4a1847459a3523dbd95d1e0acb3.zip
Attempting to widen the field of possibilities ...
Attempting to widen the field of possibilities for equality, a proof by construction that a large codebase doesn't need to perform equality checks between different primitives types if it is not so inclined.
Diffstat (limited to 'src/library')
-rw-r--r--src/library/scala/collection/generic/BitSetTemplate.scala6
-rw-r--r--src/library/scala/collection/immutable/LongMap.scala2
-rw-r--r--src/library/scala/io/BytePickle.scala2
-rw-r--r--src/library/scala/io/UTF8Codec.scala2
-rw-r--r--src/library/scala/runtime/BoxesRunTime.java75
-rw-r--r--src/library/scala/xml/Utility.scala59
-rw-r--r--src/library/scala/xml/parsing/TokenTests.scala2
7 files changed, 97 insertions, 51 deletions
diff --git a/src/library/scala/collection/generic/BitSetTemplate.scala b/src/library/scala/collection/generic/BitSetTemplate.scala
index 501a388b4d..670109a874 100644
--- a/src/library/scala/collection/generic/BitSetTemplate.scala
+++ b/src/library/scala/collection/generic/BitSetTemplate.scala
@@ -61,7 +61,7 @@ trait BitSetTemplate[+This <: BitSetTemplate[This] with Set[Int]] extends SetTem
for (i <- 0 until nwords) {
val w = word(i)
for (j <- i * WordLength until (i + 1) * WordLength) {
- if ((w & (1L << j)) != 0) f(j)
+ if ((w & (1L << j)) != 0L) f(j)
}
}
}
@@ -109,7 +109,7 @@ trait BitSetTemplate[+This <: BitSetTemplate[This] with Set[Int]] extends SetTem
/** Does the set contain the given element?
*/
def contains(elem: Int): Boolean =
- 0 <= elem && (word(elem >> LogWL) & (1L << elem)) != 0
+ 0 <= elem && (word(elem >> LogWL) & (1L << elem)) != 0L
/** Is the set a subset of the given bitset
*/
@@ -154,6 +154,6 @@ object BitSetTemplate {
private def popCount(w: Long): Int = {
def pc2(w: Int) = if (w == 0) 0 else pc1(w & 0xff) + pc1(w >>> 8)
def pc4(w: Int) = if (w == 0) 0 else pc2(w & 0xffff) + pc2(w >>> 16)
- if (w == 0) 0 else pc4(w.toInt) + pc4((w >>> 32).toInt)
+ if (w == 0L) 0 else pc4(w.toInt) + pc4((w >>> 32).toInt)
}
}
diff --git a/src/library/scala/collection/immutable/LongMap.scala b/src/library/scala/collection/immutable/LongMap.scala
index 2be51e7577..d553329114 100644
--- a/src/library/scala/collection/immutable/LongMap.scala
+++ b/src/library/scala/collection/immutable/LongMap.scala
@@ -4,7 +4,7 @@ package scala.collection.immutable;
* @author David MacIver
*/
private[immutable] object LongMapUtils{
- def zero(i : Long, mask : Long) = (i & mask) == 0;
+ def zero(i : Long, mask : Long) = (i & mask) == 0L;
def mask(i : Long, mask : Long) = i & (complement(mask - 1) ^ mask)
def hasMatch(key : Long, prefix : Long, m : Long) = mask(key, m) == prefix;
def unsignedCompare(i : Long, j : Long) = (i < j) ^ (i < 0) ^ (j < 0)
diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala
index 558a299399..7e5628e207 100644
--- a/src/library/scala/io/BytePickle.scala
+++ b/src/library/scala/io/BytePickle.scala
@@ -69,7 +69,7 @@ object BytePickle {
case Def() => Array.concat(s, Array[Byte](1))
};
def appU(s: Array[Byte]): (RefDef, Array[Byte]) =
- if (s(0) == 0) (Ref(), s.slice(1, s.length))
+ if (s(0) == (0: Byte)) (Ref(), s.slice(1, s.length))
else (Def(), s.slice(1, s.length));
}
diff --git a/src/library/scala/io/UTF8Codec.scala b/src/library/scala/io/UTF8Codec.scala
index 21d3b3bb31..6bbe6263ee 100644
--- a/src/library/scala/io/UTF8Codec.scala
+++ b/src/library/scala/io/UTF8Codec.scala
@@ -33,7 +33,7 @@ object UTF8Codec
@deprecated("""Use new String(Array(ch), 0, 1).getBytes("UTF-8") instead""")
def encode(ch: Int): Array[Byte] =
- if ((Character getType ch) == Character.SURROGATE) UNI_REPLACEMENT_BYTES
+ if ((Character getType ch) == Character.SURROGATE.toInt) UNI_REPLACEMENT_BYTES
else try new String(Array(ch), 0, 1) getBytes "UTF-8" catch {
case _: IllegalArgumentException => UNI_REPLACEMENT_BYTES
}
diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java
index 3f71bb9409..885022c01c 100644
--- a/src/library/scala/runtime/BoxesRunTime.java
+++ b/src/library/scala/runtime/BoxesRunTime.java
@@ -11,6 +11,8 @@
package scala.runtime;
+import java.io.*;
+
/** An object (static class) that defines methods used for creating,
* reverting, and calculating with, boxed values. There are four classes
* of methods in this object:
@@ -25,7 +27,44 @@ package scala.runtime;
* @author Martin Odersky
* @contributor Stepan Koltsov
* @version 2.0 */
-public class BoxesRunTime {
+public class BoxesRunTime
+{
+ /**** Temporary code to support logging all equality comparisons. ****/
+ private static boolean eqeqLogging = false;
+ private static String eqeqLogName = "/tmp/trunk-eqeq.log";
+ private static FileWriter eqeqLog;
+ public static void setEqEqLogging(boolean state) {
+ eqeqLogging = state;
+ if (state) {
+ try { eqeqLog = new FileWriter(eqeqLogName, true); }
+ catch (IOException e) { eqeqLog = null; }
+
+ log("Started eqeq log at " + (new java.util.Date()));
+ }
+ }
+ private static String obToString(Object o) {
+ String s = o.toString() + " (" + o.getClass().getSimpleName() + ")";
+ return s.replaceAll("\\n", " ");
+ }
+ private static void logInternal(String msg, Object a, Object b, String where) {
+ log(msg + obToString(a) + " == " + obToString(b) + " " + where);
+ }
+
+ public static String whereAreWe() {
+ StackTraceElement e = Thread.currentThread().getStackTrace()[3];
+ return"(" + e.getClassName() + "." + e.getMethodName() + e.getFileName() + ":" + e.getLineNumber() + ")";
+ }
+ public static void log(String msg) {
+ if (eqeqLogging && eqeqLog != null) {
+ try {
+ eqeqLog.write(msg + "\n");
+ eqeqLog.flush();
+ }
+ catch (IOException e) { }
+ }
+ }
+
+ /**** End temporary logging section. ****/
private static final int CHAR = 0, BYTE = 1, SHORT = 2, INT = 3, LONG = 4, FLOAT = 5, DOUBLE = 6, OTHER = 7;
@@ -121,16 +160,15 @@ public class BoxesRunTime {
return d == null ? 0.0d : ((Double)d).doubleValue();
}
-/* COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON ... COMPARISON */
+ /**************************************/
- /** A rich implementation of the <code>equals</code> method that overrides the
- * default equals because Java's boxed primitives are utterly broken. This equals
- * is inserted instead of a normal equals by the Scala compiler (in the
- * ICode phase, method <code>genEqEqPrimitive</code>) only when either
- * side of the comparison is a subclass of <code>AnyVal</code>, of
- * <code>java.lang.Number</code>, of <code>java.lang.Character</code> or
- * is exactly <code>Any</code> or <code>AnyRef</code>. */
public static boolean equals(Object a, Object b) {
+ if ((a instanceof Number || a instanceof Character) && (b instanceof Number || b instanceof Character)) {
+ if (a.getClass() != b.getClass()) {
+ logInternal("[ BOXED ] Comparing: ", a, b, whereAreWe());
+ }
+ }
+
if (a == null || b == null)
return a == b;
if (a.equals(b))
@@ -139,32 +177,41 @@ public class BoxesRunTime {
int acode = typeCode(a);
int bcode = typeCode(b);
int maxcode = (acode < bcode) ? bcode : acode;
+ boolean res = false;
if (maxcode <= INT) {
int aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).intValue();
int bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).intValue();
- return aa == bb;
+ res = (aa == bb);
}
if (maxcode <= LONG) {
long aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).longValue();
long bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).longValue();
- return aa == bb;
+ res = (aa == bb);
}
if (maxcode <= FLOAT) {
float aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).floatValue();
float bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).floatValue();
- return aa == bb;
+ res = (aa == bb);
}
if (maxcode <= DOUBLE) {
double aa = (acode == CHAR) ? ((Character) a).charValue() : ((Number) a).doubleValue();
double bb = (bcode == CHAR) ? ((Character) b).charValue() : ((Number) b).doubleValue();
- return aa == bb;
+ res = (aa == bb);
}
- return b.equals(a);
+ if (res || b.equals(a)) {
+ String msg;
+ if (res) msg = "[ BOXED ] Overriding equals between different types: ";
+ else msg = "[ BOXED ] Overriding equals because b.equals(a): ";
+ logInternal(msg, a, b, whereAreWe());
+ return true;
+ }
+ return false;
}
return false;
}
+
/* OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS ... OPERATORS */
/** arg1 + arg2 */
diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala
index 39e594eb05..302f77d07c 100644
--- a/src/library/scala/xml/Utility.scala
+++ b/src/library/scala/xml/Utility.scala
@@ -331,44 +331,43 @@ object Utility extends AnyRef with parsing.TokenTests
* @return ...
*/
def parseAttributeValue(value: String): Seq[Node] = {
- val zs: Seq[Char] = value
val sb = new StringBuilder
var rfb: StringBuilder = null
val nb = new NodeBuffer()
- val it = zs.iterator
+
+ val it = value.iterator
while (it.hasNext) {
var c = it.next
- c match {
- case '&' => // entity! flush buffer into text node
- it.next match {
- case '#' =>
- c = it.next
- val theChar = parseCharRef ({ ()=> c },{ () => c = it.next },{s => throw new RuntimeException(s)})
- sb.append(theChar)
-
- case x =>
- if (rfb eq null) rfb = new StringBuilder()
- rfb.append(x)
- c = it.next
- while (c != ';') {
- rfb.append(c)
- c = it.next
- }
- val ref = rfb.toString()
- rfb.setLength(0)
- unescape(ref,sb) match {
- case null =>
- if (sb.length > 0) { // flush buffer
- nb += Text(sb.toString())
- sb.setLength(0)
- }
- nb += EntityRef(sb.toString()) // add entityref
- case _ =>
+ // entity! flush buffer into text node
+ if (c == '&') {
+ c = it.next
+ if (c == '#') {
+ c = it.next
+ val theChar = parseCharRef ({ ()=> c },{ () => c = it.next },{s => throw new RuntimeException(s)})
+ sb.append(theChar)
+ }
+ else {
+ if (rfb eq null) rfb = new StringBuilder()
+ rfb append c
+ c = it.next
+ while (c != ';') {
+ rfb.append(c)
+ c = it.next
+ }
+ val ref = rfb.toString()
+ rfb.setLength(0)
+ unescape(ref,sb) match {
+ case null =>
+ if (sb.length > 0) { // flush buffer
+ nb += Text(sb.toString())
+ sb.setLength(0)
}
+ nb += EntityRef(sb.toString()) // add entityref
+ case _ =>
}
- case x =>
- sb.append(x)
+ }
}
+ else sb append c
}
if (sb.length > 0) { // flush buffer
val x = Text(sb.toString())
diff --git a/src/library/scala/xml/parsing/TokenTests.scala b/src/library/scala/xml/parsing/TokenTests.scala
index e4d9b371f8..608a715d15 100644
--- a/src/library/scala/xml/parsing/TokenTests.scala
+++ b/src/library/scala/xml/parsing/TokenTests.scala
@@ -37,7 +37,7 @@ trait TokenTests {
*/
def isNameChar(ch: Char) = isNameStart(ch) || (ch match {
case '.' | '-' | ':' => true;
- case _ => java.lang.Character.getType( ch ).asInstanceOf[Byte] match {
+ case _ => java.lang.Character.getType( ch ).toByte match {
case java.lang.Character.COMBINING_SPACING_MARK => true; // Mc
case java.lang.Character.ENCLOSING_MARK => true; // Me
case java.lang.Character.NON_SPACING_MARK => true; // Mn