Git Product home page Git Product logo

jscala's People

Contributors

nau avatar paweld2 avatar tbje avatar xeno-by avatar zbsz 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

jscala's Issues

Constructor bodies are dropped

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.

Factor out eval functionality

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?

Match/Switch impromevents

  • Don't generate block for single statement
val a = 1 match {
  case 1 => 1
}

should not generated block like this:

var a;
switch(1) {
  case 1: 
     {
        a = 1;
     };
      break;
}
  • Alternatives
1 match {
 case 1 | 2 => 1
}

should translate to

switch(1) {
  case 1:
  case 2: 1; break;
}
  • Guards
1 match {
 case 1 if true => 1
}

should translate to

switch(1) {
  case 1: if (true) { 1; break;}
}

Improve Seq JsSerializer

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
  }

Scala 3 Support

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.

AST generation should use fully qualified names?

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 {

trait T { val f1: F1 = ??? }; javascript { new T { val f1: F1 = ... } } compiles without error

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).

Don't prefix/qualify names

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.

2.12 support

Are there any plans of releasing against 2.12.x Scala series?

`for (x <- l) ...` generates `for (x in l) ...` where `l` is a sequence

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).

Iteration over `Array[Int]` causes `MatchError` in macro

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);
}

Escape strings

Currently:

javascript {
    val attribution = """&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"""
}

and

javascript {
    val attribution = "&copy; <a href=\"http://osm.org/copyright\">OpenStreetMap</a> contributors"
}

gives:

var attribution = "&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors";

javascript { L.f(3) } gives full.package.prefix.L.f(3) outside org.jscala

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)

If expression

Translate simple if expressions to ternary operator:

val a = if (true) 1 else 2

should translate to

var a = true ? 1 : 2;

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.