From d0ad2a9a112391f2d70643b0d78c48f7c56e93d2 Mon Sep 17 00:00:00 2001 From: Gabriele Petronella Date: Thu, 10 Aug 2017 22:54:10 +0200 Subject: [PATCH] Add RenameTupleApplySyntax Scalafix rewrite --- scalafix/README.md | 4 +-- .../fix/v1_0_0/RenameTupleApplySyntax.scala | 31 +++++++++++++++++++ .../fix/v1_0_0/RenameTupleApplySyntax.scala | 28 +++++++++++++++++ .../src/main/scala/fix/Cats_v1_0_0.scala | 24 ++++++++++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 scalafix/input/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala create mode 100644 scalafix/output/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala diff --git a/scalafix/README.md b/scalafix/README.md index 88fdb66ca5..3d99824c5f 100644 --- a/scalafix/README.md +++ b/scalafix/README.md @@ -28,14 +28,14 @@ sbt scalafix github:typelevel/cats/v1.0.0 - [x] cats.free.Inject is moved from cats-free to cats-core and renamed to cats.InjectK; cats.data.Prod is renamed to cats.data.Tuple2K; cats.data.Coproduct is renamed to cats.data.EitherK +- [x] Apply syntax on tuple (e.g. (x, y, z).map3(...)) was moved from cats.syntax.tuple._ to cats.syntax.apply._ and renamed to mapN, contramapN and imapN respectively. + # WIP - [ ] cats no longer publishes the all-inclusive bundle package "org.typelevel" % "cats", use cats-core, cats-free, or cats-law accordingly instead. If you need cats.free, use "org.typelevel" % "cats-free", if you need cats-laws use "org.typelevel" % "cats-laws", if neither, use "org.typelevel" % "cats-core". - [ ] FunctorFilter, MonadCombine, MonadFilter, MonadReader, MonadState, MonadTrans, MonadWriter and TraverseFilter are no longer in cats, the functionalities they provided are inhereted by the new cats-mtl project. Please check here for migration guide. -- [ ] Apply syntax on tuple (e.g. (x, y, z).map3(...)) was moved from cats.syntax.tuple._ to cats.syntax.apply._ and renamed to mapN, contramapN and imapN respectively. - - [ ] Several cats-core type class instances for cats.kernel were moved from their companion objects to separate traits and thus require imports from cats.instances.xxx._ (or the recommended import cats.implicits._) now. See #1659 for more details. - [ ] foldLeftM is removed from Free, use foldM on Foldable instead, see #1117 for detail. diff --git a/scalafix/input/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala b/scalafix/input/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala new file mode 100644 index 0000000000..b988f19716 --- /dev/null +++ b/scalafix/input/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala @@ -0,0 +1,31 @@ +/* +rewrite = "scala:fix.v1_0_0.RenameTupleApplySyntax" + */ +package fix +package to1_0_0 + +object RenameTupleApplySyntaxTests { + import cats.{Eq, Semigroup} + import cats.instances.all._ + import cats.syntax.tuple._ + + (Option(1), Option(2)).map2(_ + _) + (Option(1), Option(2), Option(3)).map3(_ + _ + _) + (Option(1), Option(2), Option(3), Option(4)).map4(_ + _ + _ + _) + + case class Foo2(a: Int, b: Int) + case class Foo3(a: Int, b: Int, c: Int) + case class Foo4(a: Int, b: Int, c: Int, d: Int) + + (Eq[Int], Eq[Int]).contramap2((f: Foo2) => (f.a, f.b)) + (Eq[Int], Eq[Int], Eq[Int]).contramap3((f: Foo3) => (f.a, f.b, f.c)) + (Eq[Int], Eq[Int], Eq[Int], Eq[Int]).contramap4((f: Foo4) => + (f.a, f.b, f.c, f.d)) + + (Semigroup[Int], Semigroup[Int]) + .imap2(Foo2.apply)(Function.unlift(Foo2.unapply)) + (Semigroup[Int], Semigroup[Int], Semigroup[Int]) + .imap3(Foo3.apply)(Function.unlift(Foo3.unapply)) + (Semigroup[Int], Semigroup[Int], Semigroup[Int], Semigroup[Int]) + .imap4(Foo4.apply)(Function.unlift(Foo4.unapply)) +} diff --git a/scalafix/output/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala b/scalafix/output/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala new file mode 100644 index 0000000000..a9abe6530a --- /dev/null +++ b/scalafix/output/src/main/scala/fix/v1_0_0/RenameTupleApplySyntax.scala @@ -0,0 +1,28 @@ +package fix +package to1_0_0 + +object RenameTupleApplySyntaxTests { + import cats.{Eq, Semigroup} + import cats.instances.all._ + import cats.syntax.apply._ + + (Option(1), Option(2)).mapN(_ + _) + (Option(1), Option(2), Option(3)).mapN(_ + _ + _) + (Option(1), Option(2), Option(3), Option(4)).mapN(_ + _ + _ + _) + + case class Foo2(a: Int, b: Int) + case class Foo3(a: Int, b: Int, c: Int) + case class Foo4(a: Int, b: Int, c: Int, d: Int) + + (Eq[Int], Eq[Int]).contramapN((f: Foo2) => (f.a, f.b)) + (Eq[Int], Eq[Int], Eq[Int]).contramapN((f: Foo3) => (f.a, f.b, f.c)) + (Eq[Int], Eq[Int], Eq[Int], Eq[Int]).contramapN((f: Foo4) => + (f.a, f.b, f.c, f.d)) + + (Semigroup[Int], Semigroup[Int]) + .imapN(Foo2.apply)(Function.unlift(Foo2.unapply)) + (Semigroup[Int], Semigroup[Int], Semigroup[Int]) + .imapN(Foo3.apply)(Function.unlift(Foo3.unapply)) + (Semigroup[Int], Semigroup[Int], Semigroup[Int], Semigroup[Int]) + .imapN(Foo4.apply)(Function.unlift(Foo4.unapply)) +} diff --git a/scalafix/rewrites/src/main/scala/fix/Cats_v1_0_0.scala b/scalafix/rewrites/src/main/scala/fix/Cats_v1_0_0.scala index 0d34724f76..a42618c6fb 100644 --- a/scalafix/rewrites/src/main/scala/fix/Cats_v1_0_0.scala +++ b/scalafix/rewrites/src/main/scala/fix/Cats_v1_0_0.scala @@ -231,3 +231,27 @@ case class RenameInjectProdAndCoproduct(semanticCtx: SemanticCtx) extends Semant } } + +// ref: https://github.com/typelevel/cats/pull/1487 +case class RenameTupleApplySyntax(semanticCtx: SemanticCtx) extends SemanticRewrite(semanticCtx) { + + private[this] val renames: Map[String, String] = + (1 to 22) + .map { arity => + Seq( + s"_root_.cats.syntax.Tuple${arity}CartesianOps.map$arity." -> "mapN", + s"_root_.cats.syntax.Tuple${arity}CartesianOps.contramap$arity." -> "contramapN", + s"_root_.cats.syntax.Tuple${arity}CartesianOps.imap$arity." -> "imapN" + ) + } + .flatten + .toMap + + def rewrite(ctx: RewriteCtx): Patch = { + ctx.tree.collect { + case t: Term.Name => rename(ctx, t, renames) + case t @ q"import cats.syntax.tuple._" => + ctx.replaceTree(t, "import cats.syntax.apply._") + }.asPatch + } +}