From 708332153c558bdc0209bff4e87e19ac972f3e08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 21 Jun 2017 11:11:51 +0200 Subject: [PATCH 01/40] Setup skeleton for rewriting with scalafix. --- build.sbt | 30 +++++++++++++++++++ .../scala/fix/Collectionstrawman_v0.scala | 8 +++++ .../scala/fix/Collectionstrawman_v0.scala | 7 +++++ project/build.properties | 1 + project/plugins.sbt | 5 ++++ readme.md | 7 +++++ .../scala/fix/Collectionstrawman_v0.scala | 16 ++++++++++ .../scala/fix/Collectionstrawman_Tests.scala | 13 ++++++++ 8 files changed, 87 insertions(+) create mode 100644 build.sbt create mode 100644 input/src/main/scala/fix/Collectionstrawman_v0.scala create mode 100644 output/src/main/scala/fix/Collectionstrawman_v0.scala create mode 100644 project/build.properties create mode 100644 project/plugins.sbt create mode 100644 readme.md create mode 100644 rewrites/src/main/scala/fix/Collectionstrawman_v0.scala create mode 100644 tests/src/test/scala/fix/Collectionstrawman_Tests.scala diff --git a/build.sbt b/build.sbt new file mode 100644 index 00000000..0a479466 --- /dev/null +++ b/build.sbt @@ -0,0 +1,30 @@ +// Use a scala version supported by scalafix. +scalaVersion in ThisBuild := org.scalameta.BuildInfo.supportedScalaVersions.last + +lazy val root = project.aggregate(rewrites, input, output, tests) + +lazy val rewrites = project.settings( + libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % "0.4.2" +) + +lazy val input = project.settings( + scalametaSourceroot := sourceDirectory.in(Compile).value +) + +lazy val output = project + +lazy val tests = project + .settings( + libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % "0.4.2" % Test cross CrossVersion.full, + buildInfoPackage := "fix", + buildInfoKeys := Seq[BuildInfoKey]( + "inputSourceroot" -> + sourceDirectory.in(input, Compile).value, + "outputSourceroot" -> + sourceDirectory.in(output, Compile).value, + "inputClassdirectory" -> + classDirectory.in(input, Compile).value + ) + ) + .dependsOn(input, rewrites) + .enablePlugins(BuildInfoPlugin) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala new file mode 100644 index 00000000..52a26255 --- /dev/null +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -0,0 +1,8 @@ +/* ONLY +rewrite = "scala:fix.Collectionstrawman_v0" +*/ +package fix + +object Collectionstrawman_v0_Test { + List(1, 2, 3) +} diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala new file mode 100644 index 00000000..5572fca3 --- /dev/null +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -0,0 +1,7 @@ +package fix + +import scala.{ List => _ } +import strawman.collection.immutable.List +object Collectionstrawman_v0_Test { + List(1, 2, 3) +} diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 00000000..27e88aa1 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.13 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 00000000..fdddc401 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,5 @@ +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.4.2") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.4.2") +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC3") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") + diff --git a/readme.md b/readme.md new file mode 100644 index 00000000..038042a2 --- /dev/null +++ b/readme.md @@ -0,0 +1,7 @@ +# Scalafix rewrites for collection-strawman + +To develop rewrite: +``` +sbt ~tests/test +# edit rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +``` diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala new file mode 100644 index 00000000..94d48d89 --- /dev/null +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -0,0 +1,16 @@ +package fix + +import scalafix._ +import scala.meta._ + +case class Collectionstrawman_v0(mirror: Mirror) + extends SemanticRewrite(mirror) { + val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") + def rewrite(ctx: RewriteCtx): Patch = { + ctx.tree.collect { + case name @ Term.Name(_) if name.symbol == immutableListSymbol => + ctx.addGlobalImport(importer"scala.{List => _}") + + ctx.addGlobalImport(importer"strawman.collection.immutable.List") + }.asPatch + } +} diff --git a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala new file mode 100644 index 00000000..789818d4 --- /dev/null +++ b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -0,0 +1,13 @@ +package fix + +import scala.meta._ +import scalafix.testkit._ + +class Collectionstrawman_Tests + extends SemanticRewriteSuite( + Database.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), + AbsolutePath(BuildInfo.inputSourceroot), + Seq(AbsolutePath(BuildInfo.outputSourceroot)) + ) { + runAllTests() +} From 51edbb469834270653d53fc2c99d8a5df714aafe Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 26 Jun 2017 17:21:09 +0200 Subject: [PATCH 02/40] Add a few examples --- .../scala/fix/Collectionstrawman_v0.scala | 35 +++++++++++++++- .../scala/fix/Collectionstrawman_v0.scala | 42 +++++++++++++++++-- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 52a26255..3b717487 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -3,6 +3,39 @@ rewrite = "scala:fix.Collectionstrawman_v0" */ package fix -object Collectionstrawman_v0_Test { +object Collectionstrawman_v0_List { List(1, 2, 3) + 1 :: 2 :: 3 :: Nil + val isEmpty: List[_] => Boolean = { + case Nil => true + case x :: xs => false + } +} + +object Collectionstrawman_v0_Stream { + Stream(1, 2, 3) + 1 #:: 2 #:: 3 #:: Stream.Empty + val isEmpty: Stream[_] => Boolean = { + case Stream.Empty => true + case x #:: xs => false + } +} + +object Collectionstrawman_v0_Vector { + val xs: Vector[Int] = Vector(1, 2, 3) +} + +object Collectionstrawman_v0_Seq { + val xs: Seq[Int] = Seq(1, 2, 3) +} + +object Collectionstrawman_v0_Map { + val xs: Map[Int, String] = Map(1 -> "1", 2 -> "2", 3 -> "3") + import scala.collection.immutable.HashMap + val ys = HashMap.empty +} + +object Collectionstrawman_v0_ArrayBuffer { + import scala.collection.mutable.ArrayBuffer + val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) } diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 5572fca3..2520bd64 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,43 @@ package fix -import scala.{ List => _ } -import strawman.collection.immutable.List -object Collectionstrawman_v0_Test { +import scala.{ List => _, Nil => _, Seq => _, Vector => _, :: => _, #:: => _ } +import scala.Predef.{ Map => _ } +import strawman.collection.immutable.{ LazyList, List, Map, Nil, Seq, Vector, :: } +import strawman.collection.immutable.LazyList.#:: + +object Collectionstrawman_v0_List { List(1, 2, 3) + 1 :: 2 :: 3 :: Nil + val isEmpty: List[_] => Boolean = { + case Nil => true + case x :: xs => false + } +} + +object Collectionstrawman_v0_Stream { + LazyList(1, 2, 3) + 1 #:: 2 #:: 3 #:: LazyList.Empty + val isEmpty: Stream[_] => Boolean = { + case Stream.Empty => true + case x #:: xs => false + } +} + +object Collectionstrawman_v0_Vector { + val xs: Vector[Int] = Vector(1, 2, 3) +} + +object Collectionstrawman_v0_Seq { + val xs: Seq[Int] = Seq(1, 2, 3) +} + +object Collectionstrawman_v0_Map { + val xs: Map[Int, String] = Map(1 -> "1", 2 -> "2", 3 -> "3") + import strawman.collection.immutable.HashMap + val ys = HashMap.empty +} + +object Collectionstrawman_v0_ArrayBuffer { + import strawman.collection.mutable.ArrayBuffer + val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) } From 29cf22bba7a6884bed826a0ebeca21dc7a152a17 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 27 Jun 2017 09:29:16 +0200 Subject: [PATCH 03/40] Add Range, Array and String examples --- .../main/scala/fix/Collectionstrawman_v0.scala | 11 +++++++++++ .../main/scala/fix/Collectionstrawman_v0.scala | 16 ++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 3b717487..ccf88c27 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -39,3 +39,14 @@ object Collectionstrawman_v0_ArrayBuffer { import scala.collection.mutable.ArrayBuffer val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) } + +object Collectionstrawman_v0_ArrayAndString { + def foo(xs: Array[Int], ys: String): Unit = { + xs.map(x => x + 1) + ys.map(c => c.toUpper) + } +} + +object Collectionstrawman_v0_Range { + for (i <- 1 to 10; j <- 0 until 10) yield (i, j) +} diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 2520bd64..43cae625 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,8 +1,9 @@ package fix import scala.{ List => _, Nil => _, Seq => _, Vector => _, :: => _, #:: => _ } -import scala.Predef.{ Map => _ } -import strawman.collection.immutable.{ LazyList, List, Map, Nil, Seq, Vector, :: } +import scala.Predef.{ Map => _, augmentString => _, intArrayOps => _ } +import strawman.collection.{ stringToStringOps, arrayToArrayOps } +import strawman.collection.immutable.{ LazyList, List, Map, Nil, Range, Seq, Vector, :: } import strawman.collection.immutable.LazyList.#:: object Collectionstrawman_v0_List { @@ -41,3 +42,14 @@ object Collectionstrawman_v0_ArrayBuffer { import strawman.collection.mutable.ArrayBuffer val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) } + +object Collectionstrawman_v0_ArrayAndString { + def foo(xs: Array[Int], ys: String): Unit = { + xs.map(x => x + 1) + ys.map(c => c.toUpper) + } +} + +object Collectionstrawman_v0_Range { + for (i <- Range.inclusive(1, 10); j <- Range(0, 10)) yield (i, j) +} From 3d46cfa1ab17c89fb208acf930cb0384497385c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 29 Jun 2017 11:29:45 +0200 Subject: [PATCH 04/40] Depend on collections project in output. --- build.sbt | 14 +++++++++++++- .../src/main/scala/fix/Collectionstrawman_v0.scala | 8 ++++---- project/build.properties | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index 0a479466..075d2be3 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,9 @@ // Use a scala version supported by scalafix. scalaVersion in ThisBuild := org.scalameta.BuildInfo.supportedScalaVersions.last -lazy val root = project.aggregate(rewrites, input, output, tests) +lazy val root = project + .in(file(".")) + .aggregate(rewrites, input, output, tests) lazy val rewrites = project.settings( libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % "0.4.2" @@ -11,7 +13,17 @@ lazy val input = project.settings( scalametaSourceroot := sourceDirectory.in(Compile).value ) +val collections = ProjectRef(file(".."), "collections") + lazy val output = project + .settings( + resolvers := resolvers.in(collections).value, + libraryDependencies := libraryDependencies.in(collections).value, + scalaVersion := scalaVersion.in(collections).value, + scalaBinaryVersion := scalaBinaryVersion.in(collections).value + ) + .dependsOn(collections) // collections/publishLocal is still necessary. + .disablePlugins(ScalahostSbtPlugin) lazy val tests = project .settings( diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 43cae625..c72d0e17 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,9 +1,9 @@ package fix import scala.{ List => _, Nil => _, Seq => _, Vector => _, :: => _, #:: => _ } -import scala.Predef.{ Map => _, augmentString => _, intArrayOps => _ } +import scala.Predef.{ Map => _, augmentString => _, intArrayOps => _, ArrowAssoc, charWrapper} import strawman.collection.{ stringToStringOps, arrayToArrayOps } -import strawman.collection.immutable.{ LazyList, List, Map, Nil, Range, Seq, Vector, :: } +import strawman.collection.immutable.{ LazyList, List, Map, Nil, Range, Seq, :: } import strawman.collection.immutable.LazyList.#:: object Collectionstrawman_v0_List { @@ -18,8 +18,8 @@ object Collectionstrawman_v0_List { object Collectionstrawman_v0_Stream { LazyList(1, 2, 3) 1 #:: 2 #:: 3 #:: LazyList.Empty - val isEmpty: Stream[_] => Boolean = { - case Stream.Empty => true + val isEmpty: LazyList[_] => Boolean = { + case LazyList.Empty => true case x #:: xs => false } } diff --git a/project/build.properties b/project/build.properties index 27e88aa1..64317fda 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.13 +sbt.version=0.13.15 From e2f2425ea8cdd9df49f38410b990479562ed330e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Sat, 15 Jul 2017 17:20:35 +0200 Subject: [PATCH 05/40] Almost complete with rewrite. Blocked by - https://github.com/scalameta/scalameta/issues/1037 - https://github.com/scalacenter/scalafix/issues/252 - https://github.com/scalacenter/scalafix/issues/253 --- build.sbt | 5 +- .../scala/fix/Collectionstrawman_v0.scala | 20 ++++++ .../scala/fix/Collectionstrawman_v0.scala | 2 - project/plugins.sbt | 5 +- .../scala/fix/Collectionstrawman_v0.scala | 67 +++++++++++++++++-- .../scala/fix/Collectionstrawman_Tests.scala | 4 ++ 6 files changed, 89 insertions(+), 14 deletions(-) diff --git a/build.sbt b/build.sbt index 075d2be3..c4441edf 100644 --- a/build.sbt +++ b/build.sbt @@ -1,3 +1,4 @@ +def scalafixVersion = _root_.scalafix.Versions.version // Use a scala version supported by scalafix. scalaVersion in ThisBuild := org.scalameta.BuildInfo.supportedScalaVersions.last @@ -6,7 +7,7 @@ lazy val root = project .aggregate(rewrites, input, output, tests) lazy val rewrites = project.settings( - libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % "0.4.2" + libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion ) lazy val input = project.settings( @@ -27,7 +28,7 @@ lazy val output = project lazy val tests = project .settings( - libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % "0.4.2" % Test cross CrossVersion.full, + libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full, buildInfoPackage := "fix", buildInfoKeys := Seq[BuildInfoKey]( "inputSourceroot" -> diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index ccf88c27..009e4eb5 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,5 +1,25 @@ /* ONLY rewrite = "scala:fix.Collectionstrawman_v0" +patches.moveSymbols = [ + { from = "scala.collection.immutable.HashMap", + to = "strawman.collection.immutable.HashMap" } + { from = "scala.collection.immutable.Map", + to = "strawman.collection.immutable.Map" } + { from = "scala.Predef.Map", + to = "strawman.collection.immutable.Map" } + { from = "scala.collection.immutable.List", + to = "strawman.collection.immutable.List" } + { from = "scala.collection.immutable.Nil", + to = "strawman.collection.immutable.Nil" } + { from = "scala.package.Stream", + to = "strawman.collection.immutable.LazyList" } + { from = "scala.package.`#::`", + to = "strawman.collection.immutable.LazyList.`#::`" } + { from = "scala.package.Vector", + to = "strawman.collection.immutable.Vector" } + { from = "scala.collection.mutable.ArrayBuffer", + to = "strawman.collection.mutable.ArrayBuffer" } +] */ package fix diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index c72d0e17..50bc1a37 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -34,12 +34,10 @@ object Collectionstrawman_v0_Seq { object Collectionstrawman_v0_Map { val xs: Map[Int, String] = Map(1 -> "1", 2 -> "2", 3 -> "3") - import strawman.collection.immutable.HashMap val ys = HashMap.empty } object Collectionstrawman_v0_ArrayBuffer { - import strawman.collection.mutable.ArrayBuffer val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) } diff --git a/project/plugins.sbt b/project/plugins.sbt index fdddc401..6696ca60 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,4 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.4.2") -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.4.2") -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC3") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M1") +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC6") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 94d48d89..309efc27 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,16 +1,69 @@ package fix +// scalafmt: { maxColumn = 120 } import scalafix._ +import scalafix.syntax._ +import scalafix.internal.util.SymbolOps import scala.meta._ -case class Collectionstrawman_v0(mirror: Mirror) - extends SemanticRewrite(mirror) { +case class Collectionstrawman_v0(mirror: Mirror) extends SemanticRewrite(mirror) { val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") + val unimports = Set( + Symbol("_root_.scala.List."), + Symbol("_root_.scala.Seq."), + Symbol("_root_.scala.Vector."), + Symbol("_root_.scala.`::`."), + Symbol("_root_.scala.`#::`."), + Symbol("_root_.scala.Predef.Map."), + Symbol("_root_.scala.Predef.intArrayOps."), + Symbol("_root_.scala.Predef.augmentString."), + Symbol("_root_.scala.Predef.intArrayOps.") + ) + + def normalize(symbol: Symbol): Symbol = { + def loop(symbol: Symbol): Symbol = symbol match { + case Symbol.Global(qual, Signature.Term("package")) => loop(qual) + case Symbol.Global(qual, name) => Symbol.Global(loop(qual), name) + case x => x + } + loop(symbol.normalized) + } + + def ifSymbolFound(ctx: RewriteCtx): Patch = { + val toUnimport = ctx.mirror.database.names.flatMap { + case (_, sym) => + val norm = normalize(sym) + if (unimports.contains(norm)) norm :: Nil + else Nil + } + val unimportss = toUnimport.toList.distinct.flatMap { sym => + SymbolOps.toImporter(sym).toList.collect { + case Importer(qual, Importee.Name(n) :: Nil) => + Importer(qual, Importee.Unimport(n) :: Nil) + } + } + val grouped = unimportss.groupBy(_.ref.syntax).collect { + case (qual, iss @ is :: _) => + val names = iss.collect { case Importer(_, name :: Nil) => name } + Importer(is.ref, names) + } + grouped.map(ctx.addGlobalImport(_)).asPatch + } + +// def isSymbol(tree: Tree, symbol: Symbol): Boolean = { +// mirror.database.names.get(tree.pos).exists(normalize(_) == symbol) +// } + + def rangePatch(ctx: RewriteCtx): Patch = { +// ctx.tree.collect { +// case q"$lhs $op $rhs" if isSymbol(op, Symbol()) => +// op +// } + Patch.empty + } + def rewrite(ctx: RewriteCtx): Patch = { - ctx.tree.collect { - case name @ Term.Name(_) if name.symbol == immutableListSymbol => - ctx.addGlobalImport(importer"scala.{List => _}") + - ctx.addGlobalImport(importer"strawman.collection.immutable.List") - }.asPatch + ctx.debugMirror() + ifSymbolFound(ctx) } } diff --git a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala index 789818d4..efb28c03 100644 --- a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala +++ b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -9,5 +9,9 @@ class Collectionstrawman_Tests AbsolutePath(BuildInfo.inputSourceroot), Seq(AbsolutePath(BuildInfo.outputSourceroot)) ) { + override def assertNoDiff(a: String, b: String, c: String) = { + println(a) + super.assertNoDiff(a, b, c) + } runAllTests() } From e7d3944b4d94eae4474757710345c5fe272eca3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 12:09:12 +0200 Subject: [PATCH 06/40] Upgrade to scalafix 0.5.0-M3. --- build.sbt | 10 ++++++---- input/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- output/src/main/scala/fix/Collectionstrawman_v0.scala | 9 ++++----- project/plugins.sbt | 4 ++-- .../src/main/scala/fix/Collectionstrawman_v0.scala | 6 ++---- .../src/test/scala/fix/Collectionstrawman_Tests.scala | 3 ++- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/build.sbt b/build.sbt index c4441edf..798af27e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,9 @@ def scalafixVersion = _root_.scalafix.Versions.version -// Use a scala version supported by scalafix. -scalaVersion in ThisBuild := org.scalameta.BuildInfo.supportedScalaVersions.last +inScope(Global)( + List( + scalaVersion := _root_.scalafix.Versions.scala212 + ) +) lazy val root = project .in(file(".")) @@ -11,7 +14,7 @@ lazy val rewrites = project.settings( ) lazy val input = project.settings( - scalametaSourceroot := sourceDirectory.in(Compile).value + scalafixSourceroot := sourceDirectory.in(Compile).value ) val collections = ProjectRef(file(".."), "collections") @@ -24,7 +27,6 @@ lazy val output = project scalaBinaryVersion := scalaBinaryVersion.in(collections).value ) .dependsOn(collections) // collections/publishLocal is still necessary. - .disablePlugins(ScalahostSbtPlugin) lazy val tests = project .settings( diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 009e4eb5..d8819ddc 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ /* ONLY rewrite = "scala:fix.Collectionstrawman_v0" -patches.moveSymbols = [ +patches.replaceSymbols = [ { from = "scala.collection.immutable.HashMap", to = "strawman.collection.immutable.HashMap" } { from = "scala.collection.immutable.Map", diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 50bc1a37..30244c93 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,11 +1,10 @@ package fix -import scala.{ List => _, Nil => _, Seq => _, Vector => _, :: => _, #:: => _ } -import scala.Predef.{ Map => _, augmentString => _, intArrayOps => _, ArrowAssoc, charWrapper} -import strawman.collection.{ stringToStringOps, arrayToArrayOps } -import strawman.collection.immutable.{ LazyList, List, Map, Nil, Range, Seq, :: } +import scala.{ Vector => _, #:: => _, :: => _, Seq => _, List => _ } +import scala.Predef.{ Map => _ } +import strawman.collection.immutable.{ HashMap, LazyList, List, Map, Nil, Vector } import strawman.collection.immutable.LazyList.#:: - +import strawman.collection.mutable.ArrayBuffer object Collectionstrawman_v0_List { List(1, 2, 3) 1 :: 2 :: 3 :: Nil diff --git a/project/plugins.sbt b/project/plugins.sbt index 6696ca60..597cfbc9 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M1") -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC6") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5-SNAPSHOT") +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC9") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 309efc27..d17233b9 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -30,9 +30,8 @@ case class Collectionstrawman_v0(mirror: Mirror) extends SemanticRewrite(mirror) } def ifSymbolFound(ctx: RewriteCtx): Patch = { - val toUnimport = ctx.mirror.database.names.flatMap { - case (_, sym) => - val norm = normalize(sym) + val toUnimport = ctx.mirror.database.names.flatMap { r => + val norm = normalize(r.sym) if (unimports.contains(norm)) norm :: Nil else Nil } @@ -63,7 +62,6 @@ case class Collectionstrawman_v0(mirror: Mirror) extends SemanticRewrite(mirror) } def rewrite(ctx: RewriteCtx): Patch = { - ctx.debugMirror() ifSymbolFound(ctx) } } diff --git a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala index efb28c03..61b07802 100644 --- a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala +++ b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -2,10 +2,11 @@ package fix import scala.meta._ import scalafix.testkit._ +import scalafix._ class Collectionstrawman_Tests extends SemanticRewriteSuite( - Database.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), + SemanticCtx.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), AbsolutePath(BuildInfo.inputSourceroot), Seq(AbsolutePath(BuildInfo.outputSourceroot)) ) { From 6f1256e828d4e47e6af8c36c449fc3bbb119d489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 13:10:10 +0200 Subject: [PATCH 07/40] Move replaceSymbol from config to rewrite --- .../scala/fix/Collectionstrawman_v0.scala | 18 -------- .../scala/fix/Collectionstrawman_v0.scala | 2 +- .../scala/fix/Collectionstrawman_v0.scala | 41 +++++++++++-------- 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index d8819ddc..7bd5c8d6 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,24 +1,6 @@ /* ONLY rewrite = "scala:fix.Collectionstrawman_v0" patches.replaceSymbols = [ - { from = "scala.collection.immutable.HashMap", - to = "strawman.collection.immutable.HashMap" } - { from = "scala.collection.immutable.Map", - to = "strawman.collection.immutable.Map" } - { from = "scala.Predef.Map", - to = "strawman.collection.immutable.Map" } - { from = "scala.collection.immutable.List", - to = "strawman.collection.immutable.List" } - { from = "scala.collection.immutable.Nil", - to = "strawman.collection.immutable.Nil" } - { from = "scala.package.Stream", - to = "strawman.collection.immutable.LazyList" } - { from = "scala.package.`#::`", - to = "strawman.collection.immutable.LazyList.`#::`" } - { from = "scala.package.Vector", - to = "strawman.collection.immutable.Vector" } - { from = "scala.collection.mutable.ArrayBuffer", - to = "strawman.collection.mutable.ArrayBuffer" } ] */ package fix diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 30244c93..1db8c396 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ package fix -import scala.{ Vector => _, #:: => _, :: => _, Seq => _, List => _ } +import scala.{ #:: => _, :: => _, List => _, Seq => _, Vector => _ } import scala.Predef.{ Map => _ } import strawman.collection.immutable.{ HashMap, LazyList, List, Map, Nil, Vector } import strawman.collection.immutable.LazyList.#:: diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index d17233b9..44bee0ff 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -6,7 +6,7 @@ import scalafix.syntax._ import scalafix.internal.util.SymbolOps import scala.meta._ -case class Collectionstrawman_v0(mirror: Mirror) extends SemanticRewrite(mirror) { +case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mirror) { val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") val unimports = Set( Symbol("_root_.scala.List."), @@ -31,9 +31,9 @@ case class Collectionstrawman_v0(mirror: Mirror) extends SemanticRewrite(mirror) def ifSymbolFound(ctx: RewriteCtx): Patch = { val toUnimport = ctx.mirror.database.names.flatMap { r => - val norm = normalize(r.sym) - if (unimports.contains(norm)) norm :: Nil - else Nil + val norm = normalize(r.sym) + if (unimports.contains(norm)) norm :: Nil + else Nil } val unimportss = toUnimport.toList.distinct.flatMap { sym => SymbolOps.toImporter(sym).toList.collect { @@ -49,19 +49,26 @@ case class Collectionstrawman_v0(mirror: Mirror) extends SemanticRewrite(mirror) grouped.map(ctx.addGlobalImport(_)).asPatch } -// def isSymbol(tree: Tree, symbol: Symbol): Boolean = { -// mirror.database.names.get(tree.pos).exists(normalize(_) == symbol) -// } - - def rangePatch(ctx: RewriteCtx): Patch = { -// ctx.tree.collect { -// case q"$lhs $op $rhs" if isSymbol(op, Symbol()) => -// op -// } - Patch.empty - } - def rewrite(ctx: RewriteCtx): Patch = { - ifSymbolFound(ctx) + ifSymbolFound(ctx) + ctx.replaceSymbols( + "scala.collection.immutable.HashMap" -> + "strawman.collection.immutable.HashMap", + "scala.collection.immutable.Map" -> + "strawman.collection.immutable.Map", + "scala.Predef.Map" -> + "strawman.collection.immutable.Map", + "scala.collection.immutable.List" -> + "strawman.collection.immutable.List", + "scala.collection.immutable.Nil" -> + "strawman.collection.immutable.Nil", + "scala.package.Stream" -> + "strawman.collection.immutable.LazyList", + "scala.package.`#::`" -> + "strawman.collection.immutable.LazyList.`#::`", + "scala.package.Vector" -> + "strawman.collection.immutable.Vector", + "scala.collection.mutable.ArrayBuffer" -> + "strawman.collection.mutable.ArrayBuffer" + ) } } From e679c853a786d07de74ffa8b730d640ed669f380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 13:44:59 +0200 Subject: [PATCH 08/40] Use scalafix.syntax.normalized instead of custom rolled. --- .../src/main/scala/fix/Collectionstrawman_v0.scala | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 44bee0ff..95f4719e 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -20,18 +20,9 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mi Symbol("_root_.scala.Predef.intArrayOps.") ) - def normalize(symbol: Symbol): Symbol = { - def loop(symbol: Symbol): Symbol = symbol match { - case Symbol.Global(qual, Signature.Term("package")) => loop(qual) - case Symbol.Global(qual, name) => Symbol.Global(loop(qual), name) - case x => x - } - loop(symbol.normalized) - } - def ifSymbolFound(ctx: RewriteCtx): Patch = { val toUnimport = ctx.mirror.database.names.flatMap { r => - val norm = normalize(r.sym) + val norm = r.sym.normalized if (unimports.contains(norm)) norm :: Nil else Nil } From 632d1dc4466fd244498832ec7947d24831cfb471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 14:09:11 +0200 Subject: [PATCH 09/40] WIP --- .../scala/fix/Collectionstrawman_v0.scala | 4 +- input/src/main/scala/fix/ListTest.scala | 10 +++++ output/src/main/scala/fix/ListTest.scala | 7 +++ .../scala/fix/Collectionstrawman_v0.scala | 44 ++++++++++--------- 4 files changed, 41 insertions(+), 24 deletions(-) create mode 100644 input/src/main/scala/fix/ListTest.scala create mode 100644 output/src/main/scala/fix/ListTest.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 7bd5c8d6..60b91a2d 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,5 @@ -/* ONLY +/* rewrite = "scala:fix.Collectionstrawman_v0" -patches.replaceSymbols = [ -] */ package fix diff --git a/input/src/main/scala/fix/ListTest.scala b/input/src/main/scala/fix/ListTest.scala new file mode 100644 index 00000000..47fcb109 --- /dev/null +++ b/input/src/main/scala/fix/ListTest.scala @@ -0,0 +1,10 @@ +/* ONLY +rewrite = "scala:fix.Collectionstrawman_v0" +*/ +package fix + +import scala.concurrent.Future + +class ListTest { + def foo(x: Future[List[Int]]) = ??? +} diff --git a/output/src/main/scala/fix/ListTest.scala b/output/src/main/scala/fix/ListTest.scala new file mode 100644 index 00000000..7d9dabb8 --- /dev/null +++ b/output/src/main/scala/fix/ListTest.scala @@ -0,0 +1,7 @@ +package fix + +import scala.concurrent.Future + +class ListTest { + def foo(x: Future[List[Int]]) = ??? +} diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 95f4719e..19562a4f 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -15,8 +15,7 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mi Symbol("_root_.scala.`::`."), Symbol("_root_.scala.`#::`."), Symbol("_root_.scala.Predef.Map."), - Symbol("_root_.scala.Predef.intArrayOps."), - Symbol("_root_.scala.Predef.augmentString."), + Symbol("_root_.scala.Predef.augmentStrugming."), Symbol("_root_.scala.Predef.intArrayOps.") ) @@ -41,25 +40,28 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mi } def rewrite(ctx: RewriteCtx): Patch = { - ifSymbolFound(ctx) + ctx.replaceSymbols( - "scala.collection.immutable.HashMap" -> - "strawman.collection.immutable.HashMap", - "scala.collection.immutable.Map" -> - "strawman.collection.immutable.Map", - "scala.Predef.Map" -> - "strawman.collection.immutable.Map", - "scala.collection.immutable.List" -> - "strawman.collection.immutable.List", - "scala.collection.immutable.Nil" -> - "strawman.collection.immutable.Nil", - "scala.package.Stream" -> - "strawman.collection.immutable.LazyList", - "scala.package.`#::`" -> - "strawman.collection.immutable.LazyList.`#::`", - "scala.package.Vector" -> - "strawman.collection.immutable.Vector", - "scala.collection.mutable.ArrayBuffer" -> - "strawman.collection.mutable.ArrayBuffer" + def p(name: String) = + s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" + def s(name: String) = + s"scala.$name" -> s"strawman.collection.immutable.$name" + def i(name: String) = + s"scala.collection.immutable.$name" -> s"strawman.collection.immutable.$name" + def m(name: String) = + s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" +// ifSymbolFound(ctx) + + ctx.replaceSymbols( + i("HashMap"), + i("Map"), + p("Map"), + s("List"), + i("List"), + s("Nil"), + i("Nil"), + s("Stream"), + s("`#::`"), + s("Vector"), + i("Vector"), + m("ArrayBuffer") ) } } From d4ea411fc2e33705a615873de00a804bdc144fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 14:43:55 +0200 Subject: [PATCH 10/40] WIP --- build.sbt | 14 ++-- .../scala/fix/Collectionstrawman_v0.scala | 2 +- input/src/main/scala/fix/ListTest.scala | 2 +- .../scala/fix/Collectionstrawman_v0.scala | 6 +- .../scala/fix/Collectionstrawman_v0.scala | 84 +++++++++---------- 5 files changed, 52 insertions(+), 56 deletions(-) diff --git a/build.sbt b/build.sbt index 798af27e..54082d39 100644 --- a/build.sbt +++ b/build.sbt @@ -17,16 +17,16 @@ lazy val input = project.settings( scalafixSourceroot := sourceDirectory.in(Compile).value ) -val collections = ProjectRef(file(".."), "collections") - +//val collections = ProjectRef(file(".."), "collections") +// lazy val output = project .settings( - resolvers := resolvers.in(collections).value, - libraryDependencies := libraryDependencies.in(collections).value, - scalaVersion := scalaVersion.in(collections).value, - scalaBinaryVersion := scalaBinaryVersion.in(collections).value +// resolvers := resolvers.in(collections).value, +// libraryDependencies := libraryDependencies.in(collections).value, +// scalaVersion := scalaVersion.in(collections).value, +// scalaBinaryVersion := scalaBinaryVersion.in(collections).value ) - .dependsOn(collections) // collections/publishLocal is still necessary. +// .dependsOn(collections) // collections/publishLocal is still necessary. lazy val tests = project .settings( diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 60b91a2d..ccf88c27 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,4 +1,4 @@ -/* +/* ONLY rewrite = "scala:fix.Collectionstrawman_v0" */ package fix diff --git a/input/src/main/scala/fix/ListTest.scala b/input/src/main/scala/fix/ListTest.scala index 47fcb109..599835df 100644 --- a/input/src/main/scala/fix/ListTest.scala +++ b/input/src/main/scala/fix/ListTest.scala @@ -1,4 +1,4 @@ -/* ONLY +/* rewrite = "scala:fix.Collectionstrawman_v0" */ package fix diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 1db8c396..bf64d45c 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,9 +1,7 @@ package fix -import scala.{ #:: => _, :: => _, List => _, Seq => _, Vector => _ } -import scala.Predef.{ Map => _ } -import strawman.collection.immutable.{ HashMap, LazyList, List, Map, Nil, Vector } -import strawman.collection.immutable.LazyList.#:: +import strawman.collection.{ arrayToArrayOps, stringToStringOps } +import strawman.collection.immutable.{ #::, ::, HashMap, LazyList, List, Map, Nil, Vector } import strawman.collection.mutable.ArrayBuffer object Collectionstrawman_v0_List { List(1, 2, 3) diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 19562a4f..316c32d0 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,67 +1,65 @@ package fix // scalafmt: { maxColumn = 120 } +import scala.collection.JavaConverters._ import scalafix._ import scalafix.syntax._ import scalafix.internal.util.SymbolOps import scala.meta._ +import org.scalameta.logger case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mirror) { val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") - val unimports = Set( - Symbol("_root_.scala.List."), - Symbol("_root_.scala.Seq."), - Symbol("_root_.scala.Vector."), - Symbol("_root_.scala.`::`."), - Symbol("_root_.scala.`#::`."), - Symbol("_root_.scala.Predef.Map."), - Symbol("_root_.scala.Predef.augmentStrugming."), - Symbol("_root_.scala.Predef.intArrayOps.") + val unimports = Map( + Symbol("_root_.scala.Predef.augmentString.") -> + Symbol("_root_.strawman.collection.stringToStringOps."), + Symbol("_root_.scala.Predef.intArrayOps.") -> + Symbol("_root_.strawman.collection.arrayToArrayOps.") ) def ifSymbolFound(ctx: RewriteCtx): Patch = { - val toUnimport = ctx.mirror.database.names.flatMap { r => - val norm = r.sym.normalized - if (unimports.contains(norm)) norm :: Nil - else Nil - } - val unimportss = toUnimport.toList.distinct.flatMap { sym => - SymbolOps.toImporter(sym).toList.collect { - case Importer(qual, Importee.Name(n) :: Nil) => - Importer(qual, Importee.Unimport(n) :: Nil) - } - } - val grouped = unimportss.groupBy(_.ref.syntax).collect { - case (qual, iss @ is :: _) => - val names = iss.collect { case Importer(_, name :: Nil) => name } - Importer(is.ref, names) - } - grouped.map(ctx.addGlobalImport(_)).asPatch + logger.elem(ctx.mirror.names) + val toImport = ctx.mirror.names + .flatMap(r => + unimports.get { + val x = r.sym.normalized + logger.elem(x) + x + }) + .map(ctx.addGlobalImport) + toImport.asPatch } def rewrite(ctx: RewriteCtx): Patch = { def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" - def s(name: String) = - s"scala.$name" -> s"strawman.collection.immutable.$name" + def s(name: String, rename: Option[String] = None) = + s"scala.$name" -> s"strawman.collection.immutable.${rename.getOrElse(name)}" def i(name: String) = s"scala.collection.immutable.$name" -> s"strawman.collection.immutable.$name" def m(name: String) = s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" -// ifSymbolFound(ctx) + - ctx.replaceSymbols( - i("HashMap"), - i("Map"), - p("Map"), - s("List"), - i("List"), - s("Nil"), - i("Nil"), - s("Stream"), - s("`#::`"), - s("Vector"), - i("Vector"), - m("ArrayBuffer") - ) + ifSymbolFound(ctx) + + ctx.replaceSymbols( + i("HashMap"), + i("Map"), + p("Map"), + s("List"), + i("List"), + s("Nil"), + i("Nil"), + s("`::`"), + i("`::`"), + s("`+:`"), + i("`+:`"), + s("`:+`"), + i("`:+`"), + s("Stream", Some("LazyList")), + s("`#::`"), + s("`#::`"), + s("Vector"), + i("Vector"), + m("ArrayBuffer") + ) } } From 791788d11027c9e5c959b05748edc92713efc92a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 14:47:25 +0200 Subject: [PATCH 11/40] WIP --- .../scala/fix/Collectionstrawman_v0.scala | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 316c32d0..ddf8f6bc 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,14 +1,11 @@ package fix -// scalafmt: { maxColumn = 120 } -import scala.collection.JavaConverters._ import scalafix._ import scalafix.syntax._ -import scalafix.internal.util.SymbolOps import scala.meta._ -import org.scalameta.logger -case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mirror) { +case class Collectionstrawman_v0(mirror: SemanticCtx) + extends SemanticRewrite(mirror) { val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") val unimports = Map( Symbol("_root_.scala.Predef.augmentString.") -> @@ -18,14 +15,8 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mi ) def ifSymbolFound(ctx: RewriteCtx): Patch = { - logger.elem(ctx.mirror.names) val toImport = ctx.mirror.names - .flatMap(r => - unimports.get { - val x = r.sym.normalized - logger.elem(x) - x - }) + .flatMap(r => unimports.get(r.sym.normalized)) .map(ctx.addGlobalImport) toImport.asPatch } @@ -35,8 +26,9 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mi s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = s"scala.$name" -> s"strawman.collection.immutable.${rename.getOrElse(name)}" - def i(name: String) = - s"scala.collection.immutable.$name" -> s"strawman.collection.immutable.$name" + def i(name: String, rename: Option[String] = None) = + s"scala.collection.immutable.$name" -> + s"strawman.collection.immutable.${rename.getOrElse(name)}" def m(name: String) = s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" ifSymbolFound(ctx) + @@ -54,6 +46,7 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) extends SemanticRewrite(mi i("`+:`"), s("`:+`"), i("`:+`"), + i("Stream", Some("LazyList")), s("Stream", Some("LazyList")), s("`#::`"), s("`#::`"), From 2466d82d95e9fa2aa82df7ce90967d0c2e16d77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 14:49:35 +0200 Subject: [PATCH 12/40] WIP --- input/src/main/scala/fix/Collectionstrawman_v0.scala | 5 +++-- output/src/main/scala/fix/Collectionstrawman_v0.scala | 3 ++- rewrites/src/main/scala/fix/Collectionstrawman_v0.scala | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index ccf88c27..f0808af5 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ /* ONLY rewrite = "scala:fix.Collectionstrawman_v0" -*/ + */ package fix object Collectionstrawman_v0_List { @@ -48,5 +48,6 @@ object Collectionstrawman_v0_ArrayAndString { } object Collectionstrawman_v0_Range { - for (i <- 1 to 10; j <- 0 until 10) yield (i, j) + (1 to 10).map(_ + 2) + (0 until 10).map(_ + 3) } diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index bf64d45c..2438f186 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -46,5 +46,6 @@ object Collectionstrawman_v0_ArrayAndString { } object Collectionstrawman_v0_Range { - for (i <- Range.inclusive(1, 10); j <- Range(0, 10)) yield (i, j) + Range.inclusive(1, 10).map(_ + 1) + Range(1, 10).map(_ + 1) } diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index ddf8f6bc..30863213 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -22,6 +22,7 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) } def rewrite(ctx: RewriteCtx): Patch = { + ctx.debugMirror() def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = From c0a5054a1cdf72d2c6a65fdb97cb2b096016c9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 10 Aug 2017 15:21:42 +0200 Subject: [PATCH 13/40] WIP --- .../scala/fix/Collectionstrawman_v0.scala | 6 +- .../scala/fix/Collectionstrawman_v0.scala | 65 ++++++++++++------- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 2438f186..2559bc9d 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,7 @@ package fix import strawman.collection.{ arrayToArrayOps, stringToStringOps } -import strawman.collection.immutable.{ #::, ::, HashMap, LazyList, List, Map, Nil, Vector } +import strawman.collection.immutable.{ #::, ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.mutable.ArrayBuffer object Collectionstrawman_v0_List { List(1, 2, 3) @@ -46,6 +46,6 @@ object Collectionstrawman_v0_ArrayAndString { } object Collectionstrawman_v0_Range { - Range.inclusive(1, 10).map(_ + 1) - Range(1, 10).map(_ + 1) + Range.inclusive(1, 10).map(_ + 2) + Range(0, 10).map(_ + 3) } diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 30863213..9cd1ea7b 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -21,8 +21,25 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) toImport.asPatch } + val rangeImport = Symbol("_root_.strawman.collection.immutable.Range.") + val inclusiveRange = Symbol( + "_root_.scala.runtime.RichInt#to(I)Lscala/collection/immutable/Range/Inclusive;.") + val rangeSymbol = Symbol( + "_root_.scala.runtime.RichInt#until(I)Lscala/collection/immutable/Range;.") + def range(ctx: RewriteCtx): Patch = { + ctx.tree.collect { + case tree @ Term.ApplyInfix(lhs, op, targs, arg :: Nil) + if op.symbol.contains(inclusiveRange) => + ctx.replaceTree(tree, q"Range.inclusive($lhs, $arg)".syntax) + + ctx.addGlobalImport(rangeImport) + case tree @ Term.ApplyInfix(lhs, op, targs, arg :: Nil) + if op.symbol.contains(rangeSymbol) => + ctx.replaceTree(tree, q"Range($lhs, $arg)".syntax) + + ctx.addGlobalImport(rangeImport) + } + }.asPatch + def rewrite(ctx: RewriteCtx): Patch = { - ctx.debugMirror() def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = @@ -32,28 +49,28 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) s"strawman.collection.immutable.${rename.getOrElse(name)}" def m(name: String) = s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" - ifSymbolFound(ctx) + - ctx.replaceSymbols( - i("HashMap"), - i("Map"), - p("Map"), - s("List"), - i("List"), - s("Nil"), - i("Nil"), - s("`::`"), - i("`::`"), - s("`+:`"), - i("`+:`"), - s("`:+`"), - i("`:+`"), - i("Stream", Some("LazyList")), - s("Stream", Some("LazyList")), - s("`#::`"), - s("`#::`"), - s("Vector"), - i("Vector"), - m("ArrayBuffer") - ) + ctx.replaceSymbols( + i("HashMap"), + i("Map"), + p("Map"), + s("List"), + i("List"), + s("Nil"), + i("Nil"), + s("`::`"), + i("`::`"), + s("`+:`"), + i("`+:`"), + s("`:+`"), + i("`:+`"), + i("Stream", Some("LazyList")), + s("Stream", Some("LazyList")), + s("`#::`"), + s("Vector"), + i("Vector"), + m("ArrayBuffer") + ) + + ifSymbolFound(ctx) + + range(ctx) } } From 5e31fb3f72b3d3683148a594de46a00af29b58f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Tue, 15 Aug 2017 14:30:50 +0200 Subject: [PATCH 14/40] Upgrade to M4. --- project/plugins.sbt | 2 +- rewrites/src/main/scala/fix/Collectionstrawman_v0.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 597cfbc9..e9e25bbe 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5-SNAPSHOT") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M4") addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC9") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 9cd1ea7b..3f3de67c 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -4,8 +4,8 @@ import scalafix._ import scalafix.syntax._ import scala.meta._ -case class Collectionstrawman_v0(mirror: SemanticCtx) - extends SemanticRewrite(mirror) { +case class Collectionstrawman_v0(sctx: SemanticCtx) + extends SemanticRewrite(sctx) { val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") val unimports = Map( Symbol("_root_.scala.Predef.augmentString.") -> @@ -15,7 +15,7 @@ case class Collectionstrawman_v0(mirror: SemanticCtx) ) def ifSymbolFound(ctx: RewriteCtx): Patch = { - val toImport = ctx.mirror.names + val toImport = ctx.semanticCtx.names .flatMap(r => unimports.get(r.sym.normalized)) .map(ctx.addGlobalImport) toImport.asPatch From 6bf57f517139d89b1b97cb90b0551eced7a8f9d0 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 28 Aug 2017 15:59:00 +0200 Subject: [PATCH 15/40] Add a few more examples --- .../src/main/scala/fix/Collectionstrawman_v0.scala | 13 +++++++++++++ .../src/main/scala/fix/Collectionstrawman_v0.scala | 14 ++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index f0808af5..9e131bdf 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -51,3 +51,16 @@ object Collectionstrawman_v0_Range { (1 to 10).map(_ + 2) (0 until 10).map(_ + 3) } + +object Collectionstrawman_v0_Traversable { + def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { + xs.toList + xs.toSet + ys.toSeq + xs.to[List] + xs.to[Set] + xs.toMap + xs.toIterator + ys.iterator + } +} \ No newline at end of file diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 2559bc9d..0435caee 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -3,6 +3,7 @@ package fix import strawman.collection.{ arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ #::, ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.mutable.ArrayBuffer + object Collectionstrawman_v0_List { List(1, 2, 3) 1 :: 2 :: 3 :: Nil @@ -49,3 +50,16 @@ object Collectionstrawman_v0_Range { Range.inclusive(1, 10).map(_ + 2) Range(0, 10).map(_ + 3) } + +object Collectionstrawman_v0_Traversable { + def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { + xs.to(List) + xs.to(Set) + ys.toSeq + xs.to(List) + xs.to(strawman.collection.immutable.Set) + xs.to(strawman.collection.Map) + xs.iterator() + ys.iterator() + } +} From 891df929f1e1f68866e3ea5bf18f723ab7617405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Mon, 28 Aug 2017 16:40:07 +0200 Subject: [PATCH 16/40] Add dep on parent project. --- build.sbt | 14 +++++++------- .../src/main/scala/fix/Collectionstrawman_v0.scala | 3 ++- .../src/main/scala/fix/Collectionstrawman_v0.scala | 4 ++++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index 54082d39..6a9bae18 100644 --- a/build.sbt +++ b/build.sbt @@ -17,16 +17,16 @@ lazy val input = project.settings( scalafixSourceroot := sourceDirectory.in(Compile).value ) -//val collections = ProjectRef(file(".."), "collections") -// +val collections = ProjectRef(file(".."), "collections") + lazy val output = project .settings( -// resolvers := resolvers.in(collections).value, -// libraryDependencies := libraryDependencies.in(collections).value, -// scalaVersion := scalaVersion.in(collections).value, -// scalaBinaryVersion := scalaBinaryVersion.in(collections).value + resolvers := resolvers.in(collections).value, + libraryDependencies := libraryDependencies.in(collections).value, + scalaVersion := scalaVersion.in(collections).value, + scalaBinaryVersion := scalaBinaryVersion.in(collections).value ) -// .dependsOn(collections) // collections/publishLocal is still necessary. + .dependsOn(collections) // collections/publishLocal is still necessary. lazy val tests = project .settings( diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 9e131bdf..9c6e4128 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -53,6 +53,7 @@ object Collectionstrawman_v0_Range { } object Collectionstrawman_v0_Traversable { + val x: Iterable[String] = ??? def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { xs.toList xs.toSet @@ -63,4 +64,4 @@ object Collectionstrawman_v0_Traversable { xs.toIterator ys.iterator } -} \ No newline at end of file +} diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 3f3de67c..e645bab8 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -40,6 +40,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) }.asPatch def rewrite(ctx: RewriteCtx): Patch = { + ctx.debugSemanticCtx() def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = @@ -50,6 +51,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) def m(name: String) = s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" ctx.replaceSymbols( + s("Set"), i("HashMap"), i("Map"), p("Map"), @@ -65,6 +67,8 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) i("`:+`"), i("Stream", Some("LazyList")), s("Stream", Some("LazyList")), + s("Traversable", Some("Iterable")), + "scala.Iterable" -> "strawman.collection.Iterable", s("`#::`"), s("Vector"), i("Vector"), From 55a410756292e4136eae1b0341569192a3aa470c Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 29 Aug 2017 15:21:28 +0200 Subject: [PATCH 17/40] Improve documentation of the migration tool --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 6a9bae18..ed537859 100644 --- a/build.sbt +++ b/build.sbt @@ -22,11 +22,11 @@ val collections = ProjectRef(file(".."), "collections") lazy val output = project .settings( resolvers := resolvers.in(collections).value, - libraryDependencies := libraryDependencies.in(collections).value, + libraryDependencies ++= libraryDependencies.in(collections).value, scalaVersion := scalaVersion.in(collections).value, scalaBinaryVersion := scalaBinaryVersion.in(collections).value ) - .dependsOn(collections) // collections/publishLocal is still necessary. + .dependsOn(collections) // collections/publishLocal is still necessary. lazy val tests = project .settings( From 9352c2caa9a8ae4f695bc09cba425565623e5db7 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 29 Aug 2017 15:33:09 +0200 Subject: [PATCH 18/40] Improve documentation of the migration tool and fix the input and output files. --- input/src/main/scala/fix/Collectionstrawman_v0.scala | 1 - output/src/main/scala/fix/Collectionstrawman_v0.scala | 7 +++++-- readme.md | 7 ------- 3 files changed, 5 insertions(+), 10 deletions(-) delete mode 100644 readme.md diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 9c6e4128..f5db091d 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -53,7 +53,6 @@ object Collectionstrawman_v0_Range { } object Collectionstrawman_v0_Traversable { - val x: Iterable[String] = ??? def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { xs.toList xs.toSet diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 0435caee..8a043dc2 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,10 @@ package fix -import strawman.collection.{ arrayToArrayOps, stringToStringOps } -import strawman.collection.immutable.{ #::, ::, HashMap, LazyList, List, Map, Nil, Range, Vector } +import scala.Predef.{augmentString => _, ArrowAssoc, charWrapper} + +import strawman.collection.{ Iterable, Set, arrayToArrayOps, stringToStringOps } +import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } +import strawman.collection.immutable.LazyList.#:: import strawman.collection.mutable.ArrayBuffer object Collectionstrawman_v0_List { diff --git a/readme.md b/readme.md deleted file mode 100644 index 038042a2..00000000 --- a/readme.md +++ /dev/null @@ -1,7 +0,0 @@ -# Scalafix rewrites for collection-strawman - -To develop rewrite: -``` -sbt ~tests/test -# edit rewrites/src/main/scala/fix/Collectionstrawman_v0.scala -``` From eb1007098e2fd4be00791c5713b8bf66e7f54194 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 29 Aug 2017 16:15:22 +0200 Subject: [PATCH 19/40] Fix the output and tuned a few rules. --- output/src/main/scala/fix/Collectionstrawman_v0.scala | 4 +--- rewrites/src/main/scala/fix/Collectionstrawman_v0.scala | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 8a043dc2..16b38fbe 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,12 +1,10 @@ package fix -import scala.Predef.{augmentString => _, ArrowAssoc, charWrapper} - +import scala.Predef.{augmentString => _, wrapString => _, _} import strawman.collection.{ Iterable, Set, arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: import strawman.collection.mutable.ArrayBuffer - object Collectionstrawman_v0_List { List(1, 2, 3) 1 :: 2 :: 3 :: Nil diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index e645bab8..e54fc2d2 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -40,7 +40,6 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) }.asPatch def rewrite(ctx: RewriteCtx): Patch = { - ctx.debugSemanticCtx() def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = @@ -69,7 +68,8 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) s("Stream", Some("LazyList")), s("Traversable", Some("Iterable")), "scala.Iterable" -> "strawman.collection.Iterable", - s("`#::`"), + "scala.Traversable" -> "strawman.collection.Iterable", + "scala.`#::`" -> "strawman.collection.immutable.LazyList.`#::`", s("Vector"), i("Vector"), m("ArrayBuffer") From e2fa3369a5cf6726300717f979e46535e39cd556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Tue, 29 Aug 2017 16:47:23 +0200 Subject: [PATCH 20/40] Unimport Predef conversions if used. --- .../scala/fix/Collectionstrawman_v0.scala | 2 +- .../scala/fix/Collectionstrawman_v0.scala | 24 +++++++++++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 16b38fbe..030b8169 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ package fix -import scala.Predef.{augmentString => _, wrapString => _, _} +import scala.Predef.{augmentString => _, intArrayOps => _, wrapString => _, _} import strawman.collection.{ Iterable, Set, arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index e54fc2d2..86e798dd 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -7,6 +7,13 @@ import scala.meta._ case class Collectionstrawman_v0(sctx: SemanticCtx) extends SemanticRewrite(sctx) { val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") + implicit class XtensionSymbolCollection(symbol: Symbol) { + def name = symbol match { + case Symbol.Global(_, sig) => sig.name + case _ => symbol.syntax + } + } + val unimports = Map( Symbol("_root_.scala.Predef.augmentString.") -> Symbol("_root_.strawman.collection.stringToStringOps."), @@ -15,10 +22,19 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) ) def ifSymbolFound(ctx: RewriteCtx): Patch = { - val toImport = ctx.semanticCtx.names - .flatMap(r => unimports.get(r.sym.normalized)) - .map(ctx.addGlobalImport) - toImport.asPatch + val toImport = for { + r <- ctx.semanticCtx.names + in = r.sym.normalized + out <- unimports.get(in).toList + } yield { + ctx.addGlobalImport(out) + + ctx.addGlobalImport( + Importer(q"scala.Predef", Importee.Unimport(Name(in.name)) :: Nil)) + } + val predefUnderscore = + if (toImport.isEmpty) Patch.empty + else ctx.addGlobalImport(importer"scala.Predef._") + toImport.asPatch + predefUnderscore } val rangeImport = Symbol("_root_.strawman.collection.immutable.Range.") From 3311594be2d8e0013de6b8c6149c4c36f62ac942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Tue, 29 Aug 2017 17:05:05 +0200 Subject: [PATCH 21/40] Unimport both augmentString+wrapString if either appears. --- output/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- .../src/main/scala/fix/Collectionstrawman_v0.scala | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 030b8169..159e9ba8 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ package fix -import scala.Predef.{augmentString => _, intArrayOps => _, wrapString => _, _} +import scala.Predef.{ augmentString => _, intArrayOps => _, wrapString => _, _ } import strawman.collection.{ Iterable, Set, arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index 86e798dd..e2426953 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -21,15 +21,24 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) Symbol("_root_.strawman.collection.arrayToArrayOps.") ) + val additionalUnimports = Map( + "augmentString" -> "wrapString", + "wrapString" -> "augmentString" + ) + def ifSymbolFound(ctx: RewriteCtx): Patch = { val toImport = for { r <- ctx.semanticCtx.names in = r.sym.normalized out <- unimports.get(in).toList } yield { + val name = in.name + val names = name :: additionalUnimports + .get(name) + .fold(List.empty[String])(_ :: Nil) ctx.addGlobalImport(out) + ctx.addGlobalImport( - Importer(q"scala.Predef", Importee.Unimport(Name(in.name)) :: Nil)) + Importer(q"scala.Predef", names.map(n => Importee.Unimport(Name(n))))) } val predefUnderscore = if (toImport.isEmpty) Patch.empty From 4b2d629168c025364529666c3b569c5e02fe61c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Tue, 29 Aug 2017 17:55:09 +0200 Subject: [PATCH 22/40] Prototype toX and to[X] conversions. Kind of hacky, but it does mostly the right thing Remaining failing tests ```diff - xs.to(Set) - xs.to(Map) - xs.iterator + xs.to(strawman.collection.immutable.Set) + xs.to(strawman.collection.Map) + xs.iterator() ``` --- .../scala/fix/Collectionstrawman_v0.scala | 14 +---- .../Collectionstrawman_v0_Traversable.scala | 17 +++++ .../scala/fix/Collectionstrawman_v0.scala | 14 +---- .../Collectionstrawman_v0_Traversable.scala | 16 +++++ output/src/main/scala/fix/ListTest.scala | 1 + .../scala/fix/Collectionstrawman_v0.scala | 62 +++++++++++++++++-- 6 files changed, 92 insertions(+), 32 deletions(-) create mode 100644 input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala create mode 100644 output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index f5db091d..dc82adec 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,4 +1,4 @@ -/* ONLY +/* rewrite = "scala:fix.Collectionstrawman_v0" */ package fix @@ -52,15 +52,3 @@ object Collectionstrawman_v0_Range { (0 until 10).map(_ + 3) } -object Collectionstrawman_v0_Traversable { - def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { - xs.toList - xs.toSet - ys.toSeq - xs.to[List] - xs.to[Set] - xs.toMap - xs.toIterator - ys.iterator - } -} diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala new file mode 100644 index 00000000..8b692c73 --- /dev/null +++ b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -0,0 +1,17 @@ +/* +rewrite = "scala:fix.Collectionstrawman_v0" + */ +package fix + +object Collectionstrawman_v0_Traversable { + def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { + xs.toList + xs.toSet + ys.toSeq + xs.to[List] + xs.to[Set] + xs.toMap + xs.toIterator + ys.iterator + } +} diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 159e9ba8..cb52e1a3 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,7 @@ package fix import scala.Predef.{ augmentString => _, intArrayOps => _, wrapString => _, _ } -import strawman.collection.{ Iterable, Set, arrayToArrayOps, stringToStringOps } +import strawman.collection.{ arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: import strawman.collection.mutable.ArrayBuffer @@ -52,15 +52,3 @@ object Collectionstrawman_v0_Range { Range(0, 10).map(_ + 3) } -object Collectionstrawman_v0_Traversable { - def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { - xs.to(List) - xs.to(Set) - ys.toSeq - xs.to(List) - xs.to(strawman.collection.immutable.Set) - xs.to(strawman.collection.Map) - xs.iterator() - ys.iterator() - } -} diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala new file mode 100644 index 00000000..347af568 --- /dev/null +++ b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -0,0 +1,16 @@ +package fix + +import strawman.collection.Iterable +import strawman.collection.immutable.List +object Collectionstrawman_v0_Traversable { + def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { + xs.to(List) + xs.to(Set) + ys.toSeq + xs.to(List) + xs.to(strawman.collection.immutable.Set) + xs.to(strawman.collection.Map) + xs.iterator() + ys.iterator() + } +} diff --git a/output/src/main/scala/fix/ListTest.scala b/output/src/main/scala/fix/ListTest.scala index 7d9dabb8..d8d160e7 100644 --- a/output/src/main/scala/fix/ListTest.scala +++ b/output/src/main/scala/fix/ListTest.scala @@ -1,6 +1,7 @@ package fix import scala.concurrent.Future +import strawman.collection.immutable.List class ListTest { def foo(x: Future[List[Int]]) = ??? diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index e2426953..b7b75e74 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -26,7 +26,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) "wrapString" -> "augmentString" ) - def ifSymbolFound(ctx: RewriteCtx): Patch = { + def replaceExtensionMethods(ctx: RewriteCtx): Patch = { val toImport = for { r <- ctx.semanticCtx.names in = r.sym.normalized @@ -51,7 +51,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) "_root_.scala.runtime.RichInt#to(I)Lscala/collection/immutable/Range/Inclusive;.") val rangeSymbol = Symbol( "_root_.scala.runtime.RichInt#until(I)Lscala/collection/immutable/Range;.") - def range(ctx: RewriteCtx): Patch = { + def replaceRange(ctx: RewriteCtx): Patch = { ctx.tree.collect { case tree @ Term.ApplyInfix(lhs, op, targs, arg :: Nil) if op.symbol.contains(inclusiveRange) => @@ -64,7 +64,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) } }.asPatch - def rewrite(ctx: RewriteCtx): Patch = { + def replaceSymbols(ctx: RewriteCtx): Patch = { def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = @@ -94,12 +94,62 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) s("Traversable", Some("Iterable")), "scala.Iterable" -> "strawman.collection.Iterable", "scala.Traversable" -> "strawman.collection.Iterable", + "scala.collection.TraversableLike.toIterator" -> "iterator", "scala.`#::`" -> "strawman.collection.immutable.LazyList.`#::`", s("Vector"), i("Vector"), m("ArrayBuffer") - ) + - ifSymbolFound(ctx) + - range(ctx) + ) + } + + case class SymbolMatcher(symbols: Symbol*) { + def unapply(arg: Tree): Option[(Tree, Symbol)] = + sctx.symbol(arg.pos).flatMap { sym => + if (symbols.exists(_.isSameNormalized(sym))) Some(arg -> sym) + else None + } + } + + object WithSymbol { + def unapply(arg: Tree): Option[(Tree, Symbol)] = + sctx.symbol(arg.pos).map(x => arg -> x) + } + + val toX = SymbolMatcher( + Symbol("_root_.scala.collection.TraversableOnce.toMap."), + Symbol("_root_.scala.collection.TraversableOnce.toList."), + Symbol("_root_.scala.collection.TraversableOnce.toSet.") + ) + val toTpe = SymbolMatcher( + Symbol("_root_.scala.collection.TraversableLike.to.") + ) + val iterator = SymbolMatcher( + Symbol("_root_.scala.collection.LinearSeqLike.iterator.") + ) + + def replaceToList(ctx: RewriteCtx) = + ctx.tree.collect { + case iterator(n: Name, _) => + ctx.addRight(n.tokens.last, "()") + case toX(n: Name, s) => + ctx.replaceTree(n, s"to(${s.name.stripPrefix("to")})") + case toTpe(n: Name, _) => + ctx.debug(n) + (for { + name <- n.tokens.lastOption + _ = ctx.debug(name) + open <- ctx.tokenList.find(name)(t => t.is[Token.LeftBracket]) + _ = ctx.debug(open) + close <- ctx.matching.close(open.asInstanceOf[Token.LeftBracket]) + } yield + ctx.replaceToken(open, "(") + + ctx.replaceToken(close, ")")).getOrElse(Patch.empty) + }.asPatch + + def rewrite(ctx: RewriteCtx): Patch = { + replaceToList(ctx) + + replaceSymbols(ctx) + + replaceExtensionMethods(ctx) + + replaceRange(ctx) } } From ea688805b9cc511022c066ef5f5289c3efa169b9 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 30 Aug 2017 11:25:14 +0200 Subject: [PATCH 23/40] Fix compilation error in the output --- output/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- .../src/main/scala/fix/Collectionstrawman_v0_Traversable.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index cb52e1a3..4850f6c3 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ package fix -import scala.Predef.{ augmentString => _, intArrayOps => _, wrapString => _, _ } +import scala.Predef.{ augmentString => _, genericArrayOps => _, genericWrapArray => _, intArrayOps => _, wrapIntArray => _, wrapString => _, _ } import strawman.collection.{ arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala index 347af568..e3e83ed1 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -5,7 +5,7 @@ import strawman.collection.immutable.List object Collectionstrawman_v0_Traversable { def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { xs.to(List) - xs.to(Set) + xs.to(strawman.collection.immutable.Set) ys.toSeq xs.to(List) xs.to(strawman.collection.immutable.Set) From c41b46efa0d1cb8565fbd1654dc4af8f931b8d5a Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 30 Aug 2017 13:36:40 +0200 Subject: [PATCH 24/40] Improve the to[X] rules --- .../fix/Collectionstrawman_v0_Traversable.scala | 6 +++--- .../main/scala/fix/Collectionstrawman_v0.scala | 17 +++++++++++------ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala index e3e83ed1..4438c121 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -1,14 +1,14 @@ package fix import strawman.collection.Iterable -import strawman.collection.immutable.List +import strawman.collection.immutable.{ List, Set } object Collectionstrawman_v0_Traversable { def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { - xs.to(List) + xs.to(strawman.collection.immutable.List) xs.to(strawman.collection.immutable.Set) ys.toSeq xs.to(List) - xs.to(strawman.collection.immutable.Set) + xs.to(Set) xs.to(strawman.collection.Map) xs.iterator() ys.iterator() diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index b7b75e74..fe396893 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -6,7 +6,7 @@ import scala.meta._ case class Collectionstrawman_v0(sctx: SemanticCtx) extends SemanticRewrite(sctx) { - val immutableListSymbol = Symbol("_root_.scala.collection.immutable.List.") + implicit class XtensionSymbolCollection(symbol: Symbol) { def name = symbol match { case Symbol.Global(_, sig) => sig.name @@ -75,7 +75,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) def m(name: String) = s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" ctx.replaceSymbols( - s("Set"), + p("Set"), i("HashMap"), i("Map"), p("Map"), @@ -115,8 +115,10 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) sctx.symbol(arg.pos).map(x => arg -> x) } - val toX = SymbolMatcher( - Symbol("_root_.scala.collection.TraversableOnce.toMap."), + val toGenericX = SymbolMatcher( + Symbol("_root_.scala.collection.TraversableOnce.toMap.") + ) + val toImmutableX = SymbolMatcher( Symbol("_root_.scala.collection.TraversableOnce.toList."), Symbol("_root_.scala.collection.TraversableOnce.toSet.") ) @@ -131,8 +133,10 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) ctx.tree.collect { case iterator(n: Name, _) => ctx.addRight(n.tokens.last, "()") - case toX(n: Name, s) => - ctx.replaceTree(n, s"to(${s.name.stripPrefix("to")})") + case toImmutableX(n: Name, s) => + ctx.replaceTree(n, s"to(strawman.collection.immutable.${s.name.stripPrefix("to")})") + case toGenericX(n: Name, s) => + ctx.replaceTree(n, s"to(strawman.collection.${s.name.stripPrefix("to")})") case toTpe(n: Name, _) => ctx.debug(n) (for { @@ -141,6 +145,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) open <- ctx.tokenList.find(name)(t => t.is[Token.LeftBracket]) _ = ctx.debug(open) close <- ctx.matching.close(open.asInstanceOf[Token.LeftBracket]) + replacedTokens = ctx.tokenList.slice(open, close) } yield ctx.replaceToken(open, "(") + ctx.replaceToken(close, ")")).getOrElse(Patch.empty) From f059ccbaed3d5a5d5fd137acfafb21ca99169b34 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 12 Sep 2017 18:45:29 +0200 Subject: [PATCH 25/40] Fix scalafix build definition --- build.sbt | 2 +- project/build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index ed537859..09890aa4 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,7 @@ lazy val input = project.settings( scalafixSourceroot := sourceDirectory.in(Compile).value ) -val collections = ProjectRef(file(".."), "collections") +val collections = ProjectRef(file(".."), "collectionsJVM") lazy val output = project .settings( diff --git a/project/build.properties b/project/build.properties index 64317fda..c091b86c 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.15 +sbt.version=0.13.16 From 8c9097f846f76f49e8c60ccbce67b4f1003ddf8a Mon Sep 17 00:00:00 2001 From: Marcelo Cenerino Date: Fri, 3 Nov 2017 02:19:15 +0000 Subject: [PATCH 26/40] Fix broken scalafix tests --- .../src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- .../src/main/scala/fix/Collectionstrawman_v0.scala | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 4850f6c3..ec71003c 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,6 +1,6 @@ package fix -import scala.Predef.{ augmentString => _, genericArrayOps => _, genericWrapArray => _, intArrayOps => _, wrapIntArray => _, wrapString => _, _ } +import scala.Predef.{ augmentString => _, genericArrayOps => _, intArrayOps => _, wrapString => _, _ } import strawman.collection.{ arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala index fe396893..eac6eec1 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala @@ -23,7 +23,8 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) val additionalUnimports = Map( "augmentString" -> "wrapString", - "wrapString" -> "augmentString" + "wrapString" -> "augmentString", + "intArrayOps" -> "genericArrayOps" ) def replaceExtensionMethods(ctx: RewriteCtx): Patch = { @@ -33,8 +34,7 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) out <- unimports.get(in).toList } yield { val name = in.name - val names = name :: additionalUnimports - .get(name) + val names = name :: additionalUnimports.get(name) .fold(List.empty[String])(_ :: Nil) ctx.addGlobalImport(out) + ctx.addGlobalImport( @@ -94,7 +94,6 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) s("Traversable", Some("Iterable")), "scala.Iterable" -> "strawman.collection.Iterable", "scala.Traversable" -> "strawman.collection.Iterable", - "scala.collection.TraversableLike.toIterator" -> "iterator", "scala.`#::`" -> "strawman.collection.immutable.LazyList.`#::`", s("Vector"), i("Vector"), @@ -126,13 +125,14 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) Symbol("_root_.scala.collection.TraversableLike.to.") ) val iterator = SymbolMatcher( - Symbol("_root_.scala.collection.LinearSeqLike.iterator.") + Symbol("_root_.scala.collection.LinearSeqLike.iterator."), + Symbol("_root_.scala.collection.TraversableLike.toIterator.") ) def replaceToList(ctx: RewriteCtx) = ctx.tree.collect { case iterator(n: Name, _) => - ctx.addRight(n.tokens.last, "()") + ctx.replaceTree(n, "iterator()") case toImmutableX(n: Name, s) => ctx.replaceTree(n, s"to(strawman.collection.immutable.${s.name.stripPrefix("to")})") case toGenericX(n: Name, s) => From 362d648a1cbbe32492892c540097e78e00beb8fc Mon Sep 17 00:00:00 2001 From: Marcelo Cenerino Date: Sat, 4 Nov 2017 14:22:08 +0000 Subject: [PATCH 27/40] Upgrade Scalafix to 0.5.3 --- build.sbt | 6 +- .../scala/fix/Collectionstrawman_v0.scala | 2 +- .../Collectionstrawman_v0_Traversable.scala | 2 +- input/src/main/scala/fix/ListTest.scala | 2 +- project/plugins.sbt | 7 +- .../scala/fix/Collectionstrawman_v0.scala | 64 +++++++------------ .../scala/fix/Collectionstrawman_Tests.scala | 4 +- 7 files changed, 35 insertions(+), 52 deletions(-) rename {rewrites => rules}/src/main/scala/fix/Collectionstrawman_v0.scala (70%) diff --git a/build.sbt b/build.sbt index 09890aa4..822d6bb4 100644 --- a/build.sbt +++ b/build.sbt @@ -7,9 +7,9 @@ inScope(Global)( lazy val root = project .in(file(".")) - .aggregate(rewrites, input, output, tests) + .aggregate(rules, input, output, tests) -lazy val rewrites = project.settings( +lazy val rules = project.settings( libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion ) @@ -41,5 +41,5 @@ lazy val tests = project classDirectory.in(input, Compile).value ) ) - .dependsOn(input, rewrites) + .dependsOn(input, rules) .enablePlugins(BuildInfoPlugin) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index dc82adec..390da069 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,5 +1,5 @@ /* -rewrite = "scala:fix.Collectionstrawman_v0" +rule = "scala:fix.Collectionstrawman_v0" */ package fix diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala index 8b692c73..3dc0e236 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -1,5 +1,5 @@ /* -rewrite = "scala:fix.Collectionstrawman_v0" +rule = "scala:fix.Collectionstrawman_v0" */ package fix diff --git a/input/src/main/scala/fix/ListTest.scala b/input/src/main/scala/fix/ListTest.scala index 599835df..c9ca5b5b 100644 --- a/input/src/main/scala/fix/ListTest.scala +++ b/input/src/main/scala/fix/ListTest.scala @@ -1,5 +1,5 @@ /* -rewrite = "scala:fix.Collectionstrawman_v0" +rule = "scala:fix.Collectionstrawman_v0" */ package fix diff --git a/project/plugins.sbt b/project/plugins.sbt index e9e25bbe..f97e1b87 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,3 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.0-M4") -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC9") -addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") - +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.3") +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC10") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") \ No newline at end of file diff --git a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala similarity index 70% rename from rewrites/src/main/scala/fix/Collectionstrawman_v0.scala rename to rules/src/main/scala/fix/Collectionstrawman_v0.scala index eac6eec1..4c54733b 100644 --- a/rewrites/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -2,10 +2,11 @@ package fix import scalafix._ import scalafix.syntax._ +import scalafix.util._ import scala.meta._ -case class Collectionstrawman_v0(sctx: SemanticCtx) - extends SemanticRewrite(sctx) { +case class Collectionstrawman_v0(index: SemanticdbIndex) + extends SemanticRule(index, "Collectionstrawman_v0") { implicit class XtensionSymbolCollection(symbol: Symbol) { def name = symbol match { @@ -27,10 +28,10 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) "intArrayOps" -> "genericArrayOps" ) - def replaceExtensionMethods(ctx: RewriteCtx): Patch = { + def replaceExtensionMethods(ctx: RuleCtx): Patch = { val toImport = for { - r <- ctx.semanticCtx.names - in = r.sym.normalized + r <- ctx.index.names + in = r.symbol.normalized out <- unimports.get(in).toList } yield { val name = in.name @@ -51,20 +52,20 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) "_root_.scala.runtime.RichInt#to(I)Lscala/collection/immutable/Range/Inclusive;.") val rangeSymbol = Symbol( "_root_.scala.runtime.RichInt#until(I)Lscala/collection/immutable/Range;.") - def replaceRange(ctx: RewriteCtx): Patch = { + def replaceRange(ctx: RuleCtx): Patch = { ctx.tree.collect { - case tree @ Term.ApplyInfix(lhs, op, targs, arg :: Nil) + case tree @ Term.ApplyInfix(lhs, op, _, arg :: Nil) if op.symbol.contains(inclusiveRange) => ctx.replaceTree(tree, q"Range.inclusive($lhs, $arg)".syntax) + ctx.addGlobalImport(rangeImport) - case tree @ Term.ApplyInfix(lhs, op, targs, arg :: Nil) + case tree @ Term.ApplyInfix(lhs, op, _, arg :: Nil) if op.symbol.contains(rangeSymbol) => ctx.replaceTree(tree, q"Range($lhs, $arg)".syntax) + ctx.addGlobalImport(rangeImport) } }.asPatch - def replaceSymbols(ctx: RewriteCtx): Patch = { + def replaceSymbols(ctx: RuleCtx): Patch = { def p(name: String) = s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" def s(name: String, rename: Option[String] = None) = @@ -101,57 +102,40 @@ case class Collectionstrawman_v0(sctx: SemanticCtx) ) } - case class SymbolMatcher(symbols: Symbol*) { - def unapply(arg: Tree): Option[(Tree, Symbol)] = - sctx.symbol(arg.pos).flatMap { sym => - if (symbols.exists(_.isSameNormalized(sym))) Some(arg -> sym) - else None - } - } - - object WithSymbol { - def unapply(arg: Tree): Option[(Tree, Symbol)] = - sctx.symbol(arg.pos).map(x => arg -> x) - } - - val toGenericX = SymbolMatcher( + val toGenericX = SymbolMatcher.normalized( Symbol("_root_.scala.collection.TraversableOnce.toMap.") ) - val toImmutableX = SymbolMatcher( + val toImmutableX = SymbolMatcher.normalized( Symbol("_root_.scala.collection.TraversableOnce.toList."), Symbol("_root_.scala.collection.TraversableOnce.toSet.") ) - val toTpe = SymbolMatcher( + val toTpe = SymbolMatcher.normalized( Symbol("_root_.scala.collection.TraversableLike.to.") ) - val iterator = SymbolMatcher( + val iterator = SymbolMatcher.normalized( Symbol("_root_.scala.collection.LinearSeqLike.iterator."), Symbol("_root_.scala.collection.TraversableLike.toIterator.") ) - def replaceToList(ctx: RewriteCtx) = + def replaceToList(ctx: RuleCtx) = ctx.tree.collect { - case iterator(n: Name, _) => - ctx.replaceTree(n, "iterator()") - case toImmutableX(n: Name, s) => - ctx.replaceTree(n, s"to(strawman.collection.immutable.${s.name.stripPrefix("to")})") - case toGenericX(n: Name, s) => - ctx.replaceTree(n, s"to(strawman.collection.${s.name.stripPrefix("to")})") - case toTpe(n: Name, _) => - ctx.debug(n) + case iterator(t: Name) => + ctx.replaceTree(t, "iterator()") + case toImmutableX(t @ Name(n)) => + ctx.replaceTree(t, s"to(strawman.collection.immutable.${n.stripPrefix("to")})") + case toGenericX(t @ Name(n)) => + ctx.replaceTree(t, s"to(strawman.collection.${n.stripPrefix("to")})") + case toTpe(n: Name) => (for { name <- n.tokens.lastOption - _ = ctx.debug(name) open <- ctx.tokenList.find(name)(t => t.is[Token.LeftBracket]) - _ = ctx.debug(open) - close <- ctx.matching.close(open.asInstanceOf[Token.LeftBracket]) - replacedTokens = ctx.tokenList.slice(open, close) + close <- ctx.matchingParens.close(open.asInstanceOf[Token.LeftBracket]) } yield ctx.replaceToken(open, "(") + ctx.replaceToken(close, ")")).getOrElse(Patch.empty) }.asPatch - def rewrite(ctx: RewriteCtx): Patch = { + override def fix(ctx: RuleCtx): Patch = { replaceToList(ctx) + replaceSymbols(ctx) + replaceExtensionMethods(ctx) + diff --git a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala index 61b07802..023382b6 100644 --- a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala +++ b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -5,8 +5,8 @@ import scalafix.testkit._ import scalafix._ class Collectionstrawman_Tests - extends SemanticRewriteSuite( - SemanticCtx.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), + extends SemanticRuleSuite( + SemanticdbIndex.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), AbsolutePath(BuildInfo.inputSourceroot), Seq(AbsolutePath(BuildInfo.outputSourceroot)) ) { From ba429112bfaab04fc8777d29cab51337d8ec7028 Mon Sep 17 00:00:00 2001 From: Marcelo Cenerino Date: Tue, 7 Nov 2017 00:53:50 +0000 Subject: [PATCH 28/40] Scalafix rewrite for lazyZip --- .../Collectionstrawman_v0_TupleNZipped.scala | 36 +++++++++++++ .../Collectionstrawman_v0_TupleNZipped.scala | 34 +++++++++++++ .../scala/fix/Collectionstrawman_v0.scala | 50 ++++++++++++++++++- 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala create mode 100644 output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala new file mode 100644 index 00000000..6130a012 --- /dev/null +++ b/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala @@ -0,0 +1,36 @@ +/* +rule = "scala:fix.Collectionstrawman_v0" + */ +package fix + +import scala.language.postfixOps +object Collectionstrawman_v0_Tuple2Zipped { + def zipped(xs: List[Int], ys: List[Int]): Unit = { + (xs, ys).zipped + (xs,ys).zipped + ((xs, ys) zipped) + (((xs) , (ys)).zipped) + (xs, // foo + ys).zipped + /* a */(/* b */ xs /* c */, /* d */ ys /* e */)/* f */./* g */zipped/* h */ + (coll(1), coll(2)).zipped + (List(1, 2, 3), Stream.from(1)).zipped + } + def coll(x: Int): List[Int] = ??? +} + +object Collectionstrawman_v0_Tuple3Zipped { + def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = { + (xs, ys, zs).zipped + (xs,ys,zs).zipped + ((xs, ys, zs) zipped) + (((xs) , (ys) , (zs)).zipped) + (xs, // foo + ys, // bar + zs).zipped + /* a */(/* b */ xs /* c */, /* d */ ys /* e */, /* f */ zs /* g */)/* h */./* i */zipped/* j */ + (coll(1), coll(2), coll(3)).zipped + (List(1, 2, 3), Set(1, 2, 3), Stream.from(1)).zipped + } + def coll(x: Int): List[Int] = ??? +} \ No newline at end of file diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala new file mode 100644 index 00000000..7c8f763d --- /dev/null +++ b/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala @@ -0,0 +1,34 @@ +package fix + +import scala.language.postfixOps +import strawman.collection.immutable.{ LazyList, List, Set } +object Collectionstrawman_v0_Tuple2Zipped { + def zipped(xs: List[Int], ys: List[Int]): Unit = { + xs.lazyZip(ys) + xs.lazyZip(ys) + (xs.lazyZip(ys) ) + ((xs).lazyZip((ys))) + xs.lazyZip(// foo + ys) + /* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */)/* f *//* g *//* h */ + coll(1).lazyZip(coll(2)) + List(1, 2, 3).lazyZip(LazyList.from(1)) + } + def coll(x: Int): List[Int] = ??? +} + +object Collectionstrawman_v0_Tuple3Zipped { + def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = { + xs.lazyZip(ys).lazyZip(zs) + xs.lazyZip(ys).lazyZip(zs) + (xs.lazyZip(ys).lazyZip(zs) ) + ((xs).lazyZip((ys)).lazyZip((zs))) + xs.lazyZip(// foo + ys).lazyZip(// bar + zs) + /* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */).lazyZip(/* f */ zs /* g */)/* h *//* i *//* j */ + coll(1).lazyZip(coll(2)).lazyZip(coll(3)) + List(1, 2, 3).lazyZip(Set(1, 2, 3)).lazyZip(LazyList.from(1)) + } + def coll(x: Int): List[Int] = ??? +} \ No newline at end of file diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala index 4c54733b..b2c90a56 100644 --- a/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -116,6 +116,10 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) Symbol("_root_.scala.collection.LinearSeqLike.iterator."), Symbol("_root_.scala.collection.TraversableLike.toIterator.") ) + val tupleZipped = SymbolMatcher.normalized( + Symbol("_root_.scala.runtime.Tuple2Zipped.Ops.zipped."), + Symbol("_root_.scala.runtime.Tuple3Zipped.Ops.zipped.") + ) def replaceToList(ctx: RuleCtx) = ctx.tree.collect { @@ -132,13 +136,55 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) close <- ctx.matchingParens.close(open.asInstanceOf[Token.LeftBracket]) } yield ctx.replaceToken(open, "(") + - ctx.replaceToken(close, ")")).getOrElse(Patch.empty) + ctx.replaceToken(close, ")") + ).asPatch + }.asPatch + + def replaceTupleZipped(ctx: RuleCtx) = + ctx.tree.collect { + case tupleZipped(Term.Select(Term.Tuple(args), name)) => + val removeTokensPatch = + (for { + zipped <- name.tokens.headOption + closeTuple <- ctx.tokenList.leading(zipped).find(_.is[Token.RightParen]) + openTuple <- ctx.matchingParens.open(closeTuple.asInstanceOf[Token.RightParen]) + maybeDot = ctx.tokenList.slice(closeTuple, zipped).find(_.is[Token.Dot]) + } yield { + ctx.removeToken(openTuple) + + maybeDot.map(ctx.removeToken).asPatch + + ctx.removeToken(zipped) + }).asPatch + + def removeSurroundingWhiteSpaces(tk: Token) = + (ctx.tokenList.trailing(tk).takeWhile(_.is[Token.Space]).map(ctx.removeToken) ++ + ctx.tokenList.leading(tk).takeWhile(_.is[Token.Space]).map(ctx.removeToken)).asPatch + + val commas = + for { + (prev, next) <- args.zip(args.tail) + tokensBetweenArgs = ctx.tokenList.slice(prev.tokens.last, next.tokens.head) + comma <- tokensBetweenArgs.find(_.is[Token.Comma]) + } yield comma + + val replaceCommasPatch = commas match { + case head :: tail => + ctx.replaceToken(head, ".lazyZip(") + + removeSurroundingWhiteSpaces(head) ++ + tail.map { comma => + ctx.replaceToken(comma, ").lazyZip(") + + removeSurroundingWhiteSpaces(comma) + } + case _ => Patch.empty + } + + removeTokensPatch + replaceCommasPatch }.asPatch override def fix(ctx: RuleCtx): Patch = { replaceToList(ctx) + replaceSymbols(ctx) + replaceExtensionMethods(ctx) + - replaceRange(ctx) + replaceRange(ctx) + + replaceTupleZipped(ctx) } } From 3edd875d058d9dd47cc789da69c8ab14313cca2a Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 6 Dec 2017 10:07:21 +0100 Subject: [PATCH 29/40] Remove rewrite rules that are not needed anymore --- .../scala/fix/Collectionstrawman_v0_Traversable.scala | 4 ---- .../scala/fix/Collectionstrawman_v0_Traversable.scala | 4 ---- rules/src/main/scala/fix/Collectionstrawman_v0.scala | 11 ----------- 3 files changed, 19 deletions(-) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala index 3dc0e236..604a3c2b 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -5,12 +5,8 @@ package fix object Collectionstrawman_v0_Traversable { def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { - xs.toList - xs.toSet - ys.toSeq xs.to[List] xs.to[Set] - xs.toMap xs.toIterator ys.iterator } diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala index 4438c121..c741d1df 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -4,12 +4,8 @@ import strawman.collection.Iterable import strawman.collection.immutable.{ List, Set } object Collectionstrawman_v0_Traversable { def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { - xs.to(strawman.collection.immutable.List) - xs.to(strawman.collection.immutable.Set) - ys.toSeq xs.to(List) xs.to(Set) - xs.to(strawman.collection.Map) xs.iterator() ys.iterator() } diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala index b2c90a56..9ef97978 100644 --- a/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -102,13 +102,6 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) ) } - val toGenericX = SymbolMatcher.normalized( - Symbol("_root_.scala.collection.TraversableOnce.toMap.") - ) - val toImmutableX = SymbolMatcher.normalized( - Symbol("_root_.scala.collection.TraversableOnce.toList."), - Symbol("_root_.scala.collection.TraversableOnce.toSet.") - ) val toTpe = SymbolMatcher.normalized( Symbol("_root_.scala.collection.TraversableLike.to.") ) @@ -125,10 +118,6 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) ctx.tree.collect { case iterator(t: Name) => ctx.replaceTree(t, "iterator()") - case toImmutableX(t @ Name(n)) => - ctx.replaceTree(t, s"to(strawman.collection.immutable.${n.stripPrefix("to")})") - case toGenericX(t @ Name(n)) => - ctx.replaceTree(t, s"to(strawman.collection.${n.stripPrefix("to")})") case toTpe(n: Name) => (for { name <- n.tokens.lastOption From 66c9265e4d092b57b600749375f88e5907c503b2 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 6 Dec 2017 10:48:53 +0100 Subject: [PATCH 30/40] Add failing test case (because of scalacenter/scalafix#478) --- input/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- output/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/input/src/main/scala/fix/Collectionstrawman_v0.scala index 390da069..3c1ea66a 100644 --- a/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/input/src/main/scala/fix/Collectionstrawman_v0.scala @@ -43,7 +43,7 @@ object Collectionstrawman_v0_ArrayBuffer { object Collectionstrawman_v0_ArrayAndString { def foo(xs: Array[Int], ys: String): Unit = { xs.map(x => x + 1) - ys.map(c => c.toUpper) + ys.map(c => c.toUpper).map(_.toLower) } } diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index ec71003c..517db2fc 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -43,7 +43,7 @@ object Collectionstrawman_v0_ArrayBuffer { object Collectionstrawman_v0_ArrayAndString { def foo(xs: Array[Int], ys: String): Unit = { xs.map(x => x + 1) - ys.map(c => c.toUpper) + ys.map(c => c.toUpper).map(_.toLower) } } From fce160813222f5cf33305da1fa2263ec2c78daca Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 6 Dec 2017 10:49:28 +0100 Subject: [PATCH 31/40] Workaround for scalacenter/scalafix#478 This commit can be reverted once the issue is closed --- .../scala/fix/Collectionstrawman_v0.scala | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala index 9ef97978..0ea23a7c 100644 --- a/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -29,17 +29,28 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) ) def replaceExtensionMethods(ctx: RuleCtx): Patch = { + val visited = collection.mutable.Set.empty[String] val toImport = for { r <- ctx.index.names in = r.symbol.normalized out <- unimports.get(in).toList + if !visited(out.name) } yield { + visited += out.name val name = in.name - val names = name :: additionalUnimports.get(name) - .fold(List.empty[String])(_ :: Nil) - ctx.addGlobalImport(out) + - ctx.addGlobalImport( - Importer(q"scala.Predef", names.map(n => Importee.Unimport(Name(n))))) + def visiting(s: String): List[String] = + if (!visited(s)) { + visited += s + s :: Nil + } else Nil + val names = visiting(name) ::: additionalUnimports.get(name) + .fold(List.empty[String])(visiting) + if (names.isEmpty) ctx.addGlobalImport(out) + else { + ctx.addGlobalImport(out) + + ctx.addGlobalImport( + Importer(q"scala.Predef", names.map(n => Importee.Unimport(Name(n))))) + } } val predefUnderscore = if (toImport.isEmpty) Patch.empty From 68f9a7013cbedd65825973ebd81010d661f56c3a Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 6 Dec 2017 10:55:44 +0100 Subject: [PATCH 32/40] =?UTF-8?q?Implement=20the=20rule=20for=20=E2=80=9Ci?= =?UTF-8?q?mport=20JavaConverters.=5F=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- input/src/main/scala/fix/ConvertersTest.scala | 13 +++++++++++++ output/src/main/scala/fix/ConvertersTest.scala | 11 +++++++++++ .../src/main/scala/fix/Collectionstrawman_v0.scala | 10 +++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 input/src/main/scala/fix/ConvertersTest.scala create mode 100644 output/src/main/scala/fix/ConvertersTest.scala diff --git a/input/src/main/scala/fix/ConvertersTest.scala b/input/src/main/scala/fix/ConvertersTest.scala new file mode 100644 index 00000000..5aeb243f --- /dev/null +++ b/input/src/main/scala/fix/ConvertersTest.scala @@ -0,0 +1,13 @@ +/* +rule = "scala:fix.Collectionstrawman_v0" + */ +package fix + +import collection.JavaConverters._ + +class ConvertersTest { + def foo(xs: java.util.List[Int]): List[Int] = xs.asScala.toList + def bar(xs: java.util.Map[Int, String]): Map[Int, String] = xs.asScala.toMap + def baz(xs: List[Int]): java.util.List[Int] = xs.asJava + def bah(xs: Map[Int, String]): java.util.Map[Int, String] = xs.asJava +} diff --git a/output/src/main/scala/fix/ConvertersTest.scala b/output/src/main/scala/fix/ConvertersTest.scala new file mode 100644 index 00000000..65aae790 --- /dev/null +++ b/output/src/main/scala/fix/ConvertersTest.scala @@ -0,0 +1,11 @@ +package fix + +import strawman.collection.JavaConverters._ +import strawman.collection.immutable.{ List, Map } + +class ConvertersTest { + def foo(xs: java.util.List[Int]): List[Int] = xs.asScala.toList + def bar(xs: java.util.Map[Int, String]): Map[Int, String] = xs.asScala.toMap + def baz(xs: List[Int]): java.util.List[Int] = xs.asJava + def bah(xs: Map[Int, String]): java.util.Map[Int, String] = xs.asJava +} diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala index 0ea23a7c..4f1ad48a 100644 --- a/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -180,11 +180,19 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) removeTokensPatch + replaceCommasPatch }.asPatch + def replaceJavaConverters(ctx: RuleCtx): Patch = { + ctx.tree.collect { + case Import(List(importer)) if importer.syntax.containsSlice("collection.JavaConverters._") => + ctx.replaceTree(importer, "strawman.collection.JavaConverters._") + }.asPatch + } + override def fix(ctx: RuleCtx): Patch = { replaceToList(ctx) + replaceSymbols(ctx) + replaceExtensionMethods(ctx) + replaceRange(ctx) + - replaceTupleZipped(ctx) + replaceTupleZipped(ctx) + + replaceJavaConverters(ctx) } } From e8de069bafdb55f5e91540b8ee609a240d186015 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 6 Dec 2017 14:15:13 +0100 Subject: [PATCH 33/40] Migrate scala.Seq to strawman.collection.Seq --- output/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- rules/src/main/scala/fix/Collectionstrawman_v0.scala | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 517db2fc..1a52dde4 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,7 @@ package fix import scala.Predef.{ augmentString => _, genericArrayOps => _, intArrayOps => _, wrapString => _, _ } -import strawman.collection.{ arrayToArrayOps, stringToStringOps } +import strawman.collection.{ Seq, arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: import strawman.collection.mutable.ArrayBuffer diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala index 4f1ad48a..ea33c5ff 100644 --- a/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -106,6 +106,7 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) s("Traversable", Some("Iterable")), "scala.Iterable" -> "strawman.collection.Iterable", "scala.Traversable" -> "strawman.collection.Iterable", + "scala.Seq" -> "strawman.collection.Seq", "scala.`#::`" -> "strawman.collection.immutable.LazyList.`#::`", s("Vector"), i("Vector"), From 9b8a3acd18ba77e74e7f5b10ab85bc45f95069bd Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 6 Dec 2017 14:17:40 +0100 Subject: [PATCH 34/40] Revert "Migrate scala.Seq to strawman.collection.Seq" This reverts commit 71dab7c6036ec8b4caf732fc0f0bbec525796629. --- output/src/main/scala/fix/Collectionstrawman_v0.scala | 2 +- rules/src/main/scala/fix/Collectionstrawman_v0.scala | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/output/src/main/scala/fix/Collectionstrawman_v0.scala index 1a52dde4..517db2fc 100644 --- a/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/output/src/main/scala/fix/Collectionstrawman_v0.scala @@ -1,7 +1,7 @@ package fix import scala.Predef.{ augmentString => _, genericArrayOps => _, intArrayOps => _, wrapString => _, _ } -import strawman.collection.{ Seq, arrayToArrayOps, stringToStringOps } +import strawman.collection.{ arrayToArrayOps, stringToStringOps } import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } import strawman.collection.immutable.LazyList.#:: import strawman.collection.mutable.ArrayBuffer diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala index ea33c5ff..4f1ad48a 100644 --- a/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -106,7 +106,6 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) s("Traversable", Some("Iterable")), "scala.Iterable" -> "strawman.collection.Iterable", "scala.Traversable" -> "strawman.collection.Iterable", - "scala.Seq" -> "strawman.collection.Seq", "scala.`#::`" -> "strawman.collection.immutable.LazyList.`#::`", s("Vector"), i("Vector"), From 589712c0a977f98c9782a02ea384a24961a6a928 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Fri, 19 Jan 2018 11:53:14 +0100 Subject: [PATCH 35/40] Create two distinct scalafix rules targeting 2.12 and 2.13 --- .../scala/fix/Collectionstrawman_v0.scala | 0 .../Collectionstrawman_v0_Traversable.scala | 0 .../Collectionstrawman_v0_TupleNZipped.scala | 0 .../src/main/scala/fix/ConvertersTest.scala | 0 .../input}/src/main/scala/fix/ListTest.scala | 0 .../scala/fix/Collectionstrawman_v0.scala | 0 .../Collectionstrawman_v0_Traversable.scala | 0 .../Collectionstrawman_v0_TupleNZipped.scala | 0 .../src/main/scala/fix/ConvertersTest.scala | 0 .../output}/src/main/scala/fix/ListTest.scala | 0 .../scala/fix/Collectionstrawman_v0.scala | 0 .../scala/fix/Collectionstrawman_Tests.scala | 0 .../fix/Collectionstrawman_v0_Stream.scala | 13 +++ .../Collectionstrawman_v0_Traversable.scala | 13 +++ .../Collectionstrawman_v0_TupleNZipped.scala | 36 +++++++ .../fix/Collectionstrawman_v0_Stream.scala | 10 ++ .../Collectionstrawman_v0_Traversable.scala | 10 ++ .../Collectionstrawman_v0_TupleNZipped.scala | 33 +++++++ .../scala/fix/Collectionstrawman_v0.scala | 94 +++++++++++++++++++ .../scala/fix/Collectionstrawman_Tests.scala | 18 ++++ build.sbt | 44 ++++++++- project/plugins.sbt | 4 +- 22 files changed, 268 insertions(+), 7 deletions(-) rename {input => 2.12/input}/src/main/scala/fix/Collectionstrawman_v0.scala (100%) rename {input => 2.12/input}/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala (100%) rename {input => 2.12/input}/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala (100%) rename {input => 2.12/input}/src/main/scala/fix/ConvertersTest.scala (100%) rename {input => 2.12/input}/src/main/scala/fix/ListTest.scala (100%) rename {output => 2.12/output}/src/main/scala/fix/Collectionstrawman_v0.scala (100%) rename {output => 2.12/output}/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala (100%) rename {output => 2.12/output}/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala (100%) rename {output => 2.12/output}/src/main/scala/fix/ConvertersTest.scala (100%) rename {output => 2.12/output}/src/main/scala/fix/ListTest.scala (100%) rename {rules => 2.12/rules}/src/main/scala/fix/Collectionstrawman_v0.scala (100%) rename {tests => 2.12/tests}/src/test/scala/fix/Collectionstrawman_Tests.scala (100%) create mode 100644 2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala create mode 100644 2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala create mode 100644 2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala create mode 100644 2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala create mode 100644 2.13/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala create mode 100644 2.13/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala create mode 100644 2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala create mode 100644 2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0.scala b/2.12/input/src/main/scala/fix/Collectionstrawman_v0.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0.scala rename to 2.12/input/src/main/scala/fix/Collectionstrawman_v0.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/2.12/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala rename to 2.12/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/2.12/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename to 2.12/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/input/src/main/scala/fix/ConvertersTest.scala b/2.12/input/src/main/scala/fix/ConvertersTest.scala similarity index 100% rename from input/src/main/scala/fix/ConvertersTest.scala rename to 2.12/input/src/main/scala/fix/ConvertersTest.scala diff --git a/input/src/main/scala/fix/ListTest.scala b/2.12/input/src/main/scala/fix/ListTest.scala similarity index 100% rename from input/src/main/scala/fix/ListTest.scala rename to 2.12/input/src/main/scala/fix/ListTest.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0.scala b/2.12/output/src/main/scala/fix/Collectionstrawman_v0.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0.scala rename to 2.12/output/src/main/scala/fix/Collectionstrawman_v0.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/2.12/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala rename to 2.12/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/2.12/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename to 2.12/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/output/src/main/scala/fix/ConvertersTest.scala b/2.12/output/src/main/scala/fix/ConvertersTest.scala similarity index 100% rename from output/src/main/scala/fix/ConvertersTest.scala rename to 2.12/output/src/main/scala/fix/ConvertersTest.scala diff --git a/output/src/main/scala/fix/ListTest.scala b/2.12/output/src/main/scala/fix/ListTest.scala similarity index 100% rename from output/src/main/scala/fix/ListTest.scala rename to 2.12/output/src/main/scala/fix/ListTest.scala diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/2.12/rules/src/main/scala/fix/Collectionstrawman_v0.scala similarity index 100% rename from rules/src/main/scala/fix/Collectionstrawman_v0.scala rename to 2.12/rules/src/main/scala/fix/Collectionstrawman_v0.scala diff --git a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/2.12/tests/src/test/scala/fix/Collectionstrawman_Tests.scala similarity index 100% rename from tests/src/test/scala/fix/Collectionstrawman_Tests.scala rename to 2.12/tests/src/test/scala/fix/Collectionstrawman_Tests.scala diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala new file mode 100644 index 00000000..5d9d809d --- /dev/null +++ b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala @@ -0,0 +1,13 @@ +/* +rule = "scala:fix.Collectionstrawman_v0" + */ +package fix + +object Collectionstrawman_v0_Stream { + Stream(1, 2, 3) + 1 #:: 2 #:: 3 #:: Stream.Empty + val isEmpty: Stream[_] => Boolean = { + case Stream.Empty => true + case x #:: xs => false + } +} diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala new file mode 100644 index 00000000..604a3c2b --- /dev/null +++ b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -0,0 +1,13 @@ +/* +rule = "scala:fix.Collectionstrawman_v0" + */ +package fix + +object Collectionstrawman_v0_Traversable { + def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { + xs.to[List] + xs.to[Set] + xs.toIterator + ys.iterator + } +} diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala new file mode 100644 index 00000000..6130a012 --- /dev/null +++ b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala @@ -0,0 +1,36 @@ +/* +rule = "scala:fix.Collectionstrawman_v0" + */ +package fix + +import scala.language.postfixOps +object Collectionstrawman_v0_Tuple2Zipped { + def zipped(xs: List[Int], ys: List[Int]): Unit = { + (xs, ys).zipped + (xs,ys).zipped + ((xs, ys) zipped) + (((xs) , (ys)).zipped) + (xs, // foo + ys).zipped + /* a */(/* b */ xs /* c */, /* d */ ys /* e */)/* f */./* g */zipped/* h */ + (coll(1), coll(2)).zipped + (List(1, 2, 3), Stream.from(1)).zipped + } + def coll(x: Int): List[Int] = ??? +} + +object Collectionstrawman_v0_Tuple3Zipped { + def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = { + (xs, ys, zs).zipped + (xs,ys,zs).zipped + ((xs, ys, zs) zipped) + (((xs) , (ys) , (zs)).zipped) + (xs, // foo + ys, // bar + zs).zipped + /* a */(/* b */ xs /* c */, /* d */ ys /* e */, /* f */ zs /* g */)/* h */./* i */zipped/* j */ + (coll(1), coll(2), coll(3)).zipped + (List(1, 2, 3), Set(1, 2, 3), Stream.from(1)).zipped + } + def coll(x: Int): List[Int] = ??? +} \ No newline at end of file diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala new file mode 100644 index 00000000..88ff29fe --- /dev/null +++ b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala @@ -0,0 +1,10 @@ +package fix + +object Collectionstrawman_v0_Stream { + LazyList(1, 2, 3) + 1 #:: 2 #:: 3 #:: LazyList.Empty + val isEmpty: LazyList[_] => Boolean = { + case LazyList.Empty => true + case x #:: xs => false + } +} diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala new file mode 100644 index 00000000..5f53f9c0 --- /dev/null +++ b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala @@ -0,0 +1,10 @@ +package fix + +object Collectionstrawman_v0_Traversable { + def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { + xs.to(List) + xs.to(Set) + xs.iterator() + ys.iterator() + } +} diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala new file mode 100644 index 00000000..e43cbc95 --- /dev/null +++ b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala @@ -0,0 +1,33 @@ +package fix + +import scala.language.postfixOps +object Collectionstrawman_v0_Tuple2Zipped { + def zipped(xs: List[Int], ys: List[Int]): Unit = { + xs.lazyZip(ys) + xs.lazyZip(ys) + (xs.lazyZip(ys) ) + ((xs).lazyZip((ys))) + xs.lazyZip(// foo + ys) + /* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */)/* f *//* g *//* h */ + coll(1).lazyZip(coll(2)) + List(1, 2, 3).lazyZip(LazyList.from(1)) + } + def coll(x: Int): List[Int] = ??? +} + +object Collectionstrawman_v0_Tuple3Zipped { + def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = { + xs.lazyZip(ys).lazyZip(zs) + xs.lazyZip(ys).lazyZip(zs) + (xs.lazyZip(ys).lazyZip(zs) ) + ((xs).lazyZip((ys)).lazyZip((zs))) + xs.lazyZip(// foo + ys).lazyZip(// bar + zs) + /* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */).lazyZip(/* f */ zs /* g */)/* h *//* i *//* j */ + coll(1).lazyZip(coll(2)).lazyZip(coll(3)) + List(1, 2, 3).lazyZip(Set(1, 2, 3)).lazyZip(LazyList.from(1)) + } + def coll(x: Int): List[Int] = ??? +} \ No newline at end of file diff --git a/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala new file mode 100644 index 00000000..17204f05 --- /dev/null +++ b/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -0,0 +1,94 @@ +package fix + +import scalafix._ +import scalafix.syntax._ +import scalafix.util._ +import scala.meta._ + +case class Collectionstrawman_v0(index: SemanticdbIndex) + extends SemanticRule(index, "Collectionstrawman_v0") { + + def replaceSymbols(ctx: RuleCtx): Patch = { + ctx.replaceSymbols( + "scala.Stream" -> "scala.LazyList", + "scala.collection.immutable.Stream" -> "scala.collection.immutable.LazyList", + "scala.Traversable" -> "scala.Iterable", + "scala.collection.Traversable" -> "scala.collection.Iterable", + "scala.TraversableOnce" -> "scala.IterableOnce", + "scala.collection.TraversableOnce" -> "scala.collection.IterableOnce" + ) + } + + val toTpe = SymbolMatcher.normalized( + Symbol("_root_.scala.collection.TraversableLike.to.") + ) + val iterator = SymbolMatcher.normalized( + Symbol("_root_.scala.collection.LinearSeqLike.iterator."), + Symbol("_root_.scala.collection.TraversableLike.toIterator.") + ) + val tupleZipped = SymbolMatcher.normalized( + Symbol("_root_.scala.runtime.Tuple2Zipped.Ops.zipped."), + Symbol("_root_.scala.runtime.Tuple3Zipped.Ops.zipped.") + ) + + def replaceToList(ctx: RuleCtx) = + ctx.tree.collect { + case iterator(t: Name) => + ctx.replaceTree(t, "iterator()") + case toTpe(n: Name) => + (for { + name <- n.tokens.lastOption + open <- ctx.tokenList.find(name)(t => t.is[Token.LeftBracket]) + close <- ctx.matchingParens.close(open.asInstanceOf[Token.LeftBracket]) + } yield + ctx.replaceToken(open, "(") + + ctx.replaceToken(close, ")") + ).asPatch + }.asPatch + + def replaceTupleZipped(ctx: RuleCtx) = + ctx.tree.collect { + case tupleZipped(Term.Select(Term.Tuple(args), name)) => + val removeTokensPatch = + (for { + zipped <- name.tokens.headOption + closeTuple <- ctx.tokenList.leading(zipped).find(_.is[Token.RightParen]) + openTuple <- ctx.matchingParens.open(closeTuple.asInstanceOf[Token.RightParen]) + maybeDot = ctx.tokenList.slice(closeTuple, zipped).find(_.is[Token.Dot]) + } yield { + ctx.removeToken(openTuple) + + maybeDot.map(ctx.removeToken).asPatch + + ctx.removeToken(zipped) + }).asPatch + + def removeSurroundingWhiteSpaces(tk: Token) = + (ctx.tokenList.trailing(tk).takeWhile(_.is[Token.Space]).map(ctx.removeToken) ++ + ctx.tokenList.leading(tk).takeWhile(_.is[Token.Space]).map(ctx.removeToken)).asPatch + + val commas = + for { + (prev, next) <- args.zip(args.tail) + tokensBetweenArgs = ctx.tokenList.slice(prev.tokens.last, next.tokens.head) + comma <- tokensBetweenArgs.find(_.is[Token.Comma]) + } yield comma + + val replaceCommasPatch = commas match { + case head :: tail => + ctx.replaceToken(head, ".lazyZip(") + + removeSurroundingWhiteSpaces(head) ++ + tail.map { comma => + ctx.replaceToken(comma, ").lazyZip(") + + removeSurroundingWhiteSpaces(comma) + } + case _ => Patch.empty + } + + removeTokensPatch + replaceCommasPatch + }.asPatch + + override def fix(ctx: RuleCtx): Patch = { + replaceToList(ctx) + + replaceSymbols(ctx) + + replaceTupleZipped(ctx) + } +} diff --git a/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala new file mode 100644 index 00000000..023382b6 --- /dev/null +++ b/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -0,0 +1,18 @@ +package fix + +import scala.meta._ +import scalafix.testkit._ +import scalafix._ + +class Collectionstrawman_Tests + extends SemanticRuleSuite( + SemanticdbIndex.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), + AbsolutePath(BuildInfo.inputSourceroot), + Seq(AbsolutePath(BuildInfo.outputSourceroot)) + ) { + override def assertNoDiff(a: String, b: String, c: String) = { + println(a) + super.assertNoDiff(a, b, c) + } + runAllTests() +} diff --git a/build.sbt b/build.sbt index 822d6bb4..4600781b 100644 --- a/build.sbt +++ b/build.sbt @@ -7,19 +7,22 @@ inScope(Global)( lazy val root = project .in(file(".")) - .aggregate(rules, input, output, tests) + .aggregate( + rules, input, output, tests, + `rules-2_13`, `input-2_13`, `output-2_13`, `tests-2_13` + ) -lazy val rules = project.settings( +lazy val rules = project.in(file("2.12") / "rules").settings( libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion ) -lazy val input = project.settings( +lazy val input = project.in(file("2.12") / "input").settings( scalafixSourceroot := sourceDirectory.in(Compile).value ) val collections = ProjectRef(file(".."), "collectionsJVM") -lazy val output = project +lazy val output = project.in(file("2.12") / "output") .settings( resolvers := resolvers.in(collections).value, libraryDependencies ++= libraryDependencies.in(collections).value, @@ -28,7 +31,7 @@ lazy val output = project ) .dependsOn(collections) // collections/publishLocal is still necessary. -lazy val tests = project +lazy val tests = project.in(file("2.12") / "tests") .settings( libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full, buildInfoPackage := "fix", @@ -43,3 +46,34 @@ lazy val tests = project ) .dependsOn(input, rules) .enablePlugins(BuildInfoPlugin) + +lazy val `rules-2_13` = project.in(file("2.13") / "rules").settings( + libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion +) + +lazy val `input-2_13` = project.in(file("2.13") / "input") + .settings( + scalafixSourceroot := sourceDirectory.in(Compile).value + ) + +lazy val `output-2_13` = project.in(file("2.13") / "output") + .settings( + resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/", + scalaVersion := "2.13.0-pre-47ffa9c-SNAPSHOT" + ) + +lazy val `tests-2_13` = project.in(file("2.13") / "tests") + .settings( + libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full, + buildInfoPackage := "fix", + buildInfoKeys := Seq[BuildInfoKey]( + "inputSourceroot" -> + sourceDirectory.in(`input-2_13`, Compile).value, + "outputSourceroot" -> + sourceDirectory.in(`output-2_13`, Compile).value, + "inputClassdirectory" -> + classDirectory.in(`input-2_13`, Compile).value + ) + ) + .dependsOn(`input-2_13`, `rules-2_13`) + .enablePlugins(BuildInfoPlugin) diff --git a/project/plugins.sbt b/project/plugins.sbt index f97e1b87..b23cfd7c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,3 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.3") -addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-RC10") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.7") +addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") \ No newline at end of file From ee1bdba98be0bea13bcf99ffb89b7557f8a70dd2 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Fri, 19 Jan 2018 20:11:30 +0100 Subject: [PATCH 36/40] Add copyToBuffer rule --- .../fix/Collectionstrawman_v0_copyToBuffer.scala | 13 +++++++++++++ .../fix/Collectionstrawman_v0_copyToBuffer.scala | 10 ++++++++++ .../src/main/scala/fix/Collectionstrawman_v0.scala | 13 ++++++++++++- .../test/scala/fix/Collectionstrawman_Tests.scala | 1 - 4 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 2.13/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala create mode 100644 2.13/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala new file mode 100644 index 00000000..a75c4fbe --- /dev/null +++ b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala @@ -0,0 +1,13 @@ +/* +rule = "scala:fix.Collectionstrawman_v0" + */ +package fix + +import scala.collection.mutable + +class Collectionstrawman_v0_copyToBuffer(xs: List[Int], b: mutable.Buffer[Int]) { + + xs.copyToBuffer(b) + (xs ++ xs).copyToBuffer(b) + +} diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala new file mode 100644 index 00000000..8615a47a --- /dev/null +++ b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala @@ -0,0 +1,10 @@ +package fix + +import scala.collection.mutable + +class Collectionstrawman_v0_copyToBuffer(xs: List[Int], b: mutable.Buffer[Int]) { + + b ++= xs + b ++= xs ++ xs + +} diff --git a/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala index 17204f05..191c6bea 100644 --- a/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -86,9 +86,20 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) removeTokensPatch + replaceCommasPatch }.asPatch + val copyToBuffer = SymbolMatcher.normalized( + Symbol("_root_.scala.collection.TraversableOnce.copyToBuffer.") + ) + + def replaceCopyToBuffer(ctx: RuleCtx): Patch = + ctx.tree.collect { + case t @ q"${copyToBuffer(Term.Select(collection, _))}($buffer)" => + ctx.replaceTree(t, q"$buffer ++= $collection".syntax) + }.asPatch + override def fix(ctx: RuleCtx): Patch = { replaceToList(ctx) + replaceSymbols(ctx) + - replaceTupleZipped(ctx) + replaceTupleZipped(ctx) + + replaceCopyToBuffer(ctx) } } diff --git a/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala index 023382b6..83e8edb8 100644 --- a/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala +++ b/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -11,7 +11,6 @@ class Collectionstrawman_Tests Seq(AbsolutePath(BuildInfo.outputSourceroot)) ) { override def assertNoDiff(a: String, b: String, c: String) = { - println(a) super.assertNoDiff(a, b, c) } runAllTests() From 60fac102360da261571002d1f43da355a7dd03dc Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 28 Mar 2018 16:27:51 +0200 Subject: [PATCH 37/40] Narrow the node on which the patch is performed --- .../scala/fix/Collectionstrawman_v0_Stream.scala | 3 ++- .../scala/fix/Collectionstrawman_v0_Stream.scala | 3 ++- .../src/main/scala/fix/Collectionstrawman_v0.scala | 13 ++++++++++++- build.sbt | 4 ++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala index 5d9d809d..91492d1b 100644 --- a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala +++ b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala @@ -4,7 +4,8 @@ rule = "scala:fix.Collectionstrawman_v0" package fix object Collectionstrawman_v0_Stream { - Stream(1, 2, 3) + val s = Stream(1, 2, 3) + s.append(List(4, 5, 6)) 1 #:: 2 #:: 3 #:: Stream.Empty val isEmpty: Stream[_] => Boolean = { case Stream.Empty => true diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala index 88ff29fe..350077c8 100644 --- a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala +++ b/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala @@ -1,7 +1,8 @@ package fix object Collectionstrawman_v0_Stream { - LazyList(1, 2, 3) + val s = LazyList(1, 2, 3) + s.lazyAppendAll(List(4, 5, 6)) 1 #:: 2 #:: 3 #:: LazyList.Empty val isEmpty: LazyList[_] => Boolean = { case LazyList.Empty => true diff --git a/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala index 191c6bea..3e720906 100644 --- a/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala @@ -96,10 +96,21 @@ case class Collectionstrawman_v0(index: SemanticdbIndex) ctx.replaceTree(t, q"$buffer ++= $collection".syntax) }.asPatch + val streamAppend = SymbolMatcher.normalized( + Symbol("_root_.scala.collection.immutable.Stream.append.") + ) + + def replaceStreamAppend(ctx: RuleCtx): Patch = + ctx.tree.collect { + case streamAppend(t: Name) => + ctx.replaceTree(t, "lazyAppendAll") + }.asPatch + override def fix(ctx: RuleCtx): Patch = { replaceToList(ctx) + replaceSymbols(ctx) + replaceTupleZipped(ctx) + - replaceCopyToBuffer(ctx) + replaceCopyToBuffer(ctx) + + replaceStreamAppend(ctx) } } diff --git a/build.sbt b/build.sbt index 4600781b..092bb590 100644 --- a/build.sbt +++ b/build.sbt @@ -58,8 +58,8 @@ lazy val `input-2_13` = project.in(file("2.13") / "input") lazy val `output-2_13` = project.in(file("2.13") / "output") .settings( - resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-pr-validation-snapshots/", - scalaVersion := "2.13.0-pre-47ffa9c-SNAPSHOT" + resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/", + scalaVersion := "2.13.0-pre-c577876" ) lazy val `tests-2_13` = project.in(file("2.13") / "tests") From 53f832b42cc89b407d4bb240a3d8450283bf462d Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 18 Apr 2018 16:15:34 +0200 Subject: [PATCH 38/40] Update the migration rule to use 2.13.0-M4-pre-20d3c21 Remove old migration rule that was using the strawman.collection namespace --- .../scala/fix/Collectionstrawman_v0.scala | 54 ----- .../src/main/scala/fix/ConvertersTest.scala | 13 -- 2.12/input/src/main/scala/fix/ListTest.scala | 10 - .../scala/fix/Collectionstrawman_v0.scala | 54 ----- .../Collectionstrawman_v0_Traversable.scala | 12 -- .../Collectionstrawman_v0_TupleNZipped.scala | 34 --- .../src/main/scala/fix/ConvertersTest.scala | 11 - 2.12/output/src/main/scala/fix/ListTest.scala | 8 - .../scala/fix/Collectionstrawman_v0.scala | 198 ------------------ .../scala/fix/Collectionstrawman_Tests.scala | 18 -- .../Collectionstrawman_v0_Traversable.scala | 13 -- .../Collectionstrawman_v0_TupleNZipped.scala | 36 ---- build.sbt | 56 +---- .../fix/Collectionstrawman_v0_Stream.scala | 0 .../Collectionstrawman_v0_Traversable.scala | 0 .../Collectionstrawman_v0_TupleNZipped.scala | 0 .../Collectionstrawman_v0_copyToBuffer.scala | 0 .../fix/Collectionstrawman_v0_Stream.scala | 0 .../Collectionstrawman_v0_Traversable.scala | 0 .../Collectionstrawman_v0_TupleNZipped.scala | 0 .../Collectionstrawman_v0_copyToBuffer.scala | 0 .../scala/fix/Collectionstrawman_v0.scala | 0 .../scala/fix/Collectionstrawman_Tests.scala | 0 23 files changed, 10 insertions(+), 507 deletions(-) delete mode 100644 2.12/input/src/main/scala/fix/Collectionstrawman_v0.scala delete mode 100644 2.12/input/src/main/scala/fix/ConvertersTest.scala delete mode 100644 2.12/input/src/main/scala/fix/ListTest.scala delete mode 100644 2.12/output/src/main/scala/fix/Collectionstrawman_v0.scala delete mode 100644 2.12/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala delete mode 100644 2.12/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala delete mode 100644 2.12/output/src/main/scala/fix/ConvertersTest.scala delete mode 100644 2.12/output/src/main/scala/fix/ListTest.scala delete mode 100644 2.12/rules/src/main/scala/fix/Collectionstrawman_v0.scala delete mode 100644 2.12/tests/src/test/scala/fix/Collectionstrawman_Tests.scala delete mode 100644 2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala delete mode 100644 2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename {2.13/input => input}/src/main/scala/fix/Collectionstrawman_v0_Stream.scala (100%) rename {2.12/input => input}/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala (100%) rename {2.12/input => input}/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala (100%) rename {2.13/input => input}/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala (100%) rename {2.13/output => output}/src/main/scala/fix/Collectionstrawman_v0_Stream.scala (100%) rename {2.13/output => output}/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala (100%) rename {2.13/output => output}/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala (100%) rename {2.13/output => output}/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala (100%) rename {2.13/rules => rules}/src/main/scala/fix/Collectionstrawman_v0.scala (100%) rename {2.13/tests => tests}/src/test/scala/fix/Collectionstrawman_Tests.scala (100%) diff --git a/2.12/input/src/main/scala/fix/Collectionstrawman_v0.scala b/2.12/input/src/main/scala/fix/Collectionstrawman_v0.scala deleted file mode 100644 index 3c1ea66a..00000000 --- a/2.12/input/src/main/scala/fix/Collectionstrawman_v0.scala +++ /dev/null @@ -1,54 +0,0 @@ -/* -rule = "scala:fix.Collectionstrawman_v0" - */ -package fix - -object Collectionstrawman_v0_List { - List(1, 2, 3) - 1 :: 2 :: 3 :: Nil - val isEmpty: List[_] => Boolean = { - case Nil => true - case x :: xs => false - } -} - -object Collectionstrawman_v0_Stream { - Stream(1, 2, 3) - 1 #:: 2 #:: 3 #:: Stream.Empty - val isEmpty: Stream[_] => Boolean = { - case Stream.Empty => true - case x #:: xs => false - } -} - -object Collectionstrawman_v0_Vector { - val xs: Vector[Int] = Vector(1, 2, 3) -} - -object Collectionstrawman_v0_Seq { - val xs: Seq[Int] = Seq(1, 2, 3) -} - -object Collectionstrawman_v0_Map { - val xs: Map[Int, String] = Map(1 -> "1", 2 -> "2", 3 -> "3") - import scala.collection.immutable.HashMap - val ys = HashMap.empty -} - -object Collectionstrawman_v0_ArrayBuffer { - import scala.collection.mutable.ArrayBuffer - val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) -} - -object Collectionstrawman_v0_ArrayAndString { - def foo(xs: Array[Int], ys: String): Unit = { - xs.map(x => x + 1) - ys.map(c => c.toUpper).map(_.toLower) - } -} - -object Collectionstrawman_v0_Range { - (1 to 10).map(_ + 2) - (0 until 10).map(_ + 3) -} - diff --git a/2.12/input/src/main/scala/fix/ConvertersTest.scala b/2.12/input/src/main/scala/fix/ConvertersTest.scala deleted file mode 100644 index 5aeb243f..00000000 --- a/2.12/input/src/main/scala/fix/ConvertersTest.scala +++ /dev/null @@ -1,13 +0,0 @@ -/* -rule = "scala:fix.Collectionstrawman_v0" - */ -package fix - -import collection.JavaConverters._ - -class ConvertersTest { - def foo(xs: java.util.List[Int]): List[Int] = xs.asScala.toList - def bar(xs: java.util.Map[Int, String]): Map[Int, String] = xs.asScala.toMap - def baz(xs: List[Int]): java.util.List[Int] = xs.asJava - def bah(xs: Map[Int, String]): java.util.Map[Int, String] = xs.asJava -} diff --git a/2.12/input/src/main/scala/fix/ListTest.scala b/2.12/input/src/main/scala/fix/ListTest.scala deleted file mode 100644 index c9ca5b5b..00000000 --- a/2.12/input/src/main/scala/fix/ListTest.scala +++ /dev/null @@ -1,10 +0,0 @@ -/* -rule = "scala:fix.Collectionstrawman_v0" -*/ -package fix - -import scala.concurrent.Future - -class ListTest { - def foo(x: Future[List[Int]]) = ??? -} diff --git a/2.12/output/src/main/scala/fix/Collectionstrawman_v0.scala b/2.12/output/src/main/scala/fix/Collectionstrawman_v0.scala deleted file mode 100644 index 517db2fc..00000000 --- a/2.12/output/src/main/scala/fix/Collectionstrawman_v0.scala +++ /dev/null @@ -1,54 +0,0 @@ -package fix - -import scala.Predef.{ augmentString => _, genericArrayOps => _, intArrayOps => _, wrapString => _, _ } -import strawman.collection.{ arrayToArrayOps, stringToStringOps } -import strawman.collection.immutable.{ ::, HashMap, LazyList, List, Map, Nil, Range, Vector } -import strawman.collection.immutable.LazyList.#:: -import strawman.collection.mutable.ArrayBuffer -object Collectionstrawman_v0_List { - List(1, 2, 3) - 1 :: 2 :: 3 :: Nil - val isEmpty: List[_] => Boolean = { - case Nil => true - case x :: xs => false - } -} - -object Collectionstrawman_v0_Stream { - LazyList(1, 2, 3) - 1 #:: 2 #:: 3 #:: LazyList.Empty - val isEmpty: LazyList[_] => Boolean = { - case LazyList.Empty => true - case x #:: xs => false - } -} - -object Collectionstrawman_v0_Vector { - val xs: Vector[Int] = Vector(1, 2, 3) -} - -object Collectionstrawman_v0_Seq { - val xs: Seq[Int] = Seq(1, 2, 3) -} - -object Collectionstrawman_v0_Map { - val xs: Map[Int, String] = Map(1 -> "1", 2 -> "2", 3 -> "3") - val ys = HashMap.empty -} - -object Collectionstrawman_v0_ArrayBuffer { - val xs: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3) -} - -object Collectionstrawman_v0_ArrayAndString { - def foo(xs: Array[Int], ys: String): Unit = { - xs.map(x => x + 1) - ys.map(c => c.toUpper).map(_.toLower) - } -} - -object Collectionstrawman_v0_Range { - Range.inclusive(1, 10).map(_ + 2) - Range(0, 10).map(_ + 3) -} - diff --git a/2.12/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/2.12/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala deleted file mode 100644 index c741d1df..00000000 --- a/2.12/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ /dev/null @@ -1,12 +0,0 @@ -package fix - -import strawman.collection.Iterable -import strawman.collection.immutable.{ List, Set } -object Collectionstrawman_v0_Traversable { - def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = { - xs.to(List) - xs.to(Set) - xs.iterator() - ys.iterator() - } -} diff --git a/2.12/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/2.12/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala deleted file mode 100644 index 7c8f763d..00000000 --- a/2.12/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala +++ /dev/null @@ -1,34 +0,0 @@ -package fix - -import scala.language.postfixOps -import strawman.collection.immutable.{ LazyList, List, Set } -object Collectionstrawman_v0_Tuple2Zipped { - def zipped(xs: List[Int], ys: List[Int]): Unit = { - xs.lazyZip(ys) - xs.lazyZip(ys) - (xs.lazyZip(ys) ) - ((xs).lazyZip((ys))) - xs.lazyZip(// foo - ys) - /* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */)/* f *//* g *//* h */ - coll(1).lazyZip(coll(2)) - List(1, 2, 3).lazyZip(LazyList.from(1)) - } - def coll(x: Int): List[Int] = ??? -} - -object Collectionstrawman_v0_Tuple3Zipped { - def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = { - xs.lazyZip(ys).lazyZip(zs) - xs.lazyZip(ys).lazyZip(zs) - (xs.lazyZip(ys).lazyZip(zs) ) - ((xs).lazyZip((ys)).lazyZip((zs))) - xs.lazyZip(// foo - ys).lazyZip(// bar - zs) - /* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */).lazyZip(/* f */ zs /* g */)/* h *//* i *//* j */ - coll(1).lazyZip(coll(2)).lazyZip(coll(3)) - List(1, 2, 3).lazyZip(Set(1, 2, 3)).lazyZip(LazyList.from(1)) - } - def coll(x: Int): List[Int] = ??? -} \ No newline at end of file diff --git a/2.12/output/src/main/scala/fix/ConvertersTest.scala b/2.12/output/src/main/scala/fix/ConvertersTest.scala deleted file mode 100644 index 65aae790..00000000 --- a/2.12/output/src/main/scala/fix/ConvertersTest.scala +++ /dev/null @@ -1,11 +0,0 @@ -package fix - -import strawman.collection.JavaConverters._ -import strawman.collection.immutable.{ List, Map } - -class ConvertersTest { - def foo(xs: java.util.List[Int]): List[Int] = xs.asScala.toList - def bar(xs: java.util.Map[Int, String]): Map[Int, String] = xs.asScala.toMap - def baz(xs: List[Int]): java.util.List[Int] = xs.asJava - def bah(xs: Map[Int, String]): java.util.Map[Int, String] = xs.asJava -} diff --git a/2.12/output/src/main/scala/fix/ListTest.scala b/2.12/output/src/main/scala/fix/ListTest.scala deleted file mode 100644 index d8d160e7..00000000 --- a/2.12/output/src/main/scala/fix/ListTest.scala +++ /dev/null @@ -1,8 +0,0 @@ -package fix - -import scala.concurrent.Future -import strawman.collection.immutable.List - -class ListTest { - def foo(x: Future[List[Int]]) = ??? -} diff --git a/2.12/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/2.12/rules/src/main/scala/fix/Collectionstrawman_v0.scala deleted file mode 100644 index 4f1ad48a..00000000 --- a/2.12/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ /dev/null @@ -1,198 +0,0 @@ -package fix - -import scalafix._ -import scalafix.syntax._ -import scalafix.util._ -import scala.meta._ - -case class Collectionstrawman_v0(index: SemanticdbIndex) - extends SemanticRule(index, "Collectionstrawman_v0") { - - implicit class XtensionSymbolCollection(symbol: Symbol) { - def name = symbol match { - case Symbol.Global(_, sig) => sig.name - case _ => symbol.syntax - } - } - - val unimports = Map( - Symbol("_root_.scala.Predef.augmentString.") -> - Symbol("_root_.strawman.collection.stringToStringOps."), - Symbol("_root_.scala.Predef.intArrayOps.") -> - Symbol("_root_.strawman.collection.arrayToArrayOps.") - ) - - val additionalUnimports = Map( - "augmentString" -> "wrapString", - "wrapString" -> "augmentString", - "intArrayOps" -> "genericArrayOps" - ) - - def replaceExtensionMethods(ctx: RuleCtx): Patch = { - val visited = collection.mutable.Set.empty[String] - val toImport = for { - r <- ctx.index.names - in = r.symbol.normalized - out <- unimports.get(in).toList - if !visited(out.name) - } yield { - visited += out.name - val name = in.name - def visiting(s: String): List[String] = - if (!visited(s)) { - visited += s - s :: Nil - } else Nil - val names = visiting(name) ::: additionalUnimports.get(name) - .fold(List.empty[String])(visiting) - if (names.isEmpty) ctx.addGlobalImport(out) - else { - ctx.addGlobalImport(out) + - ctx.addGlobalImport( - Importer(q"scala.Predef", names.map(n => Importee.Unimport(Name(n))))) - } - } - val predefUnderscore = - if (toImport.isEmpty) Patch.empty - else ctx.addGlobalImport(importer"scala.Predef._") - toImport.asPatch + predefUnderscore - } - - val rangeImport = Symbol("_root_.strawman.collection.immutable.Range.") - val inclusiveRange = Symbol( - "_root_.scala.runtime.RichInt#to(I)Lscala/collection/immutable/Range/Inclusive;.") - val rangeSymbol = Symbol( - "_root_.scala.runtime.RichInt#until(I)Lscala/collection/immutable/Range;.") - def replaceRange(ctx: RuleCtx): Patch = { - ctx.tree.collect { - case tree @ Term.ApplyInfix(lhs, op, _, arg :: Nil) - if op.symbol.contains(inclusiveRange) => - ctx.replaceTree(tree, q"Range.inclusive($lhs, $arg)".syntax) + - ctx.addGlobalImport(rangeImport) - case tree @ Term.ApplyInfix(lhs, op, _, arg :: Nil) - if op.symbol.contains(rangeSymbol) => - ctx.replaceTree(tree, q"Range($lhs, $arg)".syntax) + - ctx.addGlobalImport(rangeImport) - } - }.asPatch - - def replaceSymbols(ctx: RuleCtx): Patch = { - def p(name: String) = - s"scala.Predef.$name" -> s"strawman.collection.immutable.$name" - def s(name: String, rename: Option[String] = None) = - s"scala.$name" -> s"strawman.collection.immutable.${rename.getOrElse(name)}" - def i(name: String, rename: Option[String] = None) = - s"scala.collection.immutable.$name" -> - s"strawman.collection.immutable.${rename.getOrElse(name)}" - def m(name: String) = - s"scala.collection.mutable.$name" -> s"strawman.collection.mutable.$name" - ctx.replaceSymbols( - p("Set"), - i("HashMap"), - i("Map"), - p("Map"), - s("List"), - i("List"), - s("Nil"), - i("Nil"), - s("`::`"), - i("`::`"), - s("`+:`"), - i("`+:`"), - s("`:+`"), - i("`:+`"), - i("Stream", Some("LazyList")), - s("Stream", Some("LazyList")), - s("Traversable", Some("Iterable")), - "scala.Iterable" -> "strawman.collection.Iterable", - "scala.Traversable" -> "strawman.collection.Iterable", - "scala.`#::`" -> "strawman.collection.immutable.LazyList.`#::`", - s("Vector"), - i("Vector"), - m("ArrayBuffer") - ) - } - - val toTpe = SymbolMatcher.normalized( - Symbol("_root_.scala.collection.TraversableLike.to.") - ) - val iterator = SymbolMatcher.normalized( - Symbol("_root_.scala.collection.LinearSeqLike.iterator."), - Symbol("_root_.scala.collection.TraversableLike.toIterator.") - ) - val tupleZipped = SymbolMatcher.normalized( - Symbol("_root_.scala.runtime.Tuple2Zipped.Ops.zipped."), - Symbol("_root_.scala.runtime.Tuple3Zipped.Ops.zipped.") - ) - - def replaceToList(ctx: RuleCtx) = - ctx.tree.collect { - case iterator(t: Name) => - ctx.replaceTree(t, "iterator()") - case toTpe(n: Name) => - (for { - name <- n.tokens.lastOption - open <- ctx.tokenList.find(name)(t => t.is[Token.LeftBracket]) - close <- ctx.matchingParens.close(open.asInstanceOf[Token.LeftBracket]) - } yield - ctx.replaceToken(open, "(") + - ctx.replaceToken(close, ")") - ).asPatch - }.asPatch - - def replaceTupleZipped(ctx: RuleCtx) = - ctx.tree.collect { - case tupleZipped(Term.Select(Term.Tuple(args), name)) => - val removeTokensPatch = - (for { - zipped <- name.tokens.headOption - closeTuple <- ctx.tokenList.leading(zipped).find(_.is[Token.RightParen]) - openTuple <- ctx.matchingParens.open(closeTuple.asInstanceOf[Token.RightParen]) - maybeDot = ctx.tokenList.slice(closeTuple, zipped).find(_.is[Token.Dot]) - } yield { - ctx.removeToken(openTuple) + - maybeDot.map(ctx.removeToken).asPatch + - ctx.removeToken(zipped) - }).asPatch - - def removeSurroundingWhiteSpaces(tk: Token) = - (ctx.tokenList.trailing(tk).takeWhile(_.is[Token.Space]).map(ctx.removeToken) ++ - ctx.tokenList.leading(tk).takeWhile(_.is[Token.Space]).map(ctx.removeToken)).asPatch - - val commas = - for { - (prev, next) <- args.zip(args.tail) - tokensBetweenArgs = ctx.tokenList.slice(prev.tokens.last, next.tokens.head) - comma <- tokensBetweenArgs.find(_.is[Token.Comma]) - } yield comma - - val replaceCommasPatch = commas match { - case head :: tail => - ctx.replaceToken(head, ".lazyZip(") + - removeSurroundingWhiteSpaces(head) ++ - tail.map { comma => - ctx.replaceToken(comma, ").lazyZip(") + - removeSurroundingWhiteSpaces(comma) - } - case _ => Patch.empty - } - - removeTokensPatch + replaceCommasPatch - }.asPatch - - def replaceJavaConverters(ctx: RuleCtx): Patch = { - ctx.tree.collect { - case Import(List(importer)) if importer.syntax.containsSlice("collection.JavaConverters._") => - ctx.replaceTree(importer, "strawman.collection.JavaConverters._") - }.asPatch - } - - override def fix(ctx: RuleCtx): Patch = { - replaceToList(ctx) + - replaceSymbols(ctx) + - replaceExtensionMethods(ctx) + - replaceRange(ctx) + - replaceTupleZipped(ctx) + - replaceJavaConverters(ctx) - } -} diff --git a/2.12/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/2.12/tests/src/test/scala/fix/Collectionstrawman_Tests.scala deleted file mode 100644 index 023382b6..00000000 --- a/2.12/tests/src/test/scala/fix/Collectionstrawman_Tests.scala +++ /dev/null @@ -1,18 +0,0 @@ -package fix - -import scala.meta._ -import scalafix.testkit._ -import scalafix._ - -class Collectionstrawman_Tests - extends SemanticRuleSuite( - SemanticdbIndex.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), - AbsolutePath(BuildInfo.inputSourceroot), - Seq(AbsolutePath(BuildInfo.outputSourceroot)) - ) { - override def assertNoDiff(a: String, b: String, c: String) = { - println(a) - super.assertNoDiff(a, b, c) - } - runAllTests() -} diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala deleted file mode 100644 index 604a3c2b..00000000 --- a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala +++ /dev/null @@ -1,13 +0,0 @@ -/* -rule = "scala:fix.Collectionstrawman_v0" - */ -package fix - -object Collectionstrawman_v0_Traversable { - def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = { - xs.to[List] - xs.to[Set] - xs.toIterator - ys.iterator - } -} diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala deleted file mode 100644 index 6130a012..00000000 --- a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala +++ /dev/null @@ -1,36 +0,0 @@ -/* -rule = "scala:fix.Collectionstrawman_v0" - */ -package fix - -import scala.language.postfixOps -object Collectionstrawman_v0_Tuple2Zipped { - def zipped(xs: List[Int], ys: List[Int]): Unit = { - (xs, ys).zipped - (xs,ys).zipped - ((xs, ys) zipped) - (((xs) , (ys)).zipped) - (xs, // foo - ys).zipped - /* a */(/* b */ xs /* c */, /* d */ ys /* e */)/* f */./* g */zipped/* h */ - (coll(1), coll(2)).zipped - (List(1, 2, 3), Stream.from(1)).zipped - } - def coll(x: Int): List[Int] = ??? -} - -object Collectionstrawman_v0_Tuple3Zipped { - def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = { - (xs, ys, zs).zipped - (xs,ys,zs).zipped - ((xs, ys, zs) zipped) - (((xs) , (ys) , (zs)).zipped) - (xs, // foo - ys, // bar - zs).zipped - /* a */(/* b */ xs /* c */, /* d */ ys /* e */, /* f */ zs /* g */)/* h */./* i */zipped/* j */ - (coll(1), coll(2), coll(3)).zipped - (List(1, 2, 3), Set(1, 2, 3), Stream.from(1)).zipped - } - def coll(x: Int): List[Int] = ??? -} \ No newline at end of file diff --git a/build.sbt b/build.sbt index 092bb590..16b2758c 100644 --- a/build.sbt +++ b/build.sbt @@ -8,72 +8,36 @@ inScope(Global)( lazy val root = project .in(file(".")) .aggregate( - rules, input, output, tests, - `rules-2_13`, `input-2_13`, `output-2_13`, `tests-2_13` + rules, input, output, tests ) -lazy val rules = project.in(file("2.12") / "rules").settings( +lazy val rules = project.settings( libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion ) -lazy val input = project.in(file("2.12") / "input").settings( - scalafixSourceroot := sourceDirectory.in(Compile).value -) - -val collections = ProjectRef(file(".."), "collectionsJVM") - -lazy val output = project.in(file("2.12") / "output") - .settings( - resolvers := resolvers.in(collections).value, - libraryDependencies ++= libraryDependencies.in(collections).value, - scalaVersion := scalaVersion.in(collections).value, - scalaBinaryVersion := scalaBinaryVersion.in(collections).value - ) - .dependsOn(collections) // collections/publishLocal is still necessary. - -lazy val tests = project.in(file("2.12") / "tests") - .settings( - libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full, - buildInfoPackage := "fix", - buildInfoKeys := Seq[BuildInfoKey]( - "inputSourceroot" -> - sourceDirectory.in(input, Compile).value, - "outputSourceroot" -> - sourceDirectory.in(output, Compile).value, - "inputClassdirectory" -> - classDirectory.in(input, Compile).value - ) - ) - .dependsOn(input, rules) - .enablePlugins(BuildInfoPlugin) - -lazy val `rules-2_13` = project.in(file("2.13") / "rules").settings( - libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion -) - -lazy val `input-2_13` = project.in(file("2.13") / "input") +lazy val input = project .settings( scalafixSourceroot := sourceDirectory.in(Compile).value ) -lazy val `output-2_13` = project.in(file("2.13") / "output") +lazy val output = project .settings( resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/", - scalaVersion := "2.13.0-pre-c577876" + scalaVersion := "2.13.0-M4-pre-20d3c21" ) -lazy val `tests-2_13` = project.in(file("2.13") / "tests") +lazy val tests = project .settings( libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full, buildInfoPackage := "fix", buildInfoKeys := Seq[BuildInfoKey]( "inputSourceroot" -> - sourceDirectory.in(`input-2_13`, Compile).value, + sourceDirectory.in(input, Compile).value, "outputSourceroot" -> - sourceDirectory.in(`output-2_13`, Compile).value, + sourceDirectory.in(output, Compile).value, "inputClassdirectory" -> - classDirectory.in(`input-2_13`, Compile).value + classDirectory.in(input, Compile).value ) ) - .dependsOn(`input-2_13`, `rules-2_13`) + .dependsOn(input, rules) .enablePlugins(BuildInfoPlugin) diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala similarity index 100% rename from 2.13/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala rename to input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala diff --git a/2.12/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala similarity index 100% rename from 2.12/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala rename to input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/2.12/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala similarity index 100% rename from 2.12/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename to input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/2.13/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala b/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala similarity index 100% rename from 2.13/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala rename to input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala similarity index 100% rename from 2.13/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala rename to output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala similarity index 100% rename from 2.13/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala rename to output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala similarity index 100% rename from 2.13/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename to output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/2.13/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala b/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala similarity index 100% rename from 2.13/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala rename to output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala diff --git a/2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/rules/src/main/scala/fix/Collectionstrawman_v0.scala similarity index 100% rename from 2.13/rules/src/main/scala/fix/Collectionstrawman_v0.scala rename to rules/src/main/scala/fix/Collectionstrawman_v0.scala diff --git a/2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/tests/src/test/scala/fix/Collectionstrawman_Tests.scala similarity index 100% rename from 2.13/tests/src/test/scala/fix/Collectionstrawman_Tests.scala rename to tests/src/test/scala/fix/Collectionstrawman_Tests.scala From 8b59395b60e57b4b615c57a752aa91213f8548a2 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 19 Apr 2018 09:23:48 +0200 Subject: [PATCH 39/40] Move scalafix files into a scalafix subdirectory --- build.sbt => scalafix/build.sbt | 0 .../input}/src/main/scala/fix/Collectionstrawman_v0_Stream.scala | 0 .../src/main/scala/fix/Collectionstrawman_v0_Traversable.scala | 0 .../src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala | 0 .../src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala | 0 .../output}/src/main/scala/fix/Collectionstrawman_v0_Stream.scala | 0 .../src/main/scala/fix/Collectionstrawman_v0_Traversable.scala | 0 .../src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala | 0 .../src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala | 0 {project => scalafix/project}/build.properties | 0 {project => scalafix/project}/plugins.sbt | 0 .../rules}/src/main/scala/fix/Collectionstrawman_v0.scala | 0 .../tests}/src/test/scala/fix/Collectionstrawman_Tests.scala | 0 13 files changed, 0 insertions(+), 0 deletions(-) rename build.sbt => scalafix/build.sbt (100%) rename {input => scalafix/input}/src/main/scala/fix/Collectionstrawman_v0_Stream.scala (100%) rename {input => scalafix/input}/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala (100%) rename {input => scalafix/input}/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala (100%) rename {input => scalafix/input}/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala (100%) rename {output => scalafix/output}/src/main/scala/fix/Collectionstrawman_v0_Stream.scala (100%) rename {output => scalafix/output}/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala (100%) rename {output => scalafix/output}/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala (100%) rename {output => scalafix/output}/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala (100%) rename {project => scalafix/project}/build.properties (100%) rename {project => scalafix/project}/plugins.sbt (100%) rename {rules => scalafix/rules}/src/main/scala/fix/Collectionstrawman_v0.scala (100%) rename {tests => scalafix/tests}/src/test/scala/fix/Collectionstrawman_Tests.scala (100%) diff --git a/build.sbt b/scalafix/build.sbt similarity index 100% rename from build.sbt rename to scalafix/build.sbt diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/scalafix/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala rename to scalafix/input/src/main/scala/fix/Collectionstrawman_v0_Stream.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/scalafix/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala rename to scalafix/input/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/scalafix/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename to scalafix/input/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala b/scalafix/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala similarity index 100% rename from input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala rename to scalafix/input/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala b/scalafix/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala rename to scalafix/output/src/main/scala/fix/Collectionstrawman_v0_Stream.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala b/scalafix/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala rename to scalafix/output/src/main/scala/fix/Collectionstrawman_v0_Traversable.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala b/scalafix/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala rename to scalafix/output/src/main/scala/fix/Collectionstrawman_v0_TupleNZipped.scala diff --git a/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala b/scalafix/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala similarity index 100% rename from output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala rename to scalafix/output/src/main/scala/fix/Collectionstrawman_v0_copyToBuffer.scala diff --git a/project/build.properties b/scalafix/project/build.properties similarity index 100% rename from project/build.properties rename to scalafix/project/build.properties diff --git a/project/plugins.sbt b/scalafix/project/plugins.sbt similarity index 100% rename from project/plugins.sbt rename to scalafix/project/plugins.sbt diff --git a/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/scalafix/rules/src/main/scala/fix/Collectionstrawman_v0.scala similarity index 100% rename from rules/src/main/scala/fix/Collectionstrawman_v0.scala rename to scalafix/rules/src/main/scala/fix/Collectionstrawman_v0.scala diff --git a/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/scalafix/tests/src/test/scala/fix/Collectionstrawman_Tests.scala similarity index 100% rename from tests/src/test/scala/fix/Collectionstrawman_Tests.scala rename to scalafix/tests/src/test/scala/fix/Collectionstrawman_Tests.scala From 00cbc8fd6aea25cc1d9c90199425a73132f92bfd Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 19 Apr 2018 10:57:17 +0200 Subject: [PATCH 40/40] Update README and CONTRIBUTING files with details related to the migration rules --- CONTRIBUTING.md | 77 +++++++++++++++++++ README.md | 28 ++++++- ...0.scala => Scalacollectioncompat_v0.scala} | 2 +- 3 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 CONTRIBUTING.md rename scalafix/rules/src/main/scala/fix/{Collectionstrawman_v0.scala => Scalacollectioncompat_v0.scala} (98%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..ba80d3c0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,77 @@ +# Contributing + +## Build + +### Sbt Projects + +- `scala-collection-compat` project (in the root directory): implementation of the compatibility library ; +- In directory `scalafix/` there is an independent build containing the implementation of the migration tool. + +## Migration tool + +Several levels of contribution are possible! + +### Report a missing case + +Create an issue tagged with the +[migration](https://github.com/scala/collection-strawman/labels/migration) label. +Embrace `diff`s to describe differences between the standard collections and +the strawman: + +~~~ diff +- xs.toIterator ++ xs.iterator() +~~~ + +### Add a missing test case + +Even better, instead of providing a diff, you can directly add it as a test case! + +1. Fork this repository and create a separate branch; + +2. Add a file in the `scalafix/input/src/main/scala/fix/` directory with code + that uses the standard collections: + +~~~ scala +class toIteratorVsIterator(xs: Iterable[Int]) { + xs.toIterator +} +~~~ + +3. Add a corresponding file in the `scalafix/output/src/main/scala/fix/` directory + with the same code but using the strawman: + +~~~ scala +import strawman.collection.Iterable + +class toIteratorVsIterator(xs: Iterable[Int]) { + xs.iterator() +} +~~~ + +4. Check that your code example compiles + - run sbt from the `scalafix/` directory + and then run the following tasks `; input/compile ; output/compile`; + +5. Commit your changes, push your branch to your fork and create a pull request. + +Then maybe someone will take over and implement your use case… or maybe you will +(see next section)! + +### Implement a missing case + +Even better, complete the migration tool implementation to support the missing case! + +After you have added the missing case (see previous section), run the following +sbt task (with sbt started from the `scalafix/` directory) to run the +migration tool on the input files and check whether the result matches the +expected output files: + +~~~ +> tests/test +~~~ + +Fix the implementation of the rule (in the +`rules/src/main/scala/fix/Scalacollectioncompat_v0.scala` file) until the +tests are green. You can find more help about the scalafix API in its +[documentation](https://scalacenter.github.io/scalafix/docs/rule-authors/setup). diff --git a/README.md b/README.md index 94d35c61..e6717ba4 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ [![Build Status](https://travis-ci.org/scala/scala-collection-compat.svg?branch=master)](https://travis-ci.org/scala/scala-collection-compat) -Scala 2.13 Collection Compatibility Library -=========================================== +Scala 2.13 Collection Compatibility Library And Migration Tool +============================================================== + +## Compatibility Library This library for Scala 2.12 provides limited compatibility with the new collection library in 2.13. We try to keep the 2.13 collections as backward compatible as possible but that is not always possible. For some of these cases this @@ -24,3 +26,25 @@ This project can be cross-built on 2.13 (with new collections) and 2.12. The 2.1 empty `scala.collection.compat` package object that allows you to write `import scala.collection.compat._` in 2.13. The 2.13 version has the compatibility extensions in this package. It also adds backported version of some new collection types to other `scala.collection` subpackages. + +## Migration Tool + +A tool is being developed to automatically migrate code that uses the standard +collection to use the strawman. + +To use it, add the [scalafix](https://scalacenter.github.io/scalafix/) sbt plugin +to your build, as explained in +[its documentation](https://scalacenter.github.io/scalafix/#Installation). + +The migration tool is not exhaustive and we will continue to improve +it over time. If you encounter a use case that’s not supported, please +report it as described in the +[contributing documentation](CONTRIBUTING.md#migration-tool). + +### Migrating a 2.12 code base to 2.13 + +Run the following sbt task on your project: + +~~~ +> scalafix github:scala/scala-collection-compat/v0 +~~~ diff --git a/scalafix/rules/src/main/scala/fix/Collectionstrawman_v0.scala b/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_v0.scala similarity index 98% rename from scalafix/rules/src/main/scala/fix/Collectionstrawman_v0.scala rename to scalafix/rules/src/main/scala/fix/Scalacollectioncompat_v0.scala index 3e720906..0ddb01a1 100644 --- a/scalafix/rules/src/main/scala/fix/Collectionstrawman_v0.scala +++ b/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_v0.scala @@ -5,7 +5,7 @@ import scalafix.syntax._ import scalafix.util._ import scala.meta._ -case class Collectionstrawman_v0(index: SemanticdbIndex) +case class Scalacollectioncompat_v0(index: SemanticdbIndex) extends SemanticRule(index, "Collectionstrawman_v0") { def replaceSymbols(ctx: RuleCtx): Patch = {