summaryrefslogtreecommitdiff
path: root/examples/scala-js/library/src
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/library/src')
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala14
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Array.scala173
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/ArrayOps.scala119
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Date.scala225
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Dictionary.scala92
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Error.scala114
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Function.scala194
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/GlobalScope.scala21
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/JSApp.scala20
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala264
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/JSConverters.scala54
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/JSON.scala51
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala20
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Math.scala277
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/Primitives.scala872
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala20
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/RegExp.scala108
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/ThisFunction.scala160
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/UndefOr.scala254
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedArray.scala92
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala89
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala19
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala21
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala20
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala20
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala38
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/README.md3
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala23
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/package.scala161
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala88
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala14
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala26
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala46
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala24
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/package.scala145
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala19
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala197
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala42
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala19
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala17
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala205
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala455
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala119
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/Bits.scala240
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala31
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala87
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala162
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala686
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala338
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala507
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala23
-rw-r--r--examples/scala-js/library/src/main/scala/scala/scalajs/runtime/package.scala176
67 files changed, 7522 insertions, 0 deletions
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala
new file mode 100644
index 0000000..c159dcb
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/JSExecutionContext.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.concurrent
+
+import scala.concurrent.ExecutionContext
+
+/**
+ * Execution contexts for use in JavaScript
+ *
+ * Enables the use of Futures/Promises
+ * @author Tobias Schlatter
+ */
+object JSExecutionContext {
+
+ /** execution context that runs immediately. beware of stack growth! */
+ val runNow = RunNowExecutionContext
+ /** execution context that submits into the JavaScript runtime's
+ * task queue */
+ val queue = QueueExecutionContext
+
+ object Implicits {
+ implicit val runNow: ExecutionContext = JSExecutionContext.runNow
+ implicit val queue: ExecutionContext = JSExecutionContext.queue
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala
new file mode 100644
index 0000000..1f2ee6f
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/QueueExecutionContext.scala
@@ -0,0 +1,17 @@
+package scala.scalajs.concurrent
+
+import scala.concurrent.ExecutionContext
+import scalajs.js
+
+private[concurrent] object QueueExecutionContext extends ExecutionContext {
+
+ def execute(runnable: Runnable) = {
+ val lambda: js.Function = () =>
+ try { runnable.run() } catch { case t: Throwable => reportFailure(t) }
+ js.Dynamic.global.setTimeout(lambda, 0)
+ }
+
+ def reportFailure(t: Throwable) =
+ Console.err.println("Failure in async execution: " + t)
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala
new file mode 100644
index 0000000..ba113b4
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/concurrent/RunNowExcecutionContext.scala
@@ -0,0 +1,14 @@
+package scala.scalajs.concurrent
+
+import scala.concurrent.ExecutionContext
+
+private[concurrent] object RunNowExecutionContext extends ExecutionContext {
+
+ def execute(runnable: Runnable) =
+ try { runnable.run() }
+ catch { case t: Throwable => reportFailure(t) }
+
+ def reportFailure(t: Throwable) =
+ Console.err.println("Failure in async execution: " + t)
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Array.scala
new file mode 100644
index 0000000..4c9cf23
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Array.scala
@@ -0,0 +1,173 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+import annotation._
+
+/**
+ * Arrays are list-like objects whose prototype has methods to perform
+ * traversal and mutation operations. Neither the length of a JavaScript
+ * array nor the types of its elements are fixed. Since an array's size
+ * length grow or shrink at any time, JavaScript arrays are not guaranteed
+ * to be dense. In general, these are convenient characteristics; but if
+ * these features are not desirable for your particular use, you might
+ * consider using typed arrays.
+ *
+ * MDN
+ *
+ * To construct a new array with uninitialized elements, use the constructor
+ * of this class. To construct a new array with specified elements, as if
+ * you used the array literal syntax in JavaScript, use the
+ * [[Array$.apply Array.apply]] method instead.
+ *
+ * @tparam A Type of the elements of the array
+ *
+ * @constructor Creates a new array of length 0.
+ */
+class Array[A] extends Object {
+ /** Creates a new array with the given length.
+ * @param arrayLength Initial length of the array.
+ */
+ def this(arrayLength: Int) = this()
+
+ // Do not expose this one - use js.Array(item1, item2, ...) instead
+ // def this(items: A*) = this()
+
+ /** Length of the array. */
+ def length: Int = native
+
+ /** Sets the length of the array.
+ * If the new length is bigger than the old length, created slots are
+ * filled with `undefined` (irrespective of the type argument `A`!).
+ * If the new length is smaller than the old length, the array is shrunk.
+ */
+ def length_=(v: Int): Unit = native
+
+ /** Access the element at the given index. */
+ @JSBracketAccess
+ def apply(index: Int): A = native
+ /** Set the element at the given index. */
+ @JSBracketAccess
+ def update(index: Int, value: A): Unit = native
+
+ /**
+ * concat creates a new array consisting of the elements in the this object
+ * on which it is called, followed in order by, for each argument, the
+ * elements of that argument (if the argument is an array) or the argument
+ * itself (if the argument is not an array).
+ *
+ * MDN
+ */
+ def concat[B >: A](items: Array[_ <: B]*): Array[B] = native
+
+ /**
+ * The join() method joins all elements of an array into a string.
+ *
+ * separator Specifies a string to separate each element of the array.
+ * The separator is converted to a string if necessary. If omitted, the
+ * array elements are separated with a comma.
+ */
+ def join(seperator: String = ","): String = native
+
+ /**
+ * The pop() method removes the last element from an array and returns that
+ * element.
+ *
+ * MDN
+ */
+ def pop(): A = native
+
+ /**
+ * The push() method mutates an array by appending the given elements and
+ * returning the new length of the array.
+ *
+ * MDN
+ */
+ def push(items: A*): Int = native
+
+ /**
+ * The reverse() method reverses an array in place. The first array element
+ * becomes the last and the last becomes the first.
+ *
+ * MDN
+ */
+ @JSName("reverse")
+ def reverseInPlace(): Array[A] = native
+
+ /**
+ * The shift() method removes the first element from an array and returns that
+ * element. This method changes the length of the array.
+ *
+ * MDN
+ */
+ def shift(): A = native
+
+ /**
+ * The slice() method returns a shallow copy of a portion of an array.
+ *
+ * MDN
+ */
+ @JSName("slice")
+ def jsSlice(start: Int = 0, end: Int = Int.MaxValue): Array[A] = native
+
+ /**
+ * The sort() method sorts the elements of an array in place and returns the
+ * array. The sort is not necessarily stable. The default sort order is
+ * lexicographic (not numeric).
+ *
+ * If compareFunction is not supplied, elements are sorted by converting them
+ * to strings and comparing strings in lexicographic ("dictionary" or "telephone
+ * book," not numerical) order. For example, "80" comes before "9" in
+ * lexicographic order, but in a numeric sort 9 comes before 80.
+ *
+ * MDN
+ */
+ def sort(compareFn: Function2[A, A, Int] = ???): Array[A] = native
+
+ /** Removes and adds new elements at a given index in the array.
+ *
+ * This method first removes `deleteCount` elements starting from the index
+ * `index`, then inserts the new elements `items` at that index.
+ *
+ * If `index` is negative, it is treated as that number of elements starting
+ * from the end of the array.
+ *
+ * @param index Index where to start changes
+ * @param deleteCount Number of elements to delete from index
+ * @param items Elements to insert at index
+ * @return An array of the elements that were deleted
+ */
+ def splice(index: Int, deleteCount: Int, items: A*): Array[A] = native
+
+ /**
+ * The unshift() method adds one or more elements to the beginning of an array
+ * and returns the new length of the array.
+ *
+ * MDN
+ */
+ def unshift(items: A*): Int = native
+}
+
+/** Factory for [[js.Array]] objects. */
+object Array extends Object {
+ // Do not expose this one - use new Array(len) instead
+ // def apply[A](arrayLength: Int): Array[A] = native
+
+ /** Creates a new array with the given items. */
+ def apply[A](items: A*): Array[A] = sys.error("stub")
+
+ /** Returns true if the given value is an array. */
+ def isArray(arg: Any): Boolean = native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/ArrayOps.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/ArrayOps.scala
new file mode 100644
index 0000000..f7948ca
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/ArrayOps.scala
@@ -0,0 +1,119 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+package scala.scalajs.js
+
+import scala.annotation.tailrec
+
+import scala.collection.mutable
+import mutable.Builder
+
+/** Equivalent of scm.ArrayOps for js.Array */
+@inline
+final class ArrayOps[A](private[this] val array: Array[A])
+ extends mutable.ArrayLike[A, Array[A]]
+ with Builder[A, Array[A]] {
+
+ import ArrayOps._
+
+ /** Creates a new empty [[ArrayOps]]. */
+ def this() = this(Array())
+
+ // Implementation of ArrayLike
+
+ @inline def apply(index: Int): A = array(index)
+ @inline def length: Int = array.length
+ @inline def update(index: Int, element: A): Unit = array(index) = element
+
+ def seq: IndexedSeq[A] = new WrappedArray(array)
+
+ override def repr: Array[A] = array
+
+ override protected[this] def thisCollection: mutable.IndexedSeq[A] =
+ toCollection(array)
+ override protected[this] def toCollection(
+ repr: Array[A]): mutable.IndexedSeq[A] = new WrappedArray(repr)
+
+ protected[this] def newBuilder: Builder[A, Array[A]] =
+ new ArrayOps[A]
+
+ // Implementation of Builder
+
+ @inline def +=(elem: A): this.type = {
+ array.push(elem)
+ this
+ }
+
+ @inline def clear(): Unit =
+ array.length = 0
+
+ @inline def result(): Array[A] = array
+
+ // Scala notation for a fast concat()
+
+ @inline def ++[B >: A](that: Array[_ <: B]): Array[B] =
+ concat(array, that)
+
+ // Methods whose inherited implementations do not play nice with the optimizer
+
+ override def reduceLeft[B >: A](op: (B, A) => B): B = {
+ val length = this.length
+ if (length <= 0)
+ throwUnsupported("empty.reduceLeft")
+
+ @inline
+ @tailrec
+ def loop(start: Int, z: B): B =
+ if (start == length) z
+ else loop(start+1, op(z, this(start)))
+
+ loop(1, this(0))
+ }
+
+ override def reduceRight[B >: A](op: (A, B) => B): B = {
+ val length = this.length
+ if (length <= 0)
+ throwUnsupported("empty.reduceRight")
+
+ @inline
+ @tailrec
+ def loop(end: Int, z: B): B =
+ if (end == 0) z
+ else loop(end-1, op(this(end-1), z))
+
+ loop(length-1, this(length-1))
+ }
+
+}
+
+object ArrayOps {
+
+ /** Extract the throw in a separate, non-inlineable method. */
+ private def throwUnsupported(msg: String): Nothing =
+ throw new UnsupportedOperationException(msg)
+
+ /** Non-inlined implementation of [[ArrayOps.++]]. */
+ private def concat[A](left: Array[_ <: A], right: Array[_ <: A]): Array[A] = {
+ val leftLength = left.length
+ val rightLength = right.length
+ val result = new Array[A](leftLength + rightLength)
+
+ @inline
+ @tailrec
+ def loop(src: Array[_ <: A], i: Int, len: Int, offset: Int): Unit =
+ if (i != len) {
+ result(i+offset) = src(i)
+ loop(src, i+1, len, offset)
+ }
+
+ loop(left, 0, leftLength, 0)
+ loop(right, 0, rightLength, leftLength)
+ result
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Date.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Date.scala
new file mode 100644
index 0000000..18795c7
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Date.scala
@@ -0,0 +1,225 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+/**
+ * Creates a JavaScript Date instance that represents a single moment in time.
+ * Date objects are based on a time value that is the number of milliseconds
+ * since 1 January, 1970 UTC.
+ *
+ * MDN
+ */
+class Date extends Object {
+
+ def this(value: Double) = this()
+ def this(value: String) = this()
+
+ def this(year: Int, month: Int, date: Int = 1, hours: Int = 0,
+ minutes: Int = 0, seconds: Int = 0, ms: Int = 0) = this()
+
+ def toDateString(): String = native
+ def toTimeString(): String = native
+ def toLocaleDateString(): String = native
+ def toLocaleTimeString(): String = native
+
+ override def valueOf(): Double = native
+
+ def getTime(): Double = native
+
+ /**
+ * Returns the year (4 digits for 4-digit years) of the specified date according to local time.
+ *
+ * MDN
+ */
+ def getFullYear(): Int = native
+
+ /**
+ * Returns the year (4 digits for 4-digit years) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCFullYear(): Int = native
+
+ /**
+ * Returns the month (0-11) in the specified date according to local time.
+ *
+ * MDN
+ */
+ def getMonth(): Int = native
+
+ /**
+ * Returns the month (0-11) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCMonth(): Int = native
+
+ /**
+ * Returns the day of the month (1-31) for the specified date according to local time.
+ *
+ * MDN
+ */
+ def getDate(): Int = native
+
+ /**
+ * Returns the day (date) of the month (1-31) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCDate(): Int = native
+
+ /**
+ * Returns the day of the week (0-6) for the specified date according to local time.
+ *
+ * MDN
+ */
+ def getDay(): Int = native
+
+ /**
+ * Returns the day of the week (0-6) in the specified date according to universal time.
+ * MDN
+ */
+ def getUTCDay(): Int = native
+
+ /**
+ * Returns the hour (0-23) in the specified date according to local time.
+ *
+ * MDN
+ */
+ def getHours(): Int = native
+
+ /**
+ * Returns the hours (0-23) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCHours(): Int = native
+
+ /**
+ * Returns the minutes (0-59) in the specified date according to local time.
+ *
+ * MDN
+ */
+ def getMinutes(): Int = native
+
+ /**
+ * Returns the minutes (0-59) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCMinutes(): Int = native
+
+ /**
+ * Returns the seconds (0-59) in the specified date according to local time.
+ *
+ * MDN
+ */
+ def getSeconds(): Int = native
+
+ /**
+ * Returns the seconds (0-59) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCSeconds(): Int = native
+
+ /**
+ * Returns the milliseconds (0-999) in the specified date according to local time.
+ *
+ * MDN
+ */
+ def getMilliseconds(): Int = native
+
+ /**
+ * Returns the milliseconds (0-999) in the specified date according to universal time.
+ *
+ * MDN
+ */
+ def getUTCMilliseconds(): Int = native
+
+ /**
+ * Returns the time-zone offset in minutes for the current locale.
+ *
+ * MDN
+ */
+ def getTimezoneOffset(): Int = native
+
+ def setTime(time: Double): Unit = native
+ def setMilliseconds(ms: Int): Unit = native
+ def setUTCMilliseconds(ms: Int): Unit = native
+ def setSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = native
+ def setUTCSeconds(sec: Int, ms: Int = getMilliseconds()): Unit = native
+ def setMinutes(min: Int, sec: Int = getSeconds(),
+ ms: Int = getMilliseconds()): Unit = native
+ def setUTCMinutes(min: Int, sec: Int = getSeconds(),
+ ms: Int = getMilliseconds()): Unit = native
+ def setHours(hours: Int, min: Int = getMinutes(),
+ sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = native
+ def setUTCHours(hours: Int, min: Int = getMinutes(),
+ sec: Int = getSeconds(), ms: Int = getMilliseconds()): Unit = native
+
+ def setDate(date: Int): Unit = native
+ def setUTCDate(date: Int): Unit = native
+ def setMonth(month: Int, date: Int = getDate()): Unit = native
+ def setUTCMonth(month: Int, date: Int = getDate()): Unit = native
+ def setFullYear(year: Int, month: Int = getMonth(),
+ date: Int = getDate()): Unit = native
+ def setUTCFullYear(year: Int, month: Int = getMonth(),
+ date: Int = getDate()): Unit = native
+
+ def toUTCString(): String = native
+ def toISOString(): String = native
+ def toJSON(key: Any): String = native
+ def toJSON(): String = native
+}
+
+/** Factory for [[js.Date]] objects. */
+object Date extends Object {
+ def apply(): String = native
+
+ /**
+ * Parses a string representation of a date and returns the number of
+ * milliseconds since 1 January, 1970, 00:00:00, local time.
+ *
+ * The parse method takes a date string (such as "Dec 25, 1995") and returns
+ * the number of milliseconds since January 1, 1970, 00:00:00 UTC. The local
+ * time zone is used to interpret arguments that do not contain time zone
+ * information. This function is useful for setting date values based on
+ * string values, for example in conjunction with the setTime() method and
+ * the Date object.
+ *
+ * Given a string representing a time, parse returns the time value. It
+ * accepts the RFC2822 / IETF date syntax (RFC2822 Section 3.3), e.g.
+ * "Mon, 25 Dec 1995 13:30:00 GMT". It understands the continental US time-
+ * zone abbreviations, but for general use, use a time-zone offset, for
+ * example, "Mon, 25 Dec 1995 13:30:00 +0430" (4 hours, 30 minutes east of
+ * the Greenwich meridian). If you do not specify a time zone, the local time
+ * zone is assumed. GMT and UTC are considered equivalent.
+ *
+ * MDN
+ */
+ def parse(s: String): Int = native
+
+ def UTC(year: Int, month: Int, date: Int = 1, hours: Int = 0,
+ minutes: Int = 0, seconds: Int = 0, ms: Int = 0): Double = native
+
+ /**
+ * Returns the numeric value corresponding to the current time - the number
+ * of milliseconds elapsed since 1 January 1970 00:00:00 UTC.
+ *
+ * MDN
+ */
+ def now(): Double = native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Dictionary.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Dictionary.scala
new file mode 100644
index 0000000..fa68d08
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Dictionary.scala
@@ -0,0 +1,92 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+import annotation.JSBracketAccess
+
+/** Dictionary "view" of a JavaScript value.
+ *
+ * Using objects as dictionaries (maps from strings to values) through their
+ * properties is a common idiom in JavaScript. This trait lets you treat an
+ * object as such a dictionary.
+ *
+ * To use it, cast your object, say `x`, into a [[Dictionary]] using
+ * {{{
+ * val xDict = x.asInstanceOf[js.Dictionary[Int]]
+ * }}}
+ * then use it as
+ * {{{
+ * xDict("prop") = 5
+ * println(xDict("prop")) // displays 5
+ * xDict.delete("prop") // removes the property "prop"
+ * println(xDict("prop")) // displays undefined
+ * }}}
+ *
+ * To enumerate all the keys of a dictionary, use [[js.Object.keys]], which
+ * returns a [[js.Array]] of the properties. It can be used in a for
+ * comprehension like this:
+ * {{{
+ * for (prop <- js.Object.keys(xDict)) {
+ * val value = xDict(prop)
+ * println(prop + " -> " + value)
+ * }
+ * }}}
+ */
+sealed trait Dictionary[A] extends Object {
+ /** Reads a field of this object by its name.
+ *
+ * This will fail with a ClassCastException if the key doesn't exist and
+ * the return type doesn't allow js.undefined as value. If the return type
+ * does allow js.undefined, applying with a non-existent key will return
+ * js.undefined.
+ */
+ @JSBracketAccess
+ def apply(key: String): A = native
+
+ /** Reads a field of this object by its name.
+ *
+ * This will return undefined if the key doesn't exist. It will also return
+ * undefined if the value associated with the key is undefined. To truly
+ * check for the existence of a property, use [[js.Object.hasOwnProperty]].
+ */
+ @JSBracketAccess
+ def get(key: String): UndefOr[A] = native
+
+ /** Writes a field of this object by its name. */
+ @JSBracketAccess
+ def update(key: String, value: A): Unit = native
+
+ /** Deletes a property of this object by its name.
+ * The property must be configurable.
+ * This method is equivalent to the "delete" keyword in JavaScript.
+ *
+ * Since we are using strict mode, this throws an exception, if the property
+ * isn't configurable.
+ */
+ def delete(key: String): Unit = sys.error("stub")
+}
+
+/** Factory for [[Dictionary]] instances. */
+object Dictionary {
+ /** Returns a new empty dictionary */
+ def empty[A]: Dictionary[A] = (new Object).asInstanceOf[Dictionary[A]]
+
+ def apply[A](properties: (String, A)*): Dictionary[A] = {
+ val result = empty[A]
+ for ((key, value) <- properties)
+ result(key) = value
+ result
+ }
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Error.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Error.scala
new file mode 100644
index 0000000..129ff41
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Error.scala
@@ -0,0 +1,114 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+class Error(message0: String = "") extends Object {
+ val name: String = native
+ /**
+ * Human-readable description of the error
+ *
+ * MDN
+ */
+ val message: String = native
+}
+
+object Error extends Object {
+ def apply(message: String = ""): Error = native
+}
+
+/**
+ * An instance representing an error that occurs regarding the global function
+ * eval()
+ *
+ * MDN
+ */
+class EvalError(message: String = "") extends Error
+
+object EvalError extends Object {
+ def apply(message: String = ""): EvalError = native
+}
+
+/**
+ * An instance representing an error that occurs when a numeric variable or
+ * parameter is outside of its valid range.
+ *
+ * A RangeError is thrown when trying to pass a number as an argument to a
+ * function that does not allow a range that includes that number. This can
+ * be encountered when to create an array of an illegal length with the Array
+ * constructor, or when passing bad values to the numeric methods toExponential,
+ * toFixed, or toPrecision.
+ *
+ * MDN
+ */
+class RangeError(message: String = "") extends Error
+
+object RangeError extends Object {
+ def apply(message: String = ""): RangeError = native
+}
+
+/**
+ * Represents an error when a non-existent variable is referenced.
+ *
+ * A ReferenceError is thrown when trying to dereference a variable that has
+ * not been declared.
+ *
+ * MDN
+ */
+class ReferenceError(message: String = "") extends Error
+
+object ReferenceError extends Object {
+ def apply(message: String = ""): ReferenceError = native
+}
+
+/**
+ * Represents an error when trying to interpret syntactically invalid code.
+ *
+ * A SyntaxError is thrown when the JavaScript engine encounters tokens or
+ * token order that does not conform to the syntax of the language when parsing code.
+ *
+ * MDN
+ */
+class SyntaxError(message: String = "") extends Error
+
+object SyntaxError extends Object {
+ def apply(message: String = ""): SyntaxError = native
+}
+
+/**
+ * Represents an error when a value is not of the expected type.
+ *
+ * A TypeError is thrown when an operand or argument passed to a function is
+ * incompatible with the type expected by that operator or function.
+ *
+ * MDN
+ */
+class TypeError(message: String = "") extends Error
+
+object TypeError extends Object {
+ def apply(message: String = ""): TypeError = native
+}
+
+/**
+ * Represents an error when a malformed URI is encountered.
+ *
+ * A URIError is thrown when the URI handling functions are passed a malformed URI.
+ *
+ * MDN
+ */
+class URIError(message: String = "") extends Error
+
+object URIError extends Object {
+ def apply(message: String = ""): URIError = native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Function.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Function.scala
new file mode 100644
index 0000000..4a7d1d9
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Function.scala
@@ -0,0 +1,194 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+/**
+ * The Function constructor creates a new Function object. In JavaScript every
+ * function is actually a Function object.
+ *
+ * Function objects created with the Function constructor are parsed when the
+ * function is created. This is less efficient than declaring a function and calling
+ * it within your code, because functions declared with the function statement
+ * are parsed with the rest of the code.
+ *
+ * All arguments passed to the function are treated as the names of the
+ * identifiers of the parameters in the function to be created, in the order
+ * in which they are passed.
+ *
+ * Note: Functions created with the Function constructor do not create closures
+ * to their creation contexts; they always are created in the global scope.
+ * When running them, they will only be able to access their own local
+ * variables and global ones, not the ones from the scope in which the Function
+ * constructor was called. This is different from using eval with code for
+ * a function expression.
+ *
+ * Invoking the Function constructor as a function (without using the new
+ * operator) has the same effect as invoking it as a constructor.
+ *
+ * MDN
+ */
+class Function(args: String*) extends Object {
+ /**
+ * length is a property of a function object, and indicates how many arguments
+ * the function expects, i.e. the number of formal parameters. This number
+ * does not include the rest parameter. By contrast, arguments.length is local
+ * to a function and provides the number of arguments actually passed to the
+ * function.
+ *
+ * MDN
+ */
+ val length: Int = native
+
+ /**
+ * The call() method calls a function with a given this value and arguments
+ * provided individually.
+ *
+ * You can assign a different this object when calling an existing function.
+ * this refers to the current object, the calling object. With call, you
+ * can write a method once and then inherit it in another object, without
+ * having to rewrite the method for the new object.
+ *
+ * apply is very similar to call(), except for the type of arguments it supports.
+ * You can use an arguments array instead of a named set of parameters. With
+ * apply, you can use an array literal, for example,
+ *
+ * fun.apply(this, ['eat', 'bananas'])
+ *
+ * or an Array object, for example,
+ *
+ * fun.apply(this, new Array('eat', 'bananas')).
+ *
+ * MDN
+ *
+ * Scala.js-specific note: call() can be used instead of the apply() method
+ * available in JavaScript. Simply use the :_* notation to expand a Seq as
+ * variadic arguments, e.g.,
+ *
+ * {{{
+ * someFun.call(thisArg, argSeq: _*)
+ * }}}
+ *
+ */
+ def call(thisArg: Any, argArray: Any*): Dynamic = native
+
+ // Do not expose apply: use call(thisArg, argArray: _*) instead.
+ // def apply[A](thisArg: Any, argArray: Array[A]): Dynamic = native
+ // def apply(thisArg: Any): Dynamic = native
+
+ /**
+ * The bind() method creates a new function that, when called, has its this
+ * keyword set to the provided value, with a given sequence of arguments
+ * preceding any provided when the new function is called.
+ *
+ * MDN
+ */
+ def bind(thisArg: Any, argArray: Any*): Dynamic = native
+}
+
+object Function extends Object {
+ def apply(args: String*): Function = native
+}
+
+trait Function0[+R] extends Function {
+ def apply(): R
+}
+
+trait Function1[-T1, +R] extends Function {
+ def apply(arg1: T1): R
+}
+
+trait Function2[-T1, -T2, +R] extends Function {
+ def apply(arg1: T1, arg2: T2): R
+}
+
+trait Function3[-T1, -T2, -T3, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3): R
+}
+
+trait Function4[-T1, -T2, -T3, -T4, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4): R
+}
+
+trait Function5[-T1, -T2, -T3, -T4, -T5, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R
+}
+
+trait Function6[-T1, -T2, -T3, -T4, -T5, -T6, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R
+}
+
+trait Function7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R
+}
+
+trait Function8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R
+}
+
+trait Function9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R
+}
+
+trait Function10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R
+}
+
+trait Function11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R
+}
+
+trait Function12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R
+}
+
+trait Function13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R
+}
+
+trait Function14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R
+}
+
+trait Function15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R
+}
+
+trait Function16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R
+}
+
+trait Function17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R
+}
+
+trait Function18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R
+}
+
+trait Function19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R
+}
+
+trait Function20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R
+}
+
+trait Function21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R
+}
+
+trait Function22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R] extends Function {
+ def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21, arg22: T22): R
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/GlobalScope.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/GlobalScope.scala
new file mode 100644
index 0000000..67c09ed
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/GlobalScope.scala
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+
+package scala.scalajs.js
+
+/** Marker trait for top-level objects representing the JS global scope.
+ *
+ * When calling method on a top-level object or package object that is a
+ * subtype of GlobalScope, the receiver is dropped, and the JavaScript global
+ * scope is used instead.
+ *
+ * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]]
+ */
+trait GlobalScope extends Object
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSApp.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSApp.scala
new file mode 100644
index 0000000..fd12207
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSApp.scala
@@ -0,0 +1,20 @@
+package scala.scalajs.js
+
+import annotation.{JSExport, JSExportDescendentObjects}
+
+/** Base class for top-level, entry point main objects.
+ *
+ * Objects inheriting from [[JSApp]] are automatically exported to JavaScript
+ * under their fully qualified name, and their [[main]] method as well.
+ *
+ * [[JSApp]] is typically used to mark the entry point of a Scala.js
+ * application. As such, the sbt plugin also recognizes top-level objects
+ * extending [[JSApp]]. It allows to run their [[main]] method with `sbt run`,
+ * and can also generate a tiny JavaScript launcher snippet executing the
+ * [[main]] method of one specific [[JSApp]] object.
+ */
+@JSExportDescendentObjects
+trait JSApp {
+ @JSExport
+ def main(): Unit
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala
new file mode 100644
index 0000000..71f705d
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSArrayOps.scala
@@ -0,0 +1,264 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+import scala.language.implicitConversions
+
+import scala.scalajs.js.annotation._
+
+/** Discouraged native JavaScript Array methods.
+ *
+ * In general, you should prefer the Scala collection methods available
+ * implicitly through [[ArrayOps]], because they are inlineable, and hence
+ * faster.
+ *
+ * To enable the use of these functions on js.[[Array]]s, import the implicit
+ * conversion [[JSArrayOps.jsArrayOps]].
+ */
+trait JSArrayOps[A] extends Object {
+
+ /**
+ * The indexOf() method returns the first index at which a given element can
+ * be found in the array, or -1 if it is not present.
+ *
+ * MDN
+ */
+ @JSName("indexOf")
+ def jsIndexOf(searchElement: A, fromIndex: Int): Int = native
+ @JSName("indexOf")
+ def jsIndexOf(searchElement: A): Int = native
+
+ /**
+ * The lastIndexOf() method returns the last index at which a given element
+ * can be found in the array, or -1 if it is not present. The array is
+ * searched backwards, starting at fromIndex.
+ *
+ * MDN
+ */
+ @JSName("lastIndexOf")
+ def jsLastIndexOf(searchElement: A, fromIndex: Int): Int = native
+ @JSName("lastIndexOf")
+ def jsLastIndexOf(searchElement: A): Int = native
+
+ /**
+ * The every method executes the provided callback function once for each
+ * element present in the array until it finds one where callback returns
+ * a falsy value (a value that becomes false when converted to a Boolean).
+ * If such an element is found, the every method immediately returns false.
+ * Otherwise, if callback returned a true value for all elements, every
+ * will return true. callback is invoked only for indexes of the array
+ * which have assigned values; it is not invoked for indexes which have been
+ * deleted or which have never been assigned values.
+ *
+ * callback is invoked with three arguments:
+ *
+ * - the value of the element
+ * - the index of the element
+ * - and the Array object being traversed.
+ *
+ * If a thisObject parameter is provided to every, it will be used as the
+ * this for each invocation of the callback. If it is not provided, or is
+ * null, the global object associated with callback is used instead.
+ *
+ * every does not mutate the array on which it is called.
+ *
+ * every acts like the "for all" quantifier in mathematics. In particular, for
+ * an empty array, it returns true. (It is vacuously true that all elements of
+ * the empty set satisfy any given condition.)
+ *
+ * MDN
+ */
+ @JSName("every")
+ def jsEvery[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean],
+ thisArg: T): Boolean = native
+ @JSName("every")
+ def jsEvery(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean = native
+
+ /**
+ * some executes the callback function once for each element present in the
+ * array until it finds one where callback returns a true value. If such an
+ * element is found, some immediately returns true. Otherwise, some returns
+ * false. callback is invoked only for indexes of the array which have assigned
+ * values; it is not invoked for indexes which have been deleted or which
+ * have never been assigned values.
+ *
+ * callback is invoked with three arguments: the value of the element, the index
+ * of the element, and the Array object being traversed.
+ *
+ * If a thisObject parameter is provided to some, it will be used as the this
+ * for each invocation of the callback. If it is not provided, or is null,
+ * the global object associated with callback is used instead.
+ *
+ * some does not mutate the array on which it is called.
+ *
+ * MDN
+ */
+ @JSName("some")
+ def jsSome[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean],
+ thisArg: T): Boolean = native
+ @JSName("some")
+ def jsSome(callbackfn: Function3[A, Int, Array[A], Boolean]): Boolean = native
+ @JSName("some")
+ def jsSome(callbackfn: Function2[A, Int, Boolean]): Boolean = native
+ @JSName("some")
+ def jsSome(callbackfn: Function1[A, Boolean]): Boolean = native
+
+ /**
+ * forEach executes the provided callback once for each element of the array
+ * with an assigned value. It is not invoked for indexes which have been deleted
+ * or which have been initialized to undefined.
+ *
+ * callback is invoked with three arguments:
+ *
+ * - the element value
+ * - the element index
+ * - the array being traversed
+ *
+ * If a thisArg parameter is provided to forEach, it will be used as the
+ * this value for each callback invocation as if callback.call(thisArg,
+ * element, index, array) was called. If thisArg is undefined or null,
+ * the this value within the function depends on whether the function
+ * is in strict mode or not (passed value if in strict mode, global object
+ * if in non-strict mode).
+ *
+ * MDN
+ */
+ @JSName("forEach")
+ def jsForEach[T](callbackfn: ThisFunction3[T, A, Int, Array[A], _],
+ thisArg: T): Unit = native
+ @JSName("forEach")
+ def jsForEach(callbackfn: Function3[A, Int, Array[A], _]): Unit = native
+ @JSName("forEach")
+ def jsForEach(callbackfn: Function2[A, Int, _]): Unit = native
+ @JSName("forEach")
+ def jsForEach(callbackfn: Function1[A, _]): Unit = native
+
+ /**
+ * map calls a provided callback function once for each element in an array,
+ * in order, and constructs a new array from the results. callback is
+ * invoked only for indexes of the array which have assigned values; it is
+ * not invoked for indexes which have been deleted or which have never been
+ * assigned values.
+ *
+ * callback is invoked with three arguments: the value of the element, the
+ * index of the element, and the Array object being traversed.
+ *
+ * If a thisArg parameter is provided to map, it will be used as the this for
+ * each invocation of the callback. If it is not provided, or is null, the
+ * global object associated with callback is used instead.
+ *
+ * map does not mutate the array on which it is called.
+ *
+ * MDN
+ */
+ @JSName("map")
+ def jsMap[B, T](callbackfn: ThisFunction3[T, A, Int, Array[A], B],
+ thisArg: T): Array[B] = native
+ @JSName("map")
+ def jsMap[B](callbackfn: Function3[A, Int, Array[A], B]): Array[B] = native
+ @JSName("map")
+ def jsMap[B](callbackfn: Function2[A, Int, B]): Array[B] = native
+ @JSName("map")
+ def jsMap[B](callbackfn: Function1[A, B]): Array[B] = native
+
+ /**
+ * filter calls a provided callback function once for each element in an array,
+ * and constructs a new array of all the values for which callback returns a true
+ * value. callback is invoked only for indexes of the array which have assigned
+ * values; it is not invoked for indexes which have been deleted or which have
+ * never been assigned values. Array elements which do not pass the callback
+ * test are simply skipped, and are not included in the new array.
+ *
+ * callback is invoked with three arguments:
+ *
+ * - the value of the element
+ * - the index of the element
+ * - the Array object being traversed
+ *
+ * If a thisObject parameter is provided to filter, it will be used as the this
+ * for each invocation of the callback. If it is not provided, or is null, the
+ * global object associated with callback is used instead.
+ *
+ * filter does not mutate the array on which it is called.
+ *
+ * MDN
+ */
+ @JSName("filter")
+ def jsFilter[T](callbackfn: ThisFunction3[T, A, Int, Array[A], Boolean],
+ thisArg: T): Array[A] = native
+ @JSName("filter")
+ def jsFilter(callbackfn: Function3[A, Int, Array[A], Boolean]): Array[A] = native
+ @JSName("filter")
+ def jsFilter(callbackfn: Function2[A, Int, Boolean]): Array[A] = native
+ @JSName("filter")
+ def jsFilter(callbackfn: Function1[A, Boolean]): Array[A] = native
+
+ /**
+ * reduce executes the callback function once for each element present in
+ * the array, excluding holes in the array, receiving four arguments: the
+ * initial value (or value from the previous callback call), the value of
+ * the current element, the current index, and the array over which
+ * iteration is occurring.
+ *
+ * The first time the callback is called, previousValue and currentValue can
+ * be one of two values. If initialValue is provided in the call to reduce,
+ * then previousValue will be equal to initialValue and currentValue will be
+ * equal to the first value in the array. If no initialValue was provided,
+ * then previousValue will be equal to the first value in the array and
+ * currentValue will be equal to the second.
+ *
+ * MDN
+ */
+ @JSName("reduce")
+ def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B = native
+ @JSName("reduce")
+ def jsReduce[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B = native
+ @JSName("reduce")
+ def jsReduce[B](callbackfn: Function2[B, A, B], initialValue: B): B = native
+ @JSName("reduce")
+ def jsReduce[B](callbackfn: Function4[B, A, Int, Array[A], B]): B = native
+ @JSName("reduce")
+ def jsReduce[B](callbackfn: Function3[B, A, Int, B]): B = native
+ @JSName("reduce")
+ def jsReduce[B](callbackfn: Function2[B, A, B]): B = native
+
+ /**
+ * reduceRight executes the callback function once for each element present
+ * in the array, excluding holes in the array, receiving four arguments:
+ * the initial value (or value from the previous callback call), the value
+ * of the current element, the current index, and the array over which
+ * iteration is occurring.
+ *
+ * MDN
+ */
+ @JSName("reduceRight")
+ def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B], initialValue: B): B = native
+ @JSName("reduceRight")
+ def jsReduceRight[B](callbackfn: Function3[B, A, Int, B], initialValue: B): B = native
+ @JSName("reduceRight")
+ def jsReduceRight[B](callbackfn: Function2[B, A, B], initialValue: B): B = native
+ @JSName("reduceRight")
+ def jsReduceRight[B](callbackfn: Function4[B, A, Int, Array[A], B]): B = native
+ @JSName("reduceRight")
+ def jsReduceRight[B](callbackfn: Function3[B, A, Int, B]): B = native
+ @JSName("reduceRight")
+ def jsReduceRight[B](callbackfn: Function2[B, A, B]): B = native
+
+}
+
+object JSArrayOps {
+ @inline implicit def jsArrayOps[A](array: Array[A]): JSArrayOps[A] =
+ array.asInstanceOf[JSArrayOps[A]]
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSConverters.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSConverters.scala
new file mode 100644
index 0000000..1b21d61
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSConverters.scala
@@ -0,0 +1,54 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.js
+
+import scala.language.implicitConversions
+
+import scala.collection._
+
+import scala.scalajs.runtime.genTraversableOnce2jsArray
+
+/** A collection of decorators that allow converting Scala types to
+ * corresponding JS facade types
+ */
+object JSConverters {
+
+ implicit class JSRichOption[T](val opt: Option[T]) extends AnyVal {
+ @inline final def orUndefined: UndefOr[T] =
+ opt.fold[UndefOr[T]](undefined)(v => v)
+ }
+
+ implicit class JSRichGenTraversableOnce[T](
+ val col: GenTraversableOnce[T]) extends AnyVal {
+ @inline final def toJSArray: Array[T] = genTraversableOnce2jsArray(col)
+ }
+
+ implicit class JSRichGenMap[T](val map: GenMap[String, T]) extends AnyVal {
+ @inline final def toJSDictionary: Dictionary[T] = {
+ val result = Dictionary.empty[T]
+ map.foreach { case (key, value) => result(key) = value }
+ result
+ }
+ }
+
+ @inline
+ implicit def genTravConvertible2JSRichGenTrav[T, C](coll: C)(
+ implicit ev: C => GenTraversableOnce[T]): JSRichGenTraversableOnce[T] =
+ new JSRichGenTraversableOnce(coll)
+
+ /** Special case for scala.Array of [[genTravConvertible2JSRichGenTrav]].
+ * Needed for the 2.10.x series.
+ */
+ @inline
+ implicit def array2JSRichGenTrav[T](
+ arr: scala.Array[T]): JSRichGenTraversableOnce[T] =
+ new JSRichGenTraversableOnce(arr)
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSON.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSON.scala
new file mode 100644
index 0000000..8404f40
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JSON.scala
@@ -0,0 +1,51 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+/**
+ * The JSON object contains methods for converting values to JavaScript Object
+ * Notation (JSON) and for converting JSON to values.
+ *
+ * MDN
+ */
+object JSON extends Object {
+ /**
+ * Parse a string as JSON, optionally transforming the value produced by parsing.
+ * @param text The string to parse as JSON. See the JSON object for a
+ * description of JSON syntax.
+ * @param reviver If a function, prescribes how the value originally produced
+ * by parsing is transformed, before being returned.
+ *
+ * MDN
+ */
+ def parse(text: String, reviver: Function2[Any, Any, Any] = ???): Dynamic = native
+
+ /**
+ * Convert a value to JSON, optionally replacing values if a replacer function
+ * is specified, or optionally including only the specified properties if a
+ * replacer array is specified.
+ *
+ * @param value The value to convert to a JSON string.
+ * @param replacer If a function, transforms values and properties encountered
+ * while stringifying; if an array, specifies the set of
+ * properties included in objects in the final string.
+ * @param space Causes the resulting string to be pretty-printed.
+ *
+ * MDN
+ */
+ def stringify(value: Any, replacer: Function2[String, Any, Any] = ???, space: Any = ???): String = native
+ def stringify(value: Any, replacer: Array[Any]): String = native
+ def stringify(value: Any, replacer: Array[Any], space: Any): String = native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala
new file mode 100644
index 0000000..e4803c8
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/JavaScriptException.scala
@@ -0,0 +1,20 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+
+package scala.scalajs.js
+
+case class JavaScriptException(exception: scala.Any) extends RuntimeException {
+ override def toString() = exception.toString()
+
+ override def fillInStackTrace(): Throwable = {
+ scala.scalajs.runtime.StackTrace.captureState(this, exception)
+ this
+ }
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Math.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Math.scala
new file mode 100644
index 0000000..02caaa0
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Math.scala
@@ -0,0 +1,277 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+/**
+ * Math is a built-in object that has properties and methods for mathematical
+ * constants and functions. Not a function object.
+ *
+ * MDN
+ */
+object Math extends Object {
+ /**
+ * Euler's constant and the base of natural logarithms, approximately 2.718.
+ *
+ * MDN
+ */
+ val E: Double = native
+ /**
+ * Natural logarithm of 10, approximately 2.303.
+ *
+ * MDN
+ */
+ val LN10: Double = native
+ /**
+ * Natural logarithm of 2, approximately 0.693.
+ *
+ * MDN
+ */
+ val LN2: Double = native
+ /**
+ * Base 2 logarithm of E, approximately 1.443.
+ *
+ * MDN
+ */
+ val LOG2E: Double = native
+ /**
+ * Base 10 logarithm of E, approximately 0.434.
+ *
+ * MSN
+ */
+ val LOG10E: Double = native
+ /**
+ * Ratio of the circumference of a circle to its diameter, approximately 3.14159.
+ *
+ * MDN
+ */
+ val PI: Double = native
+
+ /**
+ * Square root of 1/2; equivalently, 1 over the square root of 2, approximately 0.707.
+ *
+ * MDN
+ */
+ val SQRT1_2: Double = native
+
+ /**
+ * Square root of 2, approximately 1.414.
+ *
+ * MDN
+ */
+ val SQRT2: Double = native
+
+ /**
+ * Returns the absolute value of a number.
+ *
+ * Passing a non-numeric string or undefined/empty variable returns NaN.
+ * Passing null returns 0.
+ *
+ * MDN
+ */
+ def abs(x: Int): Int = native
+
+ /**
+ * Returns the absolute value of a number.
+ *
+ * Passing a non-numeric string or undefined/empty variable returns NaN.
+ * Passing null returns 0.
+ *
+ * MDN
+ */
+ def abs(x: Double): Double = native
+
+ /**
+ * The Math.acos() function returns the arccosine (in radians) of a number.
+ *
+ * The acos method returns a numeric value between 0 and pi radians for x
+ * between -1 and 1. If the value of number is outside this range, it returns NaN.
+ *
+ * MDN
+ */
+ def acos(x: Double): Double = native
+
+ /**
+ * The Math.asin() function returns the arcsine (in radians) of a number.
+ *
+ * The asin method returns a numeric value between -pi/2 and pi/2 radians for x
+ * between -1 and 1. If the value of number is outside this range, it returns NaN.
+ *
+ * MDN
+ */
+ def asin(x: Double): Double = native
+
+ /**
+ * The Math.atan() function returns the arctangent (in radians) of a number.
+ *
+ * The atan method returns a numeric value between -pi/2 and pi/2 radians.
+ *
+ * MDN
+ */
+ def atan(x: Double): Double = native
+
+ /**
+ * The Math.atan2() function returns the arctangent of the quotient of its
+ * arguments.
+ *
+ * The atan2 method returns a numeric value between -pi and pi representing
+ * the angle theta of an (x,y) point. This is the counterclockwise angle,
+ * measured in radians, between the positive X axis, and the point (x,y).
+ * Note that the arguments to this function pass the y-coordinate first and
+ * the x-coordinate second.
+ *
+ * atan2 is passed separate x and y arguments, and atan is passed the ratio
+ * of those two arguments.
+ *
+ * MDN
+ */
+ def atan2(y: Double, x: Double): Double = native
+
+ /**
+ * The Math.ceil() function returns the smallest integer greater than or
+ * equal to a number.
+ *
+ * MDN
+ */
+ def ceil(x: Double): Double = native
+
+ /**
+ * The Math.cos() function returns the cosine of a number.
+ *
+ * The cos method returns a numeric value between -1 and 1, which represents
+ * the cosine of the angle.
+ *
+ * MDN
+ */
+ def cos(x: Double): Double = native
+
+ /**
+ * The Math.exp() function returns E^x, where x is the argument, and E is
+ * Euler's constant, the base of the natural logarithms.
+ *
+ * MDN
+ */
+ def exp(x: Double): Double = native
+
+ /**
+ * The Math.floor() function returns the largest integer less than or equal
+ * to a number.
+ *
+ * MDN
+ */
+ def floor(x: Double): Double = native
+
+ /**
+ * The Math.log() function returns the natural logarithm (base E) of a number.
+ *
+ * If the value of number is negative, the return value is always NaN.
+ *
+ * MDN
+ */
+ def log(x: Double): Double = native
+
+ /**
+ * The Math.max() function returns the largest of zero or more numbers.
+ *
+ * MDN
+ */
+ def max(value1: Int, values: Int*): Int = native
+
+ /**
+ * The Math.max() function returns the largest of zero or more numbers.
+ *
+ * If no arguments are given, the result is - Infinity.
+ *
+ * If at least one of arguments cannot be converted to a number, the result is NaN.
+ *
+ * MDN
+ */
+ def max(values: Double*): Double = native
+
+ /**
+ * The Math.min() function returns the smallest of zero or more numbers.
+ *
+ * MDN
+ */
+ def min(value1: Int, values: Int*): Int = native
+
+ /**
+ * The Math.min() function returns the smallest of zero or more numbers.
+ *
+ * If no arguments are given, the result is Infinity.
+ *
+ * If at least one of arguments cannot be converted to a number, the result is NaN.
+ *
+ * MDN
+ */
+ def min(values: Double*): Double = native
+
+ /**
+ * The Math.pow() function returns the base to the exponent Power, that is, base^^exponent.
+ *
+ * MDN
+ */
+ def pow(x: Double, y: Double): Double = native
+
+ /**
+ * The Math.random() function returns a floating-point, pseudo-random number in
+ * the range [0, 1) that is, from 0 (inclusive) up to but not including 1
+ * (exclusive), which you can then scale to your desired range.
+ *
+ * The random number generator is seeded from the current time, as in Java.
+ *
+ * MDN
+ */
+ def random(): Double = native
+
+ /**
+ * The Math.round() function returns the value of a number rounded to the
+ * nearest integer.
+ *
+ * If the fractional portion of number is .5 or greater, the argument is
+ * rounded to the next higher integer. If the fractional portion of number
+ * is less than .5, the argument is rounded to the next lower integer.
+ *
+ * MDN
+ */
+ def round(x: Double): Double = native
+
+ /**
+ * The Math.sin() function returns the sine of a number.
+ *
+ * The sin method returns a numeric value between -1 and 1, which represents
+ * the sine of the angle given in radians.
+ *
+ * MDN
+ */
+ def sin(x: Double): Double = native
+
+ /**
+ * The Math.sqrt() function returns the square root (x\sqrt{x}) of a number.
+ *
+ * If the value of number is negative, sqrt returns NaN.
+ *
+ * MDN
+ */
+ def sqrt(x: Double): Double = native
+
+ /**
+ * The Math.tan() function returns the tangent of a number.
+ *
+ * The tan method returns a numeric value that represents the tangent of the angle.
+ *
+ * MDN
+ */
+ def tan(x: Double): Double = native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/Primitives.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Primitives.scala
new file mode 100644
index 0000000..1a3d88c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/Primitives.scala
@@ -0,0 +1,872 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+import annotation.JSBracketAccess
+
+import scala.language.{ dynamics, implicitConversions }
+import scala.reflect.ClassTag
+import scala.collection.{ immutable, mutable }
+import scala.collection.generic.CanBuildFrom
+
+/** Super-type of all JavaScript values.
+ *
+ * All values of a subtype of this trait represent JavaScript values, without
+ * boxing of proxying of any kind.
+ */
+sealed trait Any extends scala.AnyRef {
+}
+
+/** Provides implicit conversions from Scala values to JavaScript values. */
+object Any extends LowPrioAnyImplicits {
+ @inline implicit def fromUnit(value: Unit): prim.Undefined =
+ value.asInstanceOf[prim.Undefined]
+ @inline implicit def fromBoolean(value: scala.Boolean): prim.Boolean =
+ value.asInstanceOf[prim.Boolean]
+ @inline implicit def fromByte(value: scala.Byte): prim.Number =
+ value.asInstanceOf[prim.Number]
+ @inline implicit def fromShort(value: scala.Short): prim.Number =
+ value.asInstanceOf[prim.Number]
+ @inline implicit def fromInt(value: scala.Int): prim.Number =
+ value.asInstanceOf[prim.Number]
+ @inline implicit def fromLong(value: scala.Long): prim.Number =
+ value.toDouble.asInstanceOf[prim.Number]
+ @inline implicit def fromFloat(value: scala.Float): prim.Number =
+ value.asInstanceOf[prim.Number]
+ @inline implicit def fromDouble(value: scala.Double): prim.Number =
+ value.asInstanceOf[prim.Number]
+ @inline implicit def fromString(s: java.lang.String): prim.String =
+ s.asInstanceOf[prim.String]
+
+ @inline implicit def toDouble(value: prim.Number): scala.Double =
+ value.asInstanceOf[scala.Double]
+ @inline implicit def toBoolean(value: prim.Boolean): scala.Boolean =
+ value.asInstanceOf[scala.Boolean]
+ @inline implicit def toScalaString(value: prim.String): java.lang.String =
+ value.asInstanceOf[java.lang.String]
+
+ implicit def jsArrayOps[A](array: Array[A]): ArrayOps[A] =
+ new ArrayOps(array)
+
+ implicit def canBuildFromArray[A]: CanBuildFrom[Array[_], A, Array[A]] = {
+ @inline
+ class CanBuildFromArray extends CanBuildFrom[Array[_], A, Array[A]] {
+ def apply(from: Array[_]): mutable.Builder[A, Array[A]] =
+ new ArrayOps[A]
+ def apply(): mutable.Builder[A, Array[A]] =
+ new ArrayOps[A]
+ }
+ new CanBuildFromArray
+ }
+
+ implicit def fromFunction0[R](f: scala.Function0[R]): Function0[R] = sys.error("stub")
+ implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): Function1[T1, R] = sys.error("stub")
+ implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): Function2[T1, T2, R] = sys.error("stub")
+ implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): Function3[T1, T2, T3, R] = sys.error("stub")
+ implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): Function4[T1, T2, T3, T4, R] = sys.error("stub")
+ implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): Function5[T1, T2, T3, T4, T5, R] = sys.error("stub")
+ implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): Function6[T1, T2, T3, T4, T5, T6, R] = sys.error("stub")
+ implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): Function7[T1, T2, T3, T4, T5, T6, T7, R] = sys.error("stub")
+ implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = sys.error("stub")
+ implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = sys.error("stub")
+ implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = sys.error("stub")
+ implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = sys.error("stub")
+ implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = sys.error("stub")
+ implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = sys.error("stub")
+ implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = sys.error("stub")
+ implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = sys.error("stub")
+ implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = sys.error("stub")
+ implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = sys.error("stub")
+ implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = sys.error("stub")
+ implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = sys.error("stub")
+ implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = sys.error("stub")
+ implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = sys.error("stub")
+ implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = sys.error("stub")
+
+ implicit def toFunction0[R](f: Function0[R]): scala.Function0[R] = () => f()
+ implicit def toFunction1[T1, R](f: Function1[T1, R]): scala.Function1[T1, R] = (x1) => f(x1)
+ implicit def toFunction2[T1, T2, R](f: Function2[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2)
+ implicit def toFunction3[T1, T2, T3, R](f: Function3[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3)
+ implicit def toFunction4[T1, T2, T3, T4, R](f: Function4[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4)
+ implicit def toFunction5[T1, T2, T3, T4, T5, R](f: Function5[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5)
+ implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: Function6[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6)
+ implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: Function7[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7)
+ implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8)
+ implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)
+ implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)
+ implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
+ implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)
+ implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)
+ implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)
+ implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)
+ implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)
+ implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)
+ implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)
+ implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)
+ implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)
+ implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)
+ implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)
+}
+
+trait LowPrioAnyImplicits {
+ @inline implicit def richDouble(num: prim.Number): scala.runtime.RichDouble =
+ new scala.runtime.RichDouble(Any.toDouble(num))
+ @inline implicit def richBoolean(b: prim.Boolean): scala.runtime.RichBoolean =
+ new scala.runtime.RichBoolean(Any.toBoolean(b))
+
+ @inline implicit def stringOps(string: prim.String): immutable.StringOps =
+ new immutable.StringOps(Any.toScalaString(string))
+
+ implicit def wrapArray[A](array: Array[A]): WrappedArray[A] =
+ new WrappedArray(array)
+ implicit def wrapDictionary[A](dict: Dictionary[A]): WrappedDictionary[A] =
+ new WrappedDictionary(dict)
+}
+
+/** Dynamically typed JavaScript value.
+ *
+ * Values of this trait accept all possible JavaScript operations in a
+ * dynamically typed way. You can read and write any field, call any method,
+ * apply any JavaScript operator to values of this type.
+ */
+sealed trait Dynamic extends Any with scala.Dynamic {
+ /** Calls a method of this object. */
+ def applyDynamic(name: java.lang.String)(args: Any*): Dynamic = sys.error("stub")
+
+ /** Reads a field of this object. */
+ def selectDynamic(name: java.lang.String): Dynamic = sys.error("stub")
+
+ /** Writes a field of this object. */
+ def updateDynamic(name: java.lang.String)(value: Any): Unit = sys.error("stub")
+
+ /** Calls this object as a callable. */
+ def apply(args: Any*): Dynamic = native
+
+ import prim.Number
+
+ def unary_!(): Boolean = native
+
+ def unary_+(): Number = native
+ def unary_-(): Number = native
+ def unary_~(): Number = native
+
+ def +(that: Number): Dynamic = native // could be a String if this is a String
+ def -(that: Number): Number = native
+ def *(that: Number): Number = native
+ def /(that: Number): Number = native
+ def %(that: Number): Number = native
+ def <<(that: Number): Number = native
+ def >>(that: Number): Number = native
+ def >>>(that: Number): Number = native
+ def &(that: Number): Number = native
+ def |(that: Number): Number = native
+ def ^(that: Number): Number = native
+
+ def +(that: Dynamic): Dynamic = native // could be String if this or that is a String
+ def -(that: Dynamic): Number = native
+ def *(that: Dynamic): Number = native
+ def /(that: Dynamic): Number = native
+ def %(that: Dynamic): Number = native
+ def <<(that: Dynamic): Number = native
+ def >>(that: Dynamic): Number = native
+ def >>>(that: Dynamic): Number = native
+ def &(that: Dynamic): Number = native
+ def |(that: Dynamic): Number = native
+ def ^(that: Dynamic): Number = native
+
+ def <(that: Number): Boolean = native
+ def >(that: Number): Boolean = native
+ def <=(that: Number): Boolean = native
+ def >=(that: Number): Boolean = native
+
+ def <(that: String): Boolean = native
+ def >(that: String): Boolean = native
+ def <=(that: String): Boolean = native
+ def >=(that: String): Boolean = native
+
+ def <(that: Dynamic): Boolean = native
+ def >(that: Dynamic): Boolean = native
+ def <=(that: Dynamic): Boolean = native
+ def >=(that: Dynamic): Boolean = native
+
+ /* The result of (dyn && bool) and (dyn || bool) has, in theory, type
+ * (Dynamic v Boolean). This type cannot be expressed in Scala, but if it
+ * could, the operations one could apply on a (Dynamic v Boolean) would be
+ * the *intersection* of the operations one can apply on a Dynamic and on a
+ * Boolean. Since any operation can be applied on a Dynamic, this
+ * intersection is equal to the set of operations supported by Boolean.
+ * Hence the result type is restricted to Boolean.
+ */
+ def &&(that: Boolean): Boolean = native
+ def ||(that: Boolean): Boolean = native
+
+ def &&(that: Dynamic): Dynamic = native
+ def ||(that: Dynamic): Dynamic = native
+
+ // Work around the annoying implicits in Predef in Scala 2.10.
+ def x: Dynamic = native
+ def x_=(value: Any): Unit = native
+}
+
+/** Factory for dynamically typed JavaScript values. */
+object Dynamic {
+ /** Dynamic view of the global scope. */
+ @inline def global: Dynamic = scala.scalajs.runtime.environmentInfo.global
+
+ /** Instantiates a new object of a JavaScript class. */
+ def newInstance(clazz: Dynamic)(args: Any*): Object with Dynamic = sys.error("stub")
+
+ /** Creates a new object with a literal syntax.
+ *
+ * For example,
+ * js.Dynamic.literal(foo = 3, bar = "foobar")
+ * returns the JavaScript object
+ * {foo: 3, bar: "foobar"}
+ */
+ object literal extends scala.Dynamic {
+ /** literal creation like this:
+ * js.Dynamic.literal(name1 = "value", name2 = "value")
+ */
+ def applyDynamicNamed(name: java.lang.String)(
+ fields: (java.lang.String, Any)*): Object with Dynamic = sys.error("stub")
+
+ /** literal creation like this:
+ * js.Dynamic.literal("name1" -> "value", "name2" -> "value")
+ *
+ * Note that this could be simply `def apply`, but this would make the
+ * applyDynamicNamed fail, since a call with named arguments would
+ * be routed to the `def apply`, rather than def dynamic version.
+ */
+ def applyDynamic(name: java.lang.String)(
+ fields: (java.lang.String, Any)*): Object with Dynamic = sys.error("stub")
+
+ }
+}
+
+/** Base class of all JavaScript objects. */
+class Object extends Any {
+ def this(value: Any) = this()
+
+ def toLocaleString(): String = native
+ def valueOf(): scala.Any = native
+
+ /** Tests whether this object has the specified property as a direct property.
+ *
+ * Unlike [[js.Object.hasProperty]], this method does not check down the
+ * object's prototype chain.
+ *
+ * MDN
+ */
+ def hasOwnProperty(v: String): Boolean = native
+
+ /** Tests whether this object is in the prototype chain of another object. */
+ def isPrototypeOf(v: Object): Boolean = native
+
+ /** Tests whether the specified property in an object can be enumerated by a
+ * call to [[js.Object.properties]], with the exception of properties
+ * inherited through the prototype chain. If the object does not have the
+ * specified property, this method returns false.
+ *
+ * MDN
+ */
+ def propertyIsEnumerable(v: String): Boolean = native
+}
+
+/** The top-level `Object` JavaScript object. */
+object Object extends Object {
+ def apply(): Object = native
+ def apply(value: Any): Object = native
+
+ /** Tests whether the object has a property on itself or in its prototype
+ * chain. This method is the equivalent of `p in o` in JavaScript.
+ */
+ def hasProperty(o: Object, p: String): Boolean = sys.error("stub")
+
+ /**
+ * The Object.getPrototypeOf() method returns the prototype (i.e. the
+ * internal [[Prototype]]) of the specified object.
+ *
+ * MDN
+ */
+ def getPrototypeOf(o: Object): Object = native
+
+ /**
+ * The Object.getOwnPropertyDescriptor() method returns a property descriptor
+ * for an own property (that is, one directly present on an object, not
+ * present by dint of being along an object's prototype chain) of a given object.
+ *
+ * MDN
+ */
+ def getOwnPropertyDescriptor(o: Object, p: String): PropertyDescriptor = native
+
+ /**
+ * Object.getOwnPropertyNames returns an array whose elements are strings
+ * corresponding to the enumerable and non-enumerable properties found
+ * directly upon obj. The ordering of the enumerable properties in the array
+ * is consistent with the ordering exposed by a for...in loop (or by Object.keys)
+ * over the properties of the object. The ordering of the non-enumerable
+ * properties in the array, and among the enumerable properties, is not defined.
+ *
+ * MDN
+ */
+ def getOwnPropertyNames(o: Object): Array[String] = native
+
+ /**
+ * The Object.create() method creates a new object with the specified
+ * prototype object and properties.
+ *
+ * MDN
+ */
+ def create(o: Object, properties: Any): Object = native
+ def create(o: Object): Object = native
+
+ /**
+ * The Object.defineProperty() method defines a new property directly on an
+ * object, or modifies an existing property on an object, and returns the
+ * object.
+ *
+ * This method allows precise addition to or modification of a property on an
+ * object. Normal property addition through assignment creates properties
+ * which show up during property enumeration (for...in loop or Object.keys method),
+ * whose values may be changed, and which may be deleted. This method allows
+ * these extra details to be changed from their defaults.
+ *
+ * Property descriptors present in objects come in two main flavors: data
+ * descriptors and accessor descriptors. A data descriptor is a property
+ * that has a value, which may or may not be writable. An accessor descriptor
+ * is a property described by a getter-setter pair of functions. A descriptor
+ * must be one of these two flavors; it cannot be both.
+ *
+ * MDN
+ */
+ def defineProperty(o: Object, p: String, attributes: PropertyDescriptor): o.type = native
+
+ /**
+ * The Object.defineProperties() method defines new or modifies existing
+ * properties directly on an object, returning the object.
+ *
+ * MDN
+ */
+ def defineProperties(o: Object, properties: Any): o.type = native
+
+ /**
+ * The Object.seal() method seals an object, preventing new properties from
+ * being added to it and marking all existing properties as non-configurable.
+ * Values of present properties can still be changed as long as they are
+ * writable.
+ *
+ * MDN
+ */
+ def seal(o: Object): o.type = native
+
+ /**
+ * The Object.freeze() method freezes an object: that is, prevents new properties
+ * from being added to it; prevents existing properties from being removed;
+ * and prevents existing properties, or their enumerability, configurability,
+ * or writability, from being changed. In essence the object is made effectively
+ * immutable. The method returns the object being frozen.
+ *
+ * MDN
+ */
+ def freeze(o: Object): o.type = native
+
+ /**
+ * The Object.preventExtensions() method prevents new properties from ever
+ * being added to an object (i.e. prevents future extensions to the object).
+ *
+ * An object is extensible if new properties can be added to it. preventExtensions
+ * marks an object as no longer extensible, so that it will never have
+ * properties beyond the ones it had at the time it was marked as non-extensible.
+ * Note that the properties of a non-extensible object, in general, may still be
+ * deleted. Attempting to add new properties to a non-extensible object will
+ * fail, either silently or by throwing a TypeError (most commonly, but not
+ * exclusively, when in strict mode).
+ *
+ * Object.preventExtensions only prevents addition of own properties. Properties
+ * can still be added to the object prototype. However, calling Object.preventExtensions
+ * on an object will also prevent extensions on its __proto__ property.
+ *
+ * MDN
+ */
+ def preventExtensions(o: Object): o.type = native
+
+ /**
+ * Returns true if the object is sealed, otherwise false. An object is sealed
+ * if it is not extensible and if all its properties are non-configurable and
+ * therefore not removable (but not necessarily non-writable).
+ *
+ * MDN
+ */
+ def isSealed(o: Object): Boolean = native
+
+ /**
+ * The Object.isFrozen() determines if an object is frozen.
+ *
+ * An object is frozen if and only if it is not extensible, all its properties
+ * are non-configurable, and all its data properties (that is, properties which
+ * are not accessor properties with getter or setter components) are non-writable.
+ *
+ * MDN
+ */
+ def isFrozen(o: Object): Boolean = native
+
+ /**
+ * Determines if extending of an object is allowed
+ *
+ * Objects are extensible by default: they can have new properties added to
+ * them, and (in engines that support __proto__ their __proto__ property)
+ * can be modified. An object can be marked as non-extensible using
+ * Object.preventExtensions, Object.seal, or Object.freeze
+ *
+ * MDN
+ */
+ def isExtensible(o: Object): Boolean = native
+
+ /**
+ * The Object.keys() method returns an array of a given object's own enumerable
+ * properties, in the same order as that provided by a for...in loop (the
+ * difference being that a for-in loop enumerates properties in the prototype
+ * chain as well).
+ *
+ * MDN
+ */
+ def keys(o: Object): Array[String] = native
+
+ /** Returns the names of all the enumerable properties of this object,
+ * including properties in its prototype chain.
+ *
+ * This method returns the same set of names that would be enumerated by
+ * a for-in loop in JavaScript, but not necessarily in the same order.
+ *
+ * If the underlying implementation guarantees an order for for-in loops,
+ * then this is guaranteed to be consistent with [[keys]], in the sense
+ * that the list returned by [[keys]] is a sublist of the list returned by
+ * this method (not just a subset).
+ */
+ def properties(o: Any): Array[String] = sys.error("stub")
+}
+
+package prim {
+
+/** Primitive JavaScript number.
+ *
+ * In most situations, you should not need this trait, and use
+ * [[scala.Double]] instead (or [[scala.Int]] where appropriate).
+ */
+sealed trait Number extends Any {
+ def unary_+(): Number = native
+ def unary_-(): Number = native
+ def unary_~(): Number = native
+
+ def +(that: Number): Number = native
+ def -(that: Number): Number = native
+ def *(that: Number): Number = native
+ def /(that: Number): Number = native
+ def %(that: Number): Number = native
+ def <<(that: Number): Number = native
+ def >>(that: Number): Number = native
+ def >>>(that: Number): Number = native
+ def &(that: Number): Number = native
+ def |(that: Number): Number = native
+ def ^(that: Number): Number = native
+
+ def +(that: Dynamic): Dynamic = native // could be a String if that is a String
+ def -(that: Dynamic): Number = native
+ def *(that: Dynamic): Number = native
+ def /(that: Dynamic): Number = native
+ def %(that: Dynamic): Number = native
+ def <<(that: Dynamic): Number = native
+ def >>(that: Dynamic): Number = native
+ def >>>(that: Dynamic): Number = native
+ def &(that: Dynamic): Number = native
+ def |(that: Dynamic): Number = native
+ def ^(that: Dynamic): Number = native
+
+ def <(that: Number): Boolean = native
+ def >(that: Number): Boolean = native
+ def <=(that: Number): Boolean = native
+ def >=(that: Number): Boolean = native
+
+ def <(that: Dynamic): Boolean = native
+ def >(that: Dynamic): Boolean = native
+ def <=(that: Dynamic): Boolean = native
+ def >=(that: Dynamic): Boolean = native
+
+ def toString(radix: Number): String = native
+
+ /**
+ * Returns a string representation of number that does not use exponential
+ * notation and has exactly digits digits after the decimal place. The number
+ * is rounded if necessary, and the fractional part is padded with zeros if
+ * necessary so that it has the specified length. If number is greater than
+ * 1e+21, this method simply calls Number.prototype.toString() and returns
+ * a string in exponential notation.
+ *
+ * MDN
+ */
+ def toFixed(fractionDigits: Number): String = native
+ def toFixed(): String = native
+
+ /**
+ * Returns a string representing a Number object in exponential notation with one
+ * digit before the decimal point, rounded to fractionDigits digits after the
+ * decimal point. If the fractionDigits argument is omitted, the number of
+ * digits after the decimal point defaults to the number of digits necessary
+ * to represent the value uniquely.
+ *
+ * If a number has more digits that requested by the fractionDigits parameter,
+ * the number is rounded to the nearest number represented by fractionDigits
+ * digits. See the discussion of rounding in the description of the toFixed()
+ * method, which also applies to toExponential().
+ *
+ * MDN
+ */
+ def toExponential(fractionDigits: Number): String = native
+ def toExponential(): String = native
+
+ /**
+ * Returns a string representing a Number object in fixed-point or exponential
+ * notation rounded to precision significant digits. See the discussion of
+ * rounding in the description of the Number.prototype.toFixed() method, which
+ * also applies to toPrecision.
+ *
+ * If the precision argument is omitted, behaves as Number.prototype.toString().
+ * If it is a non-integer value, it is rounded to the nearest integer.
+ *
+ * MDN
+ */
+ def toPrecision(precision: Number): String = native
+ def toPrecision(): String = native
+}
+
+/** The top-level `Number` JavaScript object */
+object Number extends Object {
+ /**
+ * The Number.MAX_VALUE property represents the maximum numeric value
+ * representable in JavaScript.
+ *
+ * The MAX_VALUE property has a value of approximately 1.79E+308. Values
+ * larger than MAX_VALUE are represented as "Infinity".
+ *
+ * MDN
+ */
+ val MAX_VALUE: Double = native
+ /**
+ * The Number.MIN_VALUE property represents the smallest positive numeric
+ * value representable in JavaScript.
+ *
+ * The MIN_VALUE property is the number closest to 0, not the most negative
+ * number, that JavaScript can represent.
+ *
+ * MIN_VALUE has a value of approximately 5e-324. Values smaller than MIN_VALUE
+ * ("underflow values") are converted to 0.
+ *
+ * MDN
+ */
+ val MIN_VALUE: Double = native
+ /**
+ * The Number.NaN property represents Not-A-Number. Equivalent of NaN.
+ *
+ * MDN
+ */
+ val NaN: Double = native
+
+ /**
+ * The Number.NEGATIVE_INFINITY property represents the negative Infinity value.
+ *
+ * MDN
+ */
+ val NEGATIVE_INFINITY: Double = native
+ /**
+ * The Number.POSITIVE_INFINITY property represents the positive Infinity value.
+ *
+ * MDN
+ */
+ val POSITIVE_INFINITY: Double = native
+}
+
+/** Primitive JavaScript boolean.
+ *
+ * In most situations, you should not need this trait, and use
+ * [[scala.Boolean]] instead.
+ */
+sealed trait Boolean extends Any {
+ def unary_!(): scala.Boolean = native
+
+ def &&(that: Boolean): Boolean = native
+ def ||(that: Boolean): Boolean = native
+
+ // See the comment in `Dynamic` for the rationale of returning Boolean here.
+ def &&(that: Dynamic): Boolean = native
+ def ||(that: Dynamic): Boolean = native
+}
+
+/** The top-level `Boolean` JavaScript object. */
+object Boolean extends Object
+
+/** Primitive JavaScript string.
+ *
+ * In most situations, you should not need this trait, and use
+ * [[java.lang.String]] instead.
+ */
+sealed trait String extends Any {
+ def +(that: String): String = native
+ def +(that: Any): String = native
+ def +(that: Dynamic): String = native
+
+ def < (that: String): Boolean = native
+ def < (that: Dynamic): Boolean = native
+
+ def > (that: String): Boolean = native
+ def > (that: Dynamic): Boolean = native
+
+ def <=(that: String): Boolean = native
+ def <=(that: Dynamic): Boolean = native
+
+ def >=(that: String): Boolean = native
+ def >=(that: Dynamic): Boolean = native
+
+ /**
+ * This property returns the number of code units in the string. UTF-16,
+ * the string format used by JavaScript, uses a single 16-bit code unit to
+ * represent the most common characters, but needs to use two code units for
+ * less commonly-used characters, so it's possible for the value returned by
+ * length to not match the actual number of characters in the string.
+ *
+ * For an empty string, length is 0.
+ *
+ * MDN
+ */
+ val length: Number = native
+
+ /**
+ * The chartAt() method returns the specified character from a string.
+ *
+ * Characters in a string are indexed from left to right. The index of the
+ * first character is 0, and the index of the last character in a string
+ * called stringName is stringName.length - 1. If the index you supply is out
+ * of range, JavaScript returns an empty string.
+ *
+ * MDN
+ */
+ def charAt(pos: Number): String = native
+
+ /**
+ * The charCodeAt() method returns the numeric Unicode value of the character
+ * at the given index (except for unicode codepoints > 0x10000).
+ *
+ * MDN
+ */
+ def charCodeAt(index: Number): Number = native
+
+ /**
+ * concat combines the text from one or more strings and returns a new string.
+ * Changes to the text in one string do not affect the other string.
+ * MDN
+ */
+ def concat(strings: String*): String = native
+
+ /**
+ * Returns the index within the calling String object of the first occurrence
+ * of the specified value, starting the search at fromIndex,
+ *
+ * returns -1 if the value is not found.
+ *
+ * MDN
+ */
+ def indexOf(searchString: String, position: Number): Number = native
+ def indexOf(searchString: String): Number = native
+
+ /**
+ * Returns the index within the calling String object of the last occurrence
+ * of the specified value, or -1 if not found. The calling string is searched
+ * backward, starting at fromIndex.
+ *
+ * MDN
+ */
+ def lastIndexOf(searchString: String, position: Number): Number = native
+ def lastIndexOf(searchString: String): Number = native
+
+ /**
+ * Returns a number indicating whether a reference string comes before or
+ * after or is the same as the given string in sort order. The new locales
+ * and options arguments let applications specify the language whose sort
+ * order should be used and customize the behavior of the function. In older
+ * implementations, which ignore the locales and options arguments, the locale
+ * and sort order used are entirely implementation dependent.
+ *
+ * MDN
+ */
+ def localeCompare(that: String): Number = native
+
+ /**
+ * Used to retrieve the matches when matching a string against a regular
+ * expression.
+ *
+ * If the regular expression does not include the g flag, returns the same
+ * result as regexp.exec(string). The returned Array has an extra input
+ * property, which contains the original string that was parsed. In addition,
+ * it has an index property, which represents the zero-based index of the
+ * match in the string.
+ *
+ * If the regular expression includes the g flag, the method returns an Array
+ * containing all matches. If there were no matches, the method returns null.
+ *
+ * MDN
+ */
+ def `match`(regexp: String): Array[String] = native
+ def `match`(regexp: RegExp): Array[String] = native
+
+ /**
+ * Returns a new string with some or all matches of a pattern replaced by a
+ * replacement. The pattern can be a string or a RegExp, and the replacement
+ * can be a string or a function to be called for each match.
+ *
+ * This method does not change the String object it is called on. It simply
+ * returns a new string.
+ *
+ * To perform a global search and replace, either include the g switch in the
+ * regular expression or if the first parameter is a string, include g in the
+ * flags parameter.
+ *
+ * MDN
+ */
+ def replace(searchValue: String, replaceValue: String): String = native
+ def replace(searchValue: String, replaceValue: Any): String = native
+ def replace(searchValue: RegExp, replaceValue: String): String = native
+ def replace(searchValue: RegExp, replaceValue: Any): String = native
+
+ /**
+ * If successful, search returns the index of the regular expression inside
+ * the string. Otherwise, it returns -1.
+ *
+ * When you want to know whether a pattern is found in a string use search
+ * (similar to the regular expression test method); for more information
+ * (but slower execution) use match (similar to the regular expression exec
+ * method).
+ *
+ * MDN
+ */
+ def search(regexp: String): Number = native
+ def search(regexp: RegExp): Number = native
+
+ /**
+ * slice extracts the text from one string and returns a new string. Changes
+ * to the text in one string do not affect the other string.
+ *
+ * slice extracts up to but not including endSlice. string.slice(1,4) extracts
+ * the second character through the fourth character (characters indexed 1, 2,
+ * and 3).
+ *
+ * As an example, string.slice(2,-1) extracts the third character through the
+ * second to last character in the string.
+ *
+ * MDN
+ */
+ def slice(start: Number, end: Number): String = native
+ def slice(start: Number): String = native
+
+ /**
+ * Splits a String object into an array of strings by separating the string
+ * into substrings.
+ *
+ * When found, separator is removed from the string and the substrings are
+ * returned in an array. If separator is omitted, the array contains one
+ * element consisting of the entire string. If separator is an empty string,
+ * string is converted to an array of characters.
+ *
+ * If separator is a regular expression that contains capturing parentheses,
+ * then each time separator is matched, the results (including any undefined
+ * results) of the capturing parentheses are spliced into the output array.
+ * However, not all browsers support this capability.
+ *
+ * Note: When the string is empty, split returns an array containing one
+ * empty string, rather than an empty array.
+ *
+ * MDN
+ */
+ def split(separator: String, limit: Number): Array[String] = native
+ def split(separator: String): Array[String] = native
+ def split(separator: RegExp, limit: Number): Array[String] = native
+ def split(separator: RegExp): Array[String] = native
+
+ /**
+ * Returns a subset of a string between one index and another, or through
+ * the end of the string.
+ *
+ * MDN
+ */
+ def substring(start: Number, end: Number): String = native
+ def substring(start: Number): String = native
+
+ /**
+ * Returns the calling string value converted to lowercase.
+ *
+ * MDN
+ */
+ def toLowerCase(): String = native
+
+ /**
+ * The toLocaleLowerCase method returns the value of the string converted to
+ * lower case according to any locale-specific case mappings. toLocaleLowerCase
+ * does not affect the value of the string itself. In most cases, this will
+ * produce the same result as toLowerCase(), but for some locales, such as
+ * Turkish, whose case mappings do not follow the default case mappings in Unicode,
+ * there may be a different result.
+ *
+ * MDN
+ */
+ def toLocaleLowerCase(): String = native
+
+ /**
+ * Returns the calling string value converted to uppercase.
+ *
+ * MDN
+ */
+ def toUpperCase(): String = native
+
+ /**
+ * The toLocaleUpperCase method returns the value of the string converted to
+ * upper case according to any locale-specific case mappings. toLocaleUpperCase
+ * does not affect the value of the string itself. In most cases, this will
+ * produce the same result as toUpperCase(), but for some locales, such as
+ * Turkish, whose case mappings do not follow the default case mappings in Unicode,
+ * there may be a different result.
+ *
+ * MDN
+ */
+ def toLocaleUpperCase(): String = native
+
+ /**
+ * Removes whitespace from both ends of the string.
+ *
+ * MDN
+ */
+ def trim(): String = native
+}
+
+/** The top-level `String` JavaScript object. */
+object String extends Object {
+ def fromCharCode(codes: Int*): java.lang.String = native
+}
+
+/** Primitive JavaScript undefined value.
+ *
+ * In most situations, you should not need this trait, and use
+ * [[scala.Unit]] instead.
+ */
+sealed trait Undefined extends Any
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala
new file mode 100644
index 0000000..b91e01d
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/PropertyDescriptor.scala
@@ -0,0 +1,20 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+
+package scala.scalajs.js
+
+trait PropertyDescriptor extends Object {
+ var configurable: Boolean = native
+ var enumerable: Boolean = native
+ var value: Any = native
+ var writable: Boolean = native
+ var get: Function0[Any] = native
+ var set: Function1[Any, Any] = native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/RegExp.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/RegExp.scala
new file mode 100644
index 0000000..73f465a
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/RegExp.scala
@@ -0,0 +1,108 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+/**
+ * The RegExp constructor creates a regular expression object for matching
+ * text with a pattern.
+ *
+ * MDN
+ */
+class RegExp(pattern: String, flags: String = "") extends Object {
+ /**
+ * The source property returns a String containing the text of the pattern,
+ * excluding the forward slashes. It is a read-only property of an individual
+ * regular expression instance. source does not contain any flags (like "g",
+ * "i" or "m") of the regular expression.
+ *
+ * MDN
+ */
+ val source: String = native
+ /**
+ * The value of global is a Boolean and true if the "g" flag was used;
+ * otherwise, false. The "g" flag indicates that the regular expression
+ * should be tested against all possible matches in a string.
+ *
+ * MDN
+ */
+ val global: Boolean = native
+ /**
+ * The value of ignoreCase is a Boolean and true if the "i" flag was used;
+ * otherwise, false. The "i" flag indicates that case should be ignored while
+ * attempting a match in a string.
+ *
+ * MDN
+ */
+ val ignoreCase: Boolean = native
+ /**
+ * The value of multiline is a Boolean and is true if the "m" flag was used;
+ * otherwise, false. The "m" flag indicates that a multiline input string
+ * should be treated as multiple lines. For example, if "m" is used, "^" and
+ * "$" change from matching at only the start or end of the entire string to
+ * the start or end of any line within the string.
+
+ * MDN
+ */
+ val multiline: Boolean = native
+
+ /**
+ * The lastIndex is a read/write integer property of regular expressions that
+ * specifies the index at which to start the next match.
+ *
+ * MDN
+ */
+ var lastIndex: Int = native
+
+ /**
+ * The exec() method executes a search for a match in a specified string.
+ * Returns a result array, or null.
+ *
+ * If you are executing a match simply to find true or false, use the
+ * RegExp.test() method or the String.search() method.
+ *
+ * If the match succeeds, the exec method returns an array and updates properties
+ * of the regular expression object. The returned array has the matched text
+ * as the first item, and then one item for each capturing parenthesis that
+ * matched containing the text that was captured.
+ *
+ * If the match fails, the exec method returns null.
+ *
+ * MDN
+ */
+ def exec(string: String): RegExp.ExecResult = native
+
+ /**
+ * The test() method executes a search for a match between a regular expression
+ * and a specified string. Returns true or false.
+ *
+ * You can use test() whenever want to know whether a pattern is found in a
+ * string (similar to the String.search method); for more information (but
+ * slower execution) use the exec method (similar to the String.match method).
+ * As with exec (or in combination with it), test called multiple times on the
+ * same global regular expression instance will advance past the previous match.
+ *
+ * MDN
+ */
+ def test(string: String): Boolean = native
+}
+
+object RegExp extends Object {
+ def apply(pattern: String, flags: String = ""): RegExp = native
+
+ trait ExecResult extends Array[UndefOr[String]] {
+ var index: Int = native
+ var input: String = native
+ }
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/ThisFunction.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/ThisFunction.scala
new file mode 100644
index 0000000..2506eed
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/ThisFunction.scala
@@ -0,0 +1,160 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+/**
+ * All doc-comments marked as "MDN" are by Mozilla Contributors,
+ * distributed under the Creative Commons Attribution-ShareAlike license from
+ * https://developer.mozilla.org/en-US/docs/Web/Reference/API
+ */
+package scala.scalajs.js
+
+import scala.language.implicitConversions
+
+/** A JavaScript function where `this` is considered as a first parameter.
+ *
+ * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]]
+ */
+trait ThisFunction extends Function {
+}
+
+object ThisFunction {
+ implicit def fromFunction1[T1, R](f: scala.Function1[T1, R]): ThisFunction0[T1, R] = sys.error("stub")
+ implicit def fromFunction2[T1, T2, R](f: scala.Function2[T1, T2, R]): ThisFunction1[T1, T2, R] = sys.error("stub")
+ implicit def fromFunction3[T1, T2, T3, R](f: scala.Function3[T1, T2, T3, R]): ThisFunction2[T1, T2, T3, R] = sys.error("stub")
+ implicit def fromFunction4[T1, T2, T3, T4, R](f: scala.Function4[T1, T2, T3, T4, R]): ThisFunction3[T1, T2, T3, T4, R] = sys.error("stub")
+ implicit def fromFunction5[T1, T2, T3, T4, T5, R](f: scala.Function5[T1, T2, T3, T4, T5, R]): ThisFunction4[T1, T2, T3, T4, T5, R] = sys.error("stub")
+ implicit def fromFunction6[T1, T2, T3, T4, T5, T6, R](f: scala.Function6[T1, T2, T3, T4, T5, T6, R]): ThisFunction5[T1, T2, T3, T4, T5, T6, R] = sys.error("stub")
+ implicit def fromFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: scala.Function7[T1, T2, T3, T4, T5, T6, T7, R]): ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R] = sys.error("stub")
+ implicit def fromFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]): ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R] = sys.error("stub")
+ implicit def fromFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = sys.error("stub")
+ implicit def fromFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = sys.error("stub")
+ implicit def fromFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = sys.error("stub")
+ implicit def fromFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = sys.error("stub")
+ implicit def fromFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = sys.error("stub")
+ implicit def fromFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = sys.error("stub")
+ implicit def fromFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = sys.error("stub")
+ implicit def fromFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = sys.error("stub")
+ implicit def fromFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = sys.error("stub")
+ implicit def fromFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = sys.error("stub")
+ implicit def fromFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = sys.error("stub")
+ implicit def fromFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = sys.error("stub")
+ implicit def fromFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = sys.error("stub")
+ implicit def fromFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = sys.error("stub")
+
+ implicit def toFunction1[T1, R](f: ThisFunction0[T1, R]): scala.Function1[T1, R] = (x1) => f(x1)
+ implicit def toFunction2[T1, T2, R](f: ThisFunction1[T1, T2, R]): scala.Function2[T1, T2, R] = (x1, x2) => f(x1, x2)
+ implicit def toFunction3[T1, T2, T3, R](f: ThisFunction2[T1, T2, T3, R]): scala.Function3[T1, T2, T3, R] = (x1, x2, x3) => f(x1, x2, x3)
+ implicit def toFunction4[T1, T2, T3, T4, R](f: ThisFunction3[T1, T2, T3, T4, R]): scala.Function4[T1, T2, T3, T4, R] = (x1, x2, x3, x4) => f(x1, x2, x3, x4)
+ implicit def toFunction5[T1, T2, T3, T4, T5, R](f: ThisFunction4[T1, T2, T3, T4, T5, R]): scala.Function5[T1, T2, T3, T4, T5, R] = (x1, x2, x3, x4, x5) => f(x1, x2, x3, x4, x5)
+ implicit def toFunction6[T1, T2, T3, T4, T5, T6, R](f: ThisFunction5[T1, T2, T3, T4, T5, T6, R]): scala.Function6[T1, T2, T3, T4, T5, T6, R] = (x1, x2, x3, x4, x5, x6) => f(x1, x2, x3, x4, x5, x6)
+ implicit def toFunction7[T1, T2, T3, T4, T5, T6, T7, R](f: ThisFunction6[T1, T2, T3, T4, T5, T6, T7, R]): scala.Function7[T1, T2, T3, T4, T5, T6, T7, R] = (x1, x2, x3, x4, x5, x6, x7) => f(x1, x2, x3, x4, x5, x6, x7)
+ implicit def toFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R](f: ThisFunction7[T1, T2, T3, T4, T5, T6, T7, T8, R]): scala.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R] = (x1, x2, x3, x4, x5, x6, x7, x8) => f(x1, x2, x3, x4, x5, x6, x7, x8)
+ implicit def toFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R](f: ThisFunction8[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]): scala.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9)
+ implicit def toFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R](f: ThisFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]): scala.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10)
+ implicit def toFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R](f: ThisFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]): scala.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
+ implicit def toFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R](f: ThisFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]): scala.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12)
+ implicit def toFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R](f: ThisFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]): scala.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13)
+ implicit def toFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R](f: ThisFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]): scala.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14)
+ implicit def toFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R](f: ThisFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]): scala.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15)
+ implicit def toFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R](f: ThisFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]): scala.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16)
+ implicit def toFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R](f: ThisFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]): scala.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17)
+ implicit def toFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R](f: ThisFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]): scala.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18)
+ implicit def toFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R](f: ThisFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]): scala.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19)
+ implicit def toFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R](f: ThisFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]): scala.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20)
+ implicit def toFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R](f: ThisFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]): scala.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21)
+ implicit def toFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R](f: ThisFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]): scala.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] = (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22)
+}
+
+trait ThisFunction0[-T0, +R] extends ThisFunction {
+ def apply(thisArg: T0): R
+}
+
+trait ThisFunction1[-T0, -T1, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1): R
+}
+
+trait ThisFunction2[-T0, -T1, -T2, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2): R
+}
+
+trait ThisFunction3[-T0, -T1, -T2, -T3, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3): R
+}
+
+trait ThisFunction4[-T0, -T1, -T2, -T3, -T4, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4): R
+}
+
+trait ThisFunction5[-T0, -T1, -T2, -T3, -T4, -T5, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R
+}
+
+trait ThisFunction6[-T0, -T1, -T2, -T3, -T4, -T5, -T6, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R
+}
+
+trait ThisFunction7[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R
+}
+
+trait ThisFunction8[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R
+}
+
+trait ThisFunction9[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R
+}
+
+trait ThisFunction10[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R
+}
+
+trait ThisFunction11[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R
+}
+
+trait ThisFunction12[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R
+}
+
+trait ThisFunction13[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R
+}
+
+trait ThisFunction14[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R
+}
+
+trait ThisFunction15[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R
+}
+
+trait ThisFunction16[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R
+}
+
+trait ThisFunction17[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R
+}
+
+trait ThisFunction18[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R
+}
+
+trait ThisFunction19[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R
+}
+
+trait ThisFunction20[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R
+}
+
+trait ThisFunction21[-T0, -T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R] extends ThisFunction {
+ def apply(thisArg: T0, arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/UndefOr.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/UndefOr.scala
new file mode 100644
index 0000000..b356e3a
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/UndefOr.scala
@@ -0,0 +1,254 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.js
+
+import scala.language.implicitConversions
+
+/** Value of type A or the JS undefined value.
+ * In a type system with union types, this would really be
+ * `A | js.prim.Undefined`. Since Scala does not have union types, but this
+ * particular union is crucial to many interoperability scenarios, it is
+ * provided as this trait.
+ *
+ * An API similar to that of [[scala.Option]] is provided through the
+ * [[UndefOrOps]] implicit class, with the understanding that `undefined` is
+ * the None value.
+ */
+@scala.scalajs.js.annotation.RawJSType // Don't do this at home!
+sealed trait UndefOr[+A]
+
+object UndefOr {
+ implicit def any2undefOrA[A](value: A): UndefOr[A] =
+ value.asInstanceOf[UndefOr[A]]
+
+ implicit def undef2undefOr(value: prim.Undefined): UndefOr[Nothing] =
+ value.asInstanceOf[UndefOr[Nothing]]
+
+ implicit def undefOr2ops[A](value: UndefOr[A]): UndefOrOps[A] =
+ new UndefOrOps(value)
+
+ implicit def undefOr2jsAny[A](value: UndefOr[A])(implicit ev: A => Any): Any =
+ value.map(ev).asInstanceOf[Any]
+}
+
+final class UndefOrOps[A](val self: UndefOr[A]) extends AnyVal {
+ import UndefOrOps._
+
+ /** Returns true if the option is `undefined`, false otherwise.
+ */
+ @inline final def isEmpty: Boolean = isUndefined(self)
+
+ /** Returns true if the option is not `undefined`, false otherwise.
+ */
+ @inline final def isDefined: Boolean = !isEmpty
+
+ /** Returns the option's value.
+ * @note The option must be nonEmpty.
+ * @throws Predef.NoSuchElementException if the option is empty.
+ */
+ @inline final def get: A =
+ if (isEmpty) throw new NoSuchElementException("undefined.get")
+ else self.asInstanceOf[A]
+
+ @inline final private def forceGet: A = self.asInstanceOf[A]
+
+ /** Returns the option's value if the option is nonempty, otherwise
+ * return the result of evaluating `default`.
+ *
+ * @param default the default expression.
+ */
+ @inline final def getOrElse[B >: A](default: => B): B =
+ if (isEmpty) default else this.forceGet
+
+ /** Returns the option's value if it is nonempty,
+ * or `null` if it is empty.
+ * Although the use of null is discouraged, code written to use
+ * $option must often interface with code that expects and returns nulls.
+ * @example {{{
+ * val initalText: Option[String] = getInitialText
+ * val textField = new JComponent(initalText.orNull,20)
+ * }}}
+ */
+ @inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 =
+ this getOrElse ev(null)
+
+ /** Returns a $some containing the result of applying $f to this $option's
+ * value if this $option is nonempty.
+ * Otherwise return $none.
+ *
+ * @note This is similar to `flatMap` except here,
+ * $f does not need to wrap its result in an $option.
+ *
+ * @param f the function to apply
+ * @see flatMap
+ * @see foreach
+ */
+ @inline final def map[B](f: A => B): UndefOr[B] =
+ if (isEmpty) undefined else f(this.forceGet)
+
+ /** Returns the result of applying $f to this $option's
+ * value if the $option is nonempty. Otherwise, evaluates
+ * expression `ifEmpty`.
+ *
+ * @note This is equivalent to `$option map f getOrElse ifEmpty`.
+ *
+ * @param ifEmpty the expression to evaluate if empty.
+ * @param f the function to apply if nonempty.
+ */
+ @inline final def fold[B](ifEmpty: => B)(f: A => B): B =
+ if (isEmpty) ifEmpty else f(this.forceGet)
+
+ /** Returns the result of applying $f to this $option's value if
+ * this $option is nonempty.
+ * Returns $none if this $option is empty.
+ * Slightly different from `map` in that $f is expected to
+ * return an $option (which could be $none).
+ *
+ * @param f the function to apply
+ * @see map
+ * @see foreach
+ */
+ @inline final def flatMap[B](f: A => UndefOr[B]): UndefOr[B] =
+ if (isEmpty) undefined else f(this.forceGet)
+
+ def flatten[B](implicit ev: A <:< UndefOr[B]): UndefOr[B] =
+ if (isEmpty) undefined else ev(this.forceGet)
+
+ /** Returns this $option if it is nonempty '''and''' applying the predicate $p to
+ * this $option's value returns true. Otherwise, return $none.
+ *
+ * @param p the predicate used for testing.
+ */
+ @inline final def filter(p: A => Boolean): UndefOr[A] =
+ if (isEmpty || p(this.forceGet)) self else undefined
+
+ /** Returns this $option if it is nonempty '''and''' applying the predicate $p to
+ * this $option's value returns false. Otherwise, return $none.
+ *
+ * @param p the predicate used for testing.
+ */
+ @inline final def filterNot(p: A => Boolean): UndefOr[A] =
+ if (isEmpty || !p(this.forceGet)) self else undefined
+
+ /** Returns false if the option is $none, true otherwise.
+ * @note Implemented here to avoid the implicit conversion to Iterable.
+ */
+ final def nonEmpty = isDefined
+
+ /** Necessary to keep $option from being implicitly converted to
+ * [[scala.collection.Iterable]] in `for` comprehensions.
+ */
+ @inline final def withFilter(p: A => Boolean): WithFilter[A] =
+ new WithFilter(self, p)
+
+ /** Returns true if this option is nonempty '''and''' the predicate
+ * $p returns true when applied to this $option's value.
+ * Otherwise, returns false.
+ *
+ * @param p the predicate to test
+ */
+ @inline final def exists(p: A => Boolean): Boolean =
+ !isEmpty && p(this.forceGet)
+
+ /** Returns true if this option is empty '''or''' the predicate
+ * $p returns true when applied to this $option's value.
+ *
+ * @param p the predicate to test
+ */
+ @inline final def forall(p: A => Boolean): Boolean =
+ isEmpty || p(this.forceGet)
+
+ /** Apply the given procedure $f to the option's value,
+ * if it is nonempty. Otherwise, do nothing.
+ *
+ * @param f the procedure to apply.
+ * @see map
+ * @see flatMap
+ */
+ @inline final def foreach[U](f: A => U): Unit =
+ if (!isEmpty) f(this.forceGet)
+
+ /** Returns a $some containing the result of
+ * applying `pf` to this $option's contained
+ * value, '''if''' this option is
+ * nonempty '''and''' `pf` is defined for that value.
+ * Returns $none otherwise.
+ *
+ * @param pf the partial function.
+ * @return the result of applying `pf` to this $option's
+ * value (if possible), or $none.
+ */
+ @inline final def collect[B](pf: PartialFunction[A, B]): UndefOr[B] =
+ if (isEmpty) undefined
+ else pf.applyOrElse(this.forceGet, (_: A) => undefined).asInstanceOf[UndefOr[B]]
+
+ /** Returns this $option if it is nonempty,
+ * otherwise return the result of evaluating `alternative`.
+ * @param alternative the alternative expression.
+ */
+ @inline final def orElse[B >: A](alternative: => UndefOr[B]): UndefOr[B] =
+ if (isEmpty) alternative else self
+
+ /** Returns a singleton iterator returning the $option's value
+ * if it is nonempty, or an empty iterator if the option is empty.
+ */
+ def iterator: Iterator[A] =
+ if (isEmpty) scala.collection.Iterator.empty
+ else scala.collection.Iterator.single(this.forceGet)
+
+ /** Returns a singleton list containing the $option's value
+ * if it is nonempty, or the empty list if the $option is empty.
+ */
+ def toList: List[A] =
+ if (isEmpty) Nil else this.forceGet :: Nil
+
+ /** Returns a [[scala.util.Left]] containing the given
+ * argument `left` if this $option is empty, or
+ * a [[scala.util.Right]] containing this $option's value if
+ * this is nonempty.
+ *
+ * @param left the expression to evaluate and return if this is empty
+ * @see toLeft
+ */
+ @inline final def toRight[X](left: => X): Either[X, A] =
+ if (isEmpty) Left(left) else Right(this.forceGet)
+
+ /** Returns a [[scala.util.Right]] containing the given
+ * argument `right` if this is empty, or
+ * a [[scala.util.Left]] containing this $option's value
+ * if this $option is nonempty.
+ *
+ * @param right the expression to evaluate and return if this is empty
+ * @see toRight
+ */
+ @inline final def toLeft[X](right: => X): Either[A, X] =
+ if (isEmpty) Right(right) else Left(this.forceGet)
+
+ /** Returns a [[scala.Some]] containing this $options's value
+ * if this $option is nonempty, [[scala.None]] otherwise.
+ */
+ @inline final def toOption: Option[A] =
+ if (isEmpty) None else Some(this.forceGet)
+}
+
+object UndefOrOps {
+
+ /** We need a whole WithFilter class to honor the "doesn't create a new
+ * collection" contract even though it seems unlikely to matter much in a
+ * collection with max size 1.
+ */
+ class WithFilter[A](self: UndefOr[A], p: A => Boolean) {
+ def map[B](f: A => B): UndefOr[B] = self filter p map f
+ def flatMap[B](f: A => UndefOr[B]): UndefOr[B] = self filter p flatMap f
+ def foreach[U](f: A => U): Unit = self filter p foreach f
+ def withFilter(q: A => Boolean): WithFilter[A] =
+ new WithFilter[A](self, x => p(x) && q(x))
+ }
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedArray.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedArray.scala
new file mode 100644
index 0000000..3626c15
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedArray.scala
@@ -0,0 +1,92 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+package scala.scalajs.js
+
+import scala.language.implicitConversions
+
+import scala.collection.mutable
+import mutable.Builder
+
+import scala.collection.generic.{CanBuildFrom, GenericCompanion, SeqFactory}
+
+/** Equivalent of scm.WrappedArray for js.Array */
+@inline
+final class WrappedArray[A](val array: Array[A])
+ extends mutable.AbstractBuffer[A]
+ with scala.collection.generic.GenericTraversableTemplate[A, WrappedArray]
+ with mutable.IndexedSeq[A]
+ with mutable.BufferLike[A, WrappedArray[A]]
+ with mutable.ArrayLike[A, WrappedArray[A]]
+ with Builder[A, WrappedArray[A]] {
+
+ /** Creates a new empty [[WrappedArray]]. */
+ def this() = this(Array())
+
+ override def companion: GenericCompanion[WrappedArray] = WrappedArray
+
+ // IndexedSeq interface
+
+ @inline def update(index: Int, elem: A): Unit = array(index) = elem
+ @inline def apply(index: Int): A = array(index)
+ @inline def length: Int = array.length
+
+ // Builder interface
+
+ @inline def +=(elem: A): this.type = {
+ array.push(elem)
+ this
+ }
+
+ @inline def clear(): Unit =
+ array.length = 0
+
+ @inline def result(): WrappedArray[A] = this
+
+ // Rest of BufferLike interface
+
+ @inline def +=:(elem: A): this.type = {
+ array.unshift(elem)
+ this
+ }
+
+ @inline override def ++=:(xs: TraversableOnce[A]): this.type = {
+ array.unshift(xs.toSeq: _*)
+ this
+ }
+
+ @inline def insertAll(n: Int,
+ elems: scala.collection.Traversable[A]): Unit = {
+ array.splice(n, 0, elems.toSeq: _*)
+ }
+
+ @inline def remove(n: Int): A =
+ array.splice(n, 1)(0)
+
+ @inline override def remove(n: Int, count: Int): Unit =
+ array.splice(n, count)
+
+ @inline override def stringPrefix: String = "WrappedArray"
+
+}
+
+/** $factoryInfo
+ * @define coll wrapped array
+ * @define Coll `WrappedArray`
+ */
+object WrappedArray extends SeqFactory[WrappedArray] {
+ /** $genericCanBuildFromInfo */
+ implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, WrappedArray[A]] =
+ ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
+
+ def newBuilder[A]: Builder[A, WrappedArray[A]] = new WrappedArray[A]
+
+ implicit def toJSArray[A](wrappedArray: WrappedArray[A]): Array[A] =
+ wrappedArray.array
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala
new file mode 100644
index 0000000..f215e6e
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/WrappedDictionary.scala
@@ -0,0 +1,89 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+package scala.scalajs.js
+
+import scala.collection.mutable
+import mutable.Builder
+
+import scala.collection.generic.CanBuildFrom
+
+/** Wrapper to use a js.Dictionary as a scala.mutable.Map */
+@inline
+class WrappedDictionary[A](val dict: Dictionary[A])
+ extends mutable.AbstractMap[String, A]
+ with mutable.Map[String, A]
+ with mutable.MapLike[String, A, WrappedDictionary[A]] {
+
+ def get(key: String): Option[A] = {
+ if (contains(key))
+ Some(dict(key))
+ else
+ None
+ }
+
+ override def contains(key: String): Boolean =
+ dict.hasOwnProperty(key)
+
+ def -=(key: String): this.type = {
+ dict.delete(key)
+ this
+ }
+
+ def +=(kv: (String, A)): this.type = {
+ dict(kv._1) = kv._2
+ this
+ }
+
+ def iterator: Iterator[(String, A)] = new Iterator[(String, A)] {
+ private[this] val keys = Object.keys(dict)
+ private[this] var index: Int = 0
+ def hasNext(): Boolean = index < keys.length
+ def next(): (String, A) = {
+ val key = keys(index)
+ index += 1
+ (key, dict(key))
+ }
+ }
+
+ override def keys: Iterable[String] =
+ Object.keys(dict)
+
+ override def empty: WrappedDictionary[A] =
+ new WrappedDictionary(Dictionary.empty)
+
+}
+
+object WrappedDictionary {
+ // Note: We can't extend MutableMapFactory[WrappedDictionary] since
+ // it requires support for any type of key
+
+ def empty[A]: WrappedDictionary[A] = new WrappedDictionary(Dictionary.empty)
+
+ type CBF[A] = CanBuildFrom[WrappedDictionary[_], (String, A), WrappedDictionary[A]]
+ implicit def canBuildFrom[A]: CBF[A] = new CBF[A] {
+ def apply(from: WrappedDictionary[_]): Builder[(String, A), WrappedDictionary[A]] =
+ new WrappedDictionaryBuilder[A]
+ def apply(): Builder[(String, A), WrappedDictionary[A]] =
+ new WrappedDictionaryBuilder[A]
+ }
+
+ class WrappedDictionaryBuilder[A]
+ extends Builder[(String, A), WrappedDictionary[A]] {
+ private[this] var dict: Dictionary[A] = Dictionary.empty
+ def +=(elem: (String, A)): this.type = {
+ dict(elem._1) = elem._2
+ this
+ }
+ def clear(): Unit =
+ dict = Dictionary.empty
+ def result(): WrappedDictionary[A] =
+ new WrappedDictionary(dict)
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala
new file mode 100644
index 0000000..596e327
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSBracketAccess.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Marks the annotated method as representing bracket access in JavaScript.
+ *
+ * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]]
+ */
+class JSBracketAccess extends scala.annotation.StaticAnnotation
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala
new file mode 100644
index 0000000..0fa9a4e
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExport.scala
@@ -0,0 +1,19 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Specifies that the given entity should be exported for use in raw JS.
+ *
+ * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]]
+ */
+class JSExport extends scala.annotation.StaticAnnotation {
+ def this(name: String) = this()
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala
new file mode 100644
index 0000000..8174595
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportAll.scala
@@ -0,0 +1,21 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Exports all public members directly defined in a class / object.
+ *
+ * Strictly equivalent to putting [[JSExport]] on every public member.
+ * Note: You are allowed to export protected members, but you'll have to do
+ * this explicitly on each member.
+ *
+ * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]]
+ */
+class JSExportAll extends scala.annotation.StaticAnnotation
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala
new file mode 100644
index 0000000..9f2be96
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentClasses.scala
@@ -0,0 +1,20 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Specifies that all the concrete classes extending the annotated class or
+ * should have all their public constructors exported for use in raw JS.
+ * The constructors exported this way are exported under their fully
+ * qualified name.
+ *
+ * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]]
+ */
+class JSExportDescendentClasses extends scala.annotation.StaticAnnotation
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala
new file mode 100644
index 0000000..c196b53
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportDescendentObjects.scala
@@ -0,0 +1,20 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Specifies that all the objects extending the annotated class or trait
+ * should be exported for use in raw JS.
+ * Note that objects exported this way are exported under their fully
+ * qualified name.
+ *
+ * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]]
+ */
+class JSExportDescendentObjects extends scala.annotation.StaticAnnotation
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala
new file mode 100644
index 0000000..718404a
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSExportNamed.scala
@@ -0,0 +1,38 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Exports the given method to JavaScript with named parameters.
+ *
+ * It can then be called like this:
+ * {{{
+ * obj.foo({
+ * param1: value1
+ * param2: value2
+ * param7: value3
+ * });
+ * }}}
+ *
+ * Note that named exports don't support overloading. Therefore the
+ * following will fail:
+ * {{{
+ * class A {
+ * @JSExportNamed
+ * def a(foo: Int) = foo + 1
+ * @JSExportNamed
+ * def a(bar: String) = "Hello " + bar
+ * }
+ * }}}
+ * @see [[http://www.scala-js.org/doc/export-to-javascript.html Export Scala.js APIs to JavaScript]]
+ */
+class JSExportNamed extends scala.annotation.StaticAnnotation {
+ def this(name: String) = this()
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala
new file mode 100644
index 0000000..5401749
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/JSName.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Specifies the JavaScript name of an entity.
+ *
+ * @see [[http://www.scala-js.org/doc/calling-javascript.html Calling JavaScript from Scala.js]]
+ */
+class JSName(name: String) extends scala.annotation.StaticAnnotation
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/README.md b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/README.md
new file mode 100644
index 0000000..9ce7ebf
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/README.md
@@ -0,0 +1,3 @@
+**Attention**: Some files in here are also published in the Scala.js stubs JVM library (see the stubs project in the Scala.js build).
+
+If you add (or rename) a file, make sure the files in the stubs project are up to date.
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala
new file mode 100644
index 0000000..a5bb771
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/annotation/RawJSType.scala
@@ -0,0 +1,23 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
+
+package scala.scalajs.js.annotation
+
+/** Marks the annotated class, trait or object as a raw JavaScript type.
+ *
+ * This annotation is added automatically by the compiler to all classes,
+ * traits and objects inheriting directly or indirectly from
+ * [[scala.scalajs.js.Any]]. It marks the annotated entity as being a raw
+ * JavaScript type, i.e., one that represents type information for an entity
+ * defined in JavaScript code.
+ *
+ * Do not use this annotation yourself.
+ */
+class RawJSType extends scala.annotation.StaticAnnotation
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/package.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/package.scala
new file mode 100644
index 0000000..4a17ba6
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/package.scala
@@ -0,0 +1,161 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+
+package scala.scalajs
+
+/** Contains primitive types for interoperability with JavaScript libraries.
+ * This package is only relevant to the Scala.js compiler, and should not be
+ * referenced by any project compiled to the JVM.
+ *
+ * All the values and methods in this package object are representatives of
+ * standard variables and functions available in the top-level scope, as
+ * standardized in ECMAScript 5.1.
+ *
+ * == Guide ==
+ *
+ * General documentation on Scala.js is available at
+ * [[http://www.scala-js.org/doc/]].
+ *
+ * == Overview ==
+ *
+ * The trait [[js.Any]] is the super type of all JavaScript values.
+ *
+ * All class, trait and object definitions that inherit, directly or
+ * indirectly, from [[js.Any]] do not have actual implementations in Scala.
+ * They are only the manifestation of static types representing libraries
+ * written directly in JavaScript. It is not possible to implement yourself
+ * a subclass of [[js.Any]]: all the method definitions will be ignored when
+ * compiling to JavaScript.
+ *
+ * Implicit conversions to and from standard Scala types to their equivalent
+ * in JavaScript are provided. For example, from Scala arrays to JavaScript
+ * arrays and back.
+ *
+ * The most important subclasses of [[js.Any]] are:
+ * - [[js.Dynamic]], a dynamically typed interface to JavaScript APIs
+ * - [[js.Object]], the superclass of all statically typed JavaScript classes,
+ * which has subclasses for all the classes standardized in ECMAScript 5.1,
+ * among which:
+ * - [[js.Array]]
+ * - [[js.Function]] (and subtraits with specific number of parameters)
+ * - [[js.ThisFunction]] and its subtraits for functions that take the
+ * JavaScript `this` as an explicit parameters
+ * - [[js.Dictionary]] to access the properties of an object in a
+ * dictionary-like way
+ * - [[js.Date]]
+ * - [[js.RegExp]]
+ *
+ * The trait [[js.Dynamic]] is a special subtrait of [[js.Any]]. It can
+ * represent any JavaScript value in a dynamically-typed way. It is possible
+ * to call any method and read and write any field of a value of type
+ * [[js.Dynamic]].
+ *
+ * The package [[scala.scalajs.js.prim]] gives definitions for the four
+ * primitive types of JavaScript as subtraits of [[js.Any]], but generally
+ * it is preferable to use the corresponding Scala type.
+ * - [[js.prim.Number]] corresponds to [[scala.Double]]
+ * - [[js.prim.Boolean]] corresponds to [[scala.Boolean]]
+ * - [[js.prim.String]] corresponds to [[java.lang.String]]
+ * - [[js.prim.Undefined]] corresponds to [[scala.Unit]]
+ *
+ * [[js.UndefOr]] gives a [[scala.Option]]-like interface where the JavaScript
+ * value `undefined` takes the role of `None`.
+ */
+package object js extends js.GlobalScope {
+ /** The type of JavaScript numbers, which is [[scala.Double]]. */
+ type Number = scala.Double
+ /** The type of JavaScript booleans, which is [[scala.Boolean]]. */
+ type Boolean = scala.Boolean
+ /** The type of JavaScript strings, which is [[java.lang.String]]. */
+ type String = java.lang.String
+ /** The type of the JavaScript undefined value, which is [[scala.Unit]]. */
+ type Undefined = scala.Unit
+
+ /** The top-level `Number` JavaScript object. */
+ val Number: js.prim.Number.type = native
+ /** The top-level `Boolean` JavaScript object. */
+ val Boolean: js.prim.Boolean.type = native
+ /** The top-level `String` JavaScript object. */
+ val String: js.prim.String.type = native
+
+ /** The constant Not-a-Number. */
+ val NaN: Double = native
+ /** The constant Positive Infinity. */
+ val Infinity: Double = native
+
+ /** The undefined value. */
+ def undefined: js.prim.Undefined = sys.error("stub")
+
+ /** Tests whether the given value is undefined. */
+ def isUndefined(v: scala.Any): Boolean = sys.error("stub")
+
+ /** Returns the type of `x` as identified by `typeof x` in JavaScript. */
+ def typeOf(x: Any): String = sys.error("stub")
+
+ /** Invokes any available debugging functionality.
+ * If no debugging functionality is available, this statement has no effect.
+ *
+ * MDN
+ *
+ * Browser support:
+ * - Has no effect in Rhino nor, apparently, in Firefox
+ * - In Chrome, it has no effect unless the developer tools are opened
+ * beforehand.
+ */
+ def debugger(): Unit = sys.error("stub")
+
+ /** Evaluates JavaScript code and returns the result. */
+ def eval(x: String): Any = native
+
+ /** Parses a string as an integer with a given radix. */
+ def parseInt(s: String, radix: Int): js.Number = native
+ /** Parses a string as an integer with auto-detected radix. */
+ def parseInt(s: String): js.Number = native
+ /** Parses a string as a floating point number. */
+ def parseFloat(string: String): Double = native
+
+ /** Tests whether the given value is Not-a-Number. */
+ def isNaN(number: Double): Boolean = native
+ /** Tests whether the given value is a finite number. */
+ def isFinite(number: Double): Boolean = native
+
+ /** Decodes a Uniform Resource Identifier (URI).
+ * @see [[encodeURI]]
+ */
+ def decodeURI(encodedURI: String): String = native
+
+ /** Decodes a Uniform Resource Identifier (URI) component.
+ * @see [[encodeURIComponent]]
+ */
+ def decodeURIComponent(encodedURIComponent: String): String = native
+
+ /** Encodes a Uniform Resource Identifier (URI).
+ * @see [[decodeURI]]
+ */
+ def encodeURI(uri: String): String = native
+
+ /** Encodes a Uniform Resource Identifier (URI) component.
+ * @see [[decodeURIComponent]]
+ */
+ def encodeURIComponent(uriComponent: String): String = native
+
+ /** Denotes a method body as native JavaScript. For use in facade types:
+ *
+ * {{{
+ * class MyJSClass extends js.Object {
+ * def myMethod(x: String): Int = js.native
+ * }
+ * }}}
+ */
+ def native: Nothing = sys.error("A method defined in a JavaScript raw " +
+ "type of a Scala.js library has been called. This is most likely " +
+ "because you tried to run Scala.js binaries on the JVM. Make sure you " +
+ "are using the JVM version of the libraries.")
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala
new file mode 100644
index 0000000..b8b8160
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBuffer.scala
@@ -0,0 +1,17 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class ArrayBuffer(length: Int) extends js.Object {
+
+ /** Length of this buffer in bytes */
+ val byteLength: Int = js.native
+
+ /** Returns a copy of the given slice of this array buffer */
+ def slice(begin: Int, end: Int = ???): ArrayBuffer = js.native
+
+ // Note: Some specifications specify a static isView method on ArrayBuffer
+ // that checks whether a given object is an ArrayBufferView. We omit it here
+ // since neither Node.js nor PhantomJS support it at the time of writing.
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala
new file mode 100644
index 0000000..f3d2afb
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferInputStream.scala
@@ -0,0 +1,88 @@
+package scala.scalajs.js.typedarray
+
+import java.io.InputStream
+
+/** A java.io.InputStream wrapping a JavaScript ArrayBuffer
+ *
+ * This class is extremely similar to a ByteArrayInputStream, but
+ * uses ArrayBuffers as the underlying representation. Stream
+ * implementations may special case on this stream for better
+ * performance and access the underlying buffer directly. (They still
+ * need to make sure the internal pointers are properly aligned
+ * though).
+ *
+ * This stream has several public members (n.b. [[buffer]], [[offset]],
+ * [[length]] and [[pos]]) in order to allow JavaScript aware applications to
+ * special case on this kind of stream and access the underlying
+ * [[ArrayBuffer]] directly for efficiency. In this case it is the client's
+ * responsibility to synchronize [[pos]], as if the stream were read normally
+ * (if the context in which it is used requires this).
+ *
+ * @param buffer Underlying ArrayBuffer
+ * @param offset Offset in bytes in [[buffer]]
+ * @param length Length in bytes in [[buffer]]
+ */
+class ArrayBufferInputStream(val buffer: ArrayBuffer, val offset: Int,
+ val length: Int) extends InputStream {
+
+ /** Convenience constructor. Strictly equivalent to
+ * {{new ArrayBufferInputStream(buffer, 0, buffer.byteLength)}
+ */
+ def this(buffer: ArrayBuffer) = this(buffer, 0, buffer.byteLength)
+
+ private val uintView = new Uint8Array(buffer, offset, length)
+ private val byteView = new Int8Array(buffer, offset, length)
+
+ /** Used to persist [[pos]] when mark is called */
+ protected var mark: Int = 0
+
+ /** Next byte to read in the buffer (after adding offset).
+ *
+ * Use [[skip]] to update (protects from overrun and moving backwards).
+ */
+ @inline def pos: Int = _pos
+ @inline protected def pos_=(x: Int): Unit = _pos = x
+ private[this] var _pos: Int = 0
+
+ override def available(): Int = length - pos
+ override def mark(readlimit: Int): Unit = { mark = pos }
+ override def markSupported(): Boolean = true
+ def read(): Int = {
+ if (pos < length) {
+ val res = uintView(pos)
+ pos += 1
+ res
+ } else -1
+ }
+
+ override def read(b: Array[Byte], off: Int, reqLen: Int): Int = {
+ if (off < 0 || reqLen < 0 || reqLen > b.length - off)
+ throw new IndexOutOfBoundsException
+
+ val len = Math.min(reqLen, length - pos)
+
+ if (reqLen == 0)
+ 0 // 0 requested, 0 returned
+ else if (len == 0)
+ -1 // nothing to read at all
+ else {
+ var i = 0
+ while (i < len) {
+ b(i + off) = byteView(pos + i)
+ i += 1
+ }
+ pos += len
+ len
+ }
+ }
+
+ override def reset(): Unit = { pos = mark }
+
+ /** Skips a given number of bytes. Always skips the maximum number possible */
+ override def skip(n: Long): Long = {
+ val k = Math.max(0, Math.min(n, length - pos)).toInt
+ pos += k
+ k.toLong
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala
new file mode 100644
index 0000000..6b25bf5
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/ArrayBufferView.scala
@@ -0,0 +1,14 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+trait ArrayBufferView extends js.Object {
+ /** The underlying buffer of this ArrayBufferView */
+ val buffer: ArrayBuffer = js.native
+
+ /** The number of bytes of this ArrayBufferView */
+ val byteLength: Int = js.native
+
+ /** The offset of this ArrayBufferView in the underlying buffer */
+ val byteOffset: Int = js.native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala
new file mode 100644
index 0000000..d97544c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/DataView.scala
@@ -0,0 +1,26 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class DataView(buffer: ArrayBuffer, byteOffset: Int = 0,
+ byteLength: Int = ???) extends ArrayBufferView {
+
+ def getInt8(byteOffset: Int): Byte = js.native
+ def getUint8(byteOffset: Int): Short = js.native
+ def getInt16(byteOffset: Int, littleEndian: Boolean = false): Short = js.native
+ def getUint16(byteOffset: Int, littleEndian: Boolean = false): Int = js.native
+ def getInt32(byteOffset: Int, littleEndian: Boolean = false): Int = js.native
+ def getUint32(byteOffset: Int, littleEndian: Boolean = false): Double = js.native
+ def getFloat32(byteOffset: Int, littleEndian: Boolean = false): Float = js.native
+ def getFloat64(byteOffset: Int, littleEndian: Boolean = false): Double = js.native
+
+ def setInt8(byteOffset: Int, value: Byte): Unit = js.native
+ def setUint8(byteOffset: Int, value: Short): Unit = js.native
+ def setInt16(byteOffset: Int, value: Short, littleEndian: Boolean = false): Unit = js.native
+ def setUint16(byteOffset: Int, value: Int, littleEndian: Boolean = false): Unit = js.native
+ def setInt32(byteOffset: Int, value: Int, littleEndian: Boolean = false): Unit = js.native
+ def setUint32(byteOffset: Int, value: Double, littleEndian: Boolean = false): Unit = js.native
+ def setFloat32(byteOffset: Int, value: Float, littleEndian: Boolean = false): Unit = js.native
+ def setFloat64(byteOffset: Int, value: Double, littleEndian: Boolean = false): Unit = js.native
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala
new file mode 100644
index 0000000..abb0dd9
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float32Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Float32Array private extends TypedArray[Float, Float32Array] {
+
+ /** Constructs a Float32Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Float32Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Float32Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Float32Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Float32Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala
new file mode 100644
index 0000000..526b376
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Float64Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Float64Array private extends TypedArray[Double, Float64Array] {
+
+ /** Constructs a Float64Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Float64Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Float64Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Float64Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Float64Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala
new file mode 100644
index 0000000..c71f101
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int16Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Int16Array private extends TypedArray[Short, Int16Array] {
+
+ /** Constructs a Int16Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Int16Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Int16Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Int16Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Int16Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala
new file mode 100644
index 0000000..37208e9
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int32Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Int32Array private extends TypedArray[Int, Int32Array] {
+
+ /** Constructs a Int32Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Int32Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Int32Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Int32Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Int32Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala
new file mode 100644
index 0000000..690ff07
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Int8Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Int8Array private extends TypedArray[Byte, Int8Array] {
+
+ /** Constructs a Int8Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Int8Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Int8Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Int8Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Int8Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala
new file mode 100644
index 0000000..4e33b5d
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/TypedArray.scala
@@ -0,0 +1,46 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+import scala.scalajs.js.annotation.JSBracketAccess
+
+trait TypedArray[T, Repr] extends ArrayBufferView {
+
+ /** The number of elements in this TypedArray */
+ val length: Int = js.native
+
+ /** Retrieve element at index */
+ @JSBracketAccess
+ def apply(index: Int): T = js.native
+
+ /** Set element at index */
+ @JSBracketAccess
+ def update(index: Int, value: T): Unit = js.native
+
+ /** Retrieve element at index */
+ @JSBracketAccess
+ def get(index: Int): T = js.native
+
+ /** Set element at index */
+ @JSBracketAccess
+ def set(index: Int, value: T): Unit = js.native
+
+ /** Set the values of typedArray in this TypedArray */
+ def set(typedArray: TypedArray[_, _]): Unit = js.native
+
+ /** Set the values of typedArray in this TypedArray at given offset */
+ def set(typedArray: TypedArray[_, _], offset: Int): Unit = js.native
+
+ /** Set the values from array in this TypedArray */
+ def set(array: js.Array[_]): Unit = js.native
+
+ /** Set the values from array in this TypedArray at given offset */
+ def set(array: js.Array[_], offset: Int): Unit = js.native
+
+ /** Create a new TypedArray view of this TypedArray at given location */
+ def subarray(begin: Int, end: Int = ???): Repr = js.native
+
+}
+
+trait TypedArrayStatic extends js.Object {
+ val BYTES_PER_ELEMENT: Int = js.native
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala
new file mode 100644
index 0000000..82d2847
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint16Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Uint16Array private extends TypedArray[Int, Uint16Array] {
+
+ /** Constructs a Uint16Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Uint16Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Uint16Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Uint16Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Uint16Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala
new file mode 100644
index 0000000..9742e19
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint32Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Uint32Array private extends TypedArray[Double, Uint32Array] {
+
+ /** Constructs a Uint32Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Uint32Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Uint32Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Uint32Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Uint32Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala
new file mode 100644
index 0000000..f54904c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8Array.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Uint8Array private extends TypedArray[Short, Uint8Array] {
+
+ /** Constructs a Uint8Array with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Uint8Array with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Uint8Array with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Uint8Array view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Uint8Array extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala
new file mode 100644
index 0000000..601d65c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/Uint8ClampedArray.scala
@@ -0,0 +1,24 @@
+package scala.scalajs.js.typedarray
+
+import scala.scalajs.js
+
+class Uint8ClampedArray private extends TypedArray[Int, Uint8ClampedArray] {
+
+ /** Constructs a Uint8ClampedArray with the given length. Initialized to all 0 */
+ def this(length: Int) = this()
+
+ /** Creates a new Uint8ClampedArray with the same elements than the given TypedArray
+ *
+ * The elements are converted before being stored in the new Int8Array.
+ */
+ def this(typedArray: TypedArray[_, _]) = this()
+
+ /** Creates a new Uint8ClampedArray with the elements in the given array */
+ def this(array: js.Array[_]) = this()
+
+ /** Creates a Uint8ClampedArray view on the given ArrayBuffer */
+ def this(buffer: ArrayBuffer, byteOffset: Int = 0, length: Int = ???) = this()
+
+}
+
+object Uint8ClampedArray extends TypedArrayStatic
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/package.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/package.scala
new file mode 100644
index 0000000..0ab5a05
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/js/typedarray/package.scala
@@ -0,0 +1,145 @@
+package scala.scalajs.js
+
+import JSConverters._
+
+/** The typdearray package provides facade types for JavaScript
+ * ArrayBuffer, TypeArrays and DataView. Further, it provides
+ * conversions between primitive Scala arrays and TypedArrays
+ */
+package object typedarray {
+
+ // Implicit classes scala.Array -> TypedArray
+ implicit class AB2TA(val array: scala.Array[Byte]) extends AnyVal {
+ def toTypedArray: Int8Array = byteArray2Int8Array(array)
+ }
+
+ implicit class AS2TA(val array: scala.Array[Short]) extends AnyVal {
+ def toTypedArray: Int16Array = shortArray2Int16Array(array)
+ }
+
+ implicit class AC2TA(val array: scala.Array[Char]) extends AnyVal {
+ def toTypedArray: Uint16Array = charArray2Uint16Array(array)
+ }
+
+ implicit class AI2TA(val array: scala.Array[Int]) extends AnyVal {
+ def toTypedArray: Int32Array = intArray2Int32Array(array)
+ }
+
+ implicit class AF2TA(val array: scala.Array[Float]) extends AnyVal {
+ def toTypedArray: Float32Array = floatArray2Float32Array(array)
+ }
+
+ implicit class AD2TA(val array: scala.Array[Double]) extends AnyVal {
+ def toTypedArray: Float64Array = doubleArray2Float64Array(array)
+ }
+
+ // Implicit classes TypedArray -> scala.Array
+ implicit class TA2AB(val array: Int8Array) extends AnyVal {
+ def toArray: scala.Array[Byte] = int8Array2ByteArray(array)
+ }
+
+ implicit class TA2AS(val array: Int16Array) extends AnyVal {
+ def toArray: scala.Array[Short] = int16Array2ShortArray(array)
+ }
+
+ implicit class TA2AC(val array: Uint16Array) extends AnyVal {
+ def toArray: scala.Array[Char] = uint16Array2CharArray(array)
+ }
+
+ implicit class TA2AI(val array: Int32Array) extends AnyVal {
+ def toArray: scala.Array[Int] = int32Array2IntArray(array)
+ }
+
+ implicit class TA2AF(val array: Float32Array) extends AnyVal {
+ def toArray: scala.Array[Float] = float32Array2FloatArray(array)
+ }
+
+ implicit class TA2AD(val array: Float64Array) extends AnyVal {
+ def toArray: scala.Array[Double] = float64Array2DoubleArray(array)
+ }
+
+ // scala.Array -> TypedArray
+
+ def byteArray2Int8Array(array: scala.Array[Byte]): Int8Array =
+ array2typedArrayImpl(array, new Int8Array(array.length))
+
+ def shortArray2Int16Array(array: scala.Array[Short]): Int16Array =
+ array2typedArrayImpl(array, new Int16Array(array.length))
+
+ def charArray2Uint16Array(array: scala.Array[Char]): Uint16Array = {
+ // Can't use array2typedArrayImpl because Uint16Array contains Ints
+ val len = array.length
+ val dest = new Uint16Array(len)
+ var i = 0
+ while (i < len) {
+ dest(i) = array(i).toInt
+ i += 1
+ }
+ dest
+ }
+
+ def intArray2Int32Array(array: scala.Array[Int]): Int32Array =
+ array2typedArrayImpl(array, new Int32Array(array.length))
+
+ def floatArray2Float32Array(array: scala.Array[Float]): Float32Array =
+ array2typedArrayImpl(array, new Float32Array(array.length))
+
+ def doubleArray2Float64Array(array: scala.Array[Double]): Float64Array =
+ array2typedArrayImpl(array, new Float64Array(array.length))
+
+ @inline private def array2typedArrayImpl[
+ @specialized(Byte, Short, Int, Float, Double) T,
+ Repr <: TypedArray[T, Repr]](
+ array: scala.Array[T], dest: Repr): Repr = {
+ val len = array.length
+ var i = 0
+ while (i < len) {
+ dest(i) = array(i)
+ i += 1
+ }
+ dest
+ }
+
+ // TypedArray -> scala.Array
+
+ def int8Array2ByteArray(array: Int8Array): scala.Array[Byte] =
+ typedArray2arrayImpl(array, new scala.Array(array.length))
+
+ def int16Array2ShortArray(array: Int16Array): scala.Array[Short] =
+ typedArray2arrayImpl(array, new scala.Array(array.length))
+
+ def uint16Array2CharArray(array: Uint16Array): scala.Array[Char] = {
+ // Can't use typedArray2arrayImpl because Uint16Array contains Ints
+ val len = array.length
+ val dest = new scala.Array[Char](len)
+ var i = 0
+ while (i < len) {
+ dest(i) = array(i).toChar
+ i += 1
+ }
+ dest
+ }
+
+ def int32Array2IntArray(array: Int32Array): scala.Array[Int] =
+ typedArray2arrayImpl(array, new scala.Array(array.length))
+
+ def float32Array2FloatArray(array: Float32Array): scala.Array[Float] =
+ typedArray2arrayImpl(array, new scala.Array(array.length))
+
+ def float64Array2DoubleArray(array: Float64Array): scala.Array[Double] =
+ typedArray2arrayImpl(array, new scala.Array(array.length))
+
+ @inline private def typedArray2arrayImpl[
+ @specialized(Byte, Short, Int, Float, Double) T,
+ Repr <: TypedArray[T, Repr]](
+ array: Repr, dest: scala.Array[T]): scala.Array[T] = {
+ val len = dest.length
+ var i = 0
+ while (i < len) {
+ dest(i) = array(i)
+ i += 1
+ }
+ dest
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala
new file mode 100644
index 0000000..7765f0c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1.scala
@@ -0,0 +1,19 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import java.nio.charset._
+
+private[niocharset] object ISO_8859_1 extends ISO_8859_1_And_US_ASCII_Common(
+ "ISO-8859-1", Array(
+ "csISOLatin1", "IBM-819", "iso-ir-100", "8859_1", "ISO_8859-1", "l1",
+ "ISO8859-1", "ISO_8859_1", "cp819", "ISO8859_1", "latin1",
+ "ISO_8859-1:1987", "819", "IBM819"),
+ maxValue = 0xff)
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala
new file mode 100644
index 0000000..ddc83db
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/ISO_8859_1_And_US_ASCII_Common.scala
@@ -0,0 +1,197 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import scala.annotation.tailrec
+
+import java.nio._
+import java.nio.charset._
+
+/** This is a very specific common implementation for ISO_8859_1 and US_ASCII.
+ * Only a single constant changes between the two algorithms (`maxValue`).
+ * No attempt was made at generalizing this to other potential charsets.
+ *
+ * `maxValue` is therefore either 0xff (ISO_8859_1) or 0x7f (US_ASCII).
+ */
+private[niocharset] abstract class ISO_8859_1_And_US_ASCII_Common protected (
+ name: String, aliases: Array[String],
+ private val maxValue: Int) extends Charset(name, aliases) {
+
+ def contains(that: Charset): Boolean = that match {
+ case that: ISO_8859_1_And_US_ASCII_Common => this.maxValue >= that.maxValue
+ case _ => false
+ }
+
+ def newDecoder(): CharsetDecoder = new Decoder
+ def newEncoder(): CharsetEncoder = new Encoder
+
+ private class Decoder extends CharsetDecoder(
+ ISO_8859_1_And_US_ASCII_Common.this, 1.0f, 1.0f) {
+ def decodeLoop(in: ByteBuffer, out: CharBuffer): CoderResult = {
+ val maxValue = ISO_8859_1_And_US_ASCII_Common.this.maxValue
+ val inRemaining = in.remaining
+ if (inRemaining == 0) {
+ CoderResult.UNDERFLOW
+ } else {
+ val outRemaining = out.remaining
+ val overflow = outRemaining < inRemaining
+ val rem = if (overflow) outRemaining else inRemaining
+
+ if (in.hasArray && out.hasArray) {
+ val inArr = in.array
+ val inOffset = in.arrayOffset
+ val inStart = in.position + inOffset
+ val inEnd = inStart + rem
+
+ val outArr = out.array
+ val outOffset = out.arrayOffset
+ val outStart = out.position + outOffset
+
+ var inPos = inStart
+ var outPos = outStart
+ while (inPos != inEnd) {
+ // Apparently ignoring the bit 7 in US_ASCII is the expected behavior
+ outArr(outPos) = (inArr(inPos).toInt & maxValue).toChar
+ inPos += 1
+ outPos += 1
+ }
+
+ in.position(inPos - inOffset)
+ out.position(outPos - outOffset)
+ } else {
+ /* Here, it's fine to read all the remaining bytes from the input,
+ * because we will *always* use all of them.
+ */
+ var i = 0
+ while (i != rem) {
+ // Apparently ignoring the bit 7 in US_ASCII is the expected behavior
+ out.put((in.get(i).toInt & maxValue).toChar)
+ i += 1
+ }
+ }
+
+ if (overflow) CoderResult.OVERFLOW
+ else CoderResult.UNDERFLOW
+ }
+ }
+ }
+
+ private class Encoder extends CharsetEncoder(
+ ISO_8859_1_And_US_ASCII_Common.this, 1.0f, 1.0f) {
+ def encodeLoop(in: CharBuffer, out: ByteBuffer): CoderResult = {
+ import java.lang.Character.{MIN_SURROGATE, MAX_SURROGATE}
+
+ val maxValue = ISO_8859_1_And_US_ASCII_Common.this.maxValue
+ val inRemaining = in.remaining
+ if (inRemaining == 0) {
+ CoderResult.UNDERFLOW
+ } else {
+ if (in.hasArray && out.hasArray) {
+ val outRemaining = out.remaining
+ val overflow = outRemaining < inRemaining
+ val rem = if (overflow) outRemaining else inRemaining
+
+ val inArr = in.array
+ val inOffset = in.arrayOffset
+ val inStart = in.position + inOffset
+ val inEnd = inStart + rem
+
+ val outArr = out.array
+ val outOffset = out.arrayOffset
+ val outStart = out.position + outOffset
+
+ @inline
+ @tailrec
+ def loop(inPos: Int, outPos: Int): CoderResult = {
+ @inline
+ def finalize(result: CoderResult): CoderResult = {
+ in.position(inPos - inOffset)
+ out.position(outPos - outOffset)
+ result
+ }
+
+ if (inPos == inEnd) {
+ finalize {
+ if (overflow) CoderResult.OVERFLOW
+ else CoderResult.UNDERFLOW
+ }
+ } else {
+ val c = inArr(inPos)
+ if (c <= maxValue) {
+ outArr(outPos) = c.toByte
+ loop(inPos+1, outPos+1)
+ } else {
+ finalize {
+ if (Character.isLowSurrogate(c)) {
+ CoderResult.malformedForLength(1)
+ } else if (Character.isHighSurrogate(c)) {
+ if (inPos + 1 < in.limit) {
+ val c2 = inArr(inPos+1)
+ if (Character.isLowSurrogate(c2))
+ CoderResult.unmappableForLength(2)
+ else
+ CoderResult.malformedForLength(1)
+ } else {
+ CoderResult.UNDERFLOW
+ }
+ } else {
+ CoderResult.unmappableForLength(1)
+ }
+ }
+ }
+ }
+ }
+
+ loop(inStart, outStart)
+ } else {
+ // Not both have arrays
+ @inline
+ @tailrec
+ def loop(): CoderResult = {
+ if (!in.hasRemaining) {
+ CoderResult.UNDERFLOW
+ } else if (!out.hasRemaining) {
+ CoderResult.OVERFLOW
+ } else {
+ val c = in.get()
+ if (c <= maxValue) {
+ out.put(c.toByte)
+ loop()
+ } else {
+ if (Character.isLowSurrogate(c)) {
+ in.position(in.position - 1)
+ CoderResult.malformedForLength(1)
+ } else if (Character.isHighSurrogate(c)) {
+ if (in.hasRemaining) {
+ val c2 = in.get()
+ in.position(in.position - 2)
+ if (Character.isLowSurrogate(c2)) {
+ CoderResult.unmappableForLength(2)
+ } else {
+ CoderResult.malformedForLength(1)
+ }
+ } else {
+ in.position(in.position - 1)
+ CoderResult.UNDERFLOW
+ }
+ } else {
+ in.position(in.position - 1)
+ CoderResult.unmappableForLength(1)
+ }
+ }
+ }
+ }
+
+ loop()
+ }
+ }
+ }
+ }
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala
new file mode 100644
index 0000000..38615f6
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/StandardCharsets.scala
@@ -0,0 +1,42 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import java.nio.charset._
+
+/** Standard charsets.
+ * This is basically the same as [[java.nio.charset.StandardCharsets]], but
+ * it is also available when compiling with a JDK 6.
+ */
+object StandardCharsets {
+ import scala.scalajs.niocharset
+
+ /** ISO-8859-1, aka latin1. */
+ def ISO_8859_1: Charset = niocharset.ISO_8859_1
+
+ /** US-ASCII. */
+ def US_ASCII: Charset = niocharset.US_ASCII
+
+ /** UTF-8. */
+ def UTF_8: Charset = niocharset.UTF_8
+
+ /** UTF-16 Big Endian without BOM. */
+ def UTF_16BE: Charset = niocharset.UTF_16BE
+
+ /** UTF-16 Little Endian without BOM. */
+ def UTF_16LE: Charset = niocharset.UTF_16LE
+
+ /** UTF-16 with an optional BOM.
+ * When encoding, Big Endian is always used.
+ * When decoding, the BOM specifies what endianness to use. If no BOM is
+ * found, it defaults to Big Endian.
+ */
+ def UTF_16: Charset = niocharset.UTF_16
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala
new file mode 100644
index 0000000..746c75b
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/US_ASCII.scala
@@ -0,0 +1,19 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import java.nio.charset._
+
+private[niocharset] object US_ASCII extends ISO_8859_1_And_US_ASCII_Common(
+ "US-ASCII", Array(
+ "cp367", "ascii7", "ISO646-US", "646", "csASCII", "us", "iso_646.irv:1983",
+ "ISO_646.irv:1991", "IBM367", "ASCII", "default", "ANSI_X3.4-1986",
+ "ANSI_X3.4-1968", "iso-ir-6"),
+ maxValue = 0x7f)
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala
new file mode 100644
index 0000000..9d1748a
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import java.nio.charset._
+
+private[niocharset] object UTF_16 extends UTF_16_Common(
+ "UTF-16", Array(
+ "utf16", "UTF_16", "UnicodeBig", "unicode"),
+ endianness = UTF_16_Common.AutoEndian)
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala
new file mode 100644
index 0000000..dece191
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16BE.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import java.nio.charset._
+
+private[niocharset] object UTF_16BE extends UTF_16_Common(
+ "UTF-16BE", Array(
+ "X-UTF-16BE", "UTF_16BE", "ISO-10646-UCS-2", "UnicodeBigUnmarked"),
+ endianness = UTF_16_Common.BigEndian)
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala
new file mode 100644
index 0000000..de469c4
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16LE.scala
@@ -0,0 +1,17 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import java.nio.charset._
+
+private[niocharset] object UTF_16LE extends UTF_16_Common(
+ "UTF-16LE", Array(
+ "UnicodeLittleUnmarked", "UTF_16LE", "X-UTF-16LE"),
+ endianness = UTF_16_Common.LittleEndian)
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala
new file mode 100644
index 0000000..3330d9c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_16_Common.scala
@@ -0,0 +1,205 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import scala.annotation.tailrec
+
+import java.nio._
+import java.nio.charset._
+
+/** This is a very specific common implementation for UTF_16BE and UTF_16LE.
+ */
+private[niocharset] abstract class UTF_16_Common protected (
+ name: String, aliases: Array[String],
+ private val endianness: Int) extends Charset(name, aliases) {
+
+ import UTF_16_Common._
+
+ def contains(that: Charset): Boolean = true
+
+ def newDecoder(): CharsetDecoder = new Decoder
+ def newEncoder(): CharsetEncoder = new Encoder
+
+ private class Decoder extends CharsetDecoder(
+ UTF_16_Common.this, 0.5f, 1.0f) {
+ private var endianness = UTF_16_Common.this.endianness
+
+ override protected def implReset(): Unit = {
+ super.implReset()
+ endianness = UTF_16_Common.this.endianness
+ }
+
+ def decodeLoop(in: ByteBuffer, out: CharBuffer): CoderResult = {
+ @inline
+ @tailrec
+ def loop(): CoderResult = {
+ if (in.remaining < 2) CoderResult.UNDERFLOW
+ else {
+ val b1 = in.get() & 0xff
+ val b2 = in.get() & 0xff
+
+ val wasBOM = if (endianness == AutoEndian) {
+ // Read BOM
+ if (b1 == 0xfe && b2 == 0xff) {
+ endianness = BigEndian
+ true
+ } else if (b1 == 0xff && b2 == 0xfe) {
+ endianness = LittleEndian
+ true
+ } else {
+ // Not a valid BOM: default to BigEndian and start reading
+ endianness = BigEndian
+ false
+ }
+ } else false
+
+ if (wasBOM) {
+ loop()
+ } else {
+ val bigEndian = endianness == BigEndian
+
+ @inline def bytes2char(hi: Int, lo: Int): Char =
+ (if (bigEndian) (hi << 8) | lo else (lo << 8) | hi).toChar
+
+ val c1 = bytes2char(b1, b2)
+
+ if (Character.isLowSurrogate(c1)) {
+ in.position(in.position - 2)
+ CoderResult.malformedForLength(2)
+ } else if (!Character.isHighSurrogate(c1)) {
+ if (out.remaining == 0) {
+ in.position(in.position - 2)
+ CoderResult.OVERFLOW
+ } else {
+ out.put(c1)
+ loop()
+ }
+ } else {
+ if (in.remaining < 2) {
+ in.position(in.position - 2)
+ CoderResult.UNDERFLOW
+ } else {
+ val b3 = in.get() & 0xff
+ val b4 = in.get() & 0xff
+ val c2 = bytes2char(b3, b4)
+
+ if (!Character.isLowSurrogate(c2)) {
+ in.position(in.position - 4)
+ CoderResult.malformedForLength(2)
+ } else {
+ if (out.remaining < 2) {
+ in.position(in.position - 4)
+ CoderResult.OVERFLOW
+ } else {
+ out.put(c1)
+ out.put(c2)
+ loop()
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ loop()
+ }
+ }
+
+ private class Encoder extends CharsetEncoder(
+ UTF_16_Common.this, 2.0f, 2.0f,
+ // Character 0xfffd
+ if (endianness == LittleEndian) Array(-3, -1) else Array(-1, -3)) {
+
+ private var needToWriteBOM: Boolean = endianness == AutoEndian
+
+ override protected def implReset(): Unit = {
+ super.implReset()
+ needToWriteBOM = endianness == AutoEndian
+ }
+
+ def encodeLoop(in: CharBuffer, out: ByteBuffer): CoderResult = {
+ if (needToWriteBOM) {
+ if (out.remaining < 2) {
+ return CoderResult.OVERFLOW
+ } else {
+ // Always encode in big endian
+ out.put(0xfe.toByte)
+ out.put(0xff.toByte)
+ needToWriteBOM = false
+ }
+ }
+
+ val bigEndian = endianness != LittleEndian
+
+ @inline
+ def putChar(c: Char): Unit = {
+ if (bigEndian) {
+ out.put((c >> 8).toByte)
+ out.put(c.toByte)
+ } else {
+ out.put(c.toByte)
+ out.put((c >> 8).toByte)
+ }
+ }
+
+ @inline
+ @tailrec
+ def loop(): CoderResult = {
+ if (in.remaining == 0) CoderResult.UNDERFLOW
+ else {
+ val c1 = in.get()
+
+ if (Character.isLowSurrogate(c1)) {
+ in.position(in.position - 1)
+ CoderResult.malformedForLength(1)
+ } else if (!Character.isHighSurrogate(c1)) {
+ if (out.remaining < 2) {
+ in.position(in.position - 1)
+ CoderResult.OVERFLOW
+ } else {
+ putChar(c1)
+ loop()
+ }
+ } else {
+ if (in.remaining < 1) {
+ in.position(in.position - 1)
+ CoderResult.UNDERFLOW
+ } else {
+ val c2 = in.get()
+
+ if (!Character.isLowSurrogate(c2)) {
+ in.position(in.position - 2)
+ CoderResult.malformedForLength(1)
+ } else {
+ if (out.remaining < 4) {
+ in.position(in.position - 2)
+ CoderResult.OVERFLOW
+ } else {
+ putChar(c1)
+ putChar(c2)
+ loop()
+ }
+ }
+ }
+ }
+ }
+ }
+
+ loop()
+ }
+ }
+}
+
+private[niocharset] object UTF_16_Common {
+ final val AutoEndian = 0
+ final val BigEndian = 1
+ final val LittleEndian = 2
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala
new file mode 100644
index 0000000..57f4ad6
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/niocharset/UTF_8.scala
@@ -0,0 +1,455 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.niocharset
+
+import scala.annotation.{switch, tailrec}
+
+import java.nio._
+import java.nio.charset._
+
+private[niocharset] object UTF_8 extends Charset("UTF-8", Array(
+ "UTF8", "unicode-1-1-utf-8")) {
+
+ import java.lang.Character._
+
+ def contains(that: Charset): Boolean = true
+
+ def newDecoder(): CharsetDecoder = new Decoder
+ def newEncoder(): CharsetEncoder = new Encoder
+
+ /* The next table contains information about UTF-8 charset and
+ * correspondence of 1st byte to the length of sequence
+ * For information please visit http://www.ietf.org/rfc/rfc3629.txt
+ *
+ * -------------------------------------------------------------------
+ * 0 1 2 3 Value
+ * -------------------------------------------------------------------
+ * 0xxxxxxx 00000000 00000000 0xxxxxxx
+ * 110yyyyy 10xxxxxx 00000000 00000yyy yyxxxxxx
+ * 1110zzzz 10yyyyyy 10xxxxxx 00000000 zzzzyyyy yyxxxxxx
+ * 11110uuu 10zzzzzz 10yyyyyy 10xxxxxx 000uuuzz zzzzyyyy yyxxxxxx
+ */
+
+ private val lengthByLeading: Array[Int] = Array(
+ // 10wwwwww
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ // 110yyyyy
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ // 1110zzzz
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ // 11110uuu
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ // > 11110111
+ -1, -1, -1, -1, -1, -1, -1, -1
+ )
+
+ @inline
+ private class DecodedMultiByte(val failure: CoderResult,
+ val high: Char, val low: Char)
+
+ private object DecodedMultiByte {
+ @inline def apply(failure: CoderResult): DecodedMultiByte =
+ new DecodedMultiByte(failure, 0, 0)
+
+ @inline def apply(single: Char): DecodedMultiByte =
+ new DecodedMultiByte(null, single, 0)
+
+ @inline def apply(high: Char, low: Char): DecodedMultiByte =
+ new DecodedMultiByte(null, high, low)
+ }
+
+ private class Decoder extends CharsetDecoder(UTF_8, 1.0f, 1.0f) {
+ def decodeLoop(in: ByteBuffer, out: CharBuffer): CoderResult = {
+ if (in.hasArray && out.hasArray)
+ decodeLoopArray(in, out)
+ else
+ decodeLoopNoArray(in, out)
+ }
+
+ private def decodeLoopArray(in: ByteBuffer, out: CharBuffer): CoderResult = {
+ val inArray = in.array
+ val inOffset = in.arrayOffset
+ val inStart = in.position + inOffset
+ val inEnd = in.limit + inOffset
+
+ val outArray = out.array
+ val outOffset = out.arrayOffset
+ val outStart = out.position + outOffset
+ val outEnd = out.limit + outOffset
+
+ @inline
+ @tailrec
+ def loop(inPos: Int, outPos: Int): CoderResult = {
+ @inline
+ def finalize(result: CoderResult): CoderResult = {
+ in.position(inPos - inOffset)
+ out.position(outPos - outOffset)
+ result
+ }
+
+ if (inPos == inEnd) {
+ finalize(CoderResult.UNDERFLOW)
+ } else {
+ val leading = inArray(inPos).toInt
+ if (leading >= 0) {
+ // US-ASCII repertoire
+ if (outPos == outEnd) {
+ finalize(CoderResult.OVERFLOW)
+ } else {
+ outArray(outPos) = leading.toChar
+ loop(inPos+1, outPos+1)
+ }
+ } else {
+ // Multi-byte
+ val length = lengthByLeading(leading & 0x7f)
+ if (length == -1) {
+ finalize(CoderResult.malformedForLength(1))
+ } else if (inPos + length > inEnd) {
+ finalize(CoderResult.UNDERFLOW)
+ } else {
+ val decoded = {
+ val b2 = inArray(inPos+1)
+ if (length == 2) decode2(leading, b2)
+ else if (length == 3) decode3(leading, b2, inArray(inPos+2))
+ else decode4(leading, b2, inArray(inPos+2), inArray(inPos+3))
+ }
+
+ if (decoded.failure != null) {
+ finalize(decoded.failure)
+ } else if (decoded.low == 0) {
+ // not a surrogate pair
+ if (outPos == outEnd)
+ finalize(CoderResult.OVERFLOW)
+ else {
+ outArray(outPos) = decoded.high
+ loop(inPos+length, outPos+1)
+ }
+ } else {
+ // a surrogate pair
+ if (outPos + 2 > outEnd)
+ finalize(CoderResult.OVERFLOW)
+ else {
+ outArray(outPos) = decoded.high
+ outArray(outPos+1) = decoded.low
+ loop(inPos+length, outPos+2)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ loop(inStart, outStart)
+ }
+
+ private def decodeLoopNoArray(in: ByteBuffer, out: CharBuffer): CoderResult = {
+ @inline
+ @tailrec
+ def loop(): CoderResult = {
+ @inline
+ def finalize(read: Int, result: CoderResult): CoderResult = {
+ in.position(in.position - read)
+ result
+ }
+
+ if (!in.hasRemaining) {
+ CoderResult.UNDERFLOW
+ } else {
+ val leading = in.get().toInt
+ if (leading >= 0) {
+ // US-ASCII repertoire
+ if (!out.hasRemaining) {
+ finalize(1, CoderResult.OVERFLOW)
+ } else {
+ out.put(leading.toChar)
+ loop()
+ }
+ } else {
+ // Multi-byte
+ val length = lengthByLeading(leading & 0x7f)
+ if (length == -1) {
+ finalize(1, CoderResult.malformedForLength(1))
+ } else if (in.remaining < length-1) {
+ finalize(1, CoderResult.UNDERFLOW)
+ } else {
+ val decoded = {
+ if (length == 2) decode2(leading, in.get())
+ else if (length == 3) decode3(leading, in.get(), in.get())
+ else decode4(leading, in.get(), in.get(), in.get())
+ }
+
+ if (decoded.failure != null) {
+ finalize(length, decoded.failure)
+ } else if (decoded.low == 0) {
+ // not a surrogate pair
+ if (!out.hasRemaining)
+ finalize(length, CoderResult.OVERFLOW)
+ else {
+ out.put(decoded.high)
+ loop()
+ }
+ } else {
+ // a surrogate pair
+ if (out.remaining < 2)
+ finalize(length, CoderResult.OVERFLOW)
+ else {
+ out.put(decoded.high)
+ out.put(decoded.low)
+ loop()
+ }
+ }
+ }
+ }
+ }
+ }
+
+ loop()
+ }
+
+ @inline private def isInvalidNextByte(b: Int): Boolean =
+ (b & 0xc0) != 0x80
+
+ @inline private def decode2(b1: Int, b2: Int): DecodedMultiByte = {
+ if (isInvalidNextByte(b2))
+ DecodedMultiByte(CoderResult.malformedForLength(1))
+ else {
+ val codePoint = (((b1 & 0x1f) << 6) | (b2 & 0x3f))
+ // By construction, 0 <= codePoint <= 0x7ff < MIN_SURROGATE
+ if (codePoint < 0x80) {
+ // Should have been encoded with only 1 byte
+ DecodedMultiByte(CoderResult.malformedForLength(2))
+ } else {
+ DecodedMultiByte(codePoint.toChar)
+ }
+ }
+ }
+
+ @inline private def decode3(b1: Int, b2: Int, b3: Int): DecodedMultiByte = {
+ if (isInvalidNextByte(b2))
+ DecodedMultiByte(CoderResult.malformedForLength(1))
+ else if (isInvalidNextByte(b3))
+ DecodedMultiByte(CoderResult.malformedForLength(2))
+ else {
+ val codePoint = (((b1 & 0xf) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f))
+ // By construction, 0 <= codePoint <= 0xffff < MIN_SUPPLEMENTARY_CODE_POINT
+ if ((codePoint < 0x800) ||
+ (codePoint >= MIN_SURROGATE && codePoint <= MAX_SURROGATE)) {
+ // Should have been encoded with only 1 or 2 bytes
+ // or it is a surrogate, which is not a valid code point
+ DecodedMultiByte(CoderResult.malformedForLength(3))
+ } else {
+ DecodedMultiByte(codePoint.toChar)
+ }
+ }
+ }
+
+ @inline private def decode4(b1: Int, b2: Int, b3: Int, b4: Int): DecodedMultiByte = {
+ if (isInvalidNextByte(b2))
+ DecodedMultiByte(CoderResult.malformedForLength(1))
+ else if (isInvalidNextByte(b3))
+ DecodedMultiByte(CoderResult.malformedForLength(2))
+ else if (isInvalidNextByte(b4))
+ DecodedMultiByte(CoderResult.malformedForLength(3))
+ else {
+ val codePoint = (((b1 & 0x7) << 18) | ((b2 & 0x3f) << 12) |
+ ((b3 & 0x3f) << 6) | (b4 & 0x3f))
+ // By construction, 0 <= codePoint <= 0x1fffff
+ if (codePoint < 0x10000 || codePoint > MAX_CODE_POINT) {
+ // It should have been encoded with 1, 2, or 3 bytes
+ // or it is not a valid code point
+ DecodedMultiByte(CoderResult.malformedForLength(4))
+ } else {
+ // Here, we need to encode the code point as a surrogate pair.
+ // http://en.wikipedia.org/wiki/UTF-16
+ val offsetCodePoint = codePoint - 0x10000
+ DecodedMultiByte(
+ ((offsetCodePoint >> 10) | 0xd800).toChar,
+ ((offsetCodePoint & 0x3ff) | 0xdc00).toChar)
+ }
+ }
+ }
+ }
+
+ private class Encoder extends CharsetEncoder(UTF_8, 1.1f, 4.0f) {
+ def encodeLoop(in: CharBuffer, out: ByteBuffer): CoderResult = {
+ if (in.hasArray && out.hasArray)
+ encodeLoopArray(in, out)
+ else
+ encodeLoopNoArray(in, out)
+ }
+
+ private def encodeLoopArray(in: CharBuffer, out: ByteBuffer): CoderResult = {
+ val inArray = in.array
+ val inOffset = in.arrayOffset
+ val inStart = in.position + inOffset
+ val inEnd = in.limit + inOffset
+
+ val outArray = out.array
+ val outOffset = out.arrayOffset
+ val outStart = out.position + outOffset
+ val outEnd = out.limit + outOffset
+
+ @inline
+ @tailrec
+ def loop(inPos: Int, outPos: Int): CoderResult = {
+ @inline
+ def finalize(result: CoderResult): CoderResult = {
+ in.position(inPos - inOffset)
+ out.position(outPos - outOffset)
+ result
+ }
+
+ if (inPos == inEnd) {
+ finalize(CoderResult.UNDERFLOW)
+ } else {
+ val c1 = inArray(inPos)
+
+ if (c1 < 0x80) {
+ // Encoding in one byte
+ if (outPos == outEnd)
+ finalize(CoderResult.OVERFLOW)
+ else {
+ outArray(outPos) = c1.toByte
+ loop(inPos+1, outPos+1)
+ }
+ } else if (c1 < 0x800) {
+ // Encoding in 2 bytes (by construction, not a surrogate)
+ if (outPos + 2 > outEnd)
+ finalize(CoderResult.OVERFLOW)
+ else {
+ outArray(outPos) = ((c1 >> 6) | 0xc0).toByte
+ outArray(outPos+1) = ((c1 & 0x3f) | 0x80).toByte
+ loop(inPos+1, outPos+2)
+ }
+ } else if (!isSurrogate(c1)) {
+ // Not a surrogate, encoding in 3 bytes
+ if (outPos + 3 > outEnd)
+ finalize(CoderResult.OVERFLOW)
+ else {
+ outArray(outPos) = ((c1 >> 12) | 0xe0).toByte
+ outArray(outPos+1) = (((c1 >> 6) & 0x3f) | 0x80).toByte
+ outArray(outPos+2) = ((c1 & 0x3f) | 0x80).toByte
+ loop(inPos+1, outPos+3)
+ }
+ } else if (isHighSurrogate(c1)) {
+ // Should have a low surrogate that follows
+ if (inPos + 1 == inEnd)
+ finalize(CoderResult.UNDERFLOW)
+ else {
+ val c2 = inArray(inPos+1)
+ if (!isLowSurrogate(c2)) {
+ finalize(CoderResult.malformedForLength(1))
+ } else {
+ // Surrogate pair, encoding in 4 bytes
+ if (outPos + 4 > outEnd)
+ finalize(CoderResult.OVERFLOW)
+ else {
+ val cp = toCodePoint(c1, c2)
+ outArray(outPos) = ((cp >> 18) | 0xf0).toByte
+ outArray(outPos+1) = (((cp >> 12) & 0x3f) | 0x80).toByte
+ outArray(outPos+2) = (((cp >> 6) & 0x3f) | 0x80).toByte
+ outArray(outPos+3) = ((cp & 0x3f) | 0x80).toByte
+ loop(inPos+2, outPos+4)
+ }
+ }
+ }
+ } else {
+ finalize(CoderResult.malformedForLength(1))
+ }
+ }
+ }
+
+ loop(inStart, outStart)
+ }
+
+ private def encodeLoopNoArray(in: CharBuffer, out: ByteBuffer): CoderResult = {
+ @inline
+ @tailrec
+ def loop(): CoderResult = {
+ @inline
+ def finalize(read: Int, result: CoderResult): CoderResult = {
+ in.position(in.position - read)
+ result
+ }
+
+ if (!in.hasRemaining) {
+ CoderResult.UNDERFLOW
+ } else {
+ val c1 = in.get()
+
+ if (c1 < 0x80) {
+ // Encoding in one byte
+ if (!out.hasRemaining)
+ finalize(1, CoderResult.OVERFLOW)
+ else {
+ out.put(c1.toByte)
+ loop()
+ }
+ } else if (c1 < 0x800) {
+ // Encoding in 2 bytes (by construction, not a surrogate)
+ if (out.remaining < 2)
+ finalize(1, CoderResult.OVERFLOW)
+ else {
+ out.put(((c1 >> 6) | 0xc0).toByte)
+ out.put(((c1 & 0x3f) | 0x80).toByte)
+ loop()
+ }
+ } else if (!isSurrogate(c1)) {
+ // Not a surrogate, encoding in 3 bytes
+ if (out.remaining < 3)
+ finalize(1, CoderResult.OVERFLOW)
+ else {
+ out.put(((c1 >> 12) | 0xe0).toByte)
+ out.put((((c1 >> 6) & 0x3f) | 0x80).toByte)
+ out.put(((c1 & 0x3f) | 0x80).toByte)
+ loop()
+ }
+ } else if (isHighSurrogate(c1)) {
+ // Should have a low surrogate that follows
+ if (!in.hasRemaining)
+ finalize(1, CoderResult.UNDERFLOW)
+ else {
+ val c2 = in.get()
+ if (!isLowSurrogate(c2)) {
+ finalize(2, CoderResult.malformedForLength(1))
+ } else {
+ // Surrogate pair, encoding in 4 bytes
+ if (out.remaining < 4)
+ finalize(2, CoderResult.OVERFLOW)
+ else {
+ val cp = toCodePoint(c1, c2)
+ out.put(((cp >> 18) | 0xf0).toByte)
+ out.put((((cp >> 12) & 0x3f) | 0x80).toByte)
+ out.put((((cp >> 6) & 0x3f) | 0x80).toByte)
+ out.put(((cp & 0x3f) | 0x80).toByte)
+ loop()
+ }
+ }
+ }
+ } else {
+ finalize(1, CoderResult.malformedForLength(1))
+ }
+ }
+ }
+
+ loop()
+ }
+ }
+
+ private final val SurrogateMask = 0xf800 // 11111 0 00 00000000
+ private final val SurrogateID = 0xd800 // 11011 0 00 00000000
+
+ @inline private def isSurrogate(c: Char): Boolean =
+ (c & SurrogateMask) == SurrogateID
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala
new file mode 100644
index 0000000..861d81a
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/AnonFunctions.scala
@@ -0,0 +1,119 @@
+package scala.scalajs.runtime
+
+import scala.scalajs.js
+import scala.runtime._
+
+@inline
+final class AnonFunction0[+R](f: js.Function0[R]) extends AbstractFunction0[R] {
+ override def apply(): R = f()
+}
+
+@inline
+final class AnonFunction1[-T1, +R](f: js.Function1[T1, R]) extends AbstractFunction1[T1, R] {
+ override def apply(arg1: T1): R = f(arg1)
+}
+
+@inline
+final class AnonFunction2[-T1, -T2, +R](f: js.Function2[T1, T2, R]) extends AbstractFunction2[T1, T2, R] {
+ override def apply(arg1: T1, arg2: T2): R = f(arg1, arg2)
+}
+
+@inline
+final class AnonFunction3[-T1, -T2, -T3, +R](f: js.Function3[T1, T2, T3, R]) extends AbstractFunction3[T1, T2, T3, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3): R = f(arg1, arg2, arg3)
+}
+
+@inline
+final class AnonFunction4[-T1, -T2, -T3, -T4, +R](f: js.Function4[T1, T2, T3, T4, R]) extends AbstractFunction4[T1, T2, T3, T4, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4): R = f(arg1, arg2, arg3, arg4)
+}
+
+@inline
+final class AnonFunction5[-T1, -T2, -T3, -T4, -T5, +R](f: js.Function5[T1, T2, T3, T4, T5, R]) extends AbstractFunction5[T1, T2, T3, T4, T5, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5): R = f(arg1, arg2, arg3, arg4, arg5)
+}
+
+@inline
+final class AnonFunction6[-T1, -T2, -T3, -T4, -T5, -T6, +R](f: js.Function6[T1, T2, T3, T4, T5, T6, R]) extends AbstractFunction6[T1, T2, T3, T4, T5, T6, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6): R = f(arg1, arg2, arg3, arg4, arg5, arg6)
+}
+
+@inline
+final class AnonFunction7[-T1, -T2, -T3, -T4, -T5, -T6, -T7, +R](f: js.Function7[T1, T2, T3, T4, T5, T6, T7, R]) extends AbstractFunction7[T1, T2, T3, T4, T5, T6, T7, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+}
+
+@inline
+final class AnonFunction8[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, +R](f: js.Function8[T1, T2, T3, T4, T5, T6, T7, T8, R]) extends AbstractFunction8[T1, T2, T3, T4, T5, T6, T7, T8, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
+}
+
+@inline
+final class AnonFunction9[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, +R](f: js.Function9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R]) extends AbstractFunction9[T1, T2, T3, T4, T5, T6, T7, T8, T9, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
+}
+
+@inline
+final class AnonFunction10[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, +R](f: js.Function10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R]) extends AbstractFunction10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
+}
+
+@inline
+final class AnonFunction11[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, +R](f: js.Function11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R]) extends AbstractFunction11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11)
+}
+
+@inline
+final class AnonFunction12[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, +R](f: js.Function12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R]) extends AbstractFunction12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12)
+}
+
+@inline
+final class AnonFunction13[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, +R](f: js.Function13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R]) extends AbstractFunction13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13)
+}
+
+@inline
+final class AnonFunction14[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, +R](f: js.Function14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R]) extends AbstractFunction14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14)
+}
+
+@inline
+final class AnonFunction15[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, +R](f: js.Function15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R]) extends AbstractFunction15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15)
+}
+
+@inline
+final class AnonFunction16[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, +R](f: js.Function16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R]) extends AbstractFunction16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16)
+}
+
+@inline
+final class AnonFunction17[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, +R](f: js.Function17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R]) extends AbstractFunction17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17)
+}
+
+@inline
+final class AnonFunction18[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, +R](f: js.Function18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R]) extends AbstractFunction18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18)
+}
+
+@inline
+final class AnonFunction19[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, +R](f: js.Function19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R]) extends AbstractFunction19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19)
+}
+
+@inline
+final class AnonFunction20[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, +R](f: js.Function20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R]) extends AbstractFunction20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20)
+}
+
+@inline
+final class AnonFunction21[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, +R](f: js.Function21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R]) extends AbstractFunction21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21)
+}
+
+@inline
+final class AnonFunction22[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, +R](f: js.Function22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R]) extends AbstractFunction22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, R] {
+ override def apply(arg1: T1, arg2: T2, arg3: T3, arg4: T4, arg5: T5, arg6: T6, arg7: T7, arg8: T8, arg9: T9, arg10: T10, arg11: T11, arg12: T12, arg13: T13, arg14: T14, arg15: T15, arg16: T16, arg17: T17, arg18: T18, arg19: T19, arg20: T20, arg21: T21, arg22: T22): R = f(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20, arg21, arg22)
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/Bits.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/Bits.scala
new file mode 100644
index 0000000..38b2c3e
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/Bits.scala
@@ -0,0 +1,240 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js API **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.runtime
+
+import scala.scalajs.js
+import js.Dynamic.global
+import js.typedarray
+
+/** Low-level stuff. */
+object Bits {
+
+ val areTypedArraysSupported = (
+ !(!global.ArrayBuffer) && !(!global.Int32Array) &&
+ !(!global.Float32Array) && !(!global.Float64Array))
+
+ private val arrayBuffer =
+ if (areTypedArraysSupported) new typedarray.ArrayBuffer(8)
+ else null
+
+ private val int32Array =
+ if (areTypedArraysSupported) new typedarray.Int32Array(arrayBuffer, 0, 2)
+ else null
+
+ private val float32Array =
+ if (areTypedArraysSupported) new typedarray.Float32Array(arrayBuffer, 0, 2)
+ else null
+
+ private val float64Array =
+ if (areTypedArraysSupported) new typedarray.Float64Array(arrayBuffer, 0, 1)
+ else null
+
+ val areTypedArraysBigEndian = {
+ if (areTypedArraysSupported) {
+ int32Array(0) = 0x01020304
+ (new typedarray.Int8Array(arrayBuffer, 0, 8))(0) == 0x01
+ } else {
+ true // as good a value as any
+ }
+ }
+
+ private val highOffset = if (areTypedArraysBigEndian) 0 else 1
+ private val lowOffset = if (areTypedArraysBigEndian) 1 else 0
+
+ /** Hash code of a number (excluding Longs).
+ *
+ * Because of the common encoding for integer and floating point values,
+ * the hashCode of Floats and Doubles must align with that of Ints for the
+ * common values.
+ *
+ * For other values, we use the hashCode specified by the JavaDoc for
+ * *Doubles*, even for values which are valid Float values. Because of the
+ * previous point, we cannot align completely with the Java specification,
+ * so there is no point trying to be a bit more aligned here. Always using
+ * the Double version should typically be faster on VMs without fround
+ * support because we avoid several fround operations.
+ */
+ def numberHashCode(value: Double): Int = {
+ val iv = value.toInt
+ if (iv == value) iv
+ else doubleToLongBits(value).hashCode()
+ }
+
+ def intBitsToFloat(bits: Int): Float = {
+ if (areTypedArraysSupported) {
+ int32Array(0) = bits
+ float32Array(0)
+ } else {
+ intBitsToFloatPolyfill(bits).toFloat
+ }
+ }
+
+ def floatToIntBits(value: Float): Int = {
+ if (areTypedArraysSupported) {
+ float32Array(0) = value
+ int32Array(0)
+ } else {
+ floatToIntBitsPolyfill(value.toDouble)
+ }
+ }
+
+ def longBitsToDouble(bits: Long): Double = {
+ if (areTypedArraysSupported) {
+ int32Array(highOffset) = (bits >>> 32).toInt
+ int32Array(lowOffset) = bits.toInt
+ float64Array(0)
+ } else {
+ longBitsToDoublePolyfill(bits)
+ }
+ }
+
+ def doubleToLongBits(value: Double): Long = {
+ if (areTypedArraysSupported) {
+ float64Array(0) = value
+ ((int32Array(highOffset).toLong << 32) |
+ (int32Array(lowOffset).toLong & 0xffffffffL))
+ } else {
+ doubleToLongBitsPolyfill(value)
+ }
+ }
+
+ /* --- Polyfills for floating point bit manipulations ---
+ *
+ * Originally inspired by
+ * https://github.com/inexorabletash/polyfill/blob/a682f42c1092280bb01907c245979fb07219513d/typedarray.js#L150-L255
+ *
+ * Note that if typed arrays are not supported, it is almost certain that
+ * fround is not supported natively, so Float operations are extremely slow.
+ *
+ * We therefore do all computations in Doubles here, which is also more
+ * predictable, since the results do not depend on strict floats semantics.
+ */
+
+ private def intBitsToFloatPolyfill(bits: Int): Double = {
+ val ebits = 8
+ val fbits = 23
+ val s = bits < 0
+ val e = (bits >> fbits) & ((1 << ebits) - 1)
+ val f = bits & ((1 << fbits) - 1)
+ decodeIEEE754(ebits, fbits, s, e, f)
+ }
+
+ private def floatToIntBitsPolyfill(value: Double): Int = {
+ val ebits = 8
+ val fbits = 23
+ val (s, e, f) = encodeIEEE754(ebits, fbits, value)
+ (if (s) 0x80000000 else 0) | (e << fbits) | f.toInt
+ }
+
+ private def longBitsToDoublePolyfill(bits: Long): Double = {
+ val ebits = 11
+ val fbits = 52
+ val hifbits = fbits-32
+ val hi = (bits >>> 32).toInt
+ val lo = ((bits.toInt: js.prim.Number) >>> 0).toDouble
+ val s = hi < 0
+ val e = (hi >> hifbits) & ((1 << ebits) - 1)
+ val f = (hi & ((1 << hifbits) - 1)).toDouble * 0x100000000L.toDouble + lo
+ decodeIEEE754(ebits, fbits, s, e, f)
+ }
+
+ private def doubleToLongBitsPolyfill(value: Double): Long = {
+ val ebits = 11
+ val fbits = 52
+ val hifbits = fbits-32
+ val (s, e, f) = encodeIEEE754(ebits, fbits, value)
+ val hif = (f / 0x100000000L.toDouble).toInt
+ val hi = (if (s) 0x80000000 else 0) | (e << hifbits) | hif
+ val lo = f.toInt
+ (hi.toLong << 32) | (lo.toLong & 0xffffffffL)
+ }
+
+ @inline private def decodeIEEE754(ebits: Int, fbits: Int,
+ s: Boolean, e: Int, f: Double): Double = {
+
+ import Math.pow
+
+ val bias = (1 << (ebits-1)) - 1 // constant
+
+ if (e == (1 << ebits) - 1) {
+ // Special
+ if (f != 0.0) Double.NaN
+ else if (s) Double.NegativeInfinity
+ else Double.PositiveInfinity
+ } else if (e > 0) {
+ // Normalized
+ val x = pow(2, e-bias) * (1 + f / pow(2, fbits))
+ if (s) -x else x
+ } else if (f != 0.0) {
+ // Subnormal
+ val x = pow(2, -(bias-1)) * (f / pow(2, fbits))
+ if (s) -x else x
+ } else {
+ // Zero
+ if (s) -0.0 else 0.0
+ }
+ }
+
+ @inline private def encodeIEEE754(ebits: Int, fbits: Int,
+ v: Double): (Boolean, Int, Double) = {
+
+ import Math._
+
+ val bias = (1 << (ebits-1)) - 1 // constant
+
+ if (v.isNaN) {
+ // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping
+ (false, (1 << ebits) - 1, pow(2, fbits-1))
+ } else if (v.isInfinite) {
+ (v < 0, (1 << ebits) - 1, 0.0)
+ } else if (v == 0.0) {
+ (1 / v == Double.NegativeInfinity, 0, 0.0)
+ } else {
+ val LN2 = 0.6931471805599453
+
+ val s = v < 0
+ val av = if (s) -v else v
+
+ if (av >= pow(2, 1-bias)) {
+ val twoPowFbits = pow(2, fbits)
+
+ var e = min(floor(log(av) / LN2).toInt, 1023)
+ var f = roundToEven(av / pow(2, e) * twoPowFbits)
+ if (f / twoPowFbits >= 2) {
+ e = e + 1
+ f = 1
+ }
+ if (e > bias) {
+ // Overflow
+ e = (1 << ebits) - 1
+ f = 0
+ } else {
+ // Normalized
+ e = e + bias
+ f = f - twoPowFbits
+ }
+ (s, e, f)
+ } else {
+ // Subnormal
+ (s, 0, roundToEven(av / pow(2, 1-bias-fbits)))
+ }
+ }
+ }
+
+ @inline private[runtime] def roundToEven(n: Double): Double = {
+ val w = Math.floor(n)
+ val f = n - w
+ if (f < 0.5) w
+ else if (f > 0.5) w + 1
+ else if (w % 2 != 0) w + 1
+ else w
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala
new file mode 100644
index 0000000..0cd562a
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/BooleanReflectiveCall.scala
@@ -0,0 +1,31 @@
+package scala.scalajs.runtime
+
+import java.lang.{Boolean => JBoolean}
+
+/** Explicit box for boolean values when doing a reflective call.
+ * This class and its methods are only here to properly support reflective
+ * calls on booleans.
+ */
+class BooleanReflectiveCall(value: Boolean) {
+
+ // Methods of java.lang.Boolean
+
+ def booleanValue(): Boolean = value
+
+ def compareTo(that: JBoolean): Int =
+ new JBoolean(value).compareTo(that)
+ def compareTo(that: AnyRef): Int =
+ new JBoolean(value).compareTo(that.asInstanceOf[JBoolean])
+
+ // Methods of scala.Boolean
+
+ def unary_! : Boolean = !value
+ def ==(x: Boolean): Boolean = value == x
+ def !=(x: Boolean): Boolean = value != x
+ def ||(x: Boolean): Boolean = value || x
+ def &&(x: Boolean): Boolean = value && x
+ def |(x: Boolean): Boolean = value | x
+ def &(x: Boolean): Boolean = value & x
+ def ^(x: Boolean): Boolean = value ^ x
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala
new file mode 100644
index 0000000..ddf65df
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/IntegerReflectiveCall.scala
@@ -0,0 +1,87 @@
+package scala.scalajs.runtime
+
+import java.lang.{Double => JDouble, Integer => JInteger}
+
+/** Explicit box for number values when doing a reflective call that was
+ * identified to be a call on Int rather than on Double (based on the
+ * result type of the method called reflectively).
+ * This class and its methods are only here to properly support reflective
+ * calls on numbers.
+ */
+class IntegerReflectiveCall(value: Int) {
+
+ // Methods of scala.Int whose result type is different than in scala.Double
+
+ def unary_+ : scala.Int = value
+ def unary_- : scala.Int = -value
+
+ def +(x: scala.Byte): scala.Int = value + x
+ def +(x: scala.Short): scala.Int = value + x
+ def +(x: scala.Char): scala.Int = value + x
+ def +(x: scala.Int): scala.Int = value + x
+ def +(x: scala.Long): scala.Long = value + x
+ def +(x: scala.Float): scala.Float = value + x
+ def +(x: scala.Double): scala.Double = value + x
+
+ def -(x: scala.Byte): scala.Int = value - x
+ def -(x: scala.Short): scala.Int = value - x
+ def -(x: scala.Char): scala.Int = value - x
+ def -(x: scala.Int): scala.Int = value - x
+ def -(x: scala.Long): scala.Long = value - x
+ def -(x: scala.Float): scala.Float = value - x
+ def -(x: scala.Double): scala.Double = value - x
+
+ def *(x: scala.Byte): scala.Int = value * x
+ def *(x: scala.Short): scala.Int = value * x
+ def *(x: scala.Char): scala.Int = value * x
+ def *(x: scala.Int): scala.Int = value * x
+ def *(x: scala.Long): scala.Long = value * x
+ def *(x: scala.Float): scala.Float = value * x
+ def *(x: scala.Double): scala.Double = value * x
+
+ def /(x: scala.Byte): scala.Int = value / x
+ def /(x: scala.Short): scala.Int = value / x
+ def /(x: scala.Char): scala.Int = value / x
+ def /(x: scala.Int): scala.Int = value / x
+ def /(x: scala.Long): scala.Long = value / x
+ def /(x: scala.Float): scala.Float = value / x
+ def /(x: scala.Double): scala.Double = value / x
+
+ def %(x: scala.Byte): scala.Int = value % x
+ def %(x: scala.Short): scala.Int = value % x
+ def %(x: scala.Char): scala.Int = value % x
+ def %(x: scala.Int): scala.Int = value % x
+ def %(x: scala.Long): scala.Long = value % x
+ def %(x: scala.Float): scala.Float = value % x
+ def %(x: scala.Double): scala.Double = value % x
+
+ // Methods of scala.Int that are not defined on scala.Double
+
+ def unary_~ : scala.Int = ~value
+
+ def <<(x: scala.Int): scala.Int = value << x
+ def <<(x: scala.Long): scala.Int = value << x
+ def >>>(x: scala.Int): scala.Int = value >>> x
+ def >>>(x: scala.Long): scala.Int = value >>> x
+ def >>(x: scala.Int): scala.Int = value >> x
+ def >>(x: scala.Long): scala.Int = value >> x
+
+ def |(x: scala.Byte): scala.Int = value | x
+ def |(x: scala.Short): scala.Int = value | x
+ def |(x: scala.Char): scala.Int = value | x
+ def |(x: scala.Int): scala.Int = value | x
+ def |(x: scala.Long): scala.Long = value | x
+
+ def &(x: scala.Byte): scala.Int = value & x
+ def &(x: scala.Short): scala.Int = value & x
+ def &(x: scala.Char): scala.Int = value & x
+ def &(x: scala.Int): scala.Int = value & x
+ def &(x: scala.Long): scala.Long = value & x
+
+ def ^(x: scala.Byte): scala.Int = value ^ x
+ def ^(x: scala.Short): scala.Int = value ^ x
+ def ^(x: scala.Char): scala.Int = value ^ x
+ def ^(x: scala.Int): scala.Int = value ^ x
+ def ^(x: scala.Long): scala.Long = value ^ x
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala
new file mode 100644
index 0000000..a237861
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/NumberReflectiveCall.scala
@@ -0,0 +1,162 @@
+package scala.scalajs.runtime
+
+import java.lang.{Double => JDouble, Integer => JInteger}
+
+/** Explicit box for number values when doing a reflective call.
+ * This class and its methods are only here to properly support reflective
+ * calls on numbers.
+ */
+class NumberReflectiveCall(value: Double) {
+
+ // Methods of java.lang.Double and java.lang.Integer
+
+ def byteValue(): Byte = value.toByte
+ def shortValue(): Short = value.toShort
+ def intValue(): Int = value.toInt
+ def longValue(): scala.Long = value.toLong
+ def floatValue(): Float = value.toFloat
+ def doubleValue(): Double = value
+
+ def compareTo(that: JDouble): Int =
+ new JDouble(value).compareTo(that)
+ def compareTo(that: JInteger): Int =
+ new JDouble(value).compareTo(new JDouble(that.doubleValue()))
+ def compareTo(that: AnyRef): Int =
+ new JDouble(value).compareTo(that.asInstanceOf[JDouble])
+
+ def isNaN(): scala.Boolean = new JDouble(value).isNaN()
+ def isInfinite(): scala.Boolean = new JDouble(value).isInfinite()
+
+ // Methods of scala.Double
+
+ def toByte: scala.Byte = value.toByte
+ def toShort: scala.Short = value.toShort
+ def toChar: scala.Char = value.toChar
+ def toInt: scala.Int = value.toInt
+ def toLong: scala.Long = value.toLong
+ def toFloat: scala.Float = value.toFloat
+ def toDouble: scala.Double = value
+
+ def unary_+ : scala.Double = value
+ def unary_- : scala.Double = -value
+
+ def +(x: String): String = value + x
+
+ def ==(x: scala.Byte): scala.Boolean = value == x
+ def ==(x: scala.Short): scala.Boolean = value == x
+ def ==(x: scala.Char): scala.Boolean = value == x
+ def ==(x: scala.Int): scala.Boolean = value == x
+ def ==(x: scala.Long): scala.Boolean = value == x
+ def ==(x: scala.Float): scala.Boolean = value == x
+ def ==(x: scala.Double): scala.Boolean = value == x
+
+ def !=(x: scala.Byte): scala.Boolean = value != x
+ def !=(x: scala.Short): scala.Boolean = value != x
+ def !=(x: scala.Char): scala.Boolean = value != x
+ def !=(x: scala.Int): scala.Boolean = value != x
+ def !=(x: scala.Long): scala.Boolean = value != x
+ def !=(x: scala.Float): scala.Boolean = value != x
+ def !=(x: scala.Double): scala.Boolean = value != x
+
+ def <(x: scala.Byte): scala.Boolean = value < x
+ def <(x: scala.Short): scala.Boolean = value < x
+ def <(x: scala.Char): scala.Boolean = value < x
+ def <(x: scala.Int): scala.Boolean = value < x
+ def <(x: scala.Long): scala.Boolean = value < x
+ def <(x: scala.Float): scala.Boolean = value < x
+ def <(x: scala.Double): scala.Boolean = value < x
+
+ def <=(x: scala.Byte): scala.Boolean = value <= x
+ def <=(x: scala.Short): scala.Boolean = value <= x
+ def <=(x: scala.Char): scala.Boolean = value <= x
+ def <=(x: scala.Int): scala.Boolean = value <= x
+ def <=(x: scala.Long): scala.Boolean = value <= x
+ def <=(x: scala.Float): scala.Boolean = value <= x
+ def <=(x: scala.Double): scala.Boolean = value <= x
+
+ def >(x: scala.Byte): scala.Boolean = value > x
+ def >(x: scala.Short): scala.Boolean = value > x
+ def >(x: scala.Char): scala.Boolean = value > x
+ def >(x: scala.Int): scala.Boolean = value > x
+ def >(x: scala.Long): scala.Boolean = value > x
+ def >(x: scala.Float): scala.Boolean = value > x
+ def >(x: scala.Double): scala.Boolean = value > x
+
+ def >=(x: scala.Byte): scala.Boolean = value >= x
+ def >=(x: scala.Short): scala.Boolean = value >= x
+ def >=(x: scala.Char): scala.Boolean = value >= x
+ def >=(x: scala.Int): scala.Boolean = value >= x
+ def >=(x: scala.Long): scala.Boolean = value >= x
+ def >=(x: scala.Float): scala.Boolean = value >= x
+ def >=(x: scala.Double): scala.Boolean = value >= x
+
+ def +(x: scala.Byte): scala.Double = value + x
+ def +(x: scala.Short): scala.Double = value + x
+ def +(x: scala.Char): scala.Double = value + x
+ def +(x: scala.Int): scala.Double = value + x
+ def +(x: scala.Long): scala.Double = value + x
+ def +(x: scala.Float): scala.Double = value + x
+ def +(x: scala.Double): scala.Double = value + x
+
+ def -(x: scala.Byte): scala.Double = value - x
+ def -(x: scala.Short): scala.Double = value - x
+ def -(x: scala.Char): scala.Double = value - x
+ def -(x: scala.Int): scala.Double = value - x
+ def -(x: scala.Long): scala.Double = value - x
+ def -(x: scala.Float): scala.Double = value - x
+ def -(x: scala.Double): scala.Double = value - x
+
+ def *(x: scala.Byte): scala.Double = value * x
+ def *(x: scala.Short): scala.Double = value * x
+ def *(x: scala.Char): scala.Double = value * x
+ def *(x: scala.Int): scala.Double = value * x
+ def *(x: scala.Long): scala.Double = value * x
+ def *(x: scala.Float): scala.Double = value * x
+ def *(x: scala.Double): scala.Double = value * x
+
+ def /(x: scala.Byte): scala.Double = value / x
+ def /(x: scala.Short): scala.Double = value / x
+ def /(x: scala.Char): scala.Double = value / x
+ def /(x: scala.Int): scala.Double = value / x
+ def /(x: scala.Long): scala.Double = value / x
+ def /(x: scala.Float): scala.Double = value / x
+ def /(x: scala.Double): scala.Double = value / x
+
+ def %(x: scala.Byte): scala.Double = value % x
+ def %(x: scala.Short): scala.Double = value % x
+ def %(x: scala.Char): scala.Double = value % x
+ def %(x: scala.Int): scala.Double = value % x
+ def %(x: scala.Long): scala.Double = value % x
+ def %(x: scala.Float): scala.Double = value % x
+ def %(x: scala.Double): scala.Double = value % x
+
+ // Methods of scala.Int that are not defined on scala.Double
+
+ def unary_~ : scala.Int = ~value.toInt
+
+ def <<(x: scala.Int): scala.Int = value.toInt << x
+ def <<(x: scala.Long): scala.Int = value.toInt << x
+ def >>>(x: scala.Int): scala.Int = value.toInt >>> x
+ def >>>(x: scala.Long): scala.Int = value.toInt >>> x
+ def >>(x: scala.Int): scala.Int = value.toInt >> x
+ def >>(x: scala.Long): scala.Int = value.toInt >> x
+
+ def |(x: scala.Byte): scala.Int = value.toInt | x
+ def |(x: scala.Short): scala.Int = value.toInt | x
+ def |(x: scala.Char): scala.Int = value.toInt | x
+ def |(x: scala.Int): scala.Int = value.toInt | x
+ def |(x: scala.Long): scala.Long = value.toInt | x
+
+ def &(x: scala.Byte): scala.Int = value.toInt & x
+ def &(x: scala.Short): scala.Int = value.toInt & x
+ def &(x: scala.Char): scala.Int = value.toInt & x
+ def &(x: scala.Int): scala.Int = value.toInt & x
+ def &(x: scala.Long): scala.Long = value.toInt & x
+
+ def ^(x: scala.Byte): scala.Int = value.toInt ^ x
+ def ^(x: scala.Short): scala.Int = value.toInt ^ x
+ def ^(x: scala.Char): scala.Int = value.toInt ^ x
+ def ^(x: scala.Int): scala.Int = value.toInt ^ x
+ def ^(x: scala.Long): scala.Long = value.toInt ^ x
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala
new file mode 100644
index 0000000..3bd6fb6
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeLong.scala
@@ -0,0 +1,686 @@
+package scala.scalajs.runtime
+
+import scala.annotation.tailrec
+
+/**
+ * emulate a Java-Long using three integers.
+ * taken from gwt LongLib:
+ * com.google.gwt.lang.LongLib
+ *
+ * only used by runtime
+ *
+ * holds values l, m, h (low, middle, high)
+ * s.t. (x.l + ((long) x.m << 22) + ((long) x.h << 44)) is equal to
+ * the original value
+ */
+final class RuntimeLong(
+ val l: Int,
+ val m: Int,
+ val h: Int
+) extends Number with Comparable[java.lang.Long] { x =>
+
+ import RuntimeLong._
+
+ /** Construct from an Int.
+ * This is the implementation of RuntimeLong.fromInt() in a way that does not
+ * require to load to module RuntimeLong.
+ */
+ def this(value: Int) = this(
+ value & RuntimeLong.MASK,
+ (value >> RuntimeLong.BITS) & RuntimeLong.MASK,
+ if (value < 0) RuntimeLong.MASK_2 else 0)
+
+ /** Creates a new RuntimeLong but masks bits as follows:
+ * l & MASK, m & MASK, h & MASK_2
+ */
+ @inline private def masked(l: Int, m: Int, h: Int) =
+ new RuntimeLong(l & MASK, m & MASK, h & MASK_2)
+
+ def toByte: Byte = toInt.toByte
+ def toShort: Short = toInt.toShort
+ def toChar: Char = toInt.toChar
+ def toInt: Int = l | (m << BITS)
+ def toLong: Long = x.asInstanceOf[Long]
+ def toFloat: Float = toDouble.toFloat
+ def toDouble: Double =
+ if (isMinValue) -9223372036854775808.0
+ else if (isNegative) -((-x).toDouble)
+ else l + m * TWO_PWR_22_DBL + h * TWO_PWR_44_DBL
+
+ // java.lang.Number
+ override def byteValue(): Byte = toByte
+ override def shortValue(): Short = toShort
+ def intValue(): Int = toInt
+ def longValue(): Long = toLong
+ def floatValue(): Float = toFloat
+ def doubleValue(): Double = toDouble
+
+ // java.lang.Comparable + overload taking scala.Long
+ def compareTo(that: RuntimeLong): Int =
+ if (this equals that) 0 else if (this > that) 1 else -1
+ def compareTo(that: java.lang.Long): Int =
+ compareTo(that.asInstanceOf[RuntimeLong])
+
+ def unary_~ : RuntimeLong = masked(~x.l, ~x.m, ~x.h)
+ def unary_+ : RuntimeLong = x
+ def unary_- : RuntimeLong = {
+ val neg0 = (~x.l + 1) & MASK
+ val neg1 = (~x.m + (if (neg0 == 0) 1 else 0)) & MASK
+ val neg2 = (~x.h + (if (neg0 == 0 && neg1 == 0) 1 else 0)) & MASK_2
+ new RuntimeLong(neg0, neg1, neg2)
+ }
+
+ def +(y: String): String = x.toString + y
+
+ def <<(n_in: Int): RuntimeLong = {
+ /* crop MSB. Note: This will cause (2L << 65 == 2L << 1)
+ * apparently this is as specified
+ */
+ val n = n_in & 63
+
+ if (n < BITS) {
+ val remBits = BITS - n
+ masked(x.l << n,
+ (x.m << n) | (x.l >> remBits),
+ (x.h << n) | (x.m >> remBits))
+ } else if (n < BITS01) {
+ val shfBits = n - BITS
+ val remBits = BITS01 - n
+ masked(0, x.l << shfBits, (x.m << shfBits) | (x.l >> remBits))
+ } else {
+ masked(0, 0, x.l << (n - BITS01))
+ }
+
+ }
+
+ /**
+ * logical right shift
+ */
+ def >>>(n_in: Int): RuntimeLong = {
+ val n = n_in & 63
+ if (n < BITS) {
+ val remBits = BITS - n
+ masked((x.l >> n) | (x.m << remBits),
+ // FIXME is this really >> and not >>>??
+ (x.m >> n) | (x.h << remBits),
+ x.h >>> n)
+ } else if (n < BITS01) {
+ val shfBits = n - BITS
+ val remBits = BITS01 - n
+ // FIXME is this really >> and not >>>??
+ masked((x.m >> shfBits) | (x.h << remBits),
+ x.h >>> shfBits, 0)
+ } else {
+ masked(x.h >>> (n - BITS01), 0, 0)
+ }
+ }
+
+ /**
+ * arithmetic right shift
+ */
+ def >>(n_in: Int): RuntimeLong = {
+ val n = n_in & 63;
+
+ // Sign extend x.h
+ val negative = (x.h & SIGN_BIT_VALUE) != 0
+ val xh = if (negative) x.h | ~MASK_2 else x.h
+
+ if (n < BITS) {
+ val remBits = BITS - n
+ // FIXME IMHO the first two >> should be >>>
+ masked((x.l >> n) | (x.m << remBits),
+ (x.m >> n) | (xh << remBits),
+ xh >> n)
+ } else if (n < BITS01) {
+ val shfBits = n - BITS
+ val remBits = BITS01 - n
+ // FIXME IMHO the first >> should be >>>
+ masked((x.m >> shfBits) | (xh << remBits),
+ xh >> shfBits,
+ if (negative) MASK_2 else 0)
+ } else {
+ masked(xh >> (n - BITS01),
+ if (negative) MASK else 0,
+ if (negative) MASK_2 else 0)
+ }
+
+ }
+
+ def equals(y: RuntimeLong): Boolean =
+ x.l == y.l && x.m == y.m && x.h == y.h
+
+ override def equals(that: Any): Boolean = that match {
+ case y: RuntimeLong => x.equals(y)
+ case _ => false
+ }
+
+ def notEquals(that: RuntimeLong) = !equals(that)
+
+ override def hashCode(): Int = {
+ (this ^ (this >>> 32)).toInt
+ }
+
+ @inline
+ def <(y: RuntimeLong): Boolean = y > x
+ @inline
+ def <=(y: RuntimeLong): Boolean = y >= x
+
+ def >(y: RuntimeLong): Boolean = {
+ if (!x.isNegative)
+ y.isNegative ||
+ x.h > y.h ||
+ x.h == y.h && x.m > y.m ||
+ x.h == y.h && x.m == y.m && x.l > y.l
+ else !(
+ !y.isNegative ||
+ x.h < y.h ||
+ x.h == y.h && x.m < y.m ||
+ x.h == y.h && x.m == y.m && x.l <= y.l
+ )
+ }
+
+ def >=(y: RuntimeLong): Boolean = {
+ if (!x.isNegative)
+ y.isNegative ||
+ x.h > y.h ||
+ x.h == y.h && x.m > y.m ||
+ x.h == y.h && x.m == y.m && x.l >= y.l
+ else !(
+ !y.isNegative ||
+ x.h < y.h ||
+ x.h == y.h && x.m < y.m ||
+ x.h == y.h && x.m == y.m && x.l < y.l
+ )
+ }
+
+ def |(y: RuntimeLong): RuntimeLong =
+ new RuntimeLong(x.l | y.l, x.m | y.m, x.h | y.h)
+ def &(y: RuntimeLong): RuntimeLong =
+ new RuntimeLong(x.l & y.l, x.m & y.m, x.h & y.h)
+ def ^(y: RuntimeLong): RuntimeLong =
+ new RuntimeLong(x.l ^ y.l, x.m ^ y.m, x.h ^ y.h)
+
+ def +(y: RuntimeLong): RuntimeLong = {
+ val sum0 = x.l + y.l
+ val sum1 = x.m + y.m + (sum0 >> BITS)
+ val sum2 = x.h + y.h + (sum1 >> BITS)
+ masked(sum0, sum1, sum2)
+ }
+
+ /**
+ * subtraction
+ * note: gwt implements this individually
+ */
+ def -(y: RuntimeLong): RuntimeLong = x + (-y)
+
+ // This assumes that BITS == 22
+ def *(y: RuntimeLong): RuntimeLong = {
+
+ /** divides v in 13bit chunks */
+ @inline def chunk13(v: RuntimeLong) = (
+ v.l & 0x1fff,
+ (v.l >> 13) | ((v.m & 0xf) << 9),
+ (v.m >> 4) & 0x1fff,
+ (v.m >> 17) | ((v.h & 0xff) << 5),
+ (v.h & 0xfff00) >> 8
+ )
+
+ val (a0, a1, a2, a3, a4) = chunk13(x)
+ val (b0, b1, b2, b3, b4) = chunk13(y)
+
+ // Compute partial products
+ // Optimization: if b is small, avoid multiplying by parts that are 0
+ var p0 = a0 * b0; // << 0
+ var p1 = a1 * b0; // << 13
+ var p2 = a2 * b0; // << 26
+ var p3 = a3 * b0; // << 39
+ var p4 = a4 * b0; // << 52
+
+ if (b1 != 0) {
+ p1 += a0 * b1;
+ p2 += a1 * b1;
+ p3 += a2 * b1;
+ p4 += a3 * b1;
+ }
+ if (b2 != 0) {
+ p2 += a0 * b2;
+ p3 += a1 * b2;
+ p4 += a2 * b2;
+ }
+ if (b3 != 0) {
+ p3 += a0 * b3;
+ p4 += a1 * b3;
+ }
+ if (b4 != 0) {
+ p4 += a0 * b4;
+ }
+
+ // Accumulate into 22-bit chunks:
+ // .........................................c10|...................c00|
+ // |....................|..................xxxx|xxxxxxxxxxxxxxxxxxxxxx| p0
+ // |....................|......................|......................|
+ // |....................|...................c11|......c01.............|
+ // |....................|....xxxxxxxxxxxxxxxxxx|xxxxxxxxx.............| p1
+ // |....................|......................|......................|
+ // |.................c22|...............c12....|......................|
+ // |..........xxxxxxxxxx|xxxxxxxxxxxxxxxxxx....|......................| p2
+ // |....................|......................|......................|
+ // |.................c23|..c13.................|......................|
+ // |xxxxxxxxxxxxxxxxxxxx|xxxxx.................|......................| p3
+ // |....................|......................|......................|
+ // |.........c24........|......................|......................|
+ // |xxxxxxxxxxxx........|......................|......................| p4
+
+ val c00 = p0 & 0x3fffff;
+ val c01 = (p1 & 0x1ff) << 13;
+ val c0 = c00 + c01;
+
+ val c10 = p0 >> 22;
+ val c11 = p1 >> 9;
+ val c12 = (p2 & 0x3ffff) << 4;
+ val c13 = (p3 & 0x1f) << 17;
+ val c1 = c10 + c11 + c12 + c13;
+
+ val c22 = p2 >> 18;
+ val c23 = p3 >> 5;
+ val c24 = (p4 & 0xfff) << 8;
+ val c2 = c22 + c23 + c24;
+
+ // Propagate high bits from c0 -> c1, c1 -> c2
+ val c1n = c1 + (c0 >> BITS)
+
+ masked(c0, c1n, c2 + (c1n >> BITS))
+ }
+
+ def /(y: RuntimeLong): RuntimeLong = (x divMod y)(0)
+ def %(y: RuntimeLong): RuntimeLong = (x divMod y)(1)
+
+ //override def getClass(): Class[Long] = null
+
+ def toBinaryString: String = {
+ val zeros = "0000000000000000000000" // 22 zeros
+ @inline def padBinary22(i: Int) = {
+ val s = Integer.toBinaryString(i)
+ zeros.substring(s.length) + s
+ }
+
+ if (h != 0) Integer.toBinaryString(h) + padBinary22(m) + padBinary22(l)
+ else if (m != 0) Integer.toBinaryString(m) + padBinary22(l)
+ else Integer.toBinaryString(l)
+ }
+
+ def toHexString: String = {
+ val zeros = "000000" // 6 zeros
+ @inline def padHex(i: Int, len: Int) = {
+ val s = Integer.toHexString(i)
+ zeros.substring(s.length + (6-len)) + s
+ }
+
+ val mp = m >> 2
+ val lp = l | ((m & 0x3) << BITS)
+
+ if (h != 0) Integer.toHexString(h) + padHex(mp, 5) + padHex(lp, 6)
+ else if (mp != 0) Integer.toHexString(mp) + padHex(lp, 6)
+ else Integer.toHexString(lp)
+ }
+
+ def toOctalString: String = {
+ val zeros = "0000000" // 7 zeros
+ @inline def padOctal7(i: Int) = {
+ val s = Integer.toOctalString(i)
+ zeros.substring(s.length) + s
+ }
+
+ val lp = l & (MASK >> 1)
+ val mp = ((m & (MASK >> 2)) << 1) | (l >> (BITS - 1))
+ val hp = (h << 2) | (m >> (BITS - 2))
+
+ if (hp != 0) Integer.toOctalString(hp) + padOctal7(mp) + padOctal7(lp)
+ else if (mp != 0) Integer.toOctalString(mp) + padOctal7(lp)
+ else Integer.toOctalString(lp)
+ }
+
+ // Any API //
+
+ override def toString: String = {
+ if (isZero) "0"
+ // Check for MinValue, because its not negatable
+ else if (isMinValue) "-9223372036854775808"
+ else if (isNegative) "-" + (-x).toString
+ else {
+ val tenPow9 = TenPow9 // local copy to access CachedConstants only once
+
+ @tailrec
+ @inline
+ def toString0(v: RuntimeLong, acc: String): String =
+ if (v.isZero) acc
+ else {
+ val quotRem = v.divMod(tenPow9)
+ val quot = quotRem(0)
+ val rem = quotRem(1)
+
+ val digits = rem.toInt.toString
+ val zeroPrefix =
+ if (quot.isZero) ""
+ else "000000000".substring(digits.length) // (9 - digits.length) zeros
+
+ toString0(quot, zeroPrefix + digits + acc)
+ }
+
+ toString0(x, "")
+ }
+ }
+
+ def bitCount: Int =
+ Integer.bitCount(l) + Integer.bitCount(m) + Integer.bitCount(h)
+
+ // helpers //
+
+ @inline private def isZero = l == 0 && m == 0 && h == 0
+ @inline private def isMinValue = x.equals(MinValue)
+ @inline private def isNegative = (h & SIGN_BIT_VALUE) != 0
+ @inline private def abs = if (isNegative) -x else x
+
+ def signum: RuntimeLong =
+ if (isNegative) MinusOne else if (isZero) Zero else One
+
+ def numberOfLeadingZeros: Int =
+ if (h != 0) Integer.numberOfLeadingZeros(h) - (32 - BITS2)
+ else if (m != 0) Integer.numberOfLeadingZeros(m) - (32 - BITS) + (64 - BITS01)
+ else Integer.numberOfLeadingZeros(l) - (32 - BITS) + (64 - BITS)
+
+ def numberOfTrailingZeros: Int =
+ if (l != 0) Integer.numberOfTrailingZeros(l)
+ else if (m != 0) Integer.numberOfTrailingZeros(m) + BITS
+ else Integer.numberOfTrailingZeros(h) + BITS01
+
+ /** return log_2(x) if power of 2 or -1 otherwise */
+ private def powerOfTwo =
+ if (h == 0 && m == 0 && l != 0 && (l & (l - 1)) == 0)
+ Integer.numberOfTrailingZeros(l)
+ else if (h == 0 && m != 0 && l == 0 && (m & (m - 1)) == 0)
+ Integer.numberOfTrailingZeros(m) + BITS
+ else if (h != 0 && m == 0 && l == 0 && (h & (h - 1)) == 0)
+ Integer.numberOfTrailingZeros(h) + BITS01
+ else
+ -1
+
+ private def setBit(bit: Int) =
+ if (bit < BITS)
+ new RuntimeLong(l | (1 << bit), m, h)
+ else if (bit < BITS01)
+ new RuntimeLong(l, m | (1 << (bit - BITS)), h)
+ else
+ new RuntimeLong(l, m, h | (1 << (bit - BITS01)))
+
+ private def divMod(y: RuntimeLong): scala.scalajs.js.Array[RuntimeLong] = {
+ import scala.scalajs.js
+ if (y.isZero) throw new ArithmeticException("/ by zero")
+ else if (x.isZero) js.Array(Zero, Zero)
+ else if (y.isMinValue) {
+ // MinValue / MinValue == 1, rem = 0
+ // otherwise == 0, rem x
+ if (x.isMinValue) js.Array(One, Zero)
+ else js.Array(Zero, x)
+ } else {
+ val xNegative = x.isNegative
+ val yNegative = y.isNegative
+
+ val xMinValue = x.isMinValue
+
+ val pow = y.powerOfTwo
+ if (pow >= 0) {
+ if (xMinValue) {
+ val z = x >> pow
+ js.Array(if (yNegative) -z else z, Zero)
+ } else {
+ // x is not min value, so we can calculate absX
+ val absX = x.abs
+ val absZ = absX >> pow
+ val z = if (xNegative ^ yNegative) -absZ else absZ
+ val remAbs = absX.maskRight(pow)
+ val rem = if (xNegative) -remAbs else remAbs
+ js.Array(z, rem)
+ }
+ } else {
+ val absY = y.abs
+
+ val newX = {
+ if (xMinValue)
+ MaxValue
+ else {
+ val absX = x.abs
+ if (absX < absY)
+ return js.Array(Zero, x) // <-- ugly but fast
+ else
+ absX
+ }
+ }
+ divModHelper(newX, absY, xNegative, yNegative, xMinValue)
+ }
+ }
+ }
+
+ @inline
+ private def maskRight(bits: Int) = {
+ if (bits <= BITS)
+ new RuntimeLong(l & ((1 << bits) - 1), 0, 0)
+ else if (bits <= BITS01)
+ new RuntimeLong(l, m & ((1 << (bits - BITS)) - 1), 0)
+ else
+ new RuntimeLong(l, m, h & ((1 << (bits - BITS01)) - 1))
+ }
+
+ /**
+ * performs division in "normal cases"
+ * @param x absolute value of the numerator
+ * @param y absolute value of the denominator
+ * @param xNegative whether numerator was negative
+ * @param yNegative whether denominator was negative
+ * @param xMinValue whether numerator was Long.minValue
+ */
+ @inline
+ private def divModHelper(x: RuntimeLong, y: RuntimeLong,
+ xNegative: Boolean, yNegative: Boolean,
+ xMinValue: Boolean): scala.scalajs.js.Array[RuntimeLong] = {
+ import scala.scalajs.js
+
+ @inline
+ @tailrec
+ def divide0(shift: Int, yShift: RuntimeLong, curX: RuntimeLong,
+ quot: RuntimeLong): (RuntimeLong, RuntimeLong) =
+ if (shift < 0 || curX.isZero) (quot, curX) else {
+ val newX = curX - yShift
+ if (!newX.isNegative)
+ divide0(shift-1, yShift >> 1, newX, quot.setBit(shift))
+ else
+ divide0(shift-1, yShift >> 1, curX, quot)
+ }
+
+ val shift = y.numberOfLeadingZeros - x.numberOfLeadingZeros
+ val yShift = y << shift
+
+ val (absQuot, absRem) = divide0(shift, yShift, x, Zero)
+
+ val quot = if (xNegative ^ yNegative) -absQuot else absQuot
+ val rem =
+ if (xNegative && xMinValue) -absRem - One
+ else if (xNegative) -absRem
+ else absRem
+
+ js.Array(quot, rem)
+ }
+
+ /*
+ * Methods of scala.Long
+ * The following methods are only here to properly support reflective calls
+ * on longs. YOU MUST NOT USE THESE METHODS.
+ */
+
+ //protected def unary_~ : Long = ~toLong // already defined
+ //protected def unary_+ : Long = toLong // already defined
+ //protected def unary_- : Long = -toLong // already defined
+
+ //protected def <<(y: Int): Long = toLong << y // already defined
+ protected def <<(y: Long): Long = toLong << y
+ //protected def >>>(y: Int): Long = toLong >>> y // already defined
+ protected def >>>(y: Long): Long = toLong >>> y
+ //protected def >>(y: Int): Long = toLong >> y // already defined
+ protected def >>(y: Long): Long = toLong >> y
+
+ protected def ==(y: Byte): Boolean = toLong == y
+ protected def ==(y: Short): Boolean = toLong == y
+ protected def ==(y: Char): Boolean = toLong == y
+ protected def ==(y: Int): Boolean = toLong == y
+ protected def ==(y: Long): Boolean = toLong == y
+ protected def ==(y: Float): Boolean = toLong == y
+ protected def ==(y: Double): Boolean = toLong == y
+
+ protected def !=(y: Byte): Boolean = toLong != y
+ protected def !=(y: Short): Boolean = toLong != y
+ protected def !=(y: Char): Boolean = toLong != y
+ protected def !=(y: Int): Boolean = toLong != y
+ protected def !=(y: Long): Boolean = toLong != y
+ protected def !=(y: Float): Boolean = toLong != y
+ protected def !=(y: Double): Boolean = toLong != y
+
+ protected def <(y: Byte): Boolean = toLong < y
+ protected def <(y: Short): Boolean = toLong < y
+ protected def <(y: Char): Boolean = toLong < y
+ protected def <(y: Int): Boolean = toLong < y
+ protected def <(y: Long): Boolean = toLong < y
+ protected def <(y: Float): Boolean = toLong < y
+ protected def <(y: Double): Boolean = toLong < y
+
+ protected def <=(y: Byte): Boolean = toLong <= y
+ protected def <=(y: Short): Boolean = toLong <= y
+ protected def <=(y: Char): Boolean = toLong <= y
+ protected def <=(y: Int): Boolean = toLong <= y
+ protected def <=(y: Long): Boolean = toLong <= y
+ protected def <=(y: Float): Boolean = toLong <= y
+ protected def <=(y: Double): Boolean = toLong <= y
+
+ protected def >(y: Byte): Boolean = toLong > y
+ protected def >(y: Short): Boolean = toLong > y
+ protected def >(y: Char): Boolean = toLong > y
+ protected def >(y: Int): Boolean = toLong > y
+ protected def >(y: Long): Boolean = toLong > y
+ protected def >(y: Float): Boolean = toLong > y
+ protected def >(y: Double): Boolean = toLong > y
+
+ protected def >=(y: Byte): Boolean = toLong >= y
+ protected def >=(y: Short): Boolean = toLong >= y
+ protected def >=(y: Char): Boolean = toLong >= y
+ protected def >=(y: Int): Boolean = toLong >= y
+ protected def >=(y: Long): Boolean = toLong >= y
+ protected def >=(y: Float): Boolean = toLong >= y
+ protected def >=(y: Double): Boolean = toLong >= y
+
+ protected def |(y: Byte): Long = toLong | y
+ protected def |(y: Short): Long = toLong | y
+ protected def |(y: Char): Long = toLong | y
+ protected def |(y: Int): Long = toLong | y
+ protected def |(y: Long): Long = toLong | y
+
+ protected def &(y: Byte): Long = toLong & y
+ protected def &(y: Short): Long = toLong & y
+ protected def &(y: Char): Long = toLong & y
+ protected def &(y: Int): Long = toLong & y
+ protected def &(y: Long): Long = toLong & y
+
+ protected def ^(y: Byte): Long = toLong ^ y
+ protected def ^(y: Short): Long = toLong ^ y
+ protected def ^(y: Char): Long = toLong ^ y
+ protected def ^(y: Int): Long = toLong ^ y
+ protected def ^(y: Long): Long = toLong ^ y
+
+ protected def +(y: Byte): Long = toLong + y
+ protected def +(y: Short): Long = toLong + y
+ protected def +(y: Char): Long = toLong + y
+ protected def +(y: Int): Long = toLong + y
+ protected def +(y: Long): Long = toLong + y
+ protected def +(y: Float): Float = toLong + y
+ protected def +(y: Double): Double = toLong + y
+
+ protected def -(y: Byte): Long = toLong - y
+ protected def -(y: Short): Long = toLong - y
+ protected def -(y: Char): Long = toLong - y
+ protected def -(y: Int): Long = toLong - y
+ protected def -(y: Long): Long = toLong - y
+ protected def -(y: Float): Float = toLong - y
+ protected def -(y: Double): Double = toLong - y
+
+ protected def *(y: Byte): Long = toLong - y
+ protected def *(y: Short): Long = toLong - y
+ protected def *(y: Char): Long = toLong - y
+ protected def *(y: Int): Long = toLong - y
+ protected def *(y: Long): Long = toLong - y
+ protected def *(y: Float): Float = toLong - y
+ protected def *(y: Double): Double = toLong - y
+
+ protected def /(y: Byte): Long = toLong / y
+ protected def /(y: Short): Long = toLong / y
+ protected def /(y: Char): Long = toLong / y
+ protected def /(y: Int): Long = toLong / y
+ protected def /(y: Long): Long = toLong / y
+ protected def /(y: Float): Float = toLong / y
+ protected def /(y: Double): Double = toLong / y
+
+ protected def %(y: Byte): Long = toLong % y
+ protected def %(y: Short): Long = toLong % y
+ protected def %(y: Char): Long = toLong % y
+ protected def %(y: Int): Long = toLong % y
+ protected def %(y: Long): Long = toLong % y
+ protected def %(y: Float): Float = toLong % y
+ protected def %(y: Double): Double = toLong % y
+
+}
+
+object RuntimeLong {
+
+ /** number of relevant bits in each Long.l and Long.m */
+ private final val BITS = 22
+ /** number of relevant bits in Long.l and Long.m together */
+ private final val BITS01 = 2 * BITS
+ /** number of relevant bits in Long.h */
+ private final val BITS2 = 64 - BITS01
+ /** bitmask for Long.l and Long.m */
+ private final val MASK = (1 << BITS) - 1
+ /** bitmask for Long.h */
+ private final val MASK_2 = (1 << BITS2) - 1
+
+ private[runtime] final val SIGN_BIT = BITS2 - 1
+ private[runtime] final val SIGN_BIT_VALUE = 1 << SIGN_BIT
+ private[runtime] final val TWO_PWR_15_DBL = 0x8000 * 1.0
+ private[runtime] final val TWO_PWR_16_DBL = 0x10000 * 1.0
+ private[runtime] final val TWO_PWR_22_DBL = 0x400000 * 1.0
+ private[runtime] final val TWO_PWR_31_DBL = TWO_PWR_16_DBL * TWO_PWR_15_DBL
+ private[runtime] final val TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL
+ private[runtime] final val TWO_PWR_44_DBL = TWO_PWR_22_DBL * TWO_PWR_22_DBL
+ private[runtime] final val TWO_PWR_63_DBL = TWO_PWR_32_DBL * TWO_PWR_31_DBL
+
+ // Cache the instances for some "literals" used in this implementation
+ val Zero = new RuntimeLong( 0, 0, 0) // 0L
+ val One = new RuntimeLong( 1, 0, 0) // 1L
+ val MinusOne = new RuntimeLong( MASK, MASK, MASK_2) // -1L
+ val MinValue = new RuntimeLong( 0, 0, 524288) // Long.MinValue
+ val MaxValue = new RuntimeLong(4194303, 4194303, 524287) // Long.MaxValue
+ val TenPow9 = new RuntimeLong(1755648, 238, 0) // 1000000000L with 9 zeros
+
+ def fromDouble(value: Double): RuntimeLong = {
+ if (java.lang.Double.isNaN(value)) Zero
+ else if (value < -TWO_PWR_63_DBL) MinValue
+ else if (value >= TWO_PWR_63_DBL) MaxValue
+ else if (value < 0) -fromDouble(-value)
+ else {
+ var acc = value
+ val a2 = if (acc >= TWO_PWR_44_DBL) (acc / TWO_PWR_44_DBL).toInt else 0
+ acc -= a2 * TWO_PWR_44_DBL
+ val a1 = if (acc >= TWO_PWR_22_DBL) (acc / TWO_PWR_22_DBL).toInt else 0
+ acc -= a1 * TWO_PWR_22_DBL
+ val a0 = acc.toInt
+ new RuntimeLong(a0, a1, a2)
+ }
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala
new file mode 100644
index 0000000..f65b1b5
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/RuntimeString.scala
@@ -0,0 +1,338 @@
+package scala.scalajs.runtime
+
+import scala.scalajs.js
+import scala.scalajs.js.prim.{String => jsString}
+
+import java.nio.ByteBuffer
+import java.nio.charset.Charset
+import java.util.regex._
+
+/** Implementation for methods on java.lang.String.
+ *
+ * Strings are represented at runtime by JavaScript strings, but they have
+ * a lot of methods. The compiler forwards methods on java.lang.String to the
+ * methods in the object, passing `this` as the first argument, that we
+ * consistently call `thiz` in this object.
+ */
+private[runtime] object RuntimeString {
+
+ @inline
+ def charAt(thiz: String, index: Int): Char =
+ (thiz: jsString).charCodeAt(index).asInstanceOf[Int].toChar
+
+ def codePointAt(thiz: String, index: Int): Int = {
+ val high = thiz.charAt(index)
+ if (index+1 < thiz.length) {
+ val low = thiz.charAt(index+1)
+ if (Character.isSurrogatePair(high, low))
+ Character.toCodePoint(high, low)
+ else
+ high.toInt
+ } else {
+ high.toInt
+ }
+ }
+
+ def hashCode(thiz: String): Int = {
+ var res = 0
+ var mul = 1 // holds pow(31, length-i-1)
+ var i = thiz.length-1
+ while (i >= 0) {
+ res += thiz.charAt(i) * mul
+ mul *= 31
+ i -= 1
+ }
+ res
+ }
+
+ @inline
+ def compareTo(thiz: String, anotherString: String): Int = {
+ if (thiz.equals(anotherString)) 0
+ else if ((thiz: jsString) < (anotherString: jsString)) -1
+ else 1
+ }
+
+ def compareToIgnoreCase(thiz: String, str: String): Int =
+ thiz.toLowerCase().compareTo(str.toLowerCase())
+
+ @inline
+ def equalsIgnoreCase(thiz: String, that: String): Boolean =
+ thiz.toLowerCase() == (if (that == null) null else that.toLowerCase())
+
+ @inline
+ def concat(thiz: String, s: String): String =
+ checkNull(thiz) + s
+
+ @inline
+ def contains(thiz: String, s: CharSequence): Boolean =
+ thiz.indexOf(s.toString) != -1
+
+ def endsWith(thiz: String, suffix: String): Boolean =
+ ((thiz: jsString).substring(thiz.length - suffix.length): String) == suffix
+
+ def getBytes(thiz: String): Array[Byte] =
+ thiz.getBytes(Charset.defaultCharset)
+
+ def getBytes(thiz: String, charsetName: String): Array[Byte] =
+ thiz.getBytes(Charset.forName(charsetName))
+
+ def getBytes(thiz: String, charset: Charset): Array[Byte] =
+ charset.encode(thiz).array()
+
+ def getChars(thiz: String, srcBegin: Int, srcEnd: Int,
+ dst: Array[Char], dstBegin: Int): Unit = {
+ if (srcEnd > thiz.length || // first test uses thiz
+ srcBegin < 0 ||
+ srcEnd < 0 ||
+ srcBegin > srcEnd) {
+ throw new StringIndexOutOfBoundsException("Index out of Bound")
+ }
+
+ val offset = dstBegin - srcBegin
+ var i = srcBegin
+ while (i < srcEnd) {
+ dst(i+offset) = thiz.charAt(i)
+ i += 1
+ }
+ }
+
+ def indexOf(thiz: String, ch: Int): Int =
+ thiz.indexOf(fromCodePoint(ch))
+
+ def indexOf(thiz: String, ch: Int, fromIndex: Int): Int =
+ thiz.indexOf(fromCodePoint(ch), fromIndex)
+
+ @inline
+ def indexOf(thiz: String, str: String): Int =
+ (thiz: jsString).indexOf(str).asInstanceOf[Int]
+
+ @inline
+ def indexOf(thiz: String, str: String, fromIndex: Int): Int =
+ (thiz: jsString).indexOf(str, fromIndex).asInstanceOf[Int]
+
+ /* Just returning this string is a valid implementation for `intern` in
+ * JavaScript, since strings are primitive values. Therefore, value equality
+ * and reference equality is the same.
+ */
+ @inline
+ def intern(thiz: String): String =
+ checkNull(thiz)
+
+ @inline
+ def isEmpty(thiz: String): Boolean =
+ checkNull(thiz) == ""
+
+ def lastIndexOf(thiz: String, ch: Int): Int =
+ thiz.lastIndexOf(fromCodePoint(ch))
+
+ def lastIndexOf(thiz: String, ch: Int, fromIndex: Int): Int =
+ thiz.lastIndexOf(fromCodePoint(ch), fromIndex)
+
+ @inline
+ def lastIndexOf(thiz: String, str: String): Int =
+ (thiz: jsString).lastIndexOf(str).asInstanceOf[Int]
+
+ @inline
+ def lastIndexOf(thiz: String, str: String, fromIndex: Int): Int =
+ (thiz: jsString).lastIndexOf(str, fromIndex).asInstanceOf[Int]
+
+ @inline
+ def length(thiz: String): Int =
+ (thiz: jsString).length.asInstanceOf[Int]
+
+ @inline
+ def matches(thiz: String, regex: String): Boolean = {
+ checkNull(thiz)
+ Pattern.matches(regex, thiz)
+ }
+
+ @inline
+ def replace(thiz: String, oldChar: Char, newChar: Char): String =
+ (thiz: String).replace(oldChar.toString, newChar.toString)
+
+ @inline
+ def replace(thiz: String, target: CharSequence, replacement: CharSequence): String =
+ (thiz: jsString).split(target.toString).join(replacement.toString)
+
+ def replaceAll(thiz: String, regex: String, replacement: String): String = {
+ checkNull(thiz)
+ Pattern.compile(regex).matcher(thiz).replaceAll(replacement)
+ }
+
+ def replaceFirst(thiz: String, regex: String, replacement: String): String = {
+ checkNull(thiz)
+ Pattern.compile(regex).matcher(thiz).replaceFirst(replacement)
+ }
+
+ @inline
+ def split(thiz: String, regex: String): Array[String] =
+ thiz.split(regex, 0)
+
+ def split(thiz: String, regex: String, limit: Int): Array[String] = {
+ checkNull(thiz)
+ Pattern.compile(regex).split(thiz, limit)
+ }
+
+ @inline
+ def startsWith(thiz: String, prefix: String): Boolean =
+ thiz.startsWith(prefix, 0)
+
+ @inline
+ def startsWith(thiz: String, prefix: String, toffset: Int): Boolean =
+ ((thiz: jsString).substring(toffset, prefix.length): String) == prefix
+
+ @inline
+ def subSequence(thiz: String, beginIndex: Int, endIndex: Int): CharSequence =
+ thiz.substring(beginIndex, endIndex)
+
+ @inline
+ def substring(thiz: String, beginIndex: Int): String =
+ (thiz: jsString).substring(beginIndex)
+
+ @inline
+ def substring(thiz: String, beginIndex: Int, endIndex: Int): String =
+ (thiz: jsString).substring(beginIndex, endIndex)
+
+ def toCharArray(thiz: String): Array[Char] = {
+ val length = thiz.length
+ val result = new Array[Char](length)
+ var i = 0
+ while (i < length) {
+ result(i) = thiz.charAt(i)
+ i += 1
+ }
+ result
+ }
+
+ @inline
+ def toLowerCase(thiz: String): String =
+ (thiz: jsString).toLowerCase()
+
+ @inline
+ def toUpperCase(thiz: String): String =
+ (thiz: jsString).toUpperCase()
+
+ @inline
+ def trim(thiz: String): String =
+ (thiz: jsString).trim()
+
+ // Constructors
+
+ def newString(): String = ""
+
+ def newString(value: Array[Char]): String =
+ newString(value, 0, value.length)
+
+ def newString(value: Array[Char], offset: Int, count: Int): String = {
+ val end = offset + count
+ if (offset < 0 || end < offset || end > value.length)
+ throw new StringIndexOutOfBoundsException
+
+ val charCodes = new js.Array[Int]
+ var i = offset
+ while (i != end) {
+ charCodes += value(i).toInt
+ i += 1
+ }
+ js.String.fromCharCode(charCodes: _*)
+ }
+
+ def newString(bytes: Array[Byte]): String =
+ newString(bytes, Charset.defaultCharset)
+
+ def newString(bytes: Array[Byte], charsetName: String): String =
+ newString(bytes, Charset.forName(charsetName))
+
+ def newString(bytes: Array[Byte], charset: Charset): String =
+ charset.decode(ByteBuffer.wrap(bytes)).toString()
+
+ def newString(bytes: Array[Byte], offset: Int, length: Int): String =
+ newString(bytes, offset, length, Charset.defaultCharset)
+
+ def newString(bytes: Array[Byte], offset: Int, length: Int,
+ charsetName: String): String =
+ newString(bytes, offset, length, Charset.forName(charsetName))
+
+ def newString(bytes: Array[Byte], offset: Int, length: Int,
+ charset: Charset): String =
+ charset.decode(ByteBuffer.wrap(bytes, offset, length)).toString()
+
+ def newString(codePoints: Array[Int], offset: Int, count: Int): String = {
+ val end = offset + count
+ if (offset < 0 || end < offset || end > codePoints.length)
+ throw new StringIndexOutOfBoundsException
+
+ val charCodes = new js.Array[Int]
+ var i = offset
+ while (i != end) {
+ val cp = codePoints(i)
+ if (cp < 0 || cp > Character.MAX_CODE_POINT)
+ throw new IllegalArgumentException
+ if (cp <= Character.MAX_VALUE) {
+ charCodes += cp
+ } else {
+ val offsetCp = cp - 0x10000
+ charCodes += (offsetCp >> 10) | 0xd800
+ charCodes += (offsetCp & 0x3ff) | 0xdc00
+ }
+ i += 1
+ }
+ js.String.fromCharCode(charCodes: _*)
+ }
+
+ def newString(original: String): String =
+ checkNull(original)
+
+ def newString(buffer: java.lang.StringBuffer): String =
+ buffer.toString
+
+ def newString(builder: java.lang.StringBuilder): String =
+ builder.toString
+
+ // Static methods (aka methods on the companion object)
+
+ def valueOf(value: Boolean): String = value.toString()
+ def valueOf(value: Char): String = value.toString()
+ def valueOf(value: Byte): String = value.toString()
+ def valueOf(value: Short): String = value.toString()
+ def valueOf(value: Int): String = value.toString()
+ def valueOf(value: Long): String = value.toString()
+ def valueOf(value: Float): String = value.toString()
+ def valueOf(value: Double): String = value.toString()
+
+ def valueOf(value: Object): String =
+ if (value eq null) "null" else value.toString()
+
+ def valueOf(data: Array[Char]): String =
+ valueOf(data, 0, data.length)
+
+ def valueOf(data: Array[Char], offset: Int, count: Int): String =
+ newString(data, offset, count)
+
+ def format(format: String, args: Array[AnyRef]): String = {
+ val frm = new java.util.Formatter()
+ val res = frm.format(format, args: _*).toString()
+ frm.close()
+ res
+ }
+
+ // Helpers
+
+ @inline
+ private def checkNull(s: String): s.type =
+ if (s == null) throw new NullPointerException()
+ else s
+
+ private def fromCodePoint(codePoint: Int): String = {
+ if ((codePoint & ~Character.MAX_VALUE) == 0)
+ js.String.fromCharCode(codePoint)
+ else if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT)
+ throw new IllegalArgumentException
+ else {
+ val offsetCp = codePoint - 0x10000
+ js.String.fromCharCode(
+ (offsetCp >> 10) | 0xd800, (offsetCp & 0x3ff) | 0xdc00)
+ }
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala
new file mode 100644
index 0000000..a9e2c00
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/StackTrace.scala
@@ -0,0 +1,507 @@
+package scala.scalajs.runtime
+
+import scala.annotation.tailrec
+
+import scala.scalajs.js
+import scala.scalajs.js.prim.{String => jsString}
+
+/** Conversions of JavaScript stack traces to Java stack traces.
+ */
+object StackTrace {
+
+ /* !!! Note that in this unit, we go to great lengths *not* to use anything
+ * from the Scala collections library.
+ *
+ * This minimizes the risk of runtime errors during the process of decoding
+ * errors, which would be very bad if it happened.
+ */
+
+ /** Captures browser-specific state recording the current stack trace.
+ * The state is stored as a magic field of the throwable, and will be used
+ * by `extract()` to create an Array[StackTraceElement].
+ */
+ def captureState(throwable: Throwable): Unit = {
+ captureState(throwable, createException())
+ }
+
+ /** Creates a JS Error with the current stack trace state. */
+ private def createException(): Any = {
+ try {
+ this.asInstanceOf[js.Dynamic].undef() // it does not exist, that's the point
+ } catch {
+ case js.JavaScriptException(e) => e
+ }
+ }
+
+ /** Captures browser-specific state recording the stack trace of a JS error.
+ * The state is stored as a magic field of the throwable, and will be used
+ * by `extract()` to create an Array[StackTraceElement].
+ */
+ def captureState(throwable: Throwable, e: Any): Unit = {
+ throwable.asInstanceOf[js.Dynamic].stackdata = e.asInstanceOf[js.Any]
+ }
+
+ /** Tests whether we're running under Rhino. */
+ private lazy val isRhino: Boolean = {
+ try {
+ js.Dynamic.global.Packages.org.mozilla.javascript.JavaScriptException
+ true
+ } catch {
+ case js.JavaScriptException(_) => false
+ }
+ }
+
+ /** Extracts a throwable's stack trace from captured browser-specific state.
+ * If no stack trace state has been recorded, or if the state cannot be
+ * analyzed in meaningful way (because we don't know the browser), an
+ * empty array is returned.
+ */
+ def extract(throwable: Throwable): Array[StackTraceElement] =
+ extract(throwable.asInstanceOf[js.Dynamic].stackdata)
+
+ /** Extracts a stack trace from captured browser-specific stackdata.
+ * If no stack trace state has been recorded, or if the state cannot be
+ * analyzed in meaningful way (because we don't know the browser), an
+ * empty array is returned.
+ */
+ def extract(stackdata: js.Dynamic): Array[StackTraceElement] = {
+ val lines = normalizeStackTraceLines(stackdata)
+ normalizedLinesToStackTrace(lines)
+ }
+
+ /* Converts an array of frame entries in normalized form to a stack trace.
+ * Each line must have either the format
+ * <functionName>@<fileName>:<lineNumber>:<columnNumber>
+ * or
+ * <functionName>@<fileName>:<lineNumber>
+ * For some reason, on some browsers, we sometimes have empty lines too.
+ * In the rest of the function, we convert the non-empty lines into
+ * StackTraceElements.
+ */
+ private def normalizedLinesToStackTrace(
+ lines: js.Array[jsString]): Array[StackTraceElement] = {
+ val NormalizedFrameLine = """^([^\@]*)\@(.*):([0-9]+)$""".re
+ val NormalizedFrameLineWithColumn = """^([^\@]*)\@(.*):([0-9]+):([0-9]+)$""".re
+
+ val trace = new js.Array[JSStackTraceElem]
+ var i = 0
+ while (i < lines.length) {
+ val line = lines(i)
+ if (!line.isEmpty) {
+ val mtch1 = NormalizedFrameLineWithColumn.exec(line)
+ if (mtch1 ne null) {
+ val (className, methodName) = extractClassMethod(mtch1(1).get)
+ trace.push(JSStackTraceElem(className, methodName, mtch1(2).get,
+ mtch1(3).get.toInt, mtch1(4).get.toInt))
+ } else {
+ val mtch2 = NormalizedFrameLine.exec(line)
+ if (mtch2 ne null) {
+ val (className, methodName) = extractClassMethod(mtch2(1).get)
+ trace.push(JSStackTraceElem(className,
+ methodName, mtch2(2).get, mtch2(3).get.toInt))
+ } else {
+ // just in case
+ trace.push(JSStackTraceElem("<jscode>", line, null, -1))
+ }
+ }
+ }
+ i += 1
+ }
+
+ // Map stack trace through environment (if supported)
+ val envInfo = environmentInfo
+ val hasMapper = envInfo != js.undefined && envInfo != null &&
+ js.typeOf(envInfo.sourceMapper) == "function"
+
+ val mappedTrace =
+ if (hasMapper)
+ envInfo.sourceMapper(trace).asInstanceOf[js.Array[JSStackTraceElem]]
+ else
+ trace
+
+ // Convert JS objects to java.lang.StackTraceElements
+ // While loop due to space concerns
+ val result = new Array[StackTraceElement](mappedTrace.length)
+
+ i = 0
+ while (i < mappedTrace.length) {
+ val jsSte = mappedTrace(i)
+ val ste = new StackTraceElement(jsSte.declaringClass, jsSte.methodName,
+ jsSte.fileName, jsSte.lineNumber)
+
+ jsSte.columnNumber foreach { cn =>
+ // Store column in magic field
+ ste.asInstanceOf[js.Dynamic].columnNumber = cn
+ }
+
+ result(i) = ste
+ i += 1
+ }
+
+ result
+ }
+
+ /** Tries and extract the class name and method from the JS function name.
+ * The recognized patterns are
+ * ScalaJS.c.<encoded class name>.prototype.<encoded method name>
+ * ScalaJS.c.<encoded class name>.<encoded method name>
+ * ScalaJS.i.<encoded trait impl name>__<encoded method name>
+ * ScalaJS.m.<encoded module name>
+ * When the function name is none of those, the pair
+ * ("<jscode>", functionName)
+ * is returned, which will instruct StackTraceElement.toString() to only
+ * display the function name.
+ */
+ private def extractClassMethod(functionName: String): (String, String) = {
+ val PatC = """^ScalaJS\.c\.([^\.]+)(?:\.prototype)?\.([^\.]+)$""".re
+ val PatI = """^(?:Object\.)?ScalaJS\.i\.((?:_[^_]|[^_])+)__([^\.]+)$""".re
+ val PatM = """^(?:Object\.)?ScalaJS\.m\.([^.\.]+)$""".re
+
+ var isModule = false
+ var mtch = PatC.exec(functionName)
+ if (mtch eq null) {
+ mtch = PatI.exec(functionName)
+ if (mtch eq null) {
+ mtch = PatM.exec(functionName)
+ isModule = true
+ }
+ }
+
+ if (mtch ne null) {
+ val className = decodeClassName(mtch(1).get + (if (isModule) "$" else ""))
+ val methodName = if (isModule)
+ "<clinit>" // that's how it would be reported on the JVM
+ else
+ decodeMethodName(mtch(2).get)
+ (className, methodName)
+ } else {
+ ("<jscode>", functionName)
+ }
+ }
+
+ // decodeClassName -----------------------------------------------------------
+
+ // !!! Duplicate logic: this code must be in sync with ir.Definitions
+
+ private def decodeClassName(encodedName: String): String = {
+ val encoded =
+ if (encodedName.charAt(0) == '$') encodedName.substring(1)
+ else encodedName
+ val base = if (decompressedClasses.hasOwnProperty(encoded)) {
+ decompressedClasses(encoded)
+ } else {
+ @tailrec
+ def loop(i: Int): String = {
+ if (i < compressedPrefixes.length) {
+ val prefix = compressedPrefixes(i)
+ if (encoded.startsWith(prefix))
+ decompressedPrefixes(prefix) + encoded.substring(prefix.length)
+ else
+ loop(i+1)
+ } else {
+ // no prefix matches
+ if (encoded.startsWith("L")) encoded.substring(1)
+ else encoded // just in case
+ }
+ }
+ loop(0)
+ }
+ base.replace("_", ".").replace("$und", "_")
+ }
+
+ private val decompressedClasses: js.Dictionary[String] = {
+ val dict = js.Dynamic.literal(
+ O = "java_lang_Object",
+ T = "java_lang_String",
+ V = "scala_Unit",
+ Z = "scala_Boolean",
+ C = "scala_Char",
+ B = "scala_Byte",
+ S = "scala_Short",
+ I = "scala_Int",
+ J = "scala_Long",
+ F = "scala_Float",
+ D = "scala_Double"
+ ).asInstanceOf[js.Dictionary[String]]
+
+ var index = 0
+ while (index <= 22) {
+ if (index >= 2)
+ dict("T"+index) = "scala_Tuple"+index
+ dict("F"+index) = "scala_Function"+index
+ index += 1
+ }
+
+ dict
+ }
+
+ private val decompressedPrefixes = js.Dynamic.literal(
+ sjsr_ = "scala_scalajs_runtime_",
+ sjs_ = "scala_scalajs_",
+ sci_ = "scala_collection_immutable_",
+ scm_ = "scala_collection_mutable_",
+ scg_ = "scala_collection_generic_",
+ sc_ = "scala_collection_",
+ sr_ = "scala_runtime_",
+ s_ = "scala_",
+ jl_ = "java_lang_",
+ ju_ = "java_util_"
+ ).asInstanceOf[js.Dictionary[String]]
+
+ private val compressedPrefixes = js.Object.keys(decompressedPrefixes)
+
+ // end of decodeClassName ----------------------------------------------------
+
+ private def decodeMethodName(encodedName: String): String = {
+ if (encodedName startsWith "init___") {
+ "<init>"
+ } else {
+ val methodNameLen = encodedName.indexOf("__")
+ if (methodNameLen < 0) encodedName
+ else encodedName.substring(0, methodNameLen)
+ }
+ }
+
+ private implicit class StringRE(val s: String) extends AnyVal {
+ def re: js.RegExp = new js.RegExp(s)
+ def re(mods: String): js.RegExp = new js.RegExp(s, mods)
+ }
+
+ /* ---------------------------------------------------------------------------
+ * Start copy-paste-translate from stacktrace.js
+ *
+ * From here on, most of the code has been copied from
+ * https://github.com/stacktracejs/stacktrace.js
+ * and translated to Scala.js almost literally, with some adaptations.
+ *
+ * Most comments -and lack thereof- have also been copied therefrom.
+ */
+
+ private def normalizeStackTraceLines(e: js.Dynamic): js.Array[jsString] = {
+ /* You would think that we could test once and for all which "mode" to
+ * adopt. But the format can actually differ for different exceptions
+ * on some browsers, e.g., exceptions in Chrome there may or may not have
+ * arguments or stack.
+ */
+ if (!e) {
+ js.Array[jsString]()
+ } else if (isRhino) {
+ extractRhino(e)
+ } else if (!(!e.arguments) && !(!e.stack)) {
+ extractChrome(e)
+ } else if (!(!e.stack) && !(!e.sourceURL)) {
+ extractSafari(e)
+ } else if (!(!e.stack) && !(!e.number)) {
+ extractIE(e)
+ } else if (!(!e.stack) && !(!e.fileName)) {
+ extractFirefox(e)
+ } else if (!(!e.message) && !(!e.`opera#sourceloc`)) {
+ // e.message.indexOf("Backtrace:") > -1 -> opera9
+ // 'opera#sourceloc' in e -> opera9, opera10a
+ // !e.stacktrace -> opera9
+ if (!e.stacktrace) {
+ extractOpera9(e) // use e.message
+ } else if ((e.message.indexOf("\n") > -1) &&
+ (e.message.split("\n").length > e.stacktrace.split("\n").length)) {
+ // e.message may have more stack entries than e.stacktrace
+ extractOpera9(e) // use e.message
+ } else {
+ extractOpera10a(e) // use e.stacktrace
+ }
+ } else if (!(!e.message) && !(!e.stack) && !(!e.stacktrace)) {
+ // e.stacktrace && e.stack -> opera10b
+ if (e.stacktrace.indexOf("called from line") < 0) {
+ extractOpera10b(e)
+ } else {
+ extractOpera11(e)
+ }
+ } else if (!(!e.stack) && !e.fileName) {
+ /* Chrome 27 does not have e.arguments as earlier versions,
+ * but still does not have e.fileName as Firefox */
+ extractChrome(e)
+ } else {
+ extractOther(e)
+ }
+ }
+
+ private def extractRhino(e: js.Dynamic): js.Array[jsString] = {
+ (e.stack.asInstanceOf[js.UndefOr[jsString]]).getOrElse[jsString]("")
+ .replace("""^\s+at\s+""".re("gm"), "") // remove 'at' and indentation
+ .replace("""^(.+?)(?: \((.+)\))?$""".re("gm"), "$2@$1")
+ .replace("""\r\n?""".re("gm"), "\n") // Rhino has platform-dependent EOL's
+ .split("\n")
+ }
+
+ private def extractChrome(e: js.Dynamic): js.Array[jsString] = {
+ (e.stack.asInstanceOf[jsString] + "\n")
+ .replace("""^[\s\S]+?\s+at\s+""".re, " at ") // remove message
+ .replace("""^\s+(at eval )?at\s+""".re("gm"), "") // remove 'at' and indentation
+ .replace("""^([^\(]+?)([\n])""".re("gm"), "{anonymous}() ($1)$2") // see note
+ .replace("""^Object.<anonymous>\s*\(([^\)]+)\)""".re("gm"), "{anonymous}() ($1)")
+ .replace("""^([^\(]+|\{anonymous\}\(\)) \((.+)\)$""".re("gm"), "$1@$2")
+ .split("\n")
+ .jsSlice(0, -1)
+
+ /* Note: there was a $ next to the \n here in the original code, but it
+ * chokes with method names with $'s, which are generated often by Scala.js.
+ */
+ }
+
+ private def extractFirefox(e: js.Dynamic): js.Array[jsString] = {
+ (e.stack.asInstanceOf[jsString])
+ .replace("""(?:\n@:0)?\s+$""".re("m"), "")
+ .replace("""^(?:\((\S*)\))?@""".re("gm"), "{anonymous}($1)@")
+ .split("\n")
+ }
+
+ private def extractIE(e: js.Dynamic): js.Array[jsString] = {
+ (e.stack.asInstanceOf[jsString])
+ .replace("""^\s*at\s+(.*)$""".re("gm"), "$1")
+ .replace("""^Anonymous function\s+""".re("gm"), "{anonymous}() ")
+ .replace("""^([^\(]+|\{anonymous\}\(\))\s+\((.+)\)$""".re("gm"), "$1@$2")
+ .split("\n")
+ .jsSlice(1)
+ }
+
+ private def extractSafari(e: js.Dynamic): js.Array[jsString] = {
+ (e.stack.asInstanceOf[jsString])
+ .replace("""\[native code\]\n""".re("m"), "")
+ .replace("""^(?=\w+Error\:).*$\n""".re("m"), "")
+ .replace("""^@""".re("gm"), "{anonymous}()@")
+ .split("\n")
+ }
+
+ private def extractOpera9(e: js.Dynamic): js.Array[jsString] = {
+ // " Line 43 of linked script file://localhost/G:/js/stacktrace.js\n"
+ // " Line 7 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html\n"
+ val lineRE = """Line (\d+).*script (?:in )?(\S+)""".re("i")
+ val lines = (e.message.asInstanceOf[jsString]).split("\n")
+ val result = new js.Array[jsString]
+
+ var i = 2
+ val len = lines.length.toInt
+ while (i < len) {
+ val mtch = lineRE.exec(lines(i))
+ if (mtch ne null) {
+ result.push("{anonymous}()@" + mtch(2).get + ":" + mtch(1).get
+ /* + " -- " + lines(i+1).replace("""^\s+""".re, "") */)
+ }
+ i += 2
+ }
+
+ result
+ }
+
+ private def extractOpera10a(e: js.Dynamic): js.Array[jsString] = {
+ // " Line 27 of linked script file://localhost/G:/js/stacktrace.js\n"
+ // " Line 11 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html: In function foo\n"
+ val lineRE = """Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$""".re("i")
+ val lines = (e.stacktrace.asInstanceOf[jsString]).split("\n")
+ val result = new js.Array[jsString]
+
+ var i = 0
+ val len = lines.length.toInt
+ while (i < len) {
+ val mtch = lineRE.exec(lines(i))
+ if (mtch ne null) {
+ val fnName = mtch(3).getOrElse("{anonymous}")
+ result.push(fnName + "()@" + mtch(2).get + ":" + mtch(1).get
+ /* + " -- " + lines(i+1).replace("""^\s+""".re, "")*/)
+ }
+ i += 2
+ }
+
+ result
+ }
+
+ private def extractOpera10b(e: js.Dynamic): js.Array[jsString] = {
+ // "<anonymous function: run>([arguments not available])@file://localhost/G:/js/stacktrace.js:27\n" +
+ // "printStackTrace([arguments not available])@file://localhost/G:/js/stacktrace.js:18\n" +
+ // "@file://localhost/G:/js/test/functional/testcase1.html:15"
+ val lineRE = """^(.*)@(.+):(\d+)$""".re
+ val lines = (e.stacktrace.asInstanceOf[jsString]).split("\n")
+ val result = new js.Array[jsString]
+
+ var i = 0
+ val len = lines.length.toInt
+ while (i < len) {
+ val mtch = lineRE.exec(lines(i))
+ if (mtch ne null) {
+ val fnName = mtch(1).fold("global code")(_ + "()")
+ result.push(fnName + "@" + mtch(2).get + ":" + mtch(3).get)
+ }
+ i += 1
+ }
+
+ result
+ }
+
+ private def extractOpera11(e: js.Dynamic): js.Array[jsString] = {
+ val lineRE = """^.*line (\d+), column (\d+)(?: in (.+))? in (\S+):$""".re
+ val lines = (e.stacktrace.asInstanceOf[jsString]).split("\n")
+ val result = new js.Array[jsString]
+
+ var i = 0
+ val len = lines.length.toInt
+ while (i < len) {
+ val mtch = lineRE.exec(lines(i))
+ if (mtch ne null) {
+ val location = mtch(4).get + ":" + mtch(1).get + ":" + mtch(2).get
+ val fnName0 = mtch(2).getOrElse("global code")
+ val fnName = (fnName0: jsString)
+ .replace("""<anonymous function: (\S+)>""".re, "$1")
+ .replace("""<anonymous function>""".re, "{anonymous}")
+ result.push(fnName + "@" + location
+ /* + " -- " + lines(i+1).replace("""^\s+""".re, "")*/)
+ }
+ i += 2
+ }
+
+ result
+ }
+
+ private def extractOther(e: js.Dynamic): js.Array[jsString] = {
+ js.Array()
+ }
+
+ /* End copy-paste-translate from stacktrace.js
+ * ---------------------------------------------------------------------------
+ */
+
+ trait JSStackTraceElem extends js.Object {
+ var declaringClass: String = js.native
+ var methodName: String = js.native
+ var fileName: String = js.native
+ /** 1-based line number */
+ var lineNumber: Int = js.native
+ /** 1-based optional columnNumber */
+ var columnNumber: js.UndefOr[Int] = js.native
+ }
+
+ object JSStackTraceElem {
+ @inline
+ def apply(declaringClass: String, methodName: String,
+ fileName: String, lineNumber: Int,
+ columnNumber: js.UndefOr[Int] = js.undefined): JSStackTraceElem = {
+ js.Dynamic.literal(
+ declaringClass = declaringClass,
+ methodName = methodName,
+ fileName = fileName,
+ lineNumber = lineNumber,
+ columnNumber = columnNumber
+ ).asInstanceOf[JSStackTraceElem]
+ }
+ }
+
+ /**
+ * Implicit class to access magic column element created in STE
+ */
+ implicit class ColumnStackTraceElement(ste: StackTraceElement) {
+ def getColumnNumber: Int = {
+ val num = ste.asInstanceOf[js.Dynamic].columnNumber
+ if (!(!num)) num.asInstanceOf[Int]
+ else -1 // Not very Scala-ish, but consistent with StackTraceElemnt
+ }
+ }
+
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala
new file mode 100644
index 0000000..b06ed7d
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/UndefinedBehaviorError.scala
@@ -0,0 +1,23 @@
+package scala.scalajs.runtime
+
+import scala.util.control.ControlThrowable
+
+/** Error thrown when an undefined behavior in Fatal mode has been detected.
+ * This error should never be caught. It indicates a severe programming bug.
+ * In Unchecked mode, the program may behave arbitrarily.
+ * The `cause` is set to the exception that would have been thrown if the
+ * given behavior was in Compliant mode.
+ * If your program relies on the proper kind of exception being thrown, as if
+ * running on the JVM, you should set the appropriate behavior to Compliant.
+ * Note that this will have (potentially major) performance impacts.
+ */
+class UndefinedBehaviorError(message: String, cause: Throwable)
+ extends java.lang.Error(message, cause) with ControlThrowable {
+
+ def this(cause: Throwable) =
+ this("An undefined behavior was detected" +
+ (if (cause == null) "" else ": "+cause.getMessage), cause)
+
+ override def fillInStackTrace(): Throwable =
+ super[Error].fillInStackTrace()
+}
diff --git a/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/package.scala b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/package.scala
new file mode 100644
index 0000000..59c774c
--- /dev/null
+++ b/examples/scala-js/library/src/main/scala/scala/scalajs/runtime/package.scala
@@ -0,0 +1,176 @@
+package scala.scalajs
+
+import scala.annotation.tailrec
+
+import scala.collection.GenTraversableOnce
+
+package object runtime {
+
+ def wrapJavaScriptException(e: Any): Throwable = e match {
+ case e: Throwable => e
+ case _ => js.JavaScriptException(e)
+ }
+
+ def unwrapJavaScriptException(th: Throwable): Any = th match {
+ case js.JavaScriptException(e) => e
+ case _ => th
+ }
+
+ def cloneObject(from: js.Object): js.Object = {
+ val ctor = ({ (self: js.Dictionary[js.Any], from: js.Dictionary[js.Any]) =>
+ for (key <- from.keys)
+ self(key) = from(key)
+ }: js.ThisFunction).asInstanceOf[js.Dynamic]
+ ctor.prototype = js.Object.getPrototypeOf(from)
+ js.Dynamic.newInstance(ctor)(from)
+ }
+
+ @inline final def genTraversableOnce2jsArray[A](
+ col: GenTraversableOnce[A]): js.Array[A] = {
+ col match {
+ case col: js.ArrayOps[A] => col.result()
+ case col: js.WrappedArray[A] => col.array
+ case _ =>
+ val result = new js.Array[A]
+ col.foreach(x => result.push(x))
+ result
+ }
+ }
+
+ /** Instantiates a JS object with variadic arguments to the constructor. */
+ def newJSObjectWithVarargs(ctor: js.Dynamic, args: js.Array[_]): js.Any = {
+ // Not really "possible" in JavaScript, so we emulate what it would be.
+ val c = ((() => ()): js.Function).asInstanceOf[js.Dynamic]
+ c.prototype = ctor.prototype
+ val instance = js.Dynamic.newInstance(c)()
+ val result = ctor.applyDynamic("apply")(instance, args)
+ (result: js.Any) match {
+ case _:js.prim.Undefined | _:js.prim.Number | _:js.prim.Boolean |
+ _:js.prim.String | null =>
+ instance
+ case _ =>
+ result
+ }
+ }
+
+ /** Returns an array of the enumerable properties in an object's prototype
+ * chain.
+ *
+ * This is the implementation of [[js.Object.properties]].
+ */
+ def propertiesOf(obj: js.Any): js.Array[String] = {
+ // See http://stackoverflow.com/questions/26445248/
+ if (obj == null || js.isUndefined(obj)) {
+ js.Array()
+ } else {
+ val result = new js.Array[String]
+ val alreadySeen = js.Dictionary.empty[Boolean]
+
+ @tailrec
+ def loop(obj: js.Object): Unit = {
+ if (obj != null) {
+ // Add own enumerable properties that have not been seen yet
+ val enumProps = js.Object.keys(obj)
+ val enumPropsLen = enumProps.length
+ var i = 0
+ while (i < enumPropsLen) {
+ val prop = enumProps(i)
+ if (!alreadySeen.get(prop).isDefined)
+ result.push(prop)
+ i += 1
+ }
+
+ /* Add all own properties to the alreadySeen set, including
+ * non-enumerable ones.
+ */
+ val allProps = js.Object.getOwnPropertyNames(obj)
+ val allPropsLen = allProps.length
+ var j = 0
+ while (j < allPropsLen) {
+ alreadySeen(allProps(j)) = true
+ j += 1
+ }
+
+ // Continue with the next object in the prototype chain
+ loop(js.Object.getPrototypeOf(obj))
+ }
+ }
+ loop(js.Object(obj))
+
+ result
+ }
+ }
+
+ /** Information about the environment Scala.js runs in. */
+ def environmentInfo: js.Dynamic = sys.error("stub")
+
+ /** Polyfill for fround in case we use strict Floats and even Typed Arrays
+ * are not available.
+ * Note: this method returns a Double, even though the value is meant
+ * to be a Float. It cannot return a Float because that would require to
+ * do `x.toFloat` somewhere in here, which would itself, in turn, call this
+ * method.
+ */
+ def froundPolyfill(v: Double): Double = {
+ /* Originally inspired by the Typed Array polyfills written by Joshua Bell:
+ * https://github.com/inexorabletash/polyfill/blob/a682f42c1092280bb01907c245979fb07219513d/typedarray.js#L150-L255
+ * Then simplified quite a lot because
+ * 1) we do not need to produce the actual bit string that serves as
+ * storage of the floats, and
+ * 2) we are only interested in the float32 case.
+ */
+ import Math._
+
+ // Special cases
+ if (v.isNaN || v == 0.0 || v.isInfinite) {
+ v
+ } else {
+ val LN2 = 0.6931471805599453
+ val ebits = 8
+ val fbits = 23
+ val bias = (1 << (ebits-1)) - 1
+ val twoPowFbits = (1 << fbits).toDouble
+ val SubnormalThreshold = 1.1754943508222875E-38 // pow(2, 1-bias)
+
+ val isNegative = v < 0
+ val av = if (isNegative) -v else v
+
+ val absResult = if (av >= SubnormalThreshold) {
+ val e0 = floor(log(av) / LN2)
+ // 1-bias <= e0 <= 1024
+ if (e0 > bias) {
+ // Overflow
+ Double.PositiveInfinity
+ } else {
+ val twoPowE0 = pow(2, e0)
+ val f0 = Bits.roundToEven(av / twoPowE0 * twoPowFbits)
+ if (f0 / twoPowFbits >= 2) {
+ //val e = e0 + 1.0 // not used
+ val f = 1.0
+ if (e0 > bias-1) { // === (e > bias) because e0 is whole
+ // Overflow
+ Double.PositiveInfinity
+ } else {
+ // Normalized case 1
+ val twoPowE = 2*twoPowE0
+ twoPowE * (1.0 + (f - twoPowFbits) / twoPowFbits)
+ }
+ } else {
+ // Normalized case 2
+ // val e = e0 // not used
+ val f = f0
+ val twoPowE = twoPowE0
+ twoPowE * (1.0 + (f - twoPowFbits) / twoPowFbits)
+ }
+ }
+ } else {
+ // Subnormal
+ val rounder = Float.MinPositiveValue.toDouble
+ Bits.roundToEven(av / rounder) * rounder
+ }
+
+ if (isNegative) -absResult else absResult
+ }
+ }
+
+}