Skip to content

Commit

Permalink
Merge pull request #276 from UdashFramework/diverging-implicits
Browse files Browse the repository at this point in the history
Property implicits cleanup
  • Loading branch information
ddworak authored May 6, 2019
2 parents cdc298d + 2277235 commit d8b6964
Show file tree
Hide file tree
Showing 17 changed files with 611 additions and 847 deletions.
8 changes: 8 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 30 additions & 32 deletions core/.js/src/test/scala/io/udash/bindings/TagsBindingTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,31 @@ import scala.collection.mutable
class TagsBindingTest extends UdashFrontendTest with Bindings { bindings: Bindings =>
import scalatags.JsDom.all._

object Model {
class WithSubClass(val i: Int, val subType: SubClass)
object WithSubClass extends HasModelPropertyCreator[WithSubClass]

class SubClass(val i: Int)
object SubClass extends HasModelPropertyCreator[SubClass]

trait WithSubTrait {
def i: Int
def subType: SubTrait
}
object WithSubTrait extends HasModelPropertyCreator[WithSubTrait]

trait SubTrait {
def i: Int
}
object SubTrait extends HasModelPropertyCreator[SubTrait]
}

trait TodoElement {
def name: String
def completed: Boolean
}
object TodoElement extends HasModelPropertyCreator[TodoElement]

"bind" should {
"update content of DOM element" in {
val p = Property[String]("A")
Expand Down Expand Up @@ -538,15 +563,7 @@ class TagsBindingTest extends UdashFrontendTest with Bindings { bindings: Bindin
}

"handle empty case class based model properties" in {
object Model {
class Test(val i: Int, val subType: SubTest)
object Test extends HasModelPropertyCreator[Test]

class SubTest(val i: Int)
object SubTest extends HasModelPropertyCreator[SubTest]
}

val p = ModelProperty(null: Model.Test)
val p = ModelProperty(null: Model.WithSubClass)
val sub = p.subProp(_.subType)
val template = div(
produce(p) { t =>
Expand All @@ -559,25 +576,12 @@ class TagsBindingTest extends UdashFrontendTest with Bindings { bindings: Bindin

template.textContent should be("")

p.set(new Model.Test(5, new Model.SubTest(7)))
p.set(new Model.WithSubClass(5, new Model.SubClass(7)))
template.textContent should be("577")
}

"handle empty trait based model properties" in {
object Model {
trait Test {
def i: Int
def subType: SubTest
}
object Test extends HasModelPropertyCreator[Test]

trait SubTest {
def i: Int
}
object SubTest extends HasModelPropertyCreator[SubTest]
}

val p = ModelProperty(null: Model.Test)
val p = ModelProperty(null: Model.WithSubTrait)
val sub = p.subProp(_.subType)
val template = div(
produce(p) { t =>
Expand All @@ -590,9 +594,9 @@ class TagsBindingTest extends UdashFrontendTest with Bindings { bindings: Bindin

template.textContent should be("")

p.set(new Model.Test {
p.set(new Model.WithSubTrait {
override def i = 5
override def subType = new Model.SubTest {
override def subType = new Model.SubTrait {
override def i = 7
}
})
Expand Down Expand Up @@ -1520,12 +1524,6 @@ class TagsBindingTest extends UdashFrontendTest with Bindings { bindings: Bindin
case object ActiveTodosFilter extends TodosFilter(todo => !todo.completed)
case object CompletedTodosFilter extends TodosFilter(todo => todo.completed)

trait TodoElement {
def name: String
def completed: Boolean
}
object TodoElement extends HasModelPropertyCreator[TodoElement]

case class Todo(override val name: String,
override val completed: Boolean) extends TodoElement

Expand Down
89 changes: 18 additions & 71 deletions core/src/main/scala/io/udash/properties/Blank.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,79 +13,26 @@ trait Blank[A] {
def value: A
}

object Blank extends LowPrioImplicits {
case class Simple[A](value: A) extends AbstractCase with Blank[A]
case class Factory[A](factory: () => A) extends AbstractCase with Blank[A] {
object Blank {
def apply[A](implicit ev: Blank[A]): Blank[A] = ev

final case class Simple[A](value: A) extends AbstractCase with Blank[A]
final case class Factory[A](factory: () => A) extends AbstractCase with Blank[A] {
override def value: A = factory()
}

implicit val double: Blank[Double] = Simple(0.0)
implicit val float: Blank[Float] = Simple(0.0f)
implicit val long: Blank[Long] = Simple(0L)
implicit val int: Blank[Int] = Simple(0)
implicit val short: Blank[Short] = Simple(0)
implicit val byte: Blank[Byte] = Simple(0)
implicit val boolean: Blank[Boolean] = Simple(false)
implicit val unit: Blank[Unit] = Simple(())
implicit val string: Blank[String] = Simple("")

private val simpleNone = Simple(None)
implicit def option[A]: Blank[Option[A]] = simpleNone.asInstanceOf[Blank[Option[A]]]
private val simpleOptEmpty = Simple(Opt.Empty)
implicit def opt[A]: Blank[Opt[A]] = simpleOptEmpty.asInstanceOf[Blank[Opt[A]]]
private val simpleMapEmpty = Simple(Map.empty)
implicit def map[K, V]: Blank[Map[K, V]] = simpleMapEmpty.asInstanceOf[Blank[Map[K, V]]]
implicit val Double: Blank[Double] = Simple(0.0)
implicit val Float: Blank[Float] = Simple(0.0f)
implicit val Long: Blank[Long] = Simple(0L)
implicit val Int: Blank[Int] = Simple(0)
implicit val Short: Blank[Short] = Simple(0)
implicit val Byte: Blank[Byte] = Simple(0)
implicit val Boolean: Blank[Boolean] = Simple(false)
implicit val Unit: Blank[Unit] = Simple(())
implicit val String: Blank[String] = Simple("")

implicit def option[A]: Blank[Option[A]] = Simple(None)
implicit def opt[A]: Blank[Opt[A]] = Simple(Opt.Empty)
implicit def map[K, V]: Blank[Map[K, V]] = Simple(Map.empty)
implicit def traversable[T, A[_] <: Traversable[_]](implicit ev: CanBuildFrom[Nothing, T, A[T]]): Blank[A[T]] = Simple(Seq.empty[T].to[A])
}

trait LowPrioImplicits {
private val nullBlank = Blank.Simple(null)
@deprecated("Setting Property value to `null` is highly discouraged. Please, define implicit `Blank` for your type.", "0.7.0")
implicit def fallbackNull[A]: Blank[A] = nullBlank.asInstanceOf[Blank[A]]

private type D[T] = Blank[T]
implicit def tuple1[T : D]: D[Tuple1[T]] =
Blank.Simple(Tuple1(implicitly[D[T]].value))
implicit def tuple2[T1 : D, T2 : D]: D[(T1, T2)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value))
implicit def tuple3[T1 : D, T2 : D, T3 : D]: D[(T1, T2, T3)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value))
implicit def tuple4[T1 : D, T2 : D, T3 : D, T4 : D]: D[(T1, T2, T3, T4)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value))
implicit def tuple5[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D]: D[(T1, T2, T3, T4, T5)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value))
implicit def tuple6[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D]: D[(T1, T2, T3, T4, T5, T6)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value))
implicit def tuple7[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D]: D[(T1, T2, T3, T4, T5, T6, T7)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value))
implicit def tuple8[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value))
implicit def tuple9[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value))
implicit def tuple10[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value))
implicit def tuple11[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value))
implicit def tuple12[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value))
implicit def tuple13[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value))
implicit def tuple14[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value))
implicit def tuple15[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value))
implicit def tuple16[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value))
implicit def tuple17[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D, T17 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value, implicitly[D[T17]].value))
implicit def tuple18[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D, T17 : D, T18 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value, implicitly[D[T17]].value, implicitly[D[T18]].value))
implicit def tuple19[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D, T17 : D, T18 : D, T19 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value, implicitly[D[T17]].value, implicitly[D[T18]].value, implicitly[D[T19]].value))
implicit def tuple20[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D, T17 : D, T18 : D, T19 : D, T20 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value, implicitly[D[T17]].value, implicitly[D[T18]].value, implicitly[D[T19]].value, implicitly[D[T20]].value))
implicit def tuple21[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D, T17 : D, T18 : D, T19 : D, T20 : D, T21 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value, implicitly[D[T17]].value, implicitly[D[T18]].value, implicitly[D[T19]].value, implicitly[D[T20]].value, implicitly[D[T21]].value))
implicit def tuple22[T1 : D, T2 : D, T3 : D, T4 : D, T5 : D, T6 : D, T7 : D, T8 : D, T9 : D, T10 : D, T11 : D, T12 : D, T13 : D, T14 : D, T15 : D, T16 : D, T17 : D, T18 : D, T19 : D, T20 : D, T21 : D, T22 : D]: D[(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22)] =
Blank.Simple((implicitly[D[T1]].value, implicitly[D[T2]].value, implicitly[D[T3]].value, implicitly[D[T4]].value, implicitly[D[T5]].value, implicitly[D[T6]].value, implicitly[D[T7]].value, implicitly[D[T8]].value, implicitly[D[T9]].value, implicitly[D[T10]].value, implicitly[D[T11]].value, implicitly[D[T12]].value, implicitly[D[T13]].value, implicitly[D[T14]].value, implicitly[D[T15]].value, implicitly[D[T16]].value, implicitly[D[T17]].value, implicitly[D[T18]].value, implicitly[D[T19]].value, implicitly[D[T20]].value, implicitly[D[T21]].value, implicitly[D[T22]].value))
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,6 @@ trait GenCodecAndModelPropertyCreator[T] {
abstract class HasGenCodecAndModelPropertyCreator[T](implicit
instances: MacroInstances[Unit, GenCodecAndModelPropertyCreator[T]]
) {
/**
* Use this constructor and pass `ModelPropertyCreator.materialize` and `GenCodec.materialize` explicitly
* if you're getting the "super constructor cannot be passed a self reference unless parameter is declared by-name" error.
*/
def this(explicitCreator: => ModelPropertyCreator[T], explicitCodec: => GenCodec[T]) =
this()(new MacroInstances[Unit, GenCodecAndModelPropertyCreator[T]] {
def apply(implicits: Unit, companion: Any): GenCodecAndModelPropertyCreator[T] =
new GenCodecAndModelPropertyCreator[T] {
def codec: GenCodec[T] = explicitCodec
def modelPropertyCreator: ModelPropertyCreator[T] = explicitCreator
}
})

implicit lazy val modelPropertyCreator: ModelPropertyCreator[T] =
instances((), this).modelPropertyCreator
implicit lazy val codec: GenCodec[T] =
instances((), this).codec
implicit final lazy val modelPropertyCreator: ModelPropertyCreator[T] = instances((), this).modelPropertyCreator
implicit final lazy val codec: GenCodec[T] = instances((), this).codec
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package io.udash.properties

abstract class HasModelPropertyCreator[T](implicit mpc: MacroModelPropertyCreator[T]) {
/**
* Use this constructor and pass `ModelPropertyCreator.materialize` explicitly if you're getting the
* "super constructor cannot be passed a self reference unless parameter is declared by-name" error.
*/
def this(creator: => ModelPropertyCreator[T]) = this()(MacroModelPropertyCreator(creator))
import com.avsystem.commons.meta.MacroInstances

implicit val modelPropertyCreator: ModelPropertyCreator[T] = mpc.pc
abstract class HasModelPropertyCreator[T](implicit instances: MacroInstances[Unit, () => ModelPropertyCreator[T]]) {
implicit final lazy val modelPropertyCreator: ModelPropertyCreator[T] = instances((), this).apply()
}
Loading

0 comments on commit d8b6964

Please sign in to comment.