Skip to content

Commit

Permalink
Fix implicit syntax collisions (#629)
Browse files Browse the repository at this point in the history
* fix GenApplyLensSyntax.value collision

* make all syntax classes to extend AnyVal with private value
  • Loading branch information
vladimirkl authored and julien-truffaut committed Feb 20, 2019
1 parent 15532ab commit e2f8212
Show file tree
Hide file tree
Showing 11 changed files with 35 additions and 18 deletions.
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/monocle/Prism.scala
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ sealed abstract class PrismInstances {
}
}

final case class PrismSyntax[S, A](self: Prism[S, A]) extends AnyVal {
final case class PrismSyntax[S, A](private val self: Prism[S, A]) extends AnyVal {

/** lift a [[Prism]] such as it only matches if all elements of `F[S]` are getOrModify */
def below[F[_]](implicit F: Traverse[F]): Prism[F[S], F[A]] =
Expand Down
2 changes: 1 addition & 1 deletion core/shared/src/main/scala/monocle/internal/IsEq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ final case class IsEq[A](lhs: A, rhs: A)
object IsEq {
implicit def syntax[A](lhs: A): IsEqOps[A] = new IsEqOps(lhs)

final class IsEqOps[A](val lhs: A) extends AnyVal {
final class IsEqOps[A](private val lhs: A) extends AnyVal {
def <==>(rhs: A): IsEq[A] = IsEq(lhs, rhs)
}
}
16 changes: 8 additions & 8 deletions core/shared/src/main/scala/monocle/syntax/Apply.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,43 +17,43 @@ trait ApplySyntax {
implicit def toApplyTraversalOps[S](value: S): ApplyTraversalOps[S] = new ApplyTraversalOps(value)
}

final case class ApplyFoldOps[S](s: S) {
final case class ApplyFoldOps[S](private val s: S) extends AnyVal {
def applyFold[A](fold: Fold[S, A]): ApplyFold[S, A] = new ApplyFold[S, A](s, fold)
}

final case class ApplyGetterOps[S](s: S) {
final case class ApplyGetterOps[S](private val s: S) extends AnyVal{
def applyGetter[A](getter: Getter[S, A]): ApplyGetter[S, A] = new ApplyGetter[S, A](s, getter)
}

final case class ApplyIsoOps[S](s: S) {
final case class ApplyIsoOps[S](private val s: S) extends AnyVal {
@inline def applyIso[T, A, B](iso: PIso[S, T, A, B]): ApplyIso[S, T, A, B] = ApplyIso[S, T, A, B](s, iso)
/** alias to applyIso */
@inline def &<->[T, A, B](iso: PIso[S, T, A, B]): ApplyIso[S, T, A, B] = applyIso(iso)
}

final case class ApplyLensOps[S](s: S) {
final case class ApplyLensOps[S](private val s: S) extends AnyVal {
def applyLens[T, A, B](lens: PLens[S, T, A, B]): ApplyLens[S, T, A, B] = ApplyLens[S, T, A, B](s, lens)
/** alias to applyLens */
def &|->[T, A, B](lens: PLens[S, T, A, B]): ApplyLens[S, T, A, B] = applyLens(lens)
}

final case class ApplyOptionalOps[S](s: S) {
final case class ApplyOptionalOps[S](private val s: S) extends AnyVal {
def applyOptional[T, A, B](optional: POptional[S, T, A, B]): ApplyOptional[S, T, A, B] = ApplyOptional[S, T, A, B](s, optional)
/** alias to applyOptional */
def &|-?[T, A, B](optional: POptional[S, T, A, B]): ApplyOptional[S, T, A, B] = applyOptional(optional)
}

final case class ApplyPrismOps[S](s: S) {
final case class ApplyPrismOps[S](private val s: S) extends AnyVal {
def applyPrism[T, A, B](prism: PPrism[S, T, A, B]): ApplyPrism[S, T, A, B] = ApplyPrism[S, T, A, B](s, prism)
/** alias to applyPrism */
def &<-?[T, A, B](prism: PPrism[S, T, A, B]): ApplyPrism[S, T, A, B] = applyPrism(prism)
}

final case class ApplySetterOps[S](s: S) {
final case class ApplySetterOps[S](private val s: S) extends AnyVal {
def applySetter[T, A, B](setter: PSetter[S, T, A, B]): ApplySetter[S, T, A, B] = new ApplySetter[S, T, A, B](s, setter)
}

final case class ApplyTraversalOps[S](s: S) {
final case class ApplyTraversalOps[S](private val s: S) extends AnyVal {
def applyTraversal[T, A, B](traversal: PTraversal[S, T, A, B]): ApplyTraversal[S, T, A, B] = ApplyTraversal[S, T, A, B](s, traversal)
/** alias to applyTraversal */
def &|->>[T, A, B](traversal: PTraversal[S, T, A, B]): ApplyTraversal[S, T, A, B] = applyTraversal(traversal)
Expand Down
10 changes: 10 additions & 0 deletions example/src/test/scala/monocle/LensExample.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ class LensMonoExample extends MonocleSuite {
test("@Lenses is for case classes only") {
illTyped( """@Lenses class C""", "Invalid annotation target: must be a case class")
}

test("GenApplyLensOps has no collision with .value") {
case class MyString(s: String)
object MyString {
implicit class Ops(self: MyString) {
val value: String = self.s
}
}
MyString("a").value shouldEqual "a"
}
}

class LensPolyExample extends MonocleSuite {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ trait GenApplyLensSyntax {
implicit def toGenApplyLensOps[S](value: S): GenApplyLensOps[S] = new GenApplyLensOps(value)
}

class GenApplyLensOps[A](val value: A) extends AnyVal {
class GenApplyLensOps[A](private val value: A) extends AnyVal {
def lens[C]( field: A => C ): ApplyLens[A,A,C,C] = macro GenApplyLensOpsImpl.lens_impl[A, C]
}

class GenApplyLensOpsImpl(val c: blackbox.Context){
def lens_impl[A: c.WeakTypeTag, C](field: c.Expr[A => C]): c.Expr[ApplyLens[A,A,C,C]] = {
import c.universe._

val subj = c.prefix.tree match {
case Apply(TypeApply(_, _), List(x)) => x
case t =>
c.abort(c.enclosingPosition, s"Invalid prefix tree ${show(t)}")
}

c.Expr[ApplyLens[A,A,C,C]](q"""
_root_.monocle.syntax.ApplyLens(
${c.prefix.tree}.value,
$subj,
_root_.monocle.macros.GenLens[${c.weakTypeOf[A]}](${field})
)
""")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait ReaderGetterSyntax {
new ReaderGetterOps[S, A](getter)
}

final class ReaderGetterOps[S, A](getter: Getter[S, A]) {
final class ReaderGetterOps[S, A](private val getter: Getter[S, A]) extends AnyVal {
/** transforms a Getter into a Reader */
def toReader: Reader[S, A] =
Reader(getter.get)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait StateGetterSyntax {
new StateGetterOps[S, A](getter)
}

final class StateGetterOps[S, A](getter: Getter[S, A]) {
final class StateGetterOps[S, A](private val getter: Getter[S, A]) extends AnyVal {
/** transforms a Getter into a State */
def toState: State[S, A] =
State(s => (s, getter.get(s)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait StateLensSyntax {
new StateLensOps[S, T, A, B](lens)
}

final class StateLensOps[S, T, A, B](lens: PLens[S, T, A, B]) {
final class StateLensOps[S, T, A, B](private val lens: PLens[S, T, A, B]) extends AnyVal {
/** transforms a PLens into a State */
def toState: State[S, A] =
State(s => (s, lens.get(s)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait StateOptionalSyntax {
new StateOptionalOps[S, T, A, B](optional)
}

final class StateOptionalOps[S, T, A, B](optional: POptional[S, T, A, B]) {
final class StateOptionalOps[S, T, A, B](private val optional: POptional[S, T, A, B]) extends AnyVal {
/** transforms a POptional into a State */
def toState: State[S, Option[A]] =
State(s => (s, optional.getOption(s)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait StateSetterSyntax {
new StateSetterOps[S, T, A, B](setter)
}

final class StateSetterOps[S, T, A, B](setter: PSetter[S, T, A, B]) {
final class StateSetterOps[S, T, A, B](private val setter: PSetter[S, T, A, B]) extends AnyVal {
/** modify the value referenced through the setter */
def mod_(f: A => B): IndexedState[S, T, Unit] =
IndexedState(s => (setter.modify(f)(s), ()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ trait StateTraversalSyntax {
new StateTraversalOps[S, T, A, B](traversal)
}

final class StateTraversalOps[S, T, A, B](traversal: PTraversal[S, T, A, B]) {
final class StateTraversalOps[S, T, A, B](private val traversal: PTraversal[S, T, A, B]) extends AnyVal {
/** transforms a PTraversal into a State */
def toState: State[S, List[A]] =
State(s => (s, traversal.getAll(s)))
Expand Down

0 comments on commit e2f8212

Please sign in to comment.