Giter Club home page Giter Club logo

scala-js's Introduction

scala-js's People

Contributors

adriaanm avatar alexander-myltsev avatar alistair-johnson avatar andreatp avatar armanbilge avatar benjaminjackman avatar catap avatar cquiroz avatar dependabot[bot] avatar dwijnand avatar ekrich avatar er1c avatar exoego avatar fabiopinheiro avatar gzm0 avatar japgolly avatar jonas avatar julienrf avatar leetibbert avatar lihaoyi avatar nicolasstucki avatar oleastre avatar sethtisue avatar siriux avatar sjrd avatar techaddict avatar toverney avatar ummels avatar xuwei-k avatar yawnt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scala-js's Issues

JS optional arguments via Scala default arguments

The current use of overloading/telescoping to handle optional arguments to JS functions leads to wrapper code like this:

def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number, width: js.Number, height: js.Number, canvasOffsetX: js.Number, canvasOffsetY: js.Number, canvasImageWidth: js.Number, canvasImageHeight: js.Number): Unit = ???
def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number, width: js.Number, height: js.Number, canvasOffsetX: js.Number, canvasOffsetY: js.Number, canvasImageWidth: js.Number): Unit = ???
def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number, width: js.Number, height: js.Number, canvasOffsetX: js.Number, canvasOffsetY: js.Number): Unit = ???
def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number, width: js.Number, height: js.Number, canvasOffsetX: js.Number): Unit = ???
def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number, width: js.Number, height: js.Number): Unit = ???
def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number, width: js.Number): Unit = ???
def drawImage(image: HTMLElement, offsetX: js.Number, offsetY: js.Number): Unit = ???

It would be great if we could leverage Scala's own "default argument" syntax to handle this somehow, since default arguments (maybe default to js.Undefined or js.Unset or something) map semantically better to the concept (a default argument) than a whole bunch of telescoping overloads.

This would greatly clean up the current mess in the source, in my autocomplete box, make it easier to understand the semantics of these methods at a glance, and provide a more logical place to put the docstring.

Numeric field names cause a compiler crash

This file causes scala-js to crash and burn:

package helloworld
object HelloWorld {
  def main() {
    println(`1`)
  }

  val `1` = ' '
}

It really shouldn't; it compiles fine under scalac. Oddly enough, I've only managed to get numeric literals to crash it: other special characters seem to get escaped fine, and calling the field /';[] works great.

Wrong 'x' conversion on negative numbers in `java.lang.String.format`

JavaDoc states:

If x is negative then the result will be an unsigned value generated by adding 2n to the value where n is the number of bits in the type as returned by the static SIZE field in the Byte, Short, Integer, or Long classes as appropriate.

Since we don't have reflection, we cannot find the correct size. Should we just assume SIZE = 32?

scala.Enumeration requires reflection

This snippet that was posted on the mailing list has been integrated into the proposed test suite for Scala.js. The initial issue mentioned in the post was that Integer.reverseBytes was unimplemented.

object HelpLevel extends Enumeration {
  type HelpLevel = Value
  val None, Basic, Medium, Full = Value
}

val h = HelpLevel.None

It turns out that scala.Enumeration also requires reflection to work properly and thus must be handled by Scala.js in a special way, if we want to support it.

Here's the stack trace from the test:

TypeError: Cannot find function getDeclaredFields__ALjava_lang_reflect_Field in object class scala.EnumerationTest$$anonfun$1$$anonfun$apply$mcV$sp$1$HelpLevel$2. in /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/0002-Enumeration.js (line 125)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/0002-Enumeration.js:125 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/0003-Enumeration$$anonfun$scala$Enumeration$$nameOf$1.js:10 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/0003-Enumeration$$anonfun$scala$Enumeration$$nameOf$1.js:14 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/collection/0001-MapLike$class.js:20 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/collection/0004-AbstractMap.js:20 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/0002-Enumeration.js:138 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scala/0003-Enumeration$Val.js:17 (anonymous)
[info]  at /opt/scala-js/test/target/streams/test/externalDependencyClasspath/$global/package-js/extracted-jars/scalajs-library_2.10.jar--6a954585/scalajs-corejslib.js:574 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/scala/0004-EnumerationTest$$anonfun$1$$anonfun$apply$mcV$sp$1.js:22 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/scala/0004-EnumerationTest$$anonfun$1$$anonfun$apply$mcV$sp$1.js:17 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/scala/0004-EnumerationTest$$anonfun$1$$anonfun$apply$mcV$sp$1.js:25 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/scala/scalajs/test/0002-ScalaJSTest.js:17 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:1087 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2119 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2072 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2399 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2119 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2072 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2544 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2119 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2072 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:2166 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/jasmine.js:825 (anonymous)
[info]  at /opt/scala-js/test/target/scala-2.10/test-classes/main.js:27

De/serialization (Pickling integration?)

I have a project, in which i directly communicate between Akka-Actors and custom "ActorSockets" implemented in JavaScript using WebSockets. I am currently thinking about migrating it to Scala.js. But there is one missing feature holding me back right now:

It should be possible to serialize/deserialize messages in some format so that the serialization and deserialization functions can be called on the server AND on the client, so that is then possible to do pattern matching on deserialized messages in the javascript-compiled part of the application. My own attempts to compile scala.pickling to javascript failed. Maybe that is even an overkill...

I was wondering if anybody is working on this. If not I would like to investigate that a little further.

scala.String.compareTo has different results to js.String.compareTo

I have executed the Scala.js StringTests.scala in both JasminSpec(scala) and Jasmine (JS) . The tests are... with JS results in the comment

it("should respond to compareTo") {
expect("Scala.js".compareTo("Scala")).toBe(3) // Changed from 1 in Scala.js tests
expect("Scala.js".compareTo("Scala.js")).toBe(0)
expect("Scala.js".compareTo("banana")).toBe(-15) // Changed from -1 in Scala.js tests
}

Package js.Object's don't work

With the following source:

// package.scala
import scala.scalajs.js
package object helloworld extends js.Object{
  def doStuff() = println(10)
}
// HelloWorld.scala
package helloworld
object HelloWorld {
  def main() {
    doStuff()
  }
}

The package object definition gets compiled into:

ScalaJS.c.helloworld\ufe33package$

While the call to doStuff() gets compiled into

ScalaJS.c.helloworld\ufe33HelloWorld$.prototype.main\ufe34V = (function() {
  ScalaJS.g["package"]["doStuff"]()
});

Which causes it to fail at runtime. I'm not sure what the correct behavior here should be, but it seems to me that to properly follow the semantics of how js.Objects work, the package object should be erased at runtime and calls to it be forwarded to the appropiate javascript global.

Also, it probably should forward to cp in this case, rather than package. In the case of nested packages each with a package js.Object, perhaps we could walk up the package tree and put together the name (e.g. ["Box2d"]["Dynamics"]["Joint"]). Unfortunately, @JSName doesn't work because you can't annotate package objects =(.

Multiple entry points

To allow for certain parts of the application to be executed as WebWorkers in a dedicated thread (which could be used to implement some kind of akka-lite for scala-js) it is necessary that not the entire output is compiled into one single file. I know that this is a big proposal, but maybe you can think about the following: (If you don't like it, please just close this issue again ;))

Why don't you compile into seperate javascript files like the scala compiler does with class files and then resolve the dependencies using require.js which in turn can be used to optimize only certain parts of the application as you can specify different entry points for the optimization.

The advantages:

  • One could define multiple entry points into the application which can be optimized seperately!
  • You could do Multithreading in scala-js (with WebWorkers) and maybe implement parts of akka.
  • It would also make incremental compilation possible, as you would not always have to update one huge javascript file
  • You can still use the code without optimization for development if you include require.js and use r.js (the require.js optimizer) to optimize
  • I would also imagine, that the optimization would run faster and probably the output would also be smaller.

Disadvantages:

  • Big change from the current way the output is generated
  • A fixed dependency to a javascript library (require.js)
  • Very many javascript files would be generated (but that also happens with class files for the normal scala compiler, so not really a big disadvantage)

Some notes:

  • You could also do multithreading right now if you use a single entry point and determine if it is running as a worker and then execute different behavior.

Plans?

Hi all,

I just tried a few examples and it works great! The speed of the generated code seems fast as well. Thanks for this wonderful project.

However, the scalajs-runtime seems to be one big download (24 MB). Is this always going to be case? I suppose that scala 2.11 with its modular libraries might help a bit, but otherwise, is there any other improvement in sight?

What other plans and road maps do you have?

null + "problemo"

This is not really a bug, as null + "problemo" is not legal Scala code anyway, but look at the following code:

val x : Object = null
val boom = x + " problemo"

In Scala, this works and leaves the value "null problemo" in boom. In Scala.js, an exception is thrown that "null" does not have a toString method.

Obviously this is not a big issue, but can be annoying, for example when you have logging code that prints out case classes which contain null fields, which will also lead to exceptions.

generating a stub scalajs-library.jar for IDEs

i am using idea/eclipse for my current scala development and the only way for me to reference the scalajs library is to include its source in the project dependencies since there is not a valid scalajs-library.jar that the ide can look at and understand.

how about generating a stub scalajs-library.jar with valid java classes inside to satisfy ide's requirement?

xml crashes compiler or expose strange behavior

From scala-js-example:

object ScalaJSExample {
  def main(): Unit = {
    val paragraph = g.document.createElement("p")
    paragraph.innerHTML = <strong>It works!</strong>
    g.document.getElementById("playground").appendChild(paragraph)
  }
}

Makes the compiler crash (see end of ticket for message).

Further:

object ScalaJSExample {
  def main(): Unit = {
    val paragraph = g.document.createElement("p")
    val x = <strong>It works! The result is</strong>
    paragraph.innerHTML = "foo"
    g.document.getElementById("playground").appendChild(paragraph)
  }
}

Gives:

[error] /home/ts/Documents/work/LAMP/scala-js-example-app/src/main/scala/example/ScalaJSExample.scala:11: applyDynamic does not support passing a vararg parameter
[error]     paragraph.innerHTML = "foo"
[error]               ^
[error] one error found
[error] (compile:compile) Compilation failed

whereas

object ScalaJSExample {
  def main(): Unit = {
    val paragraph = g.document.createElement("p")
    //val x = <strong>It works! The result is</strong>
    paragraph.innerHTML = "foo"
    g.document.getElementById("playground").appendChild(paragraph)
  }
}

works perfectly.

I'd expect a more sensible error message if XML literals are not supported, or even better, support for XML literals with a choice of whether to use scala.xml or the JS DOM.

Compiled with SBT 0.13.0, Scala-JS snapshot e9e8df9
Compiler error message:

[error] uncaught exception during compilation: java.lang.IllegalArgumentException
[trace] Stack trace suppressed: run last compile:compile for the full output.
[error] (compile:compile) java.lang.IllegalArgumentException: requirement failed: 
[error]      while compiling: /home/ts/Documents/work/LAMP/scala-js-example-app/src/main/scala/example/ScalaJSExample.scala
[error]         during phase: jscode
[error]      library version: version 2.10.2
[error]     compiler version: version 2.10.2
[error]   reconstructed args: -bootclasspath /opt/jre1.7.0_04/lib/resources.jar:/opt/jre1.7.0_04/lib/rt.jar:/opt/jre1.7.0_04/lib/sunrsasign.jar:/opt/jre1.7.0_04/lib/jsse.jar:/opt/jre1.7.0_04/lib/jce.jar:/opt/jre1.7.0_04/lib/charsets.jar:/opt/jre1.7.0_04/lib/jfr.jar:/opt/jre1.7.0_04/classes:/home/ts/.sbt/boot/scala-2.10.2/lib/scala-library.jar -Xplugin:/home/ts/.ivy2/local/org.scala-lang.modules.scalajs/scalajs-compiler_2.10/0.2-SNAPSHOT/jars/scalajs-compiler_2.10.jar -classpath /home/ts/Documents/work/LAMP/scala-js-example-app/target/scala-2.10/classes:/home/ts/.ivy2/local/org.scala-lang.modules.scalajs/scalajs-library_2.10/0.2-SNAPSHOT/jars/scalajs-library_2.10.jar:/home/ts/.sbt/boot/scala-2.10.2/lib/scala-compiler.jar:/home/ts/.sbt/boot/scala-2.10.2/lib/scala-reflect.jar
[error] 
[error]   last tree to typer: TypeTree(class Array)
[error]               symbol: class Array in package scala (flags: final)
[error]    symbol definition: final class Array[T >: ? <: ?] extends Object
[error]                  tpe: Array[Object]
[error]        symbol owners: class Array -> package scala
[error]       context owners: object ScalaJSExample -> package example
[error] 
[error] == Enclosing template or block ==
[error] 
[error] Template( // val <local ScalaJSExample>: <notype> in object ScalaJSExample, tree.tpe=example.ScalaJSExample.type
[error]   "java.lang.Object" // parents
[error]   ValDef(
[error]     private
[error]     "_"
[error]     <tpt>
[error]     <empty>
[error]   )
[error]   // 2 statements
[error]   DefDef( // def main(): Unit in object ScalaJSExample
[error]     <method>
[error]     "main"
[error]     []
[error]     List(Nil)
[error]     <tpt> // tree.tpe=Unit
[error]     Block( // tree.tpe=Unit
[error]       // 2 statements
[error]       ValDef( // val paragraph: scalajs.js.Dynamic
[error]         <triedcooking>
[error]         "paragraph"
[error]         <tpt> // tree.tpe=scalajs.js.Dynamic
[error]         Apply( // def applyDynamic(name: String,args: Seq): scalajs.js.Dynamic in trait Dynamic, tree.tpe=scalajs.js.Dynamic
[error]           scala.scalajs.js.Dynamic.global().selectDynamic("document")."applyDynamic" // def applyDynamic(name: String,args: Seq): scalajs.js.Dynamic in trait Dynamic, tree.tpe=(name: String, args: Seq)scalajs.js.Dynamic
[error]           // 2 arguments
[error]           "createElement"
[error]           Apply( // implicit def wrapRefArray(xs: Array[Object]): collection.mutable.WrappedArray in class LowPriorityImplicits, tree.tpe=collection.mutable.WrappedArray
[error]             scala.this."Predef"."wrapRefArray" // implicit def wrapRefArray(xs: Array[Object]): collection.mutable.WrappedArray in class LowPriorityImplicits, tree.tpe=(xs: Array[Object])collection.mutable.WrappedArray
[error]             Apply( // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=Array[Object]
[error]               TypeApply( // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=()Array[Object]
[error]                 Array[scalajs.js.Any]{js.this.Any.fromString("p")}."$asInstanceOf" // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=[T0 >: ? <: ?]()T0
[error]                 <tpt> // tree.tpe=Array[Object]
[error]               )
[error]               Nil
[error]             )
[error]           )
[error]         )
[error]       )
[error]       Apply( // def updateDynamic(name: String,value: scalajs.js.Any): Unit in trait Dynamic, tree.tpe=Unit
[error]         "paragraph"."updateDynamic" // def updateDynamic(name: String,value: scalajs.js.Any): Unit in trait Dynamic, tree.tpe=(name: String, value: scalajs.js.Any)Unit
[error]         // 2 arguments
[error]         "innerHTML"
[error]         Apply( // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=scalajs.js.Any
[error]           TypeApply( // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=()scalajs.js.Any
[error]             js.this.Any.fromFunction1({
[error]   {
[error]     new xml.Elem(null, "strong", scala.xml.Null, scala.this.Predef.$scope(), false, {
[error]       val $buf: xml.NodeBuffer = new xml.NodeBuffer();
[error]       $buf.&+(new xml.Text("It works! The result is"));
[error]       $buf
[error]     })
[error]   }
[error] })."$asInstanceOf" // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=[T0 >: ? <: ?]()T0
[error]             <tpt> // tree.tpe=scalajs.js.Any
[error]           )
[error]           Nil
[error]         )
[error]       )
[error]       Block( // tree.tpe=Unit
[error]         Apply( // def applyDynamic(name: String,args: Seq): scalajs.js.Dynamic in trait Dynamic, tree.tpe=scalajs.js.Dynamic
[error]           scala.scalajs.js.Dynamic.global().selectDynamic("document").applyDynamic("getElementById", scala.this.Predef.wrapRefArray(Array[scalajs.js.Any]{js.this.Any.fromString("playground")}.$asInstanceOf[Array[Object]]()))."applyDynamic" // def applyDynamic(name: String,args: Seq): scalajs.js.Dynamic in trait Dynamic, tree.tpe=(name: String, args: Seq)scalajs.js.Dynamic
[error]           // 2 arguments
[error]           "appendChild"
[error]           Apply( // implicit def wrapRefArray(xs: Array[Object]): collection.mutable.WrappedArray in class LowPriorityImplicits, tree.tpe=collection.mutable.WrappedArray
[error]             scala.this."Predef"."wrapRefArray" // implicit def wrapRefArray(xs: Array[Object]): collection.mutable.WrappedArray in class LowPriorityImplicits, tree.tpe=(xs: Array[Object])collection.mutable.WrappedArray
[error]             Apply( // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=Array[Object]
[error]               TypeApply( // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=()Array[Object]
[error]                 Array[scalajs.js.Any]{paragraph}."$asInstanceOf" // final def $asInstanceOf[T0 >: ? <: ?](): T0 in class Object, tree.tpe=[T0 >: ? <: ?]()T0
[error]                 <tpt> // tree.tpe=Array[Object]
[error]               )
[error]               Nil
[error]             )
[error]           )
[error]         )
[error]         ()
[error]       )
[error]     )
[error]   )
[error]   DefDef( // def <init>(): example.ScalaJSExample.type in object ScalaJSExample
[error]     <method>
[error]     "<init>"
[error]     []
[error]     List(Nil)
[error]     <tpt> // tree.tpe=example.ScalaJSExample.type
[error]     Block( // tree.tpe=Unit
[error]       Apply( // def <init>(): Object in class Object, tree.tpe=Object
[error]         ScalaJSExample.super."<init>" // def <init>(): Object in class Object, tree.tpe=()Object
[error]         Nil
[error]       )
[error]       ()
[error]     )
[error]   )
[error] )
[error] 
[error] == Expanded type of tree ==
[error] 
[error] TypeRef(
[error]   TypeSymbol(final class Array[T >: ? <: ?] extends Object)
[error]   args = List(TypeRef(TypeSymbol(class Object extends )))
[error] )
[error] 
[error] encodeMethodSym called with non-method symbol: value apply

Define the JavaScript name of a raw JS class/object.

Currently, when one defines a raw JavaScript class or object (inheriting from js.Object), the JavaScript name of that symbol is derived from the simple (unqualified) name of the Scala symbol.
e.g, js.Object corresponds to Object in JavaScript.

Now, what happens if I want to describe the type of a class that is namespaced in JavaScript, e.g. foo.Bar? The answer is, it is not possible.

I think the appropriate way is to be able to overwrite the JS name with an annotation, e.g., as was proposed here by Denis Nevmerzhitsky.

@JSName("foo.Bar")
class FooBar {
}

Given that definition new FooBar() would be translated to new foo.Bar().

Wrong by-name parameter semantics (partest run/t7899.scala)

The following snippet fails (stacktrace at end)

object HelloWorld {
  def main() {
    def id[A](a: => A): A = null.asInstanceOf[A]
    def foo(f: (=> Int) => Int) = () => f(???)
    foo(id)() // should be allowed and not throw ???
  }
}

Stacktrace

org.mozilla.javascript.EcmaError: TypeError: org.mozilla.javascript.Undefined@55f5f59d is not a function, it is undefined. (/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0003-HelloWorld$$anonfun$main$1.js#5)
    at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3687)
    at org.mozilla.javascript.ScriptRuntime.constructError(ScriptRuntime.java:3665)
    at org.mozilla.javascript.ScriptRuntime.typeError(ScriptRuntime.java:3693)
    at org.mozilla.javascript.ScriptRuntime.typeError2(ScriptRuntime.java:3712)
    at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3767)
    at org.mozilla.javascript.ScriptRuntime.notFunctionError(ScriptRuntime.java:3755)
    at org.mozilla.javascript.ScriptRuntime.newObject(ScriptRuntime.java:2346)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0003_HelloWorld__anonfun_main_1_js_12._c_script_0(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0003-HelloWorld$$anonfun$main$1.js:5)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0003_HelloWorld__anonfun_main_1_js_12.call(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0003-HelloWorld$$anonfun$main$1.js)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0003_HelloWorld__anonfun_main_1_js_12.exec(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0003-HelloWorld$$anonfun$main$1.js)
    at org.mozilla.javascript.Context.evaluateReader(Context.java:1110)
    at scala.scalajs.sbtplugin.RhinoBasedRun$ContextOps.evaluateFile(RhinoBasedRun.scala:23)
    at scala.scalajs.sbtplugin.RhinoBasedRun$LazyScalaJSScope$$anonfun$scala$scalajs$sbtplugin$RhinoBasedRun$LazyScalaJSScope$$load$1.apply(RhinoBasedRun.scala:80)
    at scala.scalajs.sbtplugin.RhinoBasedRun$LazyScalaJSScope$$anonfun$scala$scalajs$sbtplugin$RhinoBasedRun$LazyScalaJSScope$$load$1.apply(RhinoBasedRun.scala:78)
    at scala.Option.foreach(Option.scala:236)
    at scala.scalajs.sbtplugin.RhinoBasedRun$LazyScalaJSScope.scala$scalajs$sbtplugin$RhinoBasedRun$LazyScalaJSScope$$load(RhinoBasedRun.scala:78)
    at scala.scalajs.sbtplugin.RhinoBasedRun$LazyScalaJSScope$$anonfun$get$1.apply(RhinoBasedRun.scala:95)
    at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
    at scala.collection.AbstractMap.getOrElse(Map.scala:58)
    at scala.scalajs.sbtplugin.RhinoBasedRun$LazyScalaJSScope.get(RhinoBasedRun.scala:94)
    at org.mozilla.javascript.ScriptableObject.getProperty(ScriptableObject.java:2184)
    at org.mozilla.javascript.ScriptRuntime.getObjectProp(ScriptRuntime.java:1492)
    at org.mozilla.javascript.ScriptRuntime.getObjectProp(ScriptRuntime.java:1485)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0002_HelloWorld__js_11._c_anonymous_2(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0002-HelloWorld$.js:8)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0002_HelloWorld__js_11.call(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0002-HelloWorld$.js)
    at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:85)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0002_HelloWorld__js_11._c_anonymous_5(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0002-HelloWorld$.js:17)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_target_scala_2_10_classes_helloworld_0002_HelloWorld__js_11.call(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/target/scala-2.10/classes/helloworld/0002-HelloWorld$.js)
    at org.mozilla.javascript.optimizer.OptRuntime.callProp0(OptRuntime.java:85)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_startup_js_10._c_script_0(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/startup.js:6)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_startup_js_10.call(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/startup.js)
    at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
    at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_startup_js_10.call(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/startup.js)
    at org.mozilla.javascript.gen._Users_tschlatt_Documents_scala_js_main_examples_helloworld_startup_js_10.exec(/Users/tschlatt/Documents/scala-js-main/examples/helloworld/startup.js)
    at org.mozilla.javascript.Context.evaluateReader(Context.java:1110)
    at scala.scalajs.sbtplugin.RhinoBasedRun$ContextOps.evaluateFile(RhinoBasedRun.scala:23)
    at scala.scalajs.sbtplugin.RhinoBasedRun$$anonfun$runJavaScriptWithLazyScalaJSScopes$1.apply(RhinoBasedRun.scala:218)
    at scala.scalajs.sbtplugin.RhinoBasedRun$$anonfun$runJavaScriptWithLazyScalaJSScopes$1.apply(RhinoBasedRun.scala:173)
    at scala.collection.immutable.List.foreach(List.scala:318)
    at scala.scalajs.sbtplugin.RhinoBasedRun$.runJavaScriptWithLazyScalaJSScopes(RhinoBasedRun.scala:173)
    at scala.scalajs.sbtplugin.RhinoBasedRun$.scalaJSRunJavaScript(RhinoBasedRun.scala:154)
    at scala.scalajs.sbtplugin.ScalaJSPlugin$$anonfun$scalaJSRunJavaScriptTask$1.apply(ScalaJSPlugin.scala:453)
    at scala.scalajs.sbtplugin.ScalaJSPlugin$$anonfun$scalaJSRunJavaScriptTask$1.apply(ScalaJSPlugin.scala:450)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47)

Create new objects with the dynamically typed API to JS

With the typed interface to JavaScript, is possible to instantiate new objects of JavaScript classes, e.g.:

val today = new js.Date()

However, it is not possible to do so with the dynamically typed API. Ideally, we would want to write

val today = new js.Dynamic.global.Date()

but this is not possible, short of extending the Scala semantics of scala.Dynamic with, e.g., an additional rule saying that the previous call should be rewritten as

val today = js.Dynamic.global.Date.newDynamic()

I can see two ways to provide that ability in Scala.js.

Either through a special object js.New, used as in

val today = js.New.Date()
val obj = js.New.someNamespace.SomeClass(...)

For the record, it can be implemented by defining js.New like this:

final trait New extends scala.Dynamic {
  def applyDynamic(name: String)(args: js.Any*): js.Dynamic
  def selectDynamic(name: String): New
}
object New extends New

The two methods being compiler intrinsics. Some compiler magic would be able to recognize New.selectDynamic("someNamespace").applyDynamic("SomeClass")(...) and turn it into
new someNamespace.SomeClass(...)
in JavaScript.

The other possibility is to reserve one method name of js.Dynamic to take on the role of the new keyword. e.g., create, or new itself (or newDynamic, which would fit with the hypothetical desugaring of the "ideal" solution described above), used as in

val today = js.Dynamic.global.Date.create()
val obj = js.Dynamic.global.someNamespace.SomeClass.`new`(...)

This has the disadvantage that, if the given JS object actually has a method create, or new, it cannot be called normally (it would still be possible to call it by using explicitly applyDynamic("create")(...)).
However, it seems nicer to me than the previous alternative, and it would happen to be easier to implement.

WDYT? What syntax would you favor?

Unicode bug

I am working with Unicode strings that are outside the basic plane, and encounter problems with Scala.js. Here is an example:

val str = "Aโˆ€\uD835\uDCAB" 
var s : String = ""
for (c <- str) {
  val code : Int = c
  s = s + code + " "
}

The string s has in Scala the following value: 65 8704 55349 56491

But in Scala.js it has the following value: 65 8704 7498 98

The Unicode encoding of strings in Java and Javascript is identical, so the above outputs should be the same.

Minimal Runtime

A minimal JS Runtime allows web-developers to use the (minimal-) runtime without waiting for a (full featured-) runtime that is not too large.

Advantages:

  • can use scala-js on existing web-pages (not everyone can use a 16mb/1-2mb JS library)
  • use of advantages of scala (static typing, languange features, etc.)

Disadvantages:

  • can not use scala.collection.* and other uncommon or big scala-library packages

Problem with getting values of options in optimize-js mode

I just pushed a version of Collidium using optimize-js (now my code size is just about 1 MB ๐Ÿ˜„ ).

In my Main object here: https://github.com/shadaj/collidium/blob/463b97cbf041451a01ce0f111886763e45634d1e/src/main/scala/me/shadaj/collidium/Main.scala#L183 I am trying to print the obstacle when it has been drawn, but I get this error in the optimized js code when I uncomment that line:

Uncaught TypeError: Object Line( has no method 'eC' collidium-opt.js:28612
l.sk collidium-opt.js:28612
l.pla collidium-opt.js:28462
lp.nv collidium-opt.js:39879
lp.h collidium-opt.js:39882
l.Hka collidium-opt.js:28546
l.ax collidium-opt.js:28542
l.n collidium-opt.js:53053
l.toString collidium-opt.js:266
l.tr collidium-opt.js:43022
l.pp collidium-opt.js:43034
l.pp collidium-opt.js:11775
l.pp collidium-opt.js:37154
ov.fv collidium-opt.js:53148
ov.h collidium-opt.js:53152
(anonymous function)

It works fine with just package-js.

SBT dependencies not set right for tests

In order to test, it is required to manually issue

package
scala-js-test/test

otherwise the tests fail due to the missing package. Could this dependency be added to the build-file?

(same applies to partests btw.)

Comparing scala.String and js.String raises false warning

[warn] C:\Dropbox\Workspace\scala-js-ribbon\src\main\scala\example\Roll.scala:55: scala.scalajs.js.String and String are unrelated: they will most likely never compare equal
[warn]        .filter(_.getAttribute("fill") == "#0000FF")
[warn]                                       ^

This isn't correct. According to the docs, scala.String is exactly the same as js.String, as experimentally it works. Is there any easy way to mark them as identical, maybe making js.String a simple type-alias of scala.String so the compiler will stop yelling at us?

Implicit conversion for js.Array of Int fails with ClassCastException

Running the following code works for the first test spec but fails for the second. The error reported by Rhino is:

java.lang.ClassCastException: 7 is not an instance of java.lang.Integer
    it("should provide implicit conversion from js.Array to ArrayOps - String") {
      var propCount = 0
      var propString = ""

      for (item <- js.Array("Sc", "ala", ".", "js")) {
        propCount += 1
        propString += item
      }

      expect(propCount).toEqual(4)
      expect(propString).toEqual("Scala.js")
    }

    it("should provide implicit conversion from js.Array to ArrayOps - Int") {
      var propCount = 0
      var propString = ""

      for (item <- js.Array(7, 3, 5, 7)) {
        propCount += 1
        propString += item
      }

      expect(propCount).toEqual(4)
      expect(propString).toEqual("7357")
    }

Wrong JS-Code: to many return's

first example:
java.lang.Math.abs(...)

  def abs(a: scala.Int) = JSMath.abs(a).toInt
  def abs(a: scala.Long) = JSMath.abs(a).toLong
  def abs(a: scala.Float) = JSMath.abs(a).toFloat
  def abs(a: scala.Double) = JSMath.abs(a).toDouble

JS-Code:

   Class.prototype.abs = (function(arg$1) {
      return this["abs(D)D"](arg$1);
      return this["abs(F)F"](arg$1);
      return this["abs(J)J"](arg$1);
      return this["abs(I)I"](arg$1)
    });

other example:
The "<" method is abstract so we shouldn't generate JS-Code at all.
scala.Int.<(...)

/** `Int`, a 32-bit signed integer (equivalent to Java's `int` primitive type) is a
 *  subtype of [[scala.AnyVal]]. Instances of `Int` are not
 *  represented by an object in the underlying runtime system.
 *
 *  There is an implicit conversion from [[scala.Int]] => [[scala.runtime.RichInt]]
 *  which provides useful non-primitive operations.
 */
final abstract class Int private extends AnyVal {
  // some more lines ...
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Byte): Boolean
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Short): Boolean
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Char): Boolean
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Int): Boolean
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Long): Boolean
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Float): Boolean
  /**
  * Returns `true` if this value is less than x, `false` otherwise.
  */
  def <(x: Double): Boolean

JS-Code:

 Class.prototype["<"] = (function(arg$1) {
      return this["<(D)Z"](arg$1);
      return this["<(F)Z"](arg$1);
      return this["<(J)Z"](arg$1);
      return this["<(I)Z"](arg$1);
      return this["<(C)Z"](arg$1);
      return this["<(S)Z"](arg$1);
      return this["<(B)Z"](arg$1)
    });

btw: The generated JS-Code of java.lang.Math seems broken.

 Class.prototype["abs(D)D"] = (function(arg$a) {
      return this["JSMath()Ljava.lang.Math$MathStatic;"]().abs(arg$a)
    });

The code uses 'MathStatic' but the runtime does not contain a MathStatic class. I think MathStatic is there to represent the JavaScript Math object so scala-js compiler is broken.

+ on two js.Strings is ambiguous

This

val a : scala.js.String = "a"
val b : scala.js.String = "b"
val c : scala.js.String = a + b

results in

[error] /Users/christoph/code/scala-js-example-app/src/main/scala/example/ScalaJSExample.scala:25: error: ambiguous reference to overloaded definition,
[error] both method + in trait String of type (that: scala.js.Dynamic)scala.js.String
[error] and  method + in trait Any of type (that: scala.js.String)scala.js.String
[error] match argument types (scala.js.String) and expected result type scala.js.String
[error]         val c : scala.js.String = a + b
[error]                                     ^

Which makes the quite common task of concatenating Strings quite cumbersome.
I think overriding the +(String) in scala.js.String does the trick:

sealed trait String extends Any {
  ...
  override def +(that: String): String = sys.error("stub")

java.lang.String.format does not implement 's' conversion correctly

Currently, java.lang.String.format does use a java.util.Formatter and can therefore not correctly implement the 's' conversion (which calls formatTo on the argument if it implements Formattable, where one of the arguments is a Formatter)

This should considered for implementation in the future

Basic reflection support

It would be really awesome to have some basic reflection support:

  • listing methods / fields
  • calling methods / fields
  • dynamically creating instances

Even if it worked only for Scala classes, this would be great!
Currently I can call getClass, but it is mostly useless. The same goes about typeTags/classTags introduced in Scala 2.10.

java.lang.OutOfMemoryError while building

I wanted to build the project but get the following error. Even increasing the max heap size to 4G didn't help. My sbt flags are: /usr/bin/java -XX:+CMSClassUnloadingEnabled -Xms1536m -Xmx4g -XX:MaxPermSize=512m -XX:ReservedCodeCacheSize=192m -Dfile.encoding=UTF8 -jar /opt/local/share/sbt/sbt-launch.jar. Running on osx.

> package-js
[info] Updating {file:/Users/christoph/code/scala-js/}scalajs-compiler...
[info] Resolving org.scala-lang#scala-reflect;2.10.1 ...
[info] Done updating.
[info] Updating {file:/Users/christoph/code/scala-js/}scalajs-library...
[info] Updating {file:/Users/christoph/code/scala-js/}scalajs-javalib...
[info] Updating {file:/Users/christoph/code/scala-js/}scalajs-library-aux...
[info] Updating {file:/Users/christoph/code/scala-js/}scalajs-scalalib...
[info] Resolving org.scala-lang#scala-reflect;2.10.1 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-library;2.10.1 ...
[info] Compiling 15 Scala sources to /Users/christoph/code/scala-js/compiler/target/scala-2.10/classes...
[info] Resolving org.scala-lang#scala-reflect;2.10.1 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-reflect;2.10.1 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-reflect;2.10.1 ...
[info] Done updating.
[warn] /Users/christoph/code/scala-js/compiler/src/main/scala/scala/tools/nsc/scalajs/Main.scala:65: class RefinedBuildManager in package interactive is deprecated: Use sbt incremental compilation mechanism
[warn]         case _          => new RefinedBuildManager(settings)
[warn]                                ^
[warn] one warning found
[error] error:
[error]      while compiling: /Users/christoph/code/scala-js/scalalib/source/src/library/scala/collection/parallel/ParIterableLike.scala
[error]         during phase: typer
[error]      library version: version 2.10.1
[error]     compiler version: version 2.10.1
[error]   reconstructed args: -d /Users/christoph/code/scala-js/scalalib/target/jsclasses
[error]
[error]   last tree to typer: Function(value $anonfun)
[error]               symbol: value $anonfun (flags: <synthetic>)
[error]    symbol definition: val $anonfun: <notype>
[error]                  tpe: () => scala.collection.parallel.Combiner[(U, S),That]
[error]        symbol owners: value $anonfun -> method zip -> trait ParIterableLike -> package parallel
[error]       context owners: value $anonfun -> method zip -> trait ParIterableLike -> package parallel
[error]
[error] == Enclosing template or block ==
[error]
[error] Apply(
[error]   new Zip(combinerFactory((() => bf(repr).asCombiner)), splitter, thatseq.splitter)."mapResult"
[error]   Function(
[error]     ValDef(
[error]       <param> <synthetic>
[error]       "x$24"
[error]       <tpt>
[error]       <empty>
[error]     )
[error]     "x$24"."resultWithTaskSupport"
[error]   )
[error] )
[error]
[error] == Expanded type of tree ==
[error]
[error] TypeRef(
[error]   TypeSymbol(abstract trait Function0[+R] extends AnyRef)
[error]   args = List(
[error]     TypeRef(
[error]       TypeSymbol(
[error]         abstract trait Combiner[-Elem, +To] extends Builder[Elem,To] with Sizing with Parallel
[error]
[error]       )
[error]       args = List(
[error]         TypeRef(
[error]           TypeSymbol(
[error]             case class Tuple2[+T1, +T2] extends Product2[T1,T2] with Product with Serializable
[error]
[error]           )
[error]           args = List(
[error]             SkolemTypeRef(TypeSkolem(U >: T))
[error]             SkolemTypeRef(TypeSkolem(S))
[error]           )
[error]         )
[error]         SkolemTypeRef(TypeSkolem(That))
[error]       )
[error]     )
[error]   )
[error] )
[error]
[error] uncaught exception during compilation: java.lang.OutOfMemoryError
[error] error: java.lang.OutOfMemoryError: Java heap space
[error]     at scala.reflect.internal.util.HashSet.growTable(HashSet.scala:97)
[error]     at scala.reflect.internal.util.HashSet.findEntryOrUpdate(HashSet.scala:39)
[error]     at scala.reflect.internal.Types$class.unique(Types.scala:3932)
[error]     at scala.reflect.internal.SymbolTable.unique(SymbolTable.scala:13)
[error]     at scala.reflect.internal.Types$TypeRef$.apply(Types.scala:2524)
[error]     at scala.reflect.internal.Types$class.copyTypeRef(Types.scala:3615)
[error]     at scala.reflect.internal.SymbolTable.copyTypeRef(SymbolTable.scala:13)
[error]     at scala.reflect.internal.Types$TypeMap.mapOver(Types.scala:4170)
[error]     at scala.reflect.internal.Types$SubstMap.apply(Types.scala:4656)
[error]     at scala.reflect.internal.Types$SubstMap.apply(Types.scala:4627)
[error]     at scala.collection.immutable.List.loop$1(List.scala:170)
[error]     at scala.collection.immutable.List.mapConserve(List.scala:186)
[error]     at scala.reflect.internal.Types$TypeMap.mapOver(Types.scala:4168)
[error]     at scala.reflect.internal.Types$SubstMap.apply(Types.scala:4656)
[error]     at scala.reflect.internal.Types$Type.subst(Types.scala:796)
[error]     at scala.reflect.internal.Types$Type.instantiateTypeParams(Types.scala:572)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer$$anonfun$methTypeArgs$2.apply(Infer.scala:673)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer$$anonfun$methTypeArgs$2.apply(Infer.scala:671)
[error]     at scala.reflect.internal.util.Collections$class.map2(Collections.scala:51)
[error]     at scala.reflect.internal.SymbolTable.map2(SymbolTable.scala:13)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer.methTypeArgs(Infer.scala:671)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer.inferMethodInstance(Infer.scala:1163)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.handlePolymorphicCall$1(Typers.scala:3403)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3409)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.handleOverloaded$1(Typers.scala:3185)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3188)
[error]     at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$94.apply(Typers.scala:4580)
[error]     at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$94.apply(Typers.scala:4580)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:744)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.tryTypedApply$1(Typers.scala:4580)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:4633)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:4666)
[error]
[error] Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
[error]     at scala.reflect.internal.util.HashSet.growTable(HashSet.scala:97)
[error]     at scala.reflect.internal.util.HashSet.findEntryOrUpdate(HashSet.scala:39)
[error]     at scala.reflect.internal.Types$class.unique(Types.scala:3932)
[error]     at scala.reflect.internal.SymbolTable.unique(SymbolTable.scala:13)
[error]     at scala.reflect.internal.Types$TypeRef$.apply(Types.scala:2524)
[error]     at scala.reflect.internal.Types$class.copyTypeRef(Types.scala:3615)
[error]     at scala.reflect.internal.SymbolTable.copyTypeRef(SymbolTable.scala:13)
[error]     at scala.reflect.internal.Types$TypeMap.mapOver(Types.scala:4170)
[error]     at scala.reflect.internal.Types$SubstMap.apply(Types.scala:4656)
[error]     at scala.reflect.internal.Types$SubstMap.apply(Types.scala:4627)
[error]     at scala.collection.immutable.List.loop$1(List.scala:170)
[error]     at scala.collection.immutable.List.mapConserve(List.scala:186)
[error]     at scala.reflect.internal.Types$TypeMap.mapOver(Types.scala:4168)
[error]     at scala.reflect.internal.Types$SubstMap.apply(Types.scala:4656)
[error]     at scala.reflect.internal.Types$Type.subst(Types.scala:796)
[error]     at scala.reflect.internal.Types$Type.instantiateTypeParams(Types.scala:572)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer$$anonfun$methTypeArgs$2.apply(Infer.scala:673)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer$$anonfun$methTypeArgs$2.apply(Infer.scala:671)
[error]     at scala.reflect.internal.util.Collections$class.map2(Collections.scala:51)
[error]     at scala.reflect.internal.SymbolTable.map2(SymbolTable.scala:13)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer.methTypeArgs(Infer.scala:671)
[error]     at scala.tools.nsc.typechecker.Infer$Inferencer.inferMethodInstance(Infer.scala:1163)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.handlePolymorphicCall$1(Typers.scala:3403)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3409)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.handleOverloaded$1(Typers.scala:3185)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.doTypedApply(Typers.scala:3188)
[error]     at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$94.apply(Typers.scala:4580)
[error]     at scala.tools.nsc.typechecker.Typers$Typer$$anonfun$94.apply(Typers.scala:4580)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.silent(Typers.scala:744)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.tryTypedApply$1(Typers.scala:4580)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.normalTypedApply$1(Typers.scala:4633)
[error]     at scala.tools.nsc.typechecker.Typers$Typer.typedApply$1(Typers.scala:4666)
[trace] Stack trace suppressed: run last scalajs-scalalib/compile:package-js for the full output.
[error] (scalajs-scalalib/compile:package-js) java.lang.IllegalArgumentException: requirement failed
[error] Total time: 67 s, completed Apr 22, 2013 11:01:23 PM
>

GenJSCode abort with pattern match guards

Compiling this code will cause a compiler abort:

object ScalaJSExample {
  def go(f: Int => Int) = f(1)
  def main(): Unit = {
    go {
      case x if false => x
    }
  }
}

[error] Found unknown label apply(case5) at source-/tmp/abort.scala,line-6,offset=102: case5()
[error] at scala.reflect.internal.SymbolTable.abort(SymbolTable.scala:49)
[error] at scala.tools.nsc.Global.abort(Global.scala:253)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genApply(GenJSCode.scala:1334)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genExpr(GenJSCode.scala:783)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$37.genCaseBody$1(GenJSCode.scala:1639)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$37.apply(GenJSCode.scala:1643)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$37.apply(GenJSCode.scala:1626)
[error] at scala.collection.TraversableLike$WithFilter$$anonfun$map$2.apply(TraversableLike.scala:722)
[error] at scala.collection.immutable.List.foreach(List.scala:318)
[error] at scala.collection.TraversableLike$WithFilter.map(TraversableLike.scala:721)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genTranslatedMatch(GenJSCode.scala:1626)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genExpr(GenJSCode.scala:878)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genMethodBody(GenJSCode.scala:696)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genMethod(GenJSCode.scala:555)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$2(GenJSCode.scala:198)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$2$1.apply(GenJSCode.scala:192)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$2$1.apply(GenJSCode.scala:192)
[error] at scala.collection.immutable.List.foreach(List.scala:318)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$2(GenJSCode.scala:192)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.genClass(GenJSCode.scala:204)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$1(GenJSCode.scala:128)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$1$1.apply(GenJSCode.scala:108)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase$$anonfun$scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$1$1.apply(GenJSCode.scala:108)
[error] at scala.collection.immutable.List.foreach(List.scala:318)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.scala$tools$nsc$backend$js$GenJSCode$JSCodePhase$$gen$1(GenJSCode.scala:108)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.apply(GenJSCode.scala:139)
[error] at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:463)
[error] at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:430)
[error] at scala.tools.nsc.Global$GlobalPhase$$anonfun$run$1.apply(Global.scala:430)
[error] at scala.collection.Iterator$class.foreach(Iterator.scala:727)
[error] at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
[error] at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:430)
[error] at scala.tools.nsc.backend.js.GenJSCode$JSCodePhase.run(GenJSCode.scala:62)
[error] at scala.tools.nsc.Global$Run.compileUnitsInternal(Global.scala:1582)
[error] at scala.tools.nsc.Global$Run.compileUnits(Global.scala:1556)
[error] at scala.tools.nsc.Global$Run.compileSources(Global.scala:1552)
[error] at scala.tools.nsc.Global$Run.compile(Global.scala:1661)
[error] at scala.tools.nsc.Driver.doCompile(Driver.scala:33)
[error] at scala.tools.nsc.scalajs.Main$.doCompile(Main.scala:86)
[error] at scala.tools.nsc.Driver.process(Driver.scala:54)
[error] at scala.tools.nsc.Driver.main(Driver.scala:67)
[error] at scala.tools.nsc.scalajs.Main.main(Main.scala)

String has no method 'compareTo'

Executing the code below leads in Chrome to the error message Uncaught TypeError: Object world has no method 'compareTo'.

import scala.collection.immutable._
var collection = SortedSet("hello")
collection += "world"

optimizeJS output should be wrapped in a (function(){})()

...as described by this. Otherwise the barrage of short names pollutes your global namespace, stomping over everything! In my case, the minified name cp stomped over the cp introduced by ChipmunkJS, resulting in everything falling to pieces at runtime. I have verified that wrapping the output manually solves the problem, but it would be great if I didn't need to manually go wrap stuff after each optimizeJS

Allow passing of externs directly to optimizeJS

Externs reserve some names as coming from external sources (e.g. external libraries) preventing closure compiler from stomping over them. They can be passed as compiler args to closure or declared directly in the JS sources:

function cp(){};
function ScalaJSBundle(){};
ScalaJS.modules.example_ScalaJSExample().main();

Unfortunately, declaring them directly in JS suffers a problem: while it makes optimizeJS pass, their empty-function-ness in turn makes the code generated by packageJS fail!

A dumb solution is to comment them out before running packageJS. A better solution is to pass them to closure compiler directly from SBT, so they can be passed to optimizeJS but not interfere with the code generated by packageJS.

Can't compile

I'm trying out the package-js as described in the readme. I'm just getting this:

[info] Done updating.
[warn] /Users/hhrutz/Documents/devel/scala-js/compiler/src/main/scala/scala/tools/nsc/scalajs/Main.scala:65: class RefinedBuildManager in package interactive is deprecated: Use sbt incremental compilation mechanism
[warn]         case _          => new RefinedBuildManager(settings)
[warn]                                ^
[warn] one warning found
[error] Usage: scalac <options> <source files>
[error] where possible standard options include:
...
[error] (scalajs-scalalib/compile:package-js) java.lang.IllegalArgumentException: requirement failed
[error] (scalajs-javalib/compile:package-js) java.lang.IllegalArgumentException: requirement failed
[error] Total time: 61 s, completed Mar 15, 2013 2:54:32 PM
> last scalajs-scalalib/compile:package-js
java.lang.IllegalArgumentException: requirement failed
    at scala.Predef$.require(Predef.scala:202)
    at sbt.Process$.cat(Process.scala:66)
    at ScalaJSBuild$$anonfun$8.apply(ScalaJSBuild.scala:111)
    at ScalaJSBuild$$anonfun$8.apply(ScalaJSBuild.scala:108)
    at sbt.Scoped$$anonfun$hf3$1.apply(Structure.scala:579)
    at sbt.Scoped$$anonfun$hf3$1.apply(Structure.scala:579)
    at scala.Function1$$anonfun$compose$1.apply(Function1.scala:49)
    at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$12.apply(Structure.scala:311)
    at sbt.Scoped$Reduced$$anonfun$combine$1$$anonfun$apply$12.apply(Structure.scala:311)
    at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:41)
    at sbt.std.Transform$$anon$5.work(System.scala:71)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:232)
    at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:232)
    at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
    at sbt.Execute.work(Execute.scala:238)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:232)
    at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:232)
    at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
    at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:680)

Problem accessing Dynamic object properties

While parsing levels for my Collidium game I need to parse points, which I am doing here:
https://github.com/shadaj/collidium/blob/eac34d7b18dd839327b5665819c208540fad9fdc/src/main/scala/me/shadaj/collidium/Main.scala#L17

Since the input comes from JSON parsing, the json parameter is of type Dynamic. When I try to do json.x (by replacing the original line with new Point(json.x.toString.toInt, json.y.toString.toInt), I get this error:

[error] .../collidium-online/src/main/scala/me/shadaj/collidium/Main.scala:17: error: type mismatch;
[error] found : json.type (with underlying type scala.js.Dynamic)
[error] required: ?{def x: ?}
[error] Note that implicit conversions are not applicable because they are ambiguous:
[error] both method any2Ensuring in object Predef of type [A](x: A)Ensuring[A]
[error] and method any2ArrowAssoc in object Predef of type [A](x: A)ArrowAssoc[A]
[error] are possible conversion functions from json.type to ?{def x: ?}
[error] new Point(json.x.toString.toInt, json.y.toString.toInt)
[error] ^

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.