summaryrefslogtreecommitdiff
path: root/examples/scala-js/javalanglib/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/javalanglib/src/main')
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Appendable.scala7
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/AutoCloseable.scala5
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Boolean.scala61
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Byte.scala71
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/CharSequence.scala8
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Character.scala289
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Class.scala83
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Cloneable.scala3
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Comparable.scala5
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Double.scala110
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Float.scala96
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala5
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Integer.scala129
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Long.scala196
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Math.scala211
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Number.scala12
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Readable.scala7
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Runnable.scala5
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Runtime.scala47
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Short.scala73
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/StackTraceElement.scala55
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuffer.scala159
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuilder.scala178
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/System.scala275
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Thread.scala16
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/ThreadLocal.scala24
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Throwables.scala363
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/Void.scala7
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala7
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/ref/Reference.scala8
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala3
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala9
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala7
-rw-r--r--examples/scala-js/javalanglib/src/main/scala/java/lang/reflect/Array.scala176
34 files changed, 2710 insertions, 0 deletions
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Appendable.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Appendable.scala
new file mode 100644
index 0000000..9cd74ad
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Appendable.scala
@@ -0,0 +1,7 @@
+package java.lang
+
+trait Appendable {
+ def append(c: Char): Appendable
+ def append(csq: CharSequence): Appendable
+ def append(csq: CharSequence, start: Int, end: Int): Appendable
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/AutoCloseable.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/AutoCloseable.scala
new file mode 100644
index 0000000..21a3d0f
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/AutoCloseable.scala
@@ -0,0 +1,5 @@
+package java.lang
+
+trait AutoCloseable {
+ def close(): Unit
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Boolean.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Boolean.scala
new file mode 100644
index 0000000..94a9967
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Boolean.scala
@@ -0,0 +1,61 @@
+package java.lang
+
+import scala.scalajs.js
+
+/* This is a hijacked class. Its instances are primitive booleans.
+ * Constructors are not emitted.
+ */
+final class Boolean private () extends Comparable[Boolean] {
+
+ def this(value: scala.Boolean) = this()
+ def this(v: String) = this()
+
+ @inline def booleanValue(): scala.Boolean =
+ this.asInstanceOf[scala.Boolean]
+
+ @inline override def equals(that: Any): scala.Boolean =
+ this eq that.asInstanceOf[AnyRef]
+
+ @inline override def hashCode(): Int =
+ if (booleanValue) 1231 else 1237
+
+ @inline override def compareTo(that: Boolean): Int =
+ Boolean.compare(booleanValue, that.booleanValue)
+
+ @inline override def toString(): String =
+ Boolean.toString(booleanValue)
+
+}
+
+object Boolean {
+ final val TYPE = classOf[scala.Boolean]
+
+ /* TRUE and FALSE are supposed to be vals. However, they are better
+ * optimized as defs, because they end up being just the constant true and
+ * false (since `new Boolean(x)` is a no-op).
+ * Since vals and defs are binary-compatible (although they're not strictly
+ * speaking source-compatible, because of stability), we implement them as
+ * defs. Source-compatibility is not an issue because user code is compiled
+ * against the JDK .class files anyway.
+ * Moreover, preserving the identity of TRUE and FALSE is not an issue
+ * either, since they are primitive booleans in the end.
+ */
+ def TRUE: Boolean = new Boolean(true)
+ def FALSE: Boolean = new Boolean(false)
+
+ @inline def valueOf(booleanValue: scala.Boolean): Boolean = {
+ // We don't care about identity, since they end up as primitive booleans
+ new Boolean(booleanValue)
+ }
+
+ @inline def valueOf(s: String): Boolean = valueOf(parseBoolean(s))
+
+ @inline def parseBoolean(s: String): scala.Boolean =
+ (s != null) && s.equalsIgnoreCase("true")
+
+ @inline def toString(b: scala.Boolean): String =
+ "" + b
+
+ @inline def compare(x: scala.Boolean, y: scala.Boolean): scala.Int =
+ if (x == y) 0 else if (x) 1 else -1
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Byte.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Byte.scala
new file mode 100644
index 0000000..dc0c82f
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Byte.scala
@@ -0,0 +1,71 @@
+package java.lang
+
+import scala.scalajs.js
+
+/* This is a hijacked class. Its instances are primitive numbers.
+ * Constructors are not emitted.
+ */
+final class Byte private () extends Number with Comparable[Byte] {
+
+ def this(value: scala.Byte) = this()
+ def this(s: String) = this()
+
+ @inline override def byteValue(): scala.Byte =
+ this.asInstanceOf[scala.Byte]
+
+ @inline override def shortValue(): scala.Short = byteValue.toShort
+ @inline def intValue(): scala.Int = byteValue.toInt
+ @inline def longValue(): scala.Long = byteValue.toLong
+ @inline def floatValue(): scala.Float = byteValue.toFloat
+ @inline def doubleValue(): scala.Double = byteValue.toDouble
+
+ @inline override def equals(that: Any): scala.Boolean =
+ this eq that.asInstanceOf[AnyRef]
+
+ @inline override def hashCode(): Int =
+ byteValue
+
+ @inline override def compareTo(that: Byte): Int =
+ Byte.compare(byteValue, that.byteValue)
+
+ @inline override def toString(): String =
+ Byte.toString(byteValue)
+}
+
+object Byte {
+ final val TYPE = classOf[scala.Byte]
+ final val SIZE = 8
+
+ /* MIN_VALUE and MAX_VALUE should be 'final val's. But it is impossible to
+ * write a proper Byte literal in Scala, that would both considered a Byte
+ * and a constant expression (optimized as final val).
+ * Since vals and defs are binary-compatible (although they're not strictly
+ * speaking source-compatible, because of stability), we implement them as
+ * defs. Source-compatibility is not an issue because user code is compiled
+ * against the JDK .class files anyway.
+ */
+ def MIN_VALUE: scala.Byte = -128
+ def MAX_VALUE: scala.Byte = 127
+
+ @inline def valueOf(byteValue: scala.Byte): Byte = new Byte(byteValue)
+ @inline def valueOf(s: String): Byte = valueOf(parseByte(s))
+
+ @inline def valueOf(s: String, radix: Int): Byte =
+ valueOf(parseByte(s, radix))
+
+ @inline def parseByte(s: String): scala.Byte = parseByte(s, 10)
+
+ def parseByte(s: String, radix: Int): scala.Byte = {
+ val r = Integer.parseInt(s, radix)
+ if (r < MIN_VALUE || r > MAX_VALUE)
+ throw new NumberFormatException(s"""For input string: "$s"""")
+ else
+ r.toByte
+ }
+
+ @inline def toString(b: scala.Byte): String =
+ "" + b
+
+ @inline def compare(x: scala.Byte, y: scala.Byte): scala.Int =
+ x - y
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/CharSequence.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/CharSequence.scala
new file mode 100644
index 0000000..5875a2d
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/CharSequence.scala
@@ -0,0 +1,8 @@
+package java.lang
+
+trait CharSequence {
+ def length(): scala.Int
+ def charAt(index: scala.Int): scala.Char
+ def subSequence(start: scala.Int, end: scala.Int): CharSequence
+ def toString(): String
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Character.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Character.scala
new file mode 100644
index 0000000..1b2b565
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Character.scala
@@ -0,0 +1,289 @@
+package java.lang
+
+import scala.scalajs.js
+
+class Character(private val value: scala.Char) extends Comparable[Character] {
+
+ def charValue(): scala.Char = value
+
+ override def equals(that: Any) =
+ that.isInstanceOf[Character] && (value == that.asInstanceOf[Character].charValue)
+
+ override def compareTo(that: Character): Int =
+ Character.compare(charValue, that.charValue)
+
+ override def toString(): String =
+ Character.toString(value)
+
+ override def hashCode(): Int = value.##
+
+ /*
+ * Methods on scala.Char
+ * The following methods are only here to properly support reflective calls
+ * on boxed primitive values. YOU WILL NOT BE ABLE TO USE THESE METHODS, since
+ * we use the true javalib to lookup symbols, this file contains only
+ * implementations.
+ */
+ protected def toByte: scala.Byte = value.toByte
+ protected def toShort: scala.Short = value.toShort
+ protected def toChar: scala.Char = value.toChar
+ protected def toInt: scala.Int = value
+ protected def toLong: scala.Long = value.toLong
+ protected def toFloat: scala.Float = value.toFloat
+ protected def toDouble: scala.Double = value.toDouble
+
+ protected def unary_~ : scala.Int = ~value
+ protected def unary_+ : scala.Int = value
+ protected def unary_- : scala.Int = -value
+
+ protected def +(x: String): String = value + x
+
+ protected def <<(x: scala.Int): scala.Int = value << x
+ protected def <<(x: scala.Long): scala.Int = value << x
+ protected def >>>(x: scala.Int): scala.Int = value >>> x
+ protected def >>>(x: scala.Long): scala.Int = value >>> x
+ protected def >>(x: scala.Int): scala.Int = value >> x
+ protected def >>(x: scala.Long): scala.Int = value >> x
+
+ protected def ==(x: scala.Byte): scala.Boolean = value == x
+ protected def ==(x: scala.Short): scala.Boolean = value == x
+ protected def ==(x: scala.Char): scala.Boolean = value == x
+ protected def ==(x: scala.Int): scala.Boolean = value == x
+ protected def ==(x: scala.Long): scala.Boolean = value == x
+ protected def ==(x: scala.Float): scala.Boolean = value == x
+ protected def ==(x: scala.Double): scala.Boolean = value == x
+
+ protected def !=(x: scala.Byte): scala.Boolean = value != x
+ protected def !=(x: scala.Short): scala.Boolean = value != x
+ protected def !=(x: scala.Char): scala.Boolean = value != x
+ protected def !=(x: scala.Int): scala.Boolean = value != x
+ protected def !=(x: scala.Long): scala.Boolean = value != x
+ protected def !=(x: scala.Float): scala.Boolean = value != x
+ protected def !=(x: scala.Double): scala.Boolean = value != x
+
+ protected def <(x: scala.Byte): scala.Boolean = value < x
+ protected def <(x: scala.Short): scala.Boolean = value < x
+ protected def <(x: scala.Char): scala.Boolean = value < x
+ protected def <(x: scala.Int): scala.Boolean = value < x
+ protected def <(x: scala.Long): scala.Boolean = value < x
+ protected def <(x: scala.Float): scala.Boolean = value < x
+ protected def <(x: scala.Double): scala.Boolean = value < x
+
+ protected def <=(x: scala.Byte): scala.Boolean = value <= x
+ protected def <=(x: scala.Short): scala.Boolean = value <= x
+ protected def <=(x: scala.Char): scala.Boolean = value <= x
+ protected def <=(x: scala.Int): scala.Boolean = value <= x
+ protected def <=(x: scala.Long): scala.Boolean = value <= x
+ protected def <=(x: scala.Float): scala.Boolean = value <= x
+ protected def <=(x: scala.Double): scala.Boolean = value <= x
+
+ protected def >(x: scala.Byte): scala.Boolean = value > x
+ protected def >(x: scala.Short): scala.Boolean = value > x
+ protected def >(x: scala.Char): scala.Boolean = value > x
+ protected def >(x: scala.Int): scala.Boolean = value > x
+ protected def >(x: scala.Long): scala.Boolean = value > x
+ protected def >(x: scala.Float): scala.Boolean = value > x
+ protected def >(x: scala.Double): scala.Boolean = value > x
+
+ protected def >=(x: scala.Byte): scala.Boolean = value >= x
+ protected def >=(x: scala.Short): scala.Boolean = value >= x
+ protected def >=(x: scala.Char): scala.Boolean = value >= x
+ protected def >=(x: scala.Int): scala.Boolean = value >= x
+ protected def >=(x: scala.Long): scala.Boolean = value >= x
+ protected def >=(x: scala.Float): scala.Boolean = value >= x
+ protected def >=(x: scala.Double): scala.Boolean = value >= x
+
+ protected def |(x: scala.Byte): scala.Int = value | x
+ protected def |(x: scala.Short): scala.Int = value | x
+ protected def |(x: scala.Char): scala.Int = value | x
+ protected def |(x: scala.Int): scala.Int = value | x
+ protected def |(x: scala.Long): scala.Long = value | x
+
+ protected def &(x: scala.Byte): scala.Int = value & x
+ protected def &(x: scala.Short): scala.Int = value & x
+ protected def &(x: scala.Char): scala.Int = value & x
+ protected def &(x: scala.Int): scala.Int = value & x
+ protected def &(x: scala.Long): scala.Long = value & x
+
+ protected def ^(x: scala.Byte): scala.Int = value ^ x
+ protected def ^(x: scala.Short): scala.Int = value ^ x
+ protected def ^(x: scala.Char): scala.Int = value ^ x
+ protected def ^(x: scala.Int): scala.Int = value ^ x
+ protected def ^(x: scala.Long): scala.Long = value ^ x
+
+ protected def +(x: scala.Byte): scala.Int = value + x
+ protected def +(x: scala.Short): scala.Int = value + x
+ protected def +(x: scala.Char): scala.Int = value + x
+ protected def +(x: scala.Int): scala.Int = value + x
+ protected def +(x: scala.Long): scala.Long = value + x
+ protected def +(x: scala.Float): scala.Float = value + x
+ protected def +(x: scala.Double): scala.Double = value + x
+
+ protected def -(x: scala.Byte): scala.Int = value - x
+ protected def -(x: scala.Short): scala.Int = value - x
+ protected def -(x: scala.Char): scala.Int = value - x
+ protected def -(x: scala.Int): scala.Int = value - x
+ protected def -(x: scala.Long): scala.Long = value - x
+ protected def -(x: scala.Float): scala.Float = value - x
+ protected def -(x: scala.Double): scala.Double = value - x
+
+ protected def *(x: scala.Byte): scala.Int = value * x
+ protected def *(x: scala.Short): scala.Int = value * x
+ protected def *(x: scala.Char): scala.Int = value * x
+ protected def *(x: scala.Int): scala.Int = value * x
+ protected def *(x: scala.Long): scala.Long = value * x
+ protected def *(x: scala.Float): scala.Float = value * x
+ protected def *(x: scala.Double): scala.Double = value * x
+
+ protected def /(x: scala.Byte): scala.Int = value / x
+ protected def /(x: scala.Short): scala.Int = value / x
+ protected def /(x: scala.Char): scala.Int = value / x
+ protected def /(x: scala.Int): scala.Int = value / x
+ protected def /(x: scala.Long): scala.Long = value / x
+ protected def /(x: scala.Float): scala.Float = value / x
+ protected def /(x: scala.Double): scala.Double = value / x
+
+ protected def %(x: scala.Byte): scala.Int = value % x
+ protected def %(x: scala.Short): scala.Int = value % x
+ protected def %(x: scala.Char): scala.Int = value % x
+ protected def %(x: scala.Int): scala.Int = value % x
+ protected def %(x: scala.Long): scala.Long = value % x
+ protected def %(x: scala.Float): scala.Float = value % x
+ protected def %(x: scala.Double): scala.Double = value % x
+
+}
+
+object Character {
+ final val TYPE = classOf[scala.Char]
+ final val MIN_VALUE = '\u0000'
+ final val MAX_VALUE = '\uffff'
+ final val SIZE = 16
+
+ def valueOf(charValue: scala.Char) = new Character(charValue)
+
+ /* These are supposed to be final vals of type Byte, but that's not possible.
+ * So we implement them as def's, which are binary compatible with final vals.
+ */
+ def UPPERCASE_LETTER: scala.Byte = 1
+ def LOWERCASE_LETTER: scala.Byte = 2
+ def TITLECASE_LETTER: scala.Byte = 3
+ def MODIFIER_LETTER: scala.Byte = 4
+ def OTHER_LETTER: scala.Byte = 5
+ def NON_SPACING_MARK: scala.Byte = 6
+ def ENCLOSING_MARK: scala.Byte = 7
+ def COMBINING_SPACING_MARK: scala.Byte = 8
+ def DECIMAL_DIGIT_NUMBER: scala.Byte = 9
+ def LETTER_NUMBER: scala.Byte = 10
+ def SURROGATE: scala.Byte = 19
+
+ final val MIN_RADIX = 2
+ final val MAX_RADIX = 36
+
+ final val MIN_HIGH_SURROGATE = '\uD800'
+ final val MAX_HIGH_SURROGATE = '\uDBFF'
+ final val MIN_LOW_SURROGATE = '\uDC00'
+ final val MAX_LOW_SURROGATE = '\uDFFF'
+ final val MIN_SURROGATE = MIN_HIGH_SURROGATE
+ final val MAX_SURROGATE = MAX_LOW_SURROGATE
+
+ final val MIN_CODE_POINT = 0
+ final val MAX_CODE_POINT = 0x10ffff
+ final val MIN_SUPPLEMENTARY_CODE_POINT = 0x10000
+
+ // Not implemented:
+ //def getType(ch: scala.Char): scala.Int
+ //def getType(codePoint: scala.Int): scala.Int
+
+ def digit(c: scala.Char, radix: scala.Int): scala.Int = {
+ if (radix > MAX_RADIX || radix < MIN_RADIX)
+ -1
+ else if (c >= '0' && c <= '9' && c - '0' < radix)
+ c - '0'
+ else if (c >= 'A' && c <= 'Z' && c - 'A' < radix - 10)
+ c - 'A' + 10
+ else if (c >= 'a' && c <= 'z' && c - 'a' < radix - 10)
+ c - 'a' + 10
+ else if (c >= '\uFF21' && c <= '\uFF3A' &&
+ c - '\uFF21' < radix - 10)
+ c - '\uFF21' + 10
+ else if (c >= '\uFF41' && c <= '\uFF5A' &&
+ c - '\uFF41' < radix - 10)
+ c - '\uFF21' + 10
+ else -1
+ }
+
+ def isISOControl(c: scala.Char): scala.Boolean = isISOControl(c.toInt)
+ def isISOControl(codePoint: scala.Int): scala.Boolean = {
+ (0x00 <= codePoint && codePoint <= 0x1F) || (0x7F <= codePoint && codePoint <= 0x9F)
+ }
+
+ def isDigit(c: scala.Char): scala.Boolean = c >= '0' && c <= '9'
+ //def isLetter(c: scala.Char): scala.Boolean
+ //def isLetterOrDigit(c: scala.Char): scala.Boolean
+ def isWhitespace(c: scala.Char): scala.Boolean = js.RegExp("^\\s$").test(c.toString)
+ //def isSpaceChar(c: scala.Char): scala.Boolean
+
+ // --- UTF-16 surrogate pairs handling ---
+ // See http://en.wikipedia.org/wiki/UTF-16
+
+ private final val HighSurrogateMask = 0xfc00 // 111111 00 00000000
+ private final val HighSurrogateID = 0xd800 // 110110 00 00000000
+ private final val LowSurrogateMask = 0xfc00 // 111111 00 00000000
+ private final val LowSurrogateID = 0xdc00 // 110111 00 00000000
+ private final val SurrogateUsefulPartMask = 0x03ff // 000000 11 11111111
+
+ @inline def isHighSurrogate(c: scala.Char): scala.Boolean =
+ (c & HighSurrogateMask) == HighSurrogateID
+ @inline def isLowSurrogate(c: scala.Char): scala.Boolean =
+ (c & LowSurrogateMask) == LowSurrogateID
+ @inline def isSurrogatePair(high: scala.Char, low: scala.Char): scala.Boolean =
+ isHighSurrogate(high) && isLowSurrogate(low)
+
+ @inline def toCodePoint(high: scala.Char, low: scala.Char): scala.Int =
+ ((high & SurrogateUsefulPartMask) << 10) + (low & SurrogateUsefulPartMask) + 0x10000
+
+ // --- End of UTF-16 surrogate pairs handling ---
+
+ def isUnicodeIdentifierStart(c: scala.Char): scala.Boolean =
+ reUnicodeIdentStart.test(c.toString)
+
+ def isUnicodeIdentifierPart(c: scala.Char): scala.Boolean =
+ isUnicodeIdentifierStart(c) || isIdentifierIgnorable(c) ||
+ reUnicodeIdentPartExcl.test(c.toString)
+
+ def isIdentifierIgnorable(c: scala.Char): scala.Boolean =
+ reIdentIgnorable.test(c.toString)
+
+ //def isMirrored(c: scala.Char): scala.Boolean
+ def isLowerCase(c: scala.Char): scala.Boolean = toLowerCase(c) == c
+ def isUpperCase(c: scala.Char): scala.Boolean = toUpperCase(c) == c
+ //def isTitleCase(c: scala.Char): scala.Boolean
+ //def isJavaIdentifierPart(c: scala.Char): scala.Boolean
+
+ //def getDirectionality(c: scala.Char): scala.Byte
+
+ /* Conversions */
+ def toUpperCase(c: scala.Char): scala.Char = c.toString.toUpperCase()(0)
+ def toLowerCase(c: scala.Char): scala.Char = c.toString.toLowerCase()(0)
+ //def toTitleCase(c: scala.Char): scala.Char
+ //def getNumericValue(c: scala.Char): scala.Int
+
+ /* Misc */
+ //def reverseBytes(ch: scala.Char): scala.Char
+
+ @inline def toString(c: scala.Char) = js.String.fromCharCode(c.toInt)
+
+ @inline def compare(x: scala.Char, y: scala.Char): scala.Int =
+ x - y
+
+ // Based on Unicode 7.0.0
+ private[this] lazy val reUnicodeIdentStart =
+ new js.RegExp("""[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]""")
+
+ private[this] lazy val reUnicodeIdentPartExcl =
+ new js.RegExp("""[0-9\x5F\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u0669\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u06F0-\u06F9\u0711\u0730-\u074A\u07A6-\u07B0\u07C0-\u07C9\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0966-\u096F\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09E6-\u09EF\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A66-\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B66-\u0B6F\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0CE6-\u0CEF\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D66-\u0D6F\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0E50-\u0E59\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0ED0-\u0ED9\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1040-\u1049\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u18A9\u1920-\u192B\u1930-\u193B\u1946-\u194F\u19B0-\u19C0\u19C8\u19C9\u19D0-\u19D9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AB0-\u1ABD\u1B00-\u1B04\u1B34-\u1B44\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BB0-\u1BB9\u1BE6-\u1BF3\u1C24-\u1C37\u1C40-\u1C49\u1C50-\u1C59\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u203F\u2040\u2054\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA620-\uA629\uA66F\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F1\uA900-\uA909\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9D0-\uA9D9\uA9E5\uA9F0-\uA9F9\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA50-\uAA59\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uABF0-\uABF9\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFF10-\uFF19\uFF3F]""")
+
+ private[this] lazy val reIdentIgnorable =
+ new js.RegExp("""[\0-\x08\x0E-\x1B\x7F-\x9F\xAD\u0600-\u0605\u061C\u06DD\u070F\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]""")
+
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Class.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Class.scala
new file mode 100644
index 0000000..e8ff46f
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Class.scala
@@ -0,0 +1,83 @@
+package java.lang
+
+import scala.scalajs.js
+
+private trait ScalaJSClassData[A] extends js.Object {
+ val name: String = js.native
+ val isPrimitive: scala.Boolean = js.native
+ val isInterface: scala.Boolean = js.native
+ val isArrayClass: scala.Boolean = js.native
+
+ def isInstance(obj: Object): scala.Boolean = js.native
+ def getFakeInstance(): Object = js.native
+
+ def getSuperclass(): Class[_ >: A] = js.native
+ def getComponentType(): Class[_] = js.native
+
+ def newArrayOfThisClass(dimensions: js.Array[Int]): AnyRef = js.native
+}
+
+final class Class[A] private (data: ScalaJSClassData[A]) extends Object {
+
+ override def toString(): String = {
+ (if (isInterface()) "interface " else
+ if (isPrimitive()) "" else "class ")+getName()
+ }
+
+ def isInstance(obj: Object): scala.Boolean =
+ data.isInstance(obj)
+
+ def isAssignableFrom(that: Class[_]): scala.Boolean =
+ if (this.isPrimitive || that.isPrimitive) {
+ /* This differs from the JVM specification to mimic the behavior of
+ * runtime type tests of primitive numeric types.
+ */
+ (this eq that) || {
+ if (this eq classOf[scala.Short])
+ (that eq classOf[scala.Byte])
+ else if (this eq classOf[scala.Int])
+ (that eq classOf[scala.Byte]) || (that eq classOf[scala.Short])
+ else if (this eq classOf[scala.Float])
+ (that eq classOf[scala.Byte]) || (that eq classOf[scala.Short]) ||
+ (that eq classOf[scala.Int])
+ else if (this eq classOf[scala.Double])
+ (that eq classOf[scala.Byte]) || (that eq classOf[scala.Short]) ||
+ (that eq classOf[scala.Int]) || (that eq classOf[scala.Float])
+ else
+ false
+ }
+ } else {
+ this.isInstance(that.getFakeInstance())
+ }
+
+ private def getFakeInstance(): Object =
+ data.getFakeInstance()
+
+ def isInterface(): scala.Boolean =
+ data.isInterface
+
+ def isArray(): scala.Boolean =
+ data.isArrayClass
+
+ def isPrimitive(): scala.Boolean =
+ data.isPrimitive
+
+ def getName(): String =
+ data.name
+
+ def getSimpleName(): String =
+ data.name.split('.').last.split('$').last
+
+ def getSuperclass(): Class[_ >: A] =
+ data.getSuperclass()
+
+ def getComponentType(): Class[_] =
+ data.getComponentType()
+
+ def getEnclosingClass(): Class[_] = null
+
+ // java.lang.reflect.Array support
+
+ private[lang] def newArrayOfThisClass(dimensions: js.Array[Int]): AnyRef =
+ data.newArrayOfThisClass(dimensions)
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Cloneable.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Cloneable.scala
new file mode 100644
index 0000000..4183bf5
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Cloneable.scala
@@ -0,0 +1,3 @@
+package java.lang
+
+trait Cloneable
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Comparable.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Comparable.scala
new file mode 100644
index 0000000..8d17c6f
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Comparable.scala
@@ -0,0 +1,5 @@
+package java.lang
+
+trait Comparable[A] {
+ def compareTo(o: A): scala.Int
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Double.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Double.scala
new file mode 100644
index 0000000..25987ac
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Double.scala
@@ -0,0 +1,110 @@
+package java.lang
+
+import scala.scalajs.js
+
+/* This is a hijacked class. Its instances are primitive numbers.
+ * Constructors are not emitted.
+ */
+final class Double private () extends Number with Comparable[Double] {
+
+ def this(value: scala.Double) = this()
+ def this(s: String) = this()
+
+ @inline def doubleValue(): scala.Double =
+ this.asInstanceOf[scala.Double]
+
+ @inline override def byteValue(): scala.Byte = doubleValue.toByte
+ @inline override def shortValue(): scala.Short = doubleValue.toShort
+ @inline def intValue(): scala.Int = doubleValue.toInt
+ @inline def longValue(): scala.Long = doubleValue.toLong
+ @inline def floatValue(): scala.Float = doubleValue.toFloat
+
+ override def equals(that: Any): scala.Boolean = that match {
+ case that: Double =>
+ val a = doubleValue
+ val b = that.doubleValue
+ (a == b) || (Double.isNaN(a) && Double.isNaN(b))
+ case _ =>
+ false
+ }
+
+ @inline override def hashCode(): Int =
+ scala.scalajs.runtime.Bits.numberHashCode(doubleValue)
+
+ @inline override def compareTo(that: Double): Int =
+ Double.compare(doubleValue, that.doubleValue)
+
+ @inline override def toString(): String =
+ Double.toString(doubleValue)
+
+ @inline def isNaN(): scala.Boolean =
+ Double.isNaN(doubleValue)
+
+ @inline def isInfinite(): scala.Boolean =
+ Double.isInfinite(doubleValue)
+
+}
+
+object Double {
+ final val TYPE = classOf[scala.Double]
+ final val POSITIVE_INFINITY = 1.0 / 0.0
+ final val NEGATIVE_INFINITY = 1.0 / -0.0
+ final val NaN = 0.0 / 0.0
+ final val MAX_VALUE = scala.Double.MaxValue
+ final val MIN_VALUE = scala.Double.MinPositiveValue
+ final val MAX_EXPONENT = 1023
+ final val MIN_EXPONENT = -1022
+ final val SIZE = 64
+
+ @inline def valueOf(doubleValue: scala.Double): Double =
+ new Double(doubleValue)
+
+ @inline def valueOf(s: String): Double = valueOf(parseDouble(s))
+
+ private[this] lazy val doubleStrPat = new js.RegExp("^" +
+ "[\\x00-\\x20]*" + // optional whitespace
+ "[+-]?" + // optional sign
+ "(NaN|Infinity|" + // special cases
+ "(\\d+\\.?\\d*|" + // literal w/ leading digit
+ "\\.\\d+)" + // literal w/o leading digit
+ "([eE][+-]?\\d+)?"+ // optional exponent
+ ")[fFdD]?" + // optional float / double specifier (ignored)
+ "[\\x00-\\x20]*" + // optional whitespace
+ "$")
+
+ def parseDouble(s: String): scala.Double = {
+ if (doubleStrPat.test(s))
+ js.parseFloat(s)
+ else
+ throw new NumberFormatException(s"""For input string: "$s"""")
+ }
+
+ @inline def toString(d: scala.Double): String =
+ "" + d
+
+ def compare(a: scala.Double, b: scala.Double): scala.Int = {
+ // NaN must equal itself, and be greater than anything else
+ if (isNaN(a)) {
+ if (isNaN(b)) 0
+ else 1
+ } else if (isNaN(b)) {
+ -1
+ } else {
+ if (a == b) 0
+ else if (a < b) -1
+ else 1
+ }
+ }
+
+ @inline def isNaN(v: scala.Double): scala.Boolean =
+ v != v
+
+ @inline def isInfinite(v: scala.Double): scala.Boolean =
+ v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY
+
+ @inline def longBitsToDouble(bits: scala.Long): scala.Double =
+ scala.scalajs.runtime.Bits.longBitsToDouble(bits)
+
+ @inline def doubleToLongBits(value: scala.Double): scala.Long =
+ scala.scalajs.runtime.Bits.doubleToLongBits(value)
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Float.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Float.scala
new file mode 100644
index 0000000..70cb33e
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Float.scala
@@ -0,0 +1,96 @@
+package java.lang
+
+/* This is a hijacked class. Its instances are primitive numbers.
+ * Constructors are not emitted.
+ */
+final class Float private () extends Number with Comparable[Float] {
+
+ def this(value: scala.Float) = this()
+ def this(s: String) = this()
+
+ @inline def floatValue(): scala.Float =
+ this.asInstanceOf[scala.Float]
+
+ @inline override def byteValue(): scala.Byte = floatValue.toByte
+ @inline override def shortValue(): scala.Short = floatValue.toShort
+ @inline def intValue(): scala.Int = floatValue.toInt
+ @inline def longValue(): scala.Long = floatValue.toLong
+ @inline def doubleValue(): scala.Double = floatValue.toDouble
+
+ override def equals(that: Any): scala.Boolean = that match {
+ case that: Double => // yes, Double
+ val a = doubleValue
+ val b = that.doubleValue
+ (a == b) || (Double.isNaN(a) && Double.isNaN(b))
+ case _ =>
+ false
+ }
+
+ // Uses the hashCode of Doubles. See Bits.numberHashCode for the rationale.
+ @inline override def hashCode(): Int =
+ scala.scalajs.runtime.Bits.numberHashCode(doubleValue)
+
+ @inline override def compareTo(that: Float): Int =
+ Float.compare(floatValue, that.floatValue)
+
+ @inline override def toString(): String =
+ Float.toString(floatValue)
+
+ @inline def isNaN(): scala.Boolean =
+ Float.isNaN(floatValue)
+
+ @inline def isInfinite(): scala.Boolean =
+ Float.isInfinite(floatValue)
+
+}
+
+object Float {
+ final val TYPE = classOf[scala.Float]
+ final val POSITIVE_INFINITY = 1.0f / 0.0f
+ final val NEGATIVE_INFINITY = 1.0f / -0.0f
+ final val NaN = 0.0f / 0.0f
+ final val MAX_VALUE = scala.Float.MaxValue
+ final val MIN_VALUE = scala.Float.MinPositiveValue
+ final val MAX_EXPONENT = 127
+ final val MIN_EXPONENT = -126
+ final val SIZE = 32
+
+ @inline def valueOf(floatValue: scala.Float): Float = new Float(floatValue)
+
+ @inline def valueOf(s: String): Float = valueOf(parseFloat(s))
+
+ @inline def parseFloat(s: String): scala.Float =
+ Double.parseDouble(s).toFloat
+
+ @inline def toString(f: scala.Float): String =
+ "" + f
+
+ def compare(a: scala.Float, b: scala.Float): scala.Int = {
+ // NaN must equal itself, and be greater than anything else
+ if (isNaN(a)) {
+ if (isNaN(b)) 0
+ else 1
+ } else if (isNaN(b)) {
+ -1
+ } else {
+ if (a == b) 0
+ else if (a < b) -1
+ else 1
+ }
+ }
+
+ @inline protected def equals(a: scala.Float, b: scala.Float): scala.Boolean =
+ a == b || (isNaN(a) && isNaN(b))
+
+ @inline def isNaN(v: scala.Float): scala.Boolean =
+ v != v
+
+ @inline def isInfinite(v: scala.Float): scala.Boolean =
+ v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY
+
+ @inline def intBitsToFloat(bits: scala.Int): scala.Float =
+ scala.scalajs.runtime.Bits.intBitsToFloat(bits)
+
+ @inline def floatToIntBits(value: scala.Float): scala.Int =
+ scala.scalajs.runtime.Bits.floatToIntBits(value)
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala
new file mode 100644
index 0000000..92ef07c
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/InheritableThreadLocal.scala
@@ -0,0 +1,5 @@
+package java.lang
+
+class InheritableThreadLocal[T] extends ThreadLocal[T] {
+ protected def childValue(parentValue: T): T = parentValue
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Integer.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Integer.scala
new file mode 100644
index 0000000..a002fb7
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Integer.scala
@@ -0,0 +1,129 @@
+package java.lang
+
+import scala.scalajs.js
+
+/* This is a hijacked class. Its instances are primitive numbers.
+ * Constructors are not emitted.
+ */
+final class Integer private () extends Number with Comparable[Integer] {
+
+ def this(value: scala.Int) = this()
+ def this(s: String) = this()
+
+ @inline def intValue(): scala.Int =
+ this.asInstanceOf[scala.Int]
+
+ @inline override def byteValue(): scala.Byte = intValue.toByte
+ @inline override def shortValue(): scala.Short = intValue.toShort
+ @inline def longValue(): scala.Long = intValue.toLong
+ @inline def floatValue(): scala.Float = intValue.toFloat
+ @inline def doubleValue(): scala.Double = intValue.toDouble
+
+ @inline override def equals(that: Any): scala.Boolean =
+ this eq that.asInstanceOf[AnyRef]
+
+ @inline override def hashCode(): Int =
+ intValue
+
+ @inline override def compareTo(that: Integer): Int =
+ Integer.compare(intValue, that.intValue)
+
+ @inline override def toString(): String =
+ Integer.toString(intValue)
+
+}
+
+object Integer {
+ final val TYPE = classOf[scala.Int]
+ final val MIN_VALUE = -2147483648
+ final val MAX_VALUE = 2147483647
+ final val SIZE = 32
+
+ @inline def valueOf(intValue: scala.Int): Integer = new Integer(intValue)
+ @inline def valueOf(s: String): Integer = valueOf(parseInt(s))
+
+ @inline def valueOf(s: String, radix: Int): Integer =
+ valueOf(parseInt(s, radix))
+
+ @inline def parseInt(s: String): scala.Int = parseInt(s, 10)
+
+ def parseInt(s: String, radix: scala.Int): scala.Int = {
+ def fail = throw new NumberFormatException(s"""For input string: "$s"""")
+
+ if (s == null || s.size == 0 ||
+ radix < Character.MIN_RADIX ||
+ radix > Character.MAX_RADIX)
+ fail
+ else {
+ var i = if (s(0) == '-' || s(0) == '+') 1 else 0
+ // JavaDoc says: We need at least one digit
+ if (s.size <= i) fail
+ else {
+ // Check each character for validity
+ while (i < s.size) {
+ if (Character.digit(s(i), radix) < 0) fail
+ i += 1
+ }
+ val res = js.parseInt(s, radix)
+
+ if (js.isNaN(res) || res > MAX_VALUE || res < MIN_VALUE)
+ fail
+ else
+ res.toInt
+ }
+ }
+ }
+
+ @inline def toString(i: scala.Int): String =
+ "" + i
+
+ @inline def compare(x: scala.Int, y: scala.Int): scala.Int =
+ if (x == y) 0 else if (x < y) -1 else 1
+
+ def bitCount(i: scala.Int): scala.Int = {
+ // See http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+ // The implicit casts to 32-bit ints due to binary ops make this work in JS too
+ val t1 = i - ((i >> 1) & 0x55555555)
+ val t2 = (t1 & 0x33333333) + ((t1 >> 2) & 0x33333333)
+ ((t2 + (t2 >> 4) & 0xF0F0F0F) * 0x1010101) >> 24
+ }
+
+ def reverseBytes(i: scala.Int): scala.Int = {
+ val byte3 = i >>> 24
+ val byte2 = (i >>> 8) & 0xFF00
+ val byte1 = (i << 8) & 0xFF0000
+ val byte0 = (i << 24)
+ byte0 | byte1 | byte2 | byte3
+ }
+
+ def rotateLeft(i: scala.Int, distance: scala.Int): scala.Int =
+ (i << distance) | (i >>> -distance)
+
+ def rotateRight(i: scala.Int, distance: scala.Int): scala.Int =
+ (i >>> distance) | (i << -distance)
+
+ @inline def signum(i: scala.Int): scala.Int =
+ if (i == 0) 0 else if (i < 0) -1 else 1
+
+ def numberOfLeadingZeros(i: scala.Int): scala.Int = {
+ // See http://aggregate.org/MAGIC/#Leading%20Zero%20Count
+ var x = i
+ x |= (x >>> 1)
+ x |= (x >>> 2)
+ x |= (x >>> 4)
+ x |= (x >>> 8)
+ x |= (x >>> 16)
+ 32 - bitCount(x)
+ }
+
+ def numberOfTrailingZeros(i: scala.Int): scala.Int =
+ // See http://aggregate.org/MAGIC/#Trailing%20Zero%20Count
+ bitCount((i & -i) - 1)
+
+ def toBinaryString(i: scala.Int): String = toStringBase(i, 2)
+ def toHexString(i: scala.Int): String = toStringBase(i, 16)
+ def toOctalString(i: scala.Int): String = toStringBase(i, 8)
+
+ @inline private[this] def toStringBase(i: scala.Int, base: scala.Int): String =
+ ((i: js.prim.Number) >>> 0).toString(base)
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Long.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Long.scala
new file mode 100644
index 0000000..beeef32
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Long.scala
@@ -0,0 +1,196 @@
+package java.lang
+
+import scala.annotation.tailrec
+
+import scala.scalajs.js
+
+/* This is a hijacked class. Its instances are the representation of scala.Longs.
+ * Constructors are not emitted.
+ */
+final class Long private () extends Number with Comparable[Long] {
+ def this(value: scala.Long) = this()
+ def this(s: String) = this()
+
+ @inline def longValue(): scala.Long =
+ this.asInstanceOf[scala.Long]
+
+ @inline override def byteValue(): scala.Byte = longValue.toByte
+ @inline override def shortValue(): scala.Short = longValue.toShort
+ @inline def intValue(): scala.Int = longValue.toInt
+ @inline def floatValue(): scala.Float = longValue.toFloat
+ @inline def doubleValue(): scala.Double = longValue.toDouble
+
+ @inline override def equals(that: Any): scala.Boolean = that match {
+ case that: Long => longValue == that.longValue
+ case _ => false
+ }
+
+ @inline override def hashCode(): Int =
+ (longValue ^ (longValue >>> 32)).toInt
+
+ @inline override def compareTo(that: Long): Int =
+ Long.compare(longValue, that.longValue)
+
+ @inline override def toString(): String =
+ Long.toString(longValue)
+
+}
+
+object Long {
+ import scala.scalajs.runtime.RuntimeLong
+
+ final val TYPE = classOf[scala.Long]
+ final val MIN_VALUE = -9223372036854775808L
+ final val MAX_VALUE = 9223372036854775807L
+ final val SIZE = 64
+
+ @inline def valueOf(longValue: scala.Long): Long = new Long(longValue)
+ @inline def valueOf(s: String): Long = valueOf(parseLong(s))
+
+ @inline def valueOf(s: String, radix: Int): Long =
+ valueOf(parseLong(s, radix))
+
+ @inline def parseLong(s: String): scala.Long =
+ parseLong(s, 10)
+
+ def parseLong(s: String, radix: Int): scala.Long = {
+ def fail() = throw new NumberFormatException(s"""For input string: "$s"""")
+
+ if (s.isEmpty) {
+ fail()
+ } else if (s.charAt(0) == '-') {
+ -parseLong(s.substring(1), radix)
+ } else {
+ @inline
+ @tailrec
+ def fastPow(base: Int, exp: Int, acc: Int = 1): Int =
+ if (exp == 0) acc
+ else if (exp % 2 == 0) fastPow(base*base, exp/2, acc)
+ else fastPow(base, exp-1, acc*base)
+
+ @inline
+ @tailrec
+ def loop(str0: String, acc: scala.Long): scala.Long = if (str0.length > 0) {
+ val MaxLen = 9
+ val cur = (str0: js.prim.String).substring(0, MaxLen): String
+ val macc = acc * fastPow(radix, cur.length)
+ val ival = js.parseInt(cur, radix): scala.Double
+ if (ival.isNaN)
+ fail()
+ val cval = ival.toInt.toLong // faster than ival.toLong
+ loop((str0: js.prim.String).substring(MaxLen), macc + cval)
+ } else acc
+
+ loop(s, 0L)
+ }
+ }
+
+ def toString(l: scala.Long): String = {
+ if (l == 0L) "0"
+ // Check for MinValue, because it is not negatable
+ else if (l == MIN_VALUE) "-9223372036854775808"
+ else if (l < 0L) "-" + toString(-l)
+ else {
+ @tailrec
+ @inline
+ def toString0(v: scala.Long, acc: String): String = {
+ val quot = v / 1000000000L // 9 zeros
+ val rem = v % 1000000000L
+
+ val digits = rem.toInt.toString
+
+ if (quot == 0L) {
+ digits + acc
+ } else {
+ val padding = "000000000".substring(digits.length) // (9 - digits.length) zeros
+ toString0(quot, padding + digits + acc)
+ }
+ }
+
+ toString0(l, "")
+ }
+ }
+
+ @inline def compare(x: scala.Long, y: scala.Long): scala.Int =
+ if (x == y) 0 else if (x < y) -1 else 1
+
+ def bitCount(i: scala.Long): scala.Int = {
+ val lo = i.toInt
+ val hi = (i >>> 32).toInt
+ Integer.bitCount(lo) + Integer.bitCount(hi)
+ }
+
+ def reverseBytes(i: scala.Long): scala.Long = {
+ val hiReversed = Integer.reverseBytes((i >>> 32).toInt)
+ val loReversed = Integer.reverseBytes(i.toInt)
+ (loReversed.toLong << 32) | (hiReversed.toLong & 0xffffffffL)
+ }
+
+ def rotateLeft(i: scala.Long, distance: scala.Int): scala.Long =
+ (i << distance) | (i >>> -distance)
+
+ def rotateRight(i: scala.Long, distance: scala.Int): scala.Long =
+ (i >>> distance) | (i << -distance)
+
+ def signum(i: scala.Long): scala.Long =
+ if (i < 0L) -1L else if (i == 0L) 0L else 1L
+
+ def numberOfLeadingZeros(l: scala.Long): Int = {
+ val hi = (l >>> 32).toInt
+ if (hi != 0) Integer.numberOfLeadingZeros(hi)
+ else Integer.numberOfLeadingZeros(l.toInt) + 32
+ }
+
+ def numberOfTrailingZeros(l: scala.Long): Int = {
+ val lo = l.toInt
+ if (lo != 0) Integer.numberOfTrailingZeros(lo)
+ else Integer.numberOfTrailingZeros((l >>> 32).toInt) + 32
+ }
+
+ def toBinaryString(l: scala.Long): String = {
+ val zeros = "00000000000000000000000000000000" // 32 zeros
+ @inline def padBinary32(i: Int) = {
+ val s = Integer.toBinaryString(i)
+ zeros.substring(s.length) + s
+ }
+
+ val lo = l.toInt
+ val hi = (l >>> 32).toInt
+
+ if (hi != 0) Integer.toBinaryString(hi) + padBinary32(lo)
+ else Integer.toBinaryString(lo)
+ }
+
+ def toHexString(l: scala.Long): String = {
+ val zeros = "00000000" // 8 zeros
+ @inline def padBinary8(i: Int) = {
+ val s = Integer.toHexString(i)
+ zeros.substring(s.length) + s
+ }
+
+ val lo = l.toInt
+ val hi = (l >>> 32).toInt
+
+ if (hi != 0) Integer.toHexString(hi) + padBinary8(lo)
+ else Integer.toHexString(lo)
+ }
+
+ def toOctalString(l: scala.Long): String = {
+ val zeros = "0000000000" // 10 zeros
+ @inline def padOctal10(i: Int) = {
+ val s = Integer.toOctalString(i)
+ zeros.substring(s.length) + s
+ }
+
+ val lo = l.toInt
+ val hi = (l >>> 32).toInt
+
+ val lp = lo & 0x3fffffff
+ val mp = ((lo >>> 30) + (hi << 2)) & 0x3fffffff
+ val hp = hi >>> 28
+
+ if (hp != 0) Integer.toOctalString(hp) + padOctal10(mp) + padOctal10(lp)
+ else if (mp != 0) Integer.toOctalString(mp) + padOctal10(lp)
+ else Integer.toOctalString(lp)
+ }
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Math.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Math.scala
new file mode 100644
index 0000000..c8cd7aa
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Math.scala
@@ -0,0 +1,211 @@
+package java
+package lang
+
+import scala.scalajs.js
+
+object Math {
+ private lazy val internalRandom = new java.util.Random()
+
+ final val E = 2.718281828459045
+ final val PI = 3.141592653589793
+
+ @inline def abs(a: scala.Int): scala.Int = if (a < 0) -a else a
+ @inline def abs(a: scala.Long): scala.Long = if (a < 0) -a else a
+ @inline def abs(a: scala.Float): scala.Float = if (a < 0) -a else a
+ @inline def abs(a: scala.Double): scala.Double = if (a < 0) -a else a
+
+ @inline def max(a: scala.Int, b: scala.Int): scala.Int = if (a > b) a else b
+ @inline def max(a: scala.Long, b: scala.Long): scala.Long = if (a > b) a else b
+ @inline def max(a: scala.Float, b: scala.Float): scala.Float = if (a > b) a else b
+ @inline def max(a: scala.Double, b: scala.Double): scala.Double = if (a > b) a else b
+
+ @inline def min(a: scala.Int, b: scala.Int): scala.Int = if (a < b) a else b
+ @inline def min(a: scala.Long, b: scala.Long): scala.Long = if (a < b) a else b
+ @inline def min(a: scala.Float, b: scala.Float): scala.Float = if (a < b) a else b
+ @inline def min(a: scala.Double, b: scala.Double): scala.Double = if (a < b) a else b
+
+ @inline def ceil(a: scala.Double): scala.Double = js.Math.ceil(a)
+ @inline def floor(a: scala.Double): scala.Double = js.Math.floor(a)
+
+ @inline def round(a: scala.Float): scala.Int = js.Math.round(a).toInt
+ @inline def round(a: scala.Double): scala.Long = js.Math.round(a).toLong
+
+ @inline def sqrt(a: scala.Double): scala.Double = js.Math.sqrt(a)
+ @inline def pow(a: scala.Double, b: scala.Double): scala.Double = js.Math.pow(a, b)
+
+ @inline def exp(a: scala.Double): scala.Double = js.Math.exp(a)
+ @inline def log(a: scala.Double): scala.Double = js.Math.log(a)
+ @inline def log10(a: scala.Double): scala.Double = log(a) / 2.302585092994046
+ @inline def log1p(a: scala.Double): scala.Double = log(a + 1)
+
+ @inline def sin(a: scala.Double): scala.Double = js.Math.sin(a)
+ @inline def cos(a: scala.Double): scala.Double = js.Math.cos(a)
+ @inline def tan(a: scala.Double): scala.Double = js.Math.tan(a)
+ @inline def asin(a: scala.Double): scala.Double = js.Math.asin(a)
+ @inline def acos(a: scala.Double): scala.Double = js.Math.acos(a)
+ @inline def atan(a: scala.Double): scala.Double = js.Math.atan(a)
+ @inline def atan2(y: scala.Double, x: scala.Double): scala.Double = js.Math.atan2(y, x)
+
+ def random(): scala.Double = internalRandom.nextDouble()
+
+ @inline def toDegrees(a: scala.Double): scala.Double = a * 180.0 / PI
+ @inline def toRadians(a: scala.Double): scala.Double = a / 180.0 * PI
+
+ @inline def signum(a: scala.Double): scala.Double = {
+ if (a > 0) 1.0
+ else if (a < 0) -1.0
+ else a
+ }
+
+ @inline def signum(a: scala.Float): scala.Float = {
+ if (a > 0) 1.0f
+ else if (a < 0) -1.0f
+ else a
+ }
+
+ def cbrt(a: scala.Double): scala.Double = {
+ if (a == 0 || a.isNaN)
+ return a
+
+ val sign = if (a < 0.0) -1.0 else 1.0
+ val value = sign * a
+
+ //Initial Approximation
+ var x = 0.0
+ var xi = pow(value, 0.3333333333333333)
+
+ //Halley's Method (http://metamerist.com/cbrt/cbrt.htm)
+ while (abs(x - xi) >= 1E-16) {
+ x = xi
+ val x3 = js.Math.pow(x, 3)
+ val x3Plusa = x3 + value
+ xi = x * (x3Plusa + value) / (x3Plusa + x3)
+ }
+ return sign * xi
+ }
+
+ def nextUp(a: scala.Double): scala.Double = {
+ // js implementation of nextUp https://gist.github.com/Yaffle/4654250
+ import scala.Double._
+ if (a != a || a == PositiveInfinity)
+ a
+ else if (a == NegativeInfinity)
+ -MaxValue
+ else if (a == MaxValue)
+ PositiveInfinity
+ else if (a == 0)
+ MinValue
+ else {
+ def iter(x: scala.Double, xi: scala.Double, n: scala.Double): scala.Double = {
+ if (Math.abs(xi - x) >= 1E-16) {
+ val c0 = (xi + x) / 2
+ val c =
+ if (c0 == NegativeInfinity || c0 == PositiveInfinity)
+ x + (xi - x) / 2
+ else
+ c0
+ if (n == c) xi
+ else if (a < c) iter(x = x, xi = c, n = c)
+ else iter(x = c, xi = xi, n = c)
+ }
+ else xi
+ }
+ val d = Math.max(Math.abs(a) * 2E-16, MinValue)
+ val ad = a + d
+ val xi0 =
+ if (ad == PositiveInfinity) MaxValue
+ else ad
+ iter(x = a, xi = xi0, n = a)
+ }
+ }
+
+ def nextAfter(a: scala.Double, b: scala.Double): scala.Double = {
+ if (b < a)
+ -nextUp(-a)
+ else if (a < b)
+ nextUp(a)
+ else if (a != a || b != b)
+ scala.Double.NaN
+ else
+ b
+ }
+
+ def ulp(a: scala.Double): scala.Double = {
+ if (abs(a) == scala.Double.PositiveInfinity)
+ scala.Double.PositiveInfinity
+ else if (abs(a) == scala.Double.MaxValue)
+ pow(2, 971)
+ else
+ nextAfter(abs(a), scala.Double.MaxValue) - a
+ }
+
+ def hypot(a: scala.Double, b: scala.Double): scala.Double = {
+ // http://en.wikipedia.org/wiki/Hypot#Implementation
+ if (abs(a) == scala.Double.PositiveInfinity || abs(b) == scala.Double.PositiveInfinity)
+ scala.Double.PositiveInfinity
+ else if (a.isNaN || b.isNaN)
+ scala.Double.NaN
+ else if (a == 0 && b == 0)
+ 0.0
+ else {
+ //To Avoid Overflow and UnderFlow
+ // calculate |x| * sqrt(1 - (y/x)^2) instead of sqrt(x^2 + y^2)
+ val x = abs(a)
+ val y = abs(b)
+ val m = max(x, y)
+ val t = min(x, y) / m
+ m * sqrt(1 + t * t)
+ }
+ }
+
+ def expm1(a: scala.Double): scala.Double = {
+ // https://github.com/ghewgill/picomath/blob/master/javascript/expm1.js
+ if (a == 0 || a.isNaN)
+ a
+ // Power Series http://en.wikipedia.org/wiki/Power_series
+ // for small values of a, exp(a) = 1 + a + (a*a)/2
+ else if (abs(a) < 1E-5)
+ a + 0.5 * a * a
+ else
+ exp(a) - 1.0
+ }
+
+ def sinh(a: scala.Double): scala.Double = {
+ if (a.isNaN || a == 0.0 || abs(a) == scala.Double.PositiveInfinity)
+ a
+ else
+ (exp(a) - exp(-a)) / 2.0
+ }
+
+ def cosh(a: scala.Double): scala.Double = {
+ if (a.isNaN)
+ a
+ else if (a == 0.0)
+ 1.0
+ else if (abs(a) == scala.Double.PositiveInfinity)
+ scala.Double.PositiveInfinity
+ else
+ (exp(a) + exp(-a)) / 2.0
+ }
+
+ def tanh(a: scala.Double): scala.Double = {
+ if (a.isNaN || a == 0.0)
+ a
+ else if (abs(a) == scala.Double.PositiveInfinity)
+ signum(a)
+ else {
+ // sinh(a) / cosh(a) =
+ // 1 - 2 * (exp(-a)/ (exp(-a) + exp (a)))
+ val expma = exp(-a)
+ if (expma == scala.Double.PositiveInfinity) //Infinity / Infinity
+ -1.0
+ else {
+ val expa = exp(a)
+ val ret = expma / (expa + expma)
+ 1.0 - (2.0 * ret)
+ }
+ }
+ }
+
+ // TODO The methods not available in the JavaScript Math object
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Number.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Number.scala
new file mode 100644
index 0000000..05ffc7a
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Number.scala
@@ -0,0 +1,12 @@
+package java.lang
+
+import scala.scalajs.js
+
+abstract class Number extends Object {
+ def byteValue(): scala.Byte = intValue.toByte
+ def shortValue(): scala.Short = intValue.toShort
+ def intValue(): scala.Int
+ def longValue(): scala.Long
+ def floatValue(): scala.Float
+ def doubleValue(): scala.Double
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Readable.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Readable.scala
new file mode 100644
index 0000000..53e5689
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Readable.scala
@@ -0,0 +1,7 @@
+package java.lang
+
+import java.nio.CharBuffer
+
+trait Readable {
+ def read(cb: CharBuffer): Int
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Runnable.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Runnable.scala
new file mode 100644
index 0000000..c98cb41
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Runnable.scala
@@ -0,0 +1,5 @@
+package java.lang
+
+trait Runnable {
+ def run(): Unit
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Runtime.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Runtime.scala
new file mode 100644
index 0000000..25aaa9f
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Runtime.scala
@@ -0,0 +1,47 @@
+package java.lang
+
+import scala.scalajs.js
+
+class Runtime private {
+ def exit(status: Int): Unit =
+ halt(status)
+
+ //def addShutdownHook(hook: Thread): Unit
+ //def removeShutdownHook(hook: Thread): Unit
+
+ def halt(status: Int): Unit = {
+ val envInfo = scala.scalajs.runtime.environmentInfo
+
+ if (js.typeOf(envInfo.exitFunction) == "function") {
+ envInfo.exitFunction(status)
+ throw new IllegalStateException("__ScalaJSEnv.exitFunction returned")
+ } else {
+ // We don't have an exit function. Fail
+ throw new SecurityException("Cannot terminate a JavaScript program. " +
+ "Define a JavaScript function `__ScalaJSEnv.exitFunction` to " +
+ "be called on exit.")
+ }
+ }
+
+ def availableProcessors(): Int = 1
+ //def freeMemory(): scala.Long
+ //def totalMemory(): scala.Long
+ //def maxMemory(): scala.Long
+
+ def gc(): Unit = {
+ // Ignore
+ }
+
+ //def runFinalization(): Unit
+ //def traceInstructions(on: scala.Boolean): Unit
+ //def traceMethodCalls(on: scala.Boolean): Unit
+
+ //def load(filename: String): Unit
+ //def loadLibrary(filename: String): Unit
+}
+
+object Runtime {
+ private val currentRuntime = new Runtime
+
+ def getRuntime() = currentRuntime
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Short.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Short.scala
new file mode 100644
index 0000000..135fe12
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Short.scala
@@ -0,0 +1,73 @@
+package java.lang
+
+/* This is a hijacked class. Its instances are primitive numbers.
+ * Constructors are not emitted.
+ */
+final class Short private () extends Number with Comparable[Short] {
+
+ def this(value: scala.Short) = this()
+ def this(s: String) = this()
+
+ @inline override def shortValue(): scala.Short =
+ this.asInstanceOf[scala.Short]
+
+ @inline override def byteValue(): scala.Byte = shortValue.toByte
+ @inline def intValue(): scala.Int = shortValue.toInt
+ @inline def longValue(): scala.Long = shortValue.toLong
+ @inline def floatValue(): scala.Float = shortValue.toFloat
+ @inline def doubleValue(): scala.Double = shortValue.toDouble
+
+ @inline override def equals(that: Any): scala.Boolean =
+ this eq that.asInstanceOf[AnyRef]
+
+ @inline override def hashCode(): Int =
+ shortValue
+
+ @inline override def compareTo(that: Short): Int =
+ Short.compare(shortValue, that.shortValue)
+
+ @inline override def toString(): String =
+ Short.toString(shortValue)
+
+}
+
+object Short {
+ final val TYPE = classOf[scala.Short]
+ final val SIZE = 16
+
+ /* MIN_VALUE and MAX_VALUE should be 'final val's. But it is impossible to
+ * write a proper Short literal in Scala, that would both considered a Short
+ * and a constant expression (optimized as final val).
+ * Since vals and defs are binary-compatible (although they're not strictly
+ * speaking source-compatible, because of stability), we implement them as
+ * defs. Source-compatibility is not an issue because user code is compiled
+ * against the JDK .class files anyway.
+ */
+ def MIN_VALUE: scala.Short = -32768
+ def MAX_VALUE: scala.Short = 32767
+
+ @inline def valueOf(shortValue: scala.Short): Short = new Short(shortValue)
+ @inline def valueOf(s: String): Short = valueOf(parseShort(s))
+
+ @inline def valueOf(s: String, radix: Int): Short =
+ valueOf(parseShort(s, radix))
+
+ @inline def parseShort(s: String): scala.Short = parseShort(s, 10)
+
+ def parseShort(s: String, radix: Int): scala.Short = {
+ val r = Integer.parseInt(s, radix)
+ if (r < MIN_VALUE || r > MAX_VALUE)
+ throw new NumberFormatException(s"""For input string: "$s"""")
+ else
+ r.toShort
+ }
+
+ @inline def toString(s: scala.Short): String =
+ "" + s
+
+ @inline def compare(x: scala.Short, y: scala.Short): scala.Int =
+ x - y
+
+ def reverseBytes(i: scala.Short): scala.Short =
+ (((i >>> 8) & 0xff) + ((i & 0xff) << 8)).toShort
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/StackTraceElement.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/StackTraceElement.scala
new file mode 100644
index 0000000..cc87aec
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/StackTraceElement.scala
@@ -0,0 +1,55 @@
+package java.lang
+
+import scala.scalajs.js
+
+final class StackTraceElement(declaringClass: String, methodName: String,
+ fileName: String, lineNumber: Int) extends AnyRef with java.io.Serializable {
+
+ def getFileName(): String = fileName
+ def getLineNumber(): Int = lineNumber
+ def getClassName(): String = declaringClass
+ def getMethodName(): String = methodName
+ def isNativeMethod(): scala.Boolean = false
+
+ override def equals(that: Any): scala.Boolean = that match {
+ case that: StackTraceElement =>
+ (getFileName == that.getFileName) &&
+ (getLineNumber == that.getLineNumber) &&
+ (getClassName == that.getClassName) &&
+ (getMethodName == that.getMethodName)
+ case _ =>
+ false
+ }
+
+ override def toString(): String = {
+ var result = ""
+ if (declaringClass != "<jscode>")
+ result += declaringClass + "."
+ result += methodName
+ if (fileName eq null) {
+ if (isNativeMethod)
+ result += "(Native Method)"
+ else
+ result += "(Unknown Source)"
+ } else {
+ result += s"($fileName"
+ if (lineNumber >= 0) {
+ result += s":$lineNumber"
+ if (columnNumber >= 0)
+ result += s":$columnNumber"
+ }
+ result += ")"
+ }
+ result
+ }
+
+ override def hashCode(): Int = {
+ declaringClass.hashCode() ^ methodName.hashCode()
+ }
+
+ private def columnNumber: Int = {
+ val rawNum = this.asInstanceOf[js.Dynamic].columnNumber
+ if (!(!rawNum)) rawNum.asInstanceOf[Int]
+ else -1
+ }
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuffer.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuffer.scala
new file mode 100644
index 0000000..31ee89a
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuffer.scala
@@ -0,0 +1,159 @@
+package java.lang
+
+class StringBuffer(private var content: String) extends CharSequence
+ with Appendable
+ with java.io.Serializable {
+ def this() = this("")
+ def this(initialCapacity: Int) = this("")
+ def this(csq: CharSequence) = this(csq.toString)
+
+ def append(s: String): StringBuffer = {
+ content += { if (s == null) "null" else s }
+ this
+ }
+
+ def append(b: scala.Boolean): StringBuffer = append(b.toString())
+ def append(c: scala.Char): StringBuffer = append(c.toString())
+
+ def append(str: Array[scala.Char]): StringBuffer =
+ append(str, 0, str.length)
+
+ def append(str: Array[scala.Char], offset: Int, len: Int): StringBuffer = {
+ var i = 0
+ while (i < len) {
+ content += str(i + offset)
+ i += 1
+ }
+ this
+ }
+
+ def append(b: scala.Byte): StringBuffer = append(b.toString())
+ def append(s: scala.Short): StringBuffer = append(s.toString())
+ def append(i: scala.Int): StringBuffer = append(i.toString())
+ def append(lng: scala.Long): StringBuffer = append(lng.toString())
+ def append(f: scala.Float): StringBuffer = append(f.toString())
+ def append(d: scala.Double): StringBuffer = append(d.toString())
+
+ def append(obj: AnyRef): StringBuffer = {
+ if (obj == null) append(null: String)
+ else append(obj.toString())
+ }
+
+ def append(csq: CharSequence): StringBuffer = append(csq: AnyRef)
+ def append(csq: CharSequence, start: Int, end: Int): StringBuffer = {
+ if (csq == null) append("null", start, end)
+ else append(csq.subSequence(start, end).toString())
+ }
+
+ override def toString() = content
+
+ def length() = content.length()
+
+ def charAt(index: Int) = content.charAt(index)
+ def codePointAt(index: Int) = content.codePointAt(index)
+
+ def indexOf(str: String) = content.indexOf(str)
+ def indexOf(str: String, fromIndex: Int) = content.indexOf(str, fromIndex)
+
+ def lastIndexOf(str: String) = content.lastIndexOf(str)
+ def lastIndexOf(str: String, fromIndex: Int) = content.lastIndexOf(str, fromIndex)
+
+ def subSequence(start: Int, end: Int): CharSequence = substring(start, end)
+ def substring(start: Int): String = content.substring(start)
+ def substring(start: Int, end: Int): String = content.substring(start, end)
+
+ def reverse(): StringBuffer = {
+ content = new StringBuilder(content).reverse().toString()
+ this
+ }
+
+ def deleteCharAt(index: Int): StringBuffer = {
+ if (index < 0 || index >= content.length)
+ throw new StringIndexOutOfBoundsException("String index out of range: " + index)
+ content = content.substring(0, index) + content.substring(index+1)
+ this
+ }
+
+ /**
+ * @param start The beginning index, inclusive.
+ * @param end The ending index, exclusive.
+ * @param str String that will replace previous contents.
+ * @return This StringBuilder.
+ */
+ def replace(start: Int, end: Int, str: String): StringBuffer = {
+ val length = content.length
+ if (start < 0 || start > end || start >= length)
+ throw new StringIndexOutOfBoundsException(s"Illegal to replace substring at [$start - $end] in string of length $length")
+ val realEnd = if (end > length) length else end // java api convention
+ content = content.substring(0, start) + str + content.substring(realEnd)
+ this
+ }
+
+ def setCharAt(index: Int, ch: scala.Char): Unit = {
+ if (index < 0 || index >= content.length)
+ throw new IndexOutOfBoundsException("String index out of range: " + index)
+ content = content.substring(0, index) + ch + content.substring(index + 1)
+ }
+
+ def setLength(newLength: Int): Unit = {
+ if (newLength < 0)
+ throw new IndexOutOfBoundsException("String index out of range: " + newLength)
+
+ val len = length()
+ if (len == newLength) {
+ } else if (len < newLength) {
+ var index = len
+ while (index < newLength) {
+ append("\u0000")
+ index += 1
+ }
+ } else {
+ content = substring(0, newLength)
+ }
+ }
+
+ def insert(index: Int, b: scala.Boolean): StringBuffer = insert(index, b.toString)
+ def insert(index: Int, b: scala.Byte): StringBuffer = insert(index, b.toString)
+ def insert(index: Int, s: scala.Short): StringBuffer = insert(index, s.toString)
+ def insert(index: Int, i: scala.Int): StringBuffer = insert(index, i.toString)
+ def insert(index: Int, l: scala.Long): StringBuffer = insert(index, l.toString)
+ def insert(index: Int, f: scala.Float): StringBuffer = insert(index, f.toString)
+ def insert(index: Int, d: scala.Double): StringBuffer = insert(index, d.toString)
+ def insert(index: Int, c: scala.Char): StringBuffer = insert(index, c.toString)
+ def insert(index: Int, csq: CharSequence): StringBuffer = insert(index: Int, csq: AnyRef)
+ def insert(index: Int, arr: Array[scala.Char]): StringBuffer = insert(index, arr, 0, arr.length)
+
+ def insert(index: Int, ref: AnyRef): StringBuffer =
+ if (ref == null)
+ insert(index, null: String)
+ else
+ insert(index, ref.toString)
+
+ def insert(index: Int, csq: CharSequence, start: Int, end: Int): StringBuffer =
+ if (csq == null)
+ insert(index, "null", start, end)
+ else
+ insert(index, csq.subSequence(start, end).toString)
+
+
+ def insert(index: Int, arr: Array[scala.Char], offset: Int, len: Int): StringBuffer = {
+ var str = ""
+ var i = 0
+ while (i < len) {
+ str += arr(i + offset)
+ i += 1
+ }
+ insert(index, str)
+ }
+
+ def insert(index: Int, str: String): StringBuffer = {
+ val thisLength = length()
+ if (index < 0 || index > thisLength)
+ throw new StringIndexOutOfBoundsException(index)
+ else if (index == thisLength)
+ append(str)
+ else
+ content = content.substring(0, index) + Option(str).getOrElse("null") + content.substring(index)
+ this
+ }
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuilder.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuilder.scala
new file mode 100644
index 0000000..e8bd2b7
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/StringBuilder.scala
@@ -0,0 +1,178 @@
+package java.lang
+
+class StringBuilder(private var content: String) extends CharSequence
+ with Appendable
+ with java.io.Serializable {
+ def this() = this("")
+ def this(initialCapacity: Int) = this("")
+ def this(csq: CharSequence) = this(csq.toString)
+
+ def append(s: String): StringBuilder = {
+ content += { if (s == null) "null" else s }
+ this
+ }
+
+ def append(b: scala.Boolean): StringBuilder = append(b.toString())
+ def append(c: scala.Char): StringBuilder = append(c.toString())
+
+ def append(str: Array[scala.Char]): StringBuilder =
+ append(str, 0, str.length)
+
+ def append(str: Array[scala.Char], offset: Int, len: Int): StringBuilder = {
+ var i = 0
+ while (i < len) {
+ content += str(i + offset)
+ i += 1
+ }
+ this
+ }
+
+ def append(b: scala.Byte): StringBuilder = append(b.toString())
+ def append(s: scala.Short): StringBuilder = append(s.toString())
+ def append(i: scala.Int): StringBuilder = append(i.toString())
+ def append(lng: scala.Long): StringBuilder = append(lng.toString())
+ def append(f: scala.Float): StringBuilder = append(f.toString())
+ def append(d: scala.Double): StringBuilder = append(d.toString())
+
+ def append(obj: AnyRef): StringBuilder = {
+ if (obj == null) append(null: String)
+ else append(obj.toString())
+ }
+
+ def append(csq: CharSequence): StringBuilder = append(csq: AnyRef)
+ def append(csq: CharSequence, start: Int, end: Int): StringBuilder = {
+ if (csq == null) append("null", start, end)
+ else append(csq.subSequence(start, end).toString())
+ }
+
+ override def toString() = content
+
+ def length() = content.length()
+
+ def charAt(index: Int) = content.charAt(index)
+ def codePointAt(index: Int) = content.codePointAt(index)
+
+ def indexOf(str: String) = content.indexOf(str)
+ def indexOf(str: String, fromIndex: Int) = content.indexOf(str, fromIndex)
+
+ def lastIndexOf(str: String) = content.lastIndexOf(str)
+ def lastIndexOf(str: String, fromIndex: Int) = content.lastIndexOf(str, fromIndex)
+
+ def subSequence(start: Int, end: Int): CharSequence = substring(start, end)
+ def substring(start: Int): String = content.substring(start)
+ def substring(start: Int, end: Int): String = content.substring(start, end)
+
+ def reverse(): StringBuilder = {
+ val original = content
+ var result = ""
+ var i = 0
+ while (i < original.length) {
+ val c = original.charAt(i)
+ if (Character.isHighSurrogate(c) && (i+1 < original.length)) {
+ val c2 = original.charAt(i+1)
+ if (Character.isLowSurrogate(c2)) {
+ result = c.toString + c2.toString + result
+ i += 2
+ } else {
+ result = c.toString + result
+ i += 1
+ }
+ } else {
+ result = c.toString + result
+ i += 1
+ }
+ }
+ content = result
+ this
+ }
+
+ def deleteCharAt(index: Int): StringBuilder = {
+ if (index < 0 || index >= content.length)
+ throw new StringIndexOutOfBoundsException("String index out of range: " + index)
+ content = content.substring(0, index) + content.substring(index+1)
+ this
+ }
+
+ /**
+ * @param start The beginning index, inclusive.
+ * @param end The ending index, exclusive.
+ * @param str String that will replace previous contents.
+ * @return This StringBuilder.
+ */
+ def replace(start: Int, end: Int, str: String): StringBuilder = {
+ val length = content.length
+ if (start < 0 || start > end || start >= length)
+ throw new StringIndexOutOfBoundsException(s"Illegal to replace substring at [$start - $end] in string of length $length")
+ val realEnd = if (end > length) length else end // java api convention
+ content = content.substring(0, start) + str + content.substring(realEnd)
+ this
+ }
+
+ def setCharAt(index: Int, ch: scala.Char): Unit = {
+ if (index < 0 || index >= content.length)
+ throw new IndexOutOfBoundsException("String index out of range: " + index)
+ content = content.substring(0, index) + ch + content.substring(index + 1)
+ }
+
+ def setLength(newLength: Int): Unit = {
+ if (newLength < 0)
+ throw new IndexOutOfBoundsException("String index out of range: " + newLength)
+
+ val len = length()
+ if (len == newLength) {
+ } else if (len < newLength) {
+ var index = len
+ while (index < newLength) {
+ append("\u0000")
+ index += 1
+ }
+ } else {
+ content = substring(0, newLength)
+ }
+ }
+
+ def insert(index: Int, b: scala.Boolean): StringBuilder = insert(index, b.toString)
+ def insert(index: Int, b: scala.Byte): StringBuilder = insert(index, b.toString)
+ def insert(index: Int, s: scala.Short): StringBuilder = insert(index, s.toString)
+ def insert(index: Int, i: scala.Int): StringBuilder = insert(index, i.toString)
+ def insert(index: Int, l: scala.Long): StringBuilder = insert(index, l.toString)
+ def insert(index: Int, f: scala.Float): StringBuilder = insert(index, f.toString)
+ def insert(index: Int, d: scala.Double): StringBuilder = insert(index, d.toString)
+ def insert(index: Int, c: scala.Char): StringBuilder = insert(index, c.toString)
+ def insert(index: Int, csq: CharSequence): StringBuilder = insert(index: Int, csq: AnyRef)
+ def insert(index: Int, arr: Array[scala.Char]): StringBuilder = insert(index, arr, 0, arr.length)
+
+ def insert(index: Int, ref: AnyRef): StringBuilder =
+ if (ref == null)
+ insert(index, null: String)
+ else
+ insert(index, ref.toString)
+
+ def insert(index: Int, csq: CharSequence, start: Int, end: Int): StringBuilder =
+ if (csq == null)
+ insert(index, "null", start, end)
+ else
+ insert(index, csq.subSequence(start, end).toString)
+
+
+ def insert(index: Int, arr: Array[scala.Char], offset: Int, len: Int): StringBuilder = {
+ var str = ""
+ var i = 0
+ while (i < len) {
+ str += arr(i + offset)
+ i += 1
+ }
+ insert(index, str)
+ }
+
+ def insert(index: Int, str: String): StringBuilder = {
+ val thisLength = length()
+ if (index < 0 || index > thisLength)
+ throw new StringIndexOutOfBoundsException(index)
+ else if (index == thisLength)
+ append(str)
+ else
+ content = content.substring(0, index) + Option(str).getOrElse("null") + content.substring(index)
+ this
+ }
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/System.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/System.scala
new file mode 100644
index 0000000..6d80eaf
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/System.scala
@@ -0,0 +1,275 @@
+package java.lang
+
+import java.io._
+
+import scala.scalajs.js
+import js.Dynamic.global
+
+object System {
+ var out: PrintStream = new JSConsoleBasedPrintStream(isErr = false)
+ var err: PrintStream = new JSConsoleBasedPrintStream(isErr = true)
+ var in: InputStream = null
+
+ def currentTimeMillis(): scala.Long = {
+ (new js.Date).getTime().toLong
+ }
+
+ private[this] val getHighPrecisionTime: js.Function0[scala.Double] = {
+ if (!(!global.performance)) {
+ if (!(!global.performance.now)) {
+ () => global.performance.now().asInstanceOf[scala.Double]
+ } else if (!(!(global.performance.webkitNow))) {
+ () => global.performance.webkitNow().asInstanceOf[scala.Double]
+ } else {
+ () => new js.Date().getTime()
+ }
+ } else {
+ () => new js.Date().getTime()
+ }
+ }
+
+ def nanoTime(): scala.Long =
+ (getHighPrecisionTime() * 1000000).toLong
+
+ def arraycopy(src: Object, srcPos: scala.Int, dest: Object,
+ destPos: scala.Int, length: scala.Int): Unit = {
+
+ import scala.{Boolean, Char, Byte, Short, Int, Long, Float, Double}
+
+ @inline def checkIndices(srcLen: Int, destLen: Int): Unit = {
+ if (srcPos < 0 || destPos < 0 || length < 0 ||
+ srcPos + length > srcLen || destPos + length > destLen)
+ throw new ArrayIndexOutOfBoundsException("Array index out of bounds")
+ }
+
+ def mismatch(): Nothing =
+ throw new ArrayStoreException("Incompatible array types")
+
+ val forward = (src ne dest) || destPos < srcPos || srcPos + length < destPos
+
+ def copyPrim[@specialized T](src: Array[T], dest: Array[T]): Unit = {
+ checkIndices(src.length, dest.length)
+ if (forward) {
+ var i = 0
+ while (i < length) {
+ dest(i+destPos) = src(i+srcPos)
+ i += 1
+ }
+ } else {
+ var i = length-1
+ while (i >= 0) {
+ dest(i+destPos) = src(i+srcPos)
+ i -= 1
+ }
+ }
+ }
+
+ def copyRef(src: Array[AnyRef], dest: Array[AnyRef]): Unit = {
+ checkIndices(src.length, dest.length)
+ if (forward) {
+ var i = 0
+ while (i < length) {
+ dest(i+destPos) = src(i+srcPos)
+ i += 1
+ }
+ } else {
+ var i = length-1
+ while (i >= 0) {
+ dest(i+destPos) = src(i+srcPos)
+ i -= 1
+ }
+ }
+ }
+
+ if (src == null || dest == null) {
+ throw new NullPointerException()
+ } else (src match {
+ case src: Array[AnyRef] =>
+ dest match {
+ case dest: Array[AnyRef] => copyRef(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Boolean] =>
+ dest match {
+ case dest: Array[Boolean] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Char] =>
+ dest match {
+ case dest: Array[Char] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Byte] =>
+ dest match {
+ case dest: Array[Byte] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Short] =>
+ dest match {
+ case dest: Array[Short] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Int] =>
+ dest match {
+ case dest: Array[Int] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Long] =>
+ dest match {
+ case dest: Array[Long] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Float] =>
+ dest match {
+ case dest: Array[Float] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case src: Array[Double] =>
+ dest match {
+ case dest: Array[Double] => copyPrim(src, dest)
+ case _ => mismatch()
+ }
+ case _ =>
+ mismatch()
+ })
+ }
+
+ def identityHashCode(x: Object): scala.Int = {
+ import js.prim
+ x match {
+ case null => 0
+ case _:prim.Boolean | _:prim.Number | _:prim.String | _:prim.Undefined =>
+ x.hashCode()
+ case _ =>
+ if (x.getClass == null) {
+ // This is not a Scala.js object
+ 42
+ } else {
+ val hash = x.asInstanceOf[js.Dynamic].selectDynamic("$idHashCode$0")
+ if (!js.isUndefined(hash)) {
+ hash.asInstanceOf[Int]
+ } else {
+ val newHash = IDHashCode.nextIDHashCode()
+ x.asInstanceOf[js.Dynamic].updateDynamic("$idHashCode$0")(newHash)
+ newHash
+ }
+ }
+ }
+ }
+
+ private object IDHashCode {
+ private var lastIDHashCode: Int = 0
+
+ def nextIDHashCode(): Int = {
+ val r = lastIDHashCode + 1
+ lastIDHashCode = r
+ r
+ }
+ }
+
+ //def getProperties(): java.util.Properties
+ //def getProperty(key: String): String
+ //def getProperty(key: String, default: String): String
+ //def clearProperty(key: String): String
+ //def setProperty(key: String, value: String): String
+
+ //def getenv(): java.util.Map[String,String]
+ //def getenv(name: String): String
+
+ def exit(status: scala.Int) = Runtime.getRuntime().exit(status)
+ def gc() = Runtime.getRuntime().gc()
+}
+
+private[lang] final class JSConsoleBasedPrintStream(isErr: Boolean)
+ extends PrintStream(new JSConsoleBasedPrintStream.DummyOutputStream) {
+
+ import JSConsoleBasedPrintStream._
+
+ /** Whether the buffer is flushed.
+ * This can be true even if buffer != "" because of line continuations.
+ * However, the converse is never true, i.e., !flushed => buffer != "".
+ */
+ private var flushed: scala.Boolean = true
+ private var buffer: String = ""
+
+ override def write(b: Int): Unit =
+ write(Array(b.toByte), 0, 1)
+
+ override def write(buf: Array[scala.Byte], off: Int, len: Int): Unit = {
+ /* This does *not* decode buf as a sequence of UTF-8 code units.
+ * This is not really useful, and would uselessly pull in the UTF-8 decoder
+ * in all applications that use OutputStreams (not just PrintStreams).
+ * Instead, we use a trivial ISO-8859-1 decoder in here.
+ */
+ if (off < 0 || len < 0 || len > buf.length - off)
+ throw new IndexOutOfBoundsException
+
+ var i = 0
+ while (i < len) {
+ print((buf(i + off) & 0xff).toChar)
+ i += 1
+ }
+ }
+
+ override def print(b: scala.Boolean): Unit = printString(String.valueOf(b))
+ override def print(c: scala.Char): Unit = printString(String.valueOf(c))
+ override def print(i: scala.Int): Unit = printString(String.valueOf(i))
+ override def print(l: scala.Long): Unit = printString(String.valueOf(l))
+ override def print(f: scala.Float): Unit = printString(String.valueOf(f))
+ override def print(d: scala.Double): Unit = printString(String.valueOf(d))
+ override def print(s: Array[scala.Char]): Unit = printString(String.valueOf(s))
+ override def print(s: String): Unit = printString(if (s == null) "null" else s)
+ override def print(obj: AnyRef): Unit = printString(String.valueOf(obj))
+
+ override def println(): Unit = printString("\n")
+
+ private def printString(s: String): Unit = {
+ var rest: String = s
+ while (rest != "") {
+ val nlPos = rest.indexOf("\n")
+ if (nlPos < 0) {
+ buffer += rest
+ flushed = false
+ rest = ""
+ } else {
+ doWriteLine(buffer + rest.substring(0, nlPos))
+ buffer = ""
+ flushed = true
+ rest = rest.substring(nlPos+1)
+ }
+ }
+ }
+
+ /**
+ * Since we cannot write a partial line in JavaScript, we write a whole
+ * line with continuation symbol at the end and schedule a line continuation
+ * symbol for the new line if the buffer is flushed.
+ */
+ override def flush(): Unit = if (!flushed) {
+ doWriteLine(buffer + LineContEnd)
+ buffer = LineContStart
+ flushed = true
+ }
+
+ override def close(): Unit = ()
+
+ private def doWriteLine(line: String): Unit = {
+ if (!(!global.console)) {
+ if (isErr && !(!global.console.error))
+ global.console.error(line)
+ else
+ global.console.log(line)
+ }
+ }
+}
+
+private[lang] object JSConsoleBasedPrintStream {
+ private final val LineContEnd: String = "\u21A9"
+ private final val LineContStart: String = "\u21AA"
+
+ class DummyOutputStream extends OutputStream {
+ def write(c: Int): Unit =
+ throw new AssertionError(
+ "Should not get in JSConsoleBasedPrintStream.DummyOutputStream")
+ }
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Thread.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Thread.scala
new file mode 100644
index 0000000..e52d7f6
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Thread.scala
@@ -0,0 +1,16 @@
+package java.lang
+
+/* We need a constructor to create SingleThread in the companion object, but
+ * we don't want user code doing a 'new Thread()' to link, because that could
+ * be confusing.
+ * So we use a binary signature that no Java source file can ever produce.
+ */
+class Thread private (dummy: Unit) extends Runnable {
+ def run(): Unit = ()
+}
+
+object Thread {
+ private[this] val SingleThread = new Thread(())
+
+ def currentThread(): Thread = SingleThread
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/ThreadLocal.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/ThreadLocal.scala
new file mode 100644
index 0000000..a36a40c
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/ThreadLocal.scala
@@ -0,0 +1,24 @@
+package java.lang
+
+class ThreadLocal[T] {
+ private var hasValue: Boolean = false
+ private var v: T = _
+
+ protected def initialValue(): T = null.asInstanceOf[T]
+
+ def get(): T = {
+ if (!hasValue)
+ set(initialValue)
+ v
+ }
+
+ def set(o: T): Unit = {
+ v = o
+ hasValue = true
+ }
+
+ def remove(): Unit = {
+ hasValue = false
+ v = null.asInstanceOf[T] // for gc
+ }
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Throwables.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Throwables.scala
new file mode 100644
index 0000000..a38fee9
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Throwables.scala
@@ -0,0 +1,363 @@
+package java.lang
+
+import scala.scalajs.js
+
+class Throwable(s: String, private var e: Throwable) extends Object with java.io.Serializable {
+ def this() = this(null, null)
+ def this(s: String) = this(s, null)
+ def this(e: Throwable) = this(null, e)
+
+ private[this] var stackTrace: Array[StackTraceElement] = _
+
+ fillInStackTrace()
+
+ def initCause(cause: Throwable): Throwable = {
+ e = cause
+ this
+ }
+
+ def getMessage(): String = s
+ def getCause(): Throwable = e
+ def getLocalizedMessage(): String = getMessage()
+
+ def fillInStackTrace(): Throwable = {
+ scala.scalajs.runtime.StackTrace.captureState(this)
+ this
+ }
+
+ def getStackTrace(): Array[StackTraceElement] = {
+ if (stackTrace eq null)
+ stackTrace = scala.scalajs.runtime.StackTrace.extract(this)
+ stackTrace
+ }
+
+ def setStackTrace(stackTrace: Array[StackTraceElement]): Unit = {
+ var i = 0
+ while (i < stackTrace.length) {
+ if (stackTrace(i) eq null)
+ throw new NullPointerException()
+ i += 1
+ }
+
+ this.stackTrace = stackTrace.clone()
+ }
+
+ def printStackTrace(): Unit = printStackTrace(System.err)
+
+ def printStackTrace(s: java.io.PrintStream): Unit =
+ printStackTraceImpl(s.println(_))
+
+ def printStackTrace(s: java.io.PrintWriter): Unit =
+ printStackTraceImpl(s.println(_))
+
+ private[this] def printStackTraceImpl(sprintln: String => Unit): Unit = {
+ getStackTrace() // will init it if still null
+
+ // Message
+ sprintln(toString)
+
+ // Trace
+ if (stackTrace.length != 0) {
+ var i = 0
+ while (i < stackTrace.length) {
+ sprintln(" at "+stackTrace(i))
+ i += 1
+ }
+ } else {
+ sprintln(" <no stack trace available>")
+ }
+
+ // Causes
+ var wCause: Throwable = this
+ while ((wCause ne wCause.getCause) && (wCause.getCause ne null)) {
+ val parentTrace = wCause.getStackTrace
+ wCause = wCause.getCause
+ val thisTrace = wCause.getStackTrace
+
+ val thisLength = thisTrace.length
+ val parentLength = parentTrace.length
+
+ sprintln("Caused by: " + wCause.toString)
+
+ if (thisLength != 0) {
+ /* Count how many frames are shared between this stack trace and the
+ * parent stack trace, so that we can omit them when printing.
+ */
+ var sameFrameCount: Int = 0
+ while (sameFrameCount < thisLength && sameFrameCount < parentLength &&
+ thisTrace(thisLength-sameFrameCount-1) == parentTrace(parentLength-sameFrameCount-1)) {
+ sameFrameCount += 1
+ }
+
+ /* If at least one, decrement so that the first common frame is still
+ * printed. According to Harmony this is spec'ed and common practice.
+ */
+ if (sameFrameCount > 0)
+ sameFrameCount -= 1
+
+ // Print the non-common frames
+ val lengthToPrint = thisLength - sameFrameCount
+ var i = 0
+ while (i < lengthToPrint) {
+ sprintln(" at "+thisTrace(i))
+ i += 1
+ }
+
+ if (sameFrameCount > 0)
+ sprintln(" ... " + sameFrameCount + " more")
+ } else {
+ sprintln(" <no stack trace available>")
+ }
+ }
+ }
+
+ override def toString() = {
+ val className = getClass.getName
+ val message = getMessage()
+ if (message eq null) className
+ else className + ": " + message
+ }
+}
+
+class ThreadDeath() extends Error()
+
+
+/* java.lang.*Error.java */
+
+class AbstractMethodError(s: String) extends IncompatibleClassChangeError(s) {
+ def this() = this(null)
+}
+
+class AssertionError private (s: String) extends Error(s) {
+ def this() = this(null)
+ def this(o: Object) = this(o.toString)
+ def this(b: scala.Boolean) = this(b.toString)
+ def this(c: scala.Char) = this(c.toString)
+ def this(i: scala.Int) = this(i.toString)
+ def this(l: scala.Long) = this(l.toString)
+ def this(f: scala.Float) = this(f.toString)
+ def this(d: scala.Double) = this(d.toString)
+}
+
+class BootstrapMethodError(s: String, e: Throwable) extends LinkageError(s) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class ClassCircularityError(s: String) extends LinkageError(s) {
+ def this() = this(null)
+}
+
+class ClassFormatError(s: String) extends LinkageError(s) {
+ def this() = this(null)
+}
+
+class Error(s: String, e: Throwable) extends Throwable(s, e) {
+ def this() = this(null, null)
+ def this(s: String) = this(s, null)
+ def this(e: Throwable) = this(null, e)
+}
+
+class ExceptionInInitializerError private (s: String, private val e: Throwable) extends LinkageError(s) {
+ def this(thrown: Throwable) = this(null, thrown)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+ def getException(): Throwable = e
+ override def getCause(): Throwable = e
+}
+
+class IllegalAccessError(s: String) extends IncompatibleClassChangeError(s) {
+ def this() = this(null)
+}
+
+class IncompatibleClassChangeError(s: String) extends LinkageError(s) {
+ def this() = this(null)
+}
+
+class InstantiationError(s: String) extends IncompatibleClassChangeError(s) {
+ def this() = this(null)
+}
+
+class InternalError(s: String) extends VirtualMachineError(s) {
+ def this() = this(null)
+}
+
+class LinkageError(s: String) extends Error(s) {
+ def this() = this(null)
+}
+
+class NoClassDefFoundError(s: String) extends LinkageError(s) {
+ def this() = this(null)
+}
+
+class NoSuchFieldError(s: String) extends IncompatibleClassChangeError(s) {
+ def this() = this(null)
+}
+
+class NoSuchMethodError(s: String) extends IncompatibleClassChangeError(s) {
+ def this() = this(null)
+}
+
+class OutOfMemoryError(s: String) extends VirtualMachineError(s) {
+ def this() = this(null)
+}
+
+class StackOverflowError(s: String) extends VirtualMachineError(s) {
+ def this() = this(null)
+}
+
+class UnknownError(s: String) extends VirtualMachineError(s) {
+ def this() = this(null)
+}
+
+class UnsatisfiedLinkError(s: String) extends LinkageError(s) {
+ def this() = this(null)
+}
+
+class UnsupportedClassVersionError(s: String) extends ClassFormatError(s) {
+ def this() = this(null)
+}
+
+class VerifyError(s: String) extends LinkageError(s) {
+ def this() = this(null)
+}
+
+abstract class VirtualMachineError(s: String) extends Error(s) {
+ def this() = this(null)
+}
+
+
+/* java.lang.*Exception.java */
+
+class ArithmeticException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class ArrayIndexOutOfBoundsException(s: String) extends IndexOutOfBoundsException(s) {
+ def this(index: Int) = this("Array index out of range: " + index)
+ def this() = this(null)
+}
+
+class ArrayStoreException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class ClassCastException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class ClassNotFoundException(s: String, e: Throwable) extends ReflectiveOperationException(s) {
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+ def getException(): Throwable = e
+ override def getCause(): Throwable = e
+}
+
+class CloneNotSupportedException(s: String) extends Exception(s) {
+ def this() = this(null)
+}
+
+import scala.language.existentials
+class EnumConstantNotPresentException(
+ e: Class[_ <: Enum[T] forSome { type T <: Enum[T] }], c: String)
+ extends RuntimeException(e.getName() + "." + c) {
+ def enumType() = e
+ def constantName() = c
+}
+
+class Exception(s: String, e: Throwable) extends Throwable(s, e) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class IllegalAccessException(s: String) extends ReflectiveOperationException(s) {
+ def this() = this(null)
+}
+
+class IllegalArgumentException(s: String, e: Throwable) extends RuntimeException(s, e) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class IllegalMonitorStateException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class IllegalStateException(s: String, e: Throwable) extends RuntimeException(s, e) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class IllegalThreadStateException(s: String) extends IllegalArgumentException(s) {
+ def this() = this(null)
+}
+
+class IndexOutOfBoundsException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class InstantiationException(s: String) extends ReflectiveOperationException(s) {
+ def this() = this(null)
+}
+
+class InterruptedException(s: String) extends Exception(s) {
+ def this() = this(null)
+}
+
+class NegativeArraySizeException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class NoSuchFieldException(s: String) extends ReflectiveOperationException(s) {
+ def this() = this(null)
+}
+
+class NoSuchMethodException(s: String) extends ReflectiveOperationException(s) {
+ def this() = this(null)
+}
+
+class NullPointerException(s: String) extends RuntimeException(s) {
+ def this() = this(null)
+}
+
+class NumberFormatException(s: String) extends IllegalArgumentException(s) {
+ def this() = this(null)
+}
+
+class ReflectiveOperationException(s: String, e: Throwable) extends Exception(s, e) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class RuntimeException(s: String, e: Throwable) extends Exception(s, e) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class SecurityException(s: String, e: Throwable) extends RuntimeException(s, e) {
+ def this(e: Throwable) = this(null, e)
+ def this(s: String) = this(s, null)
+ def this() = this(null, null)
+}
+
+class StringIndexOutOfBoundsException(s: String) extends IndexOutOfBoundsException(s) {
+ def this(index: Int) = this("String index out of range: " + index)
+ def this() = this(null)
+}
+
+class TypeNotPresentException(t: String, e: Throwable)
+ extends RuntimeException("Type " + t + " not present", e) {
+ def typeName(): String = t
+}
+
+class UnsupportedOperationException(s: String, e: Throwable) extends RuntimeException(s, e) {
+ def this() = this(null, null)
+ def this(s: String) = this(s, null)
+ def this(e: Throwable) = this(null, e)
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/Void.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/Void.scala
new file mode 100644
index 0000000..fbe68fb
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/Void.scala
@@ -0,0 +1,7 @@
+package java.lang
+
+final class Void private {}
+
+object Void {
+ final val TYPE = classOf[scala.Unit]
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala
new file mode 100644
index 0000000..ecace8a
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/PhantomReference.scala
@@ -0,0 +1,7 @@
+package java.lang.ref
+
+class PhantomReference[T >: Null <: AnyRef](referent: T,
+ queue: ReferenceQueue[_ >: T]) extends Reference[T](null) {
+
+ override def get(): T = null
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/Reference.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/Reference.scala
new file mode 100644
index 0000000..76909cf
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/Reference.scala
@@ -0,0 +1,8 @@
+package java.lang.ref
+
+abstract class Reference[T >: Null <: AnyRef](private[this] var referent: T) {
+ def get(): T = referent
+ def clear(): Unit = referent = null
+ def isEnqueued(): Boolean = false
+ def enqueue(): Boolean = false
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala
new file mode 100644
index 0000000..e9c5110
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/ReferenceQueue.scala
@@ -0,0 +1,3 @@
+package java.lang.ref
+
+class ReferenceQueue[T >: Null <: AnyRef]
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala
new file mode 100644
index 0000000..eb0fdf7
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/SoftReference.scala
@@ -0,0 +1,9 @@
+package java.lang.ref
+
+class SoftReference[T >: Null <: AnyRef](referent: T,
+ queue: ReferenceQueue[_ >: T]) extends Reference[T](referent) {
+
+ def this(referent: T) = this(referent, null)
+
+ override def get(): T = super.get()
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala
new file mode 100644
index 0000000..2a74aa1
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/ref/WeakReference.scala
@@ -0,0 +1,7 @@
+package java.lang.ref
+
+class WeakReference[T >: Null <: AnyRef](referent: T,
+ queue: ReferenceQueue[_ >: T]) extends Reference[T](referent) {
+
+ def this(referent: T) = this(referent, null)
+}
diff --git a/examples/scala-js/javalanglib/src/main/scala/java/lang/reflect/Array.scala b/examples/scala-js/javalanglib/src/main/scala/java/lang/reflect/Array.scala
new file mode 100644
index 0000000..bc3696e
--- /dev/null
+++ b/examples/scala-js/javalanglib/src/main/scala/java/lang/reflect/Array.scala
@@ -0,0 +1,176 @@
+package java.lang.reflect
+
+import scala.scalajs.js
+
+import js.JSConverters._
+
+import java.lang.Class
+
+object Array {
+ def newInstance(componentType: Class[_], length: Int): AnyRef =
+ componentType.newArrayOfThisClass(js.Array(length))
+
+ def newInstance(componentType: Class[_], dimensions: scala.Array[Int]): AnyRef =
+ componentType.newArrayOfThisClass(dimensions.toJSArray)
+
+ def getLength(array: AnyRef): Int = array match {
+ // yes, this is kind of stupid, but that's how it is
+ case array: Array[Object] => array.length
+ case array: Array[Boolean] => array.length
+ case array: Array[Char] => array.length
+ case array: Array[Byte] => array.length
+ case array: Array[Short] => array.length
+ case array: Array[Int] => array.length
+ case array: Array[Long] => array.length
+ case array: Array[Float] => array.length
+ case array: Array[Double] => array.length
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def get(array: AnyRef, index: Int): AnyRef = array match {
+ case array: Array[Object] => array(index)
+ case array: Array[Boolean] => new java.lang.Boolean(array(index))
+ case array: Array[Char] => new java.lang.Character(array(index))
+ case array: Array[Byte] => new java.lang.Byte(array(index))
+ case array: Array[Short] => new java.lang.Short(array(index))
+ case array: Array[Int] => new java.lang.Integer(array(index))
+ case array: Array[Long] => new java.lang.Long(array(index))
+ case array: Array[Float] => new java.lang.Float(array(index))
+ case array: Array[Double] => new java.lang.Double(array(index))
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getBoolean(array: AnyRef, index: Int): Boolean = array match {
+ case array: Array[Boolean] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getChar(array: AnyRef, index: Int): Char = array match {
+ case array: Array[Char] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getByte(array: AnyRef, index: Int): Byte = array match {
+ case array: Array[Byte] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getShort(array: AnyRef, index: Int): Short = array match {
+ case array: Array[Short] => array(index)
+ case array: Array[Byte] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getInt(array: AnyRef, index: Int): Int = array match {
+ case array: Array[Int] => array(index)
+ case array: Array[Char] => array(index)
+ case array: Array[Byte] => array(index)
+ case array: Array[Short] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getLong(array: AnyRef, index: Int): Long = array match {
+ case array: Array[Long] => array(index)
+ case array: Array[Char] => array(index)
+ case array: Array[Byte] => array(index)
+ case array: Array[Short] => array(index)
+ case array: Array[Int] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getFloat(array: AnyRef, index: Int): Float = array match {
+ case array: Array[Float] => array(index)
+ case array: Array[Char] => array(index)
+ case array: Array[Byte] => array(index)
+ case array: Array[Short] => array(index)
+ case array: Array[Int] => array(index)
+ case array: Array[Long] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def getDouble(array: AnyRef, index: Int): Double = array match {
+ case array: Array[Double] => array(index)
+ case array: Array[Char] => array(index)
+ case array: Array[Byte] => array(index)
+ case array: Array[Short] => array(index)
+ case array: Array[Int] => array(index)
+ case array: Array[Long] => array(index)
+ case array: Array[Float] => array(index)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def set(array: AnyRef, index: Int, value: AnyRef): Unit = array match {
+ case array: Array[Object] => array(index) = value
+ case _ =>
+ (value: Any) match {
+ case value: Boolean => setBoolean(array, index, value)
+ case value: Char => setChar(array, index, value)
+ case value: Byte => setByte(array, index, value)
+ case value: Short => setShort(array, index, value)
+ case value: Int => setInt(array, index, value)
+ case value: Long => setLong(array, index, value)
+ case value: Float => setFloat(array, index, value)
+ case value: Double => setDouble(array, index, value)
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+ }
+
+ def setBoolean(array: AnyRef, index: Int, value: Boolean): Unit = array match {
+ case array: Array[Boolean] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setChar(array: AnyRef, index: Int, value: Char): Unit = array match {
+ case array: Array[Char] => array(index) = value
+ case array: Array[Int] => array(index) = value
+ case array: Array[Long] => array(index) = value
+ case array: Array[Float] => array(index) = value
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setByte(array: AnyRef, index: Int, value: Byte): Unit = array match {
+ case array: Array[Byte] => array(index) = value
+ case array: Array[Short] => array(index) = value
+ case array: Array[Int] => array(index) = value
+ case array: Array[Long] => array(index) = value
+ case array: Array[Float] => array(index) = value
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setShort(array: AnyRef, index: Int, value: Short): Unit = array match {
+ case array: Array[Short] => array(index) = value
+ case array: Array[Int] => array(index) = value
+ case array: Array[Long] => array(index) = value
+ case array: Array[Float] => array(index) = value
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setInt(array: AnyRef, index: Int, value: Int): Unit = array match {
+ case array: Array[Int] => array(index) = value
+ case array: Array[Long] => array(index) = value
+ case array: Array[Float] => array(index) = value
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setLong(array: AnyRef, index: Int, value: Long): Unit = array match {
+ case array: Array[Long] => array(index) = value
+ case array: Array[Float] => array(index) = value
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setFloat(array: AnyRef, index: Int, value: Float): Unit = array match {
+ case array: Array[Float] => array(index) = value
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+
+ def setDouble(array: AnyRef, index: Int, value: Double): Unit = array match {
+ case array: Array[Double] => array(index) = value
+ case _ => throw new IllegalArgumentException("argument type mismatch")
+ }
+}