nau / jscala Goto Github PK
View Code? Open in Web Editor NEWScala macro that produces JavaScript from Scala code.
License: MIT License
Scala macro that produces JavaScript from Scala code.
License: MIT License
scala> javascript { class C { console.log() } }.asString
res1: String =
{
function C() {
};
}
Should output
function C() {
console.log()
};
Also the constructor body should be inserted after all method "definitions" so it has access to them.
I think it'd be useful to have the pure JS generation as a distinct library from being able to evaluate the JS. Evaluation of JS isn't something that I need in sbt-web (we have js-engine for that), however JS code generation is something that we're interested in.
WDYT?
...so that they can be used in scala, and rendered to javascript.
This would require a different approach than adding a method to the companion object, like the one I described here: https://groups.google.com/d/msg/jscala-user/b8QV0oofg3c/w_95Bjx7GQ0J
Is it one word or two words? If it's one word then the S should always be lowercase (including the annotation and the method it generates), no?
val a = 1 match {
case 1 => 1
}
should not generated block like this:
var a;
switch(1) {
case 1:
{
a = 1;
};
break;
}
1 match {
case 1 | 2 => 1
}
should translate to
switch(1) {
case 1:
case 2: 1; break;
}
1 match {
case 1 if true => 1
}
should translate to
switch(1) {
case 1: if (true) { 1; break;}
}
Actual behavior:
res = (((("Sorry, I can't greet you in ") + language)) + " yet")
Expected behavior:
res = "Sorry, I can't greet you in " + language + " yet"
Currently only Seq[JsExpr]
is supported. I suppose you could do xs.map(inject) but with the following any Seq[A] where A can be serialized is supported.
implicit def seqJsSerializer[A, S[X] <: Seq[X]](implicit ev: JsSerializer[A]): JsSerializer[S[A]] = new JsSerializer[S[A]] {
def apply(a: S[A]) = JsArray(a.map(ev.apply(_)).toList)
}
To support the currently supported Seq[JsExpr] you may want to add
implicit object exprJsSerializer extends JsSerializer[JsExpr] {
def apply(a: JsExpr) = a
}
def m1 = javascript { "string" }
def m2() = javascript { "string" }
javascript {
console.log(m2()) // seems it prints `string`
console.log(m1) // seems it gets an error `m1` is not defined
}
May I know if there is a plan to support Scala 3? This is a nice tool to write js snippet but one concern is this may be a blocker when we are upgrading to Scala 3.
Cheers.
This one was a little bit surprising. I assume the AST generator is not specifying which JsIf to use and that the lift one is picked as it's imported specifically.
import org.jscala._
import net.liftweb.http.js.JsCmds.JsIf
javascript {
if (true) "ter" else "er"
}
/..../Js.scala:120: overloaded method value apply with alternatives:
(condition: net.liftweb.http.js.JsExp,bodyTrue: net.liftweb.http.js.JsExp,bodyFalse: net.liftweb.http.js.JsExp)net.liftweb.http.js.JsCmd
(condition: net.liftweb.http.js.JsExp,body: net.liftweb.http.js.JsExp)net.liftweb.http.js.JsCmd
(condition: net.liftweb.http.js.JsExp,bodyTrue: net.liftweb.http.js.JsCmd,bodyFalse: net.liftweb.http.js.JsCmd)net.liftweb.http.js.JsCmd
(condition: net.liftweb.http.js.JsExp,body: net.liftweb.http.js.JsCmd)net.liftweb.http.js.JsCmd
cannot be applied to (org.jscala.JsBinOp, org.jscala.JsCall, Some[org.jscala.JsCall])
javascript {
{ x: Int => x }
generates
function (x) {
return x;
};
I was hoping for a (relatively) type safe and lightweight way of providing options to JavaScript APIs. Suppose we have:
scala> object L { def f(opt: Opt): Int = ???; trait Opt { val a: String = ??? } }
defined module L
Then the following:
scala> javascript { L.f(new L.Opt { val a = "a" }) } asString
$anon
L.Opt{}
res0: String =
L.f({
a: "a"
})
scala> javascript { new L.Opt { val a = "a" } } asString
res1: String =
{
function $anon() {
this.a = "a";
};
new $anon();
}
compiles and generates proper JavaScript, but it should fail like this:
scala> new L.Opt { val a = "a" }
<console>:13: error: overriding value a in class Opt$class of type String;
value a needs `override' modifier
new L.Opt { val a = "a" }
I thought that simple c.typeCheck(...)
in jsAnonObjDecl
will fix this, but apparently this doesn't work (it still type checks).
What/how common is the use case?
If a user wants prefixed javascript names, there could be an annotation (like in scala-js) that specifies the javascript name to use. This is more general than adding a prefix. The javascript name could be completely different if desired.
Are there any plans of releasing against 2.12.x Scala series?
Please add support for the javascript instanceof operator.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof
I'm trying to make a JSON stringifier function and I'm blocked on this.
This works for objects, but not for sequences (e.g. arrays), because x
is a string index in js in this case and iteration order is implementation dependent:
var l = [true, false]; for (var x in l) console.log(x, typeof(x), l[x], typeof(l[x]))
0 string true boolean
1 string false boolean
Something like this:
for (var i = 0, x = l[i]; i < l.length; x = l[++i]) body
could be generated instead (i
is synthetic) (so that body doesn't have to be rewritten).
Support for trait and class generation
scala> javascript { val l = Array("1"); for (x <- l) { console.log(x); } }.asString
res18: String =
{
var l = ["1"];
for (x in l) console.log(x);
}
scala> javascript { val l = Array(1); for (x <- l) { console.log(x); } }.asString
<console>:11: error: exception during macro expansion:
scala.MatchError: scala.this.Predef.intArrayOps(l).foreach[Unit] (of class scala.reflect.internal.Trees$TypeApply)
but you can iterate over Array[Array[Int]]
:
scala> javascript { val l = Array(Array(1)); for (x <- l) { console.log(x); } }.asString
res20: String =
{
var l = [[1]];
for (x in l) console.log(x);
}
E.g., delete array[10]
;
Currently:
javascript {
val attribution = """© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"""
}
and
javascript {
val attribution = "© <a href=\"http://osm.org/copyright\">OpenStreetMap</a> contributors"
}
gives:
var attribution = "© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors";
One can just put all APIs in package org.jscala { ... }
to temporarily fix this issue.
This can be showed in repl:
scala> import org.jscala._
import org.jscala._
scala> object L { def f(x: Int): Int = ??? }
defined module L
scala> javascript { L.f(3) }
res0: org.jscala.JsCall = JsCall(JsSelect(JsSelect(JsSelect(JsSelect(JsSelect(JsSelect(JsSelect(JsIdent($line4),$read),$iw),$iw),$iw),$iw),L),f),List(JsNum(3.0,false)))
Note that repl strips its internal wrappers when printing results, so:
scala> javascript { L.f(3) } asString
res1: String = L.f(3)
but you can println
to show full prefix.
scala> println(javascript { L.f(3) } asString)
$line4.$read.$iw.$iw.$iw.$iw.L.f(3)
Create Fiddle for JScala like:
http://jsfiddle.net/
http://cljsfiddle.net/
It can be run here:
http://fiddle.jscala.org
or here:
http://run.jscala.org
Translate simple if expressions to ternary operator:
val a = if (true) 1 else 2
should translate to
var a = true ? 1 : 2;
Use https://github.com/sjrd/scala-js-ts-importer to import TypeScript definitions from https://github.com/borisyankov/DefinitelyTyped
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.