nau / jscala

Scala macro that produces JavaScript from Scala code.
MIT License
205 stars 25 forks source link

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

Open mattpap opened 11 years ago

mattpap commented 11 years ago

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

nau commented 11 years ago

That's an interesting one. As @xeno_by explained that's because Scala checks overriding during refchecks phase, which apparently is executed after macro expansion. And as after javascript macro expansion there is no original Scala code which should not compile - the original code compiles. As a solution it's recommended to keep original Scala code after expansion. I'll implement it a bit later.