seanjensengrey / kiama

Automatically exported from code.google.com/p/kiama
GNU Lesser General Public License v3.0
0 stars 0 forks source link

ScalaJS support #64

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
It will be great if you would add scalajs support, this will allow to use kiama 
on the client and in cross scala/scalajs libs

Original issue reported on code.google.com by antonkul...@gmail.com on 6 May 2014 at 4:40

GoogleCodeExporter commented 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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago

Original comment by inkytonik on 12 Jan 2015 at 3:07

GoogleCodeExporter commented 9 years ago

Original comment by inkytonik on 12 Jan 2015 at 3:08

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
sorry for type errors =(

Original comment by antonkul...@gmail.com on 29 Jan 2015 at 1:26

GoogleCodeExporter commented 9 years ago
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