Chat: #scala-js on Discord.
This is the repository for Scala.js, the Scala to JavaScript compiler.
Scala.js is distributed under the Apache License Version 2.0.
Scala.js, the Scala to JavaScript compiler
Home Page: https://www.scala-js.org/
License: Apache License 2.0
Chat: #scala-js on Discord.
This is the repository for Scala.js, the Scala to JavaScript compiler.
Scala.js is distributed under the Apache License Version 2.0.
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
}
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.
The following fails on the second line
val it: Array[Byte] = Array(0, 1)
it(0).toString
Cannot call method toString
of undefined
[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?
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"
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.
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
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)
Except if it is an anonymous function (sym.isAnonymousFunction == true
)
It seems the standard lib is missing stubs for those two classes (which are probably auto-inserted during compilation at some point). If I add stubs for those two the script errors reported in sjrd/scala-js-example-app#1 go away.
After doing a clone with the following command
git clone --recursive https://github.com/lampepfl/scala-js.git
Running sbt in the scala.js folder ends up getting hung on
Getting net.java.dev.jna jna 3.2.3 ...
I am not sure if this is an issue with the sbt used with scala-js or just an issue with sbt alone
Im using sbt version 0.12.4
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.
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")
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?
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:
Disadvantages:
Some notes:
The following line should dispatch split
on WrappedString
(after PIMPing).
println("a?b".split('?').toList)
However, the line yields List("a?b")
rather than List("a", "b")
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] ^
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
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.
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?
Hi,
If I do 7 / 2.0, the expected result it's a double, but the js codes cast it to an Int because it only takes into account the left operand. It should take instead the "largest", in the sense Short < Int < Long < Float < Double ....
The problem can be seen clearly here:
https://github.com/lampepfl/scala-js/blob/master/compiler/src/main/scala/scala/tools/nsc/backend/js/GenJSCode.scala#L1739
String.format("%0#8x", new Integer(5))
yields 000000x5 instead of 0x000005
This fails on the subSequence
call.
(Cannot find function subSequence__I__I__java_lang_CharSequence in object abcdefghi)
val arr = Array[Char]('a' to 'i': _*)
val seq: CharSequence = arr
val ss1 = seq.subSequence(0, 8)
println(seq)
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?
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")
}
See discussion here:
https://groups.google.com/forum/#!topic/scala-js/gYPl16lPe5I
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.
we need a way to loop through native javascript object's properties. the current workaround is mentioned in this email on the scala-js mailing list: https://groups.google.com/forum/?fromgroups#!topic/scala-js/0HyNNM1Chxc
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
...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
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.
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:
Disadvantages:
Here is a minimised failing test:
it("should not throw a StackOverflowError") {
class A (s: String, e: Object) {
def this(e: Object) = this("", e)
def this(s: String) = this(s, "")
}
class B(s: String, e: Object) extends A(s)
new B("", "")
}
This fails at runtime: "abc".toCharArray
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
.
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.Object
s 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 =(.
Headline says it all, for example the expression "aa".replace('a', 'b') will result in "bb" in Scala and in "ba" in Scala.js.
def clone[T](arr: Array[T]) = arr.clone()
clone(Array("one", "two"))
Cannot find function scala_runtime_ArrayRuntime in object [object Object].
scala.collection.mutable.BitSet
does not correctly calculate its size. This is certainly due to the restrictions on Longs on the JavaScript platform.
This should be fixed as soon as longs are implemented.
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()
.
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)
At this point it throw a ☹ TypeError
. Here is a failing test:
it("should throw a NullPointerException when calling a method on null") {
try {
null.toString()
} catch {
case e: NullPointerException => ()
}
}
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)
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
>
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?
The package scala.js
should provide static types for all of the ECMAScript 5 standard library. See the spec at
http://www.ecma-international.org/ecma-262/5.1/#sec-15
DOM and other libraries are not part of this, and should be defined in separate projects (not in the core scala-js repo).
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.)
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.
It would be really awesome to have some basic reflection support:
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.