Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property implicits cleanup #276

Merged
merged 22 commits into from
May 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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