Open GoogleCodeExporter opened 9 years ago
Yes, I agree that this would be good to have. In the past we have not tried to
do it since we make some use of macros and ScalaJS didn't support those.
However, I notice that there is some support for macros now. We will try when
some time becomes available and see how it goes. I will report back here once
we have something to say.
Original comment by inkytonik
on 7 May 2014 at 12:24
It appears that we will also have a sticking point over reflection. The Kiama
rewriting facility uses Java reflection via getConstructors so it can build a
new value with the same class as a value that is being generically rewritten.
The ScalaJS docs say that there is some support for java.lang.Class but It's
not clear whether getConstructors is included. Until we get a way to do that on
the JS platform, we won't be able to move rewriting over.
Original comment by inkytonik
on 15 May 2014 at 5:21
Without knowing too much about Kiama, but might a type class like
CanInstantiate[T] be an appropriate generalization of calling getConstructors
directly? On the JVM there could be a default implicit which uses
getConstructors whereas for ScalaJS one could create another solution.
Original comment by Martin.Mauch@gmail.com
on 3 Jan 2015 at 9:26
That might be a way forward. Do you know enough about the ScalaJS platform to
suggest whether an implementation of this generic operation would be easy
enough to write?
Original comment by inkytonik
on 12 Jan 2015 at 3:07
Original comment by inkytonik
on 12 Jan 2015 at 3:07
Original comment by inkytonik
on 12 Jan 2015 at 3:08
TBH, I didn't have the chance to use ScalaJS myself, so I posted the question
on the mailing list:
https://groups.google.com/forum/#!topic/scala-js/NnSvK_FmEgc
Original comment by Martin.Mauch@gmail.com
on 28 Jan 2015 at 10:41
getConstructors() is not support on Scala.js, no, and will never be. Just like
getMethods, getFields.
If a purely compile-time implementation via (possibly macro-generated)
type-classes or factory methods is not possible, the standard way to
instantiate "reflectively" instances of classes in Scala.js is via JS
reflection.
With the @JSExport and @JSExportDescendentClasses annotations (see the doc at
http://www.scala-js.org/api/scalajs-library/0.6.0-RC2/#scala.scalajs.js.annotati
on.package), one can force a class/constructor, or all the classes inheriting
from a class or trait, to be exported to JavaScript under their fully qualified
name. This forces these classes to be always emitted in the file .js file,
because they cannot be dead-code-eliminated. But in exchange you get the
ability to load them via JS interop: (example for Scala.js 0.6.x, currently in
RC2)
package foo
import scala.scalajs.js
import js.annotation.JSExport
@JSExport // in 0.5.x, need to write @JSExport("foo.Bar")
class Bar(val x: Int)
val instance = instantiateReflectively(classOf[Bar])(5)
def instantiateReflectively[A](cls: Class[A])(args: Any*): A = {
val ctor = (js.Dynamic.global /: cls.getName.split("\\.")) { (prev, part) =>
prev.selectDynamic(part)
}
js.Dynamic.newInstance(ctor)(args.asInstanceOf[Seq[js.Any]]: _*).asInstanceOf[A]
}
Original comment by sjrdoera...@gmail.com
on 28 Jan 2015 at 10:57
Thanks for taking the time to help us out. Your solution seems to be a good
one. I will take a look in more detail when I have a bit more time to
investigate the JS direction.
BTW, perhaps you can answer something else for me. Is there a standard approach
to publishing ScalaJS compiled libraries. For the JVM version we publish via
Maven Central but I'm not aware of the convention for ScalaJS. If we are to
make a ScalaJS version of Kiama how would we best make it available to user?
Original comment by inkytonik
on 29 Jan 2015 at 1:13
You can publish to Maven central without any problems. The only difference is
artifact name. Scalajs sbt plugin automatically adds "sjs-0.6.0" (or whatever
scalajs version you are using) to the artifact name. Everything else is the
same, most of scalajs projects are p suffix publshed either to maven central or
to bintray.
In your case it is better to to with 0.6.0 version of ScalaJS as it has some
nice features, like CrossProjects (
http://www.scala-js.org/api/sbt-scalajs/0.6.0-RC2/#org.scalajs.sbtplugin.cross.C
rossProject ) that make it easy to share source between projects
Original comment by antonkul...@gmail.com
on 29 Jan 2015 at 1:25
sorry for type errors =(
Original comment by antonkul...@gmail.com
on 29 Jan 2015 at 1:26
As was said, you publish Scala.js libraries exactly like Scala/JVM libraries:
on Maven Central or on Bintray, or anything you may prefer. The mechanism is
*exactly* the same (publish/publishLocal/publishSigned/etc.). Similarly, you
use libraryDependencies to depend on other Scala.js libraries, with the slight
variation that you use %%% instead of %% in the module specification.
When publishing a cross-compiling library, it is customary to give the same
`name` setting to both the JVM and JS versions. The moduleName will therefore
be the same. The Scala.js sbt plugin will automatically append a
Scala.js-specific suffix to the artifact that is published. Just like sbt
already appends a Scala-specific suffix such as _2.11. With Scala.js you
therefore end up with a suffix like _sjs0.5_2.11. The %%% transparently
resolves the appropriate artifacts.
Original comment by sjrdoera...@gmail.com
on 29 Jan 2015 at 10:42
Original issue reported on code.google.com by
antonkul...@gmail.com
on 6 May 2014 at 4:40