These are chat archives for chandu0101/scalajs-react-components

1st
Jun 2017
Roberto Leibman
@rleibman
Jun 01 2017 21:03
And on a different topic... I'm now also generating elemental files, but the problem I'm struggling with there is that the js is structured differently for a lot of their classes, and the parsing you're using is not very intuitive. Some classes are declaring a var and then doing the module.exports explicitly, but others don't declare a var and instead export implicitly, for example:
module.exports = React.createClass({
        displayName: 'Button',
        ...
So I'm trying to wrap my head around the parser, and figure out where in the visitor I should do what.
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 21:59
right, i would propose we do things piece by piece though, how about we start as simple as possible and fix materialui first? :)
in terms of the generator source code
the visitors are actually pretty simple, although they dont look like it!
what i did was i would parse a file with nashorn, then use the intellij debugger to dig into the trees to see what i needed
Roberto Leibman
@rleibman
Jun 01 2017 22:00
Yes, that's my intent, but I left here my last error message that I didn't know how to manage and wanted to go on.
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:00
its a bit unwieldy since we dont have extractors for the java ast, but it works out fine enough
the other part of the generator, which finds files, does it recursively and so on is... not clever
i have already rewritten it to be more clever, but then i ended up with a lot of extra files which didnt compile after generation :)
right, as to that error message
its the result of two conflicting hacks
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:06
the problem is that the macro generates the props object, and to do that it uses js.Dynamic. js.Dynamic require that the prop values be (convertible to) js.Any.
so for type parameters, the generator inserts a conversion
so if you have, i guess js.UndefOr[T | js.Array[T]]
there is probably some conflict with that inserted conversion and the "proof" we supply that js.| is js.Any
the generated proof is hack in printers.scala
Roberto Leibman
@rleibman
Jun 01 2017 22:11
What if we force it by changing the declaration to T <: js.Any
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:12
that would definitely work. i wanted it to work for case classes, which is why i solved it that way
im not sure how well that worked anyway, so feel free to add the type bound
Roberto Leibman
@rleibman
Jun 01 2017 22:13
The type bound didn't seem to do nanything
So the problem is not with the T, but with the js.Array[T]
Because this works value: js.UndefOr[T] = js.undefined, but this doesn't value: js.UndefOr[js.Array[T]] = js.undefined,
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:18
hmm, hang on
that works on my side
Roberto Leibman
@rleibman
Jun 01 2017 22:21
Adding the bound?
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:21
without a bound even, because js.Array is already js.Any
Roberto Leibman
@rleibman
Jun 01 2017 22:22
I thoughts so too.
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:24
  a:           js.UndefOr[js.UndefOr[T]] = js.undefined,
  b:           js.UndefOr[js.UndefOr[T | js.Array[T]]] = js.undefined
those work. adding the bound is necessary for a
Roberto Leibman
@rleibman
Jun 01 2017 22:25
ah!
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:25
what is your types exactly?
Roberto Leibman
@rleibman
Jun 01 2017 22:26
case class MuiIconMenu[T](
value:                    js.UndefOr[T | js.Array[T]]                              = js.undefined,
)
I'm assuming that's the one that's giving me the error.
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:31
same compile error as above?
Roberto Leibman
@rleibman
Jun 01 2017 22:31
Let me try again with the added bounds (I made the change in com.olvind.props)
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:32
you can debug these things with implicitly by the way
implicitly[T => js.Any]
if it compiles it works, so you gradually simplify the type until you figure out whats wrong
that fragment there does need the bound to compile
Roberto Leibman
@rleibman
Jun 01 2017 22:36
Compiling now... the compiler takes forever!
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:37
the generation added quite a bit of time i can imagine
Roberto Leibman
@rleibman
Jun 01 2017 22:38
The generation is quite quick actually... I think it's the JsMacro that slows everything down.
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 22:39
most probably
we could move that the work of the macro to the generation actually
Roberto Leibman
@rleibman
Jun 01 2017 22:40
I thought about that, it would make what's happening clearer in a way.
Roberto Leibman
@rleibman
Jun 01 2017 23:01
:( It finally got to MuiIconMenu. Same error, with the bounds.
The error is:
[error] /home/rleibman/workspace.scala/scalajs-react-components/gen/target/scala-2.12/src_managed/chandu0101/scalajs/react/components/materialui/MuiIconMenu.scala:154: diverging implicit expansion for type scala.scalajs.js.|.Evidence[T,B]
[error] starting with method left in class EvidenceLowPrioImplicits
[error]     val props = JSMacro[MuiIconMenu[T]](this)
[error]                        ^
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 23:05
can you post the whole file?
Roberto Leibman
@rleibman
Jun 01 2017 23:05
The class looks like this (abstracting only what I think are the relevant parts:)
case class MuiIconMenu[T <: js.Any](

  onChange:                 js.UndefOr[(TouchTapEvent, T | js.Array[T]) => Callback] = js.undefined,
  value:                    js.UndefOr[T | js.Array[T]]                              = js.undefined,
){

  /**
    * @param children Should be used to pass `MenuItem` components.
   */
  def apply(children: VdomNode*) = {
    implicit def evT(t: T): js.Any = t.asInstanceOf[js.Any]
    val props = JSMacro[MuiIconMenu[T]](this)
    val f = JsComponent[js.Object, Children.Varargs, Null](Mui.IconMenu)
    f(props)(children: _*)
  }
}
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 23:07
try to remove evT
Roberto Leibman
@rleibman
Jun 01 2017 23:08
Same thing
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 23:09
can you comment out onChange to make sure that is not the problem?
also, put these in there to see where it stopsimplicitly[T => js.Any] implicitly[js.Array[T] => js.Any] implicitly[T | js.Array[T] => js.Any]
put them on different lines, so you can see the line number
also, what are the package/import statements? because that compiles here
Roberto Leibman
@rleibman
Jun 01 2017 23:14
import chandu0101.macros.tojs.JSMacro
import japgolly.scalajs.react.
import japgolly.scalajs.react.raw.

import japgolly.scalajs.react.vdom._
import org.scalajs.dom
import scala.scalajs.js
import scala.scalajs.js.|
It doesn't have any problem with implicitly[T => js.Any] or implicitly[js.Array[T] => js.Any]
But with implicitly[T | js.Array[T] => js.Any] I get
diverging implicit expansion for type T | scala.scalajs.js.Array[T] ⇒ scala.scalajs.js.Any starting with method base in object Evidence
not enough arguments for method implicitly: (implicit e: T | scala.scalajs.js.Array[T] ⇒ scala.scalajs.js.Any)T | scala.scalajs.js.Array[T] ⇒ scala.scalajs.js.Any. Unspecified value parameter e.
Roberto Leibman
@rleibman
Jun 01 2017 23:20
Adding this, obviously fixes it, but it's a hack implicit def evT2(t: T | js.Array[T]): js.Any = t.asInstanceOf[js.Any]
Øyvind Raddum Berg
@oyvindberg
Jun 01 2017 23:24
this seems like one of those magical problems only sbt clean can fix :D
leave the hack in, and i can have a look at your code when youre ready to push
Roberto Leibman
@rleibman
Jun 01 2017 23:24
Yeah, I tried that, no.
I'll leave the hack in.
Roberto Leibman
@rleibman
Jun 01 2017 23:31
I've commited all my latest work, I've got to go for now.