From f01ff56e831b83d5366dac925c9e51b0f904badf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 20 Nov 2020 10:05:35 +0100 Subject: [PATCH 1/2] Give explicit result types to all methods in scala.deriving. They are public API. They should have explicit types. --- library/src/scala/deriving.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src/scala/deriving.scala b/library/src/scala/deriving.scala index 827285123d95..60928ebdfcee 100644 --- a/library/src/scala/deriving.scala +++ b/library/src/scala/deriving.scala @@ -36,7 +36,7 @@ object deriving { type MirroredType = this.type type MirroredElemTypes = EmptyTuple type MirroredElemLabels = EmptyTuple - def fromProduct(p: scala.Product) = this + def fromProduct(p: scala.Product): MirroredMonoType = this } /** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */ @@ -45,7 +45,7 @@ object deriving { type MirroredType = value.type type MirroredElemTypes = EmptyTuple type MirroredElemLabels = EmptyTuple - def fromProduct(p: scala.Product) = value + def fromProduct(p: scala.Product): MirroredMonoType = value } type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple } @@ -57,16 +57,16 @@ object deriving { class ArrayProduct(val elems: Array[AnyRef]) extends Product { def this(size: Int) = this(new Array[AnyRef](size)) def canEqual(that: Any): Boolean = true - def productElement(n: Int) = elems(n) - def productArity = elems.length + def productElement(n: Int): Any = elems(n) + def productArity: Int = elems.length override def productIterator: Iterator[Any] = elems.iterator - def update(n: Int, x: Any) = elems(n) = x.asInstanceOf[AnyRef] + def update(n: Int, x: Any): Unit = elems(n) = x.asInstanceOf[AnyRef] } /** The empty product */ object EmptyProduct extends ArrayProduct(Array.emptyObjectArray) /** Helper method to select a product element */ - def productElement[T](x: Any, idx: Int) = + def productElement[T](x: Any, idx: Int): T = x.asInstanceOf[Product].productElement(idx).asInstanceOf[T] } From 0f1a3316590514aa7641f17a20dde65243a9e57f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 20 Nov 2020 10:30:02 +0100 Subject: [PATCH 2/2] Make scala.deriving a package instead of an object. The fundamental `Mirror` trait receives its own file. The helpers `ArrayProduct`, `EmptyProduct` and `productElement` are put together in a `Helpers.scala` file. --- library/src/scala/deriving.scala | 72 ------------------------ library/src/scala/deriving/Helpers.scala | 18 ++++++ library/src/scala/deriving/Mirror.scala | 52 +++++++++++++++++ 3 files changed, 70 insertions(+), 72 deletions(-) delete mode 100644 library/src/scala/deriving.scala create mode 100644 library/src/scala/deriving/Helpers.scala create mode 100644 library/src/scala/deriving/Mirror.scala diff --git a/library/src/scala/deriving.scala b/library/src/scala/deriving.scala deleted file mode 100644 index 60928ebdfcee..000000000000 --- a/library/src/scala/deriving.scala +++ /dev/null @@ -1,72 +0,0 @@ -package scala - -object deriving { - - /** Mirrors allows typelevel access to enums, case classes and objects, and their sealed parents. - */ - sealed trait Mirror { - - /** The mirrored *-type */ - type MirroredMonoType - - /** The name of the type */ - type MirroredLabel <: String - - /** The names of the product elements */ - type MirroredElemLabels <: Tuple - } - - object Mirror { - - /** The Mirror for a sum type */ - trait Sum extends Mirror { self => - /** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */ - def ordinal(x: MirroredMonoType): Int - } - - /** The Mirror for a product type */ - trait Product extends Mirror { - - /** Create a new instance of type `T` with elements taken from product `p`. */ - def fromProduct(p: scala.Product): MirroredMonoType - } - - trait Singleton extends Product { - type MirroredMonoType = this.type - type MirroredType = this.type - type MirroredElemTypes = EmptyTuple - type MirroredElemLabels = EmptyTuple - def fromProduct(p: scala.Product): MirroredMonoType = this - } - - /** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */ - class SingletonProxy(val value: AnyRef) extends Product { - type MirroredMonoType = value.type - type MirroredType = value.type - type MirroredElemTypes = EmptyTuple - type MirroredElemLabels = EmptyTuple - def fromProduct(p: scala.Product): MirroredMonoType = value - } - - type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple } - type ProductOf[T] = Mirror.Product { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple } - type SumOf[T] = Mirror.Sum { type MirroredType = T; type MirroredMonoType = T; type MirroredElemTypes <: Tuple } - } - - /** Helper class to turn arrays into products */ - class ArrayProduct(val elems: Array[AnyRef]) extends Product { - def this(size: Int) = this(new Array[AnyRef](size)) - def canEqual(that: Any): Boolean = true - def productElement(n: Int): Any = elems(n) - def productArity: Int = elems.length - override def productIterator: Iterator[Any] = elems.iterator - def update(n: Int, x: Any): Unit = elems(n) = x.asInstanceOf[AnyRef] - } - - /** The empty product */ - object EmptyProduct extends ArrayProduct(Array.emptyObjectArray) - - /** Helper method to select a product element */ - def productElement[T](x: Any, idx: Int): T = - x.asInstanceOf[Product].productElement(idx).asInstanceOf[T] -} diff --git a/library/src/scala/deriving/Helpers.scala b/library/src/scala/deriving/Helpers.scala new file mode 100644 index 000000000000..67f8dabcfa04 --- /dev/null +++ b/library/src/scala/deriving/Helpers.scala @@ -0,0 +1,18 @@ +package scala.deriving + +/** Helper class to turn arrays into products */ +class ArrayProduct(val elems: Array[AnyRef]) extends Product { + def this(size: Int) = this(new Array[AnyRef](size)) + def canEqual(that: Any): Boolean = true + def productElement(n: Int): Any = elems(n) + def productArity: Int = elems.length + override def productIterator: Iterator[Any] = elems.iterator + def update(n: Int, x: Any): Unit = elems(n) = x.asInstanceOf[AnyRef] +} + +/** The empty product */ +object EmptyProduct extends ArrayProduct(Array.emptyObjectArray) + +/** Helper method to select a product element */ +def productElement[T](x: Any, idx: Int): T = + x.asInstanceOf[Product].productElement(idx).asInstanceOf[T] diff --git a/library/src/scala/deriving/Mirror.scala b/library/src/scala/deriving/Mirror.scala new file mode 100644 index 000000000000..d20ea3e5f01e --- /dev/null +++ b/library/src/scala/deriving/Mirror.scala @@ -0,0 +1,52 @@ +package scala.deriving + +/** Mirrors allows typelevel access to enums, case classes and objects, and their sealed parents. + */ +sealed trait Mirror { + + /** The mirrored *-type */ + type MirroredMonoType + + /** The name of the type */ + type MirroredLabel <: String + + /** The names of the product elements */ + type MirroredElemLabels <: Tuple +} + +object Mirror { + + /** The Mirror for a sum type */ + trait Sum extends Mirror { self => + /** The ordinal number of the case class of `x`. For enums, `ordinal(x) == x.ordinal` */ + def ordinal(x: MirroredMonoType): Int + } + + /** The Mirror for a product type */ + trait Product extends Mirror { + + /** Create a new instance of type `T` with elements taken from product `p`. */ + def fromProduct(p: scala.Product): MirroredMonoType + } + + trait Singleton extends Product { + type MirroredMonoType = this.type + type MirroredType = this.type + type MirroredElemTypes = EmptyTuple + type MirroredElemLabels = EmptyTuple + def fromProduct(p: scala.Product): MirroredMonoType = this + } + + /** A proxy for Scala 2 singletons, which do not inherit `Singleton` directly */ + class SingletonProxy(val value: AnyRef) extends Product { + type MirroredMonoType = value.type + type MirroredType = value.type + type MirroredElemTypes = EmptyTuple + type MirroredElemLabels = EmptyTuple + def fromProduct(p: scala.Product): MirroredMonoType = value + } + + type Of[T] = Mirror { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple } + type ProductOf[T] = Mirror.Product { type MirroredType = T; type MirroredMonoType = T ; type MirroredElemTypes <: Tuple } + type SumOf[T] = Mirror.Sum { type MirroredType = T; type MirroredMonoType = T; type MirroredElemTypes <: Tuple } +}