diff --git a/scalafix/build.sbt b/scalafix/build.sbt index 5cf2d509..61b464a3 100644 --- a/scalafix/build.sbt +++ b/scalafix/build.sbt @@ -1,23 +1,31 @@ def scalafixVersion = _root_.scalafix.Versions.version -inScope(Global)( - List( - scalaVersion := _root_.scalafix.Versions.scala212 - ) + +lazy val baseSettings = Seq( + scalaVersion := _root_.scalafix.Versions.scala212 ) lazy val root = project .in(file(".")) - .aggregate( - rules, input, output, tests - ) + .settings(baseSettings) + .aggregate(rules, input, output, tests) -lazy val rules = project.settings( - libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion -) +lazy val rules = project + .settings(baseSettings) + .settings( + libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion + ) lazy val input = project +.settings(baseSettings) .settings( - scalafixSourceroot := sourceDirectory.in(Compile).value + addCompilerPlugin(scalafixSemanticdb), + scalacOptions ++= { + val sourceroot = sourceDirectory.in(Compile).value / "scala" + Seq( + "-Yrangepos", + s"-P:semanticdb:sourceroot:$sourceroot" + ) + } ) lazy val output = project @@ -27,18 +35,15 @@ lazy val output = project ) lazy val tests = project + .settings(baseSettings) .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 - ), - test in Test := (test in Test).dependsOn(compile in (output, Compile)).value + scalafixTestkitOutputSourceDirectories := + sourceDirectories.in(output, Compile).value, + scalafixTestkitInputSourceDirectories := + sourceDirectories.in(input, Compile).value, + scalafixTestkitInputClasspath := + fullClasspath.in(input, Compile).value ) .dependsOn(input, rules) - .enablePlugins(BuildInfoPlugin) + .enablePlugins(ScalafixTestkitPlugin) diff --git a/scalafix/input/src/main/scala/fix/ShiftingSrc.scala b/scalafix/input/src/main/scala/fix/ShiftingSrc.scala new file mode 100644 index 00000000..dee7a6e7 --- /dev/null +++ b/scalafix/input/src/main/scala/fix/ShiftingSrc.scala @@ -0,0 +1,32 @@ +/* +rule = "scala:fix.Scalacollectioncompat_newcollections" + */ +package fix + +object ShiftingSrc { + val b = 1.toByte + val c = 'c' + val i = 1 + val s = 1.toShort + val l = 1L + + b << l + b >>> l + b >> l + + c << l + c >>> l + c >> l + + i << l + i >>> l + i >> l + + s << l + s >>> l + s >> l + + l << l + l >>> l + l >> l +} diff --git a/scalafix/output/src/main/scala/fix/ShiftingSrc.scala b/scalafix/output/src/main/scala/fix/ShiftingSrc.scala new file mode 100644 index 00000000..62bce2c3 --- /dev/null +++ b/scalafix/output/src/main/scala/fix/ShiftingSrc.scala @@ -0,0 +1,32 @@ + + + +package fix + +object ShiftingSrc { + val b = 1.toByte + val c = 'c' + val i = 1 + val s = 1.toShort + val l = 1L + + b.toLong << l + b.toLong >>> l + b.toLong >> l + + c.toLong << l + c.toLong >>> l + c.toLong >> l + + i.toLong << l + i.toLong >>> l + i.toLong >> l + + s.toLong << l + s.toLong >>> l + s.toLong >> l + + l << l + l >>> l + l >> l +} diff --git a/scalafix/project/plugins.sbt b/scalafix/project/plugins.sbt index 0fd7a907..5782adbf 100644 --- a/scalafix/project/plugins.sbt +++ b/scalafix/project/plugins.sbt @@ -1,3 +1,3 @@ -addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.5.10") +addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.6.0-M8") addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.6.1") \ No newline at end of file diff --git a/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala b/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala index a310662f..75889313 100644 --- a/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala +++ b/scalafix/rules/src/main/scala/fix/Scalacollectioncompat_newcollections.scala @@ -8,6 +8,16 @@ import scala.meta._ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) extends SemanticRule(index, "Scalacollectioncompat_newcollections") { + val naturalNumberTypes = List("Byte", "Char", "Int", "Short") + val shiffingOperators = List("<<", ">>>", ">>") + val naturalNumberShiftingSymbols = + for { + tpe <- naturalNumberTypes + op <- shiffingOperators + } yield Symbol(s"scala.$tpe#`$op`(Long).") + + val naturalShiffting = SymbolMatcher.exact(naturalNumberShiftingSymbols: _*) + def replaceSymbols(ctx: RuleCtx): Patch = { ctx.replaceSymbols( "scala.Stream" -> "scala.LazyList", @@ -49,13 +59,13 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) Symbol("_root_.scala.collection.mutable.SetLike.retain.") ) - def replaceMutableSet(ctx: RuleCtx) = + def replaceMutableSet(ctx: RuleCtx): Patch = ctx.tree.collect { case retainSet(n: Name) => ctx.replaceTree(n, "filterInPlace") }.asPatch - def replaceMutableMap(ctx: RuleCtx) = + def replaceMutableMap(ctx: RuleCtx): Patch = ctx.tree.collect { case Term.Apply(Term.Select(_, retainMap(n: Name)), List(_: Term.PartialFunction)) => ctx.replaceTree(n, "filterInPlace") @@ -72,7 +82,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) ).asPatch }.asPatch - def replaceSymbolicFold(ctx: RuleCtx) = + def replaceSymbolicFold(ctx: RuleCtx): Patch = ctx.tree.collect { case Term.Apply(ap @ Term.ApplyInfix(rhs, foldRightSymbol(_), _, List(lhs)), _) => ctx.replaceTree(ap, s"$rhs.foldRight($lhs)") @@ -81,7 +91,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) ctx.replaceTree(ap, s"$rhs.foldLeft($lhs)") }.asPatch - def replaceToList(ctx: RuleCtx) = + def replaceToList(ctx: RuleCtx): Patch = ctx.tree.collect { case iterator(t: Name) => ctx.replaceTree(t, "iterator") @@ -96,7 +106,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) ).asPatch }.asPatch - def replaceTupleZipped(ctx: RuleCtx) = + def replaceTupleZipped(ctx: RuleCtx): Patch = ctx.tree.collect { case tupleZipped(Term.Select(Term.Tuple(args), name)) => val removeTokensPatch = @@ -156,9 +166,13 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) ctx.replaceTree(t, "lazyAppendedAll") }.asPatch - override def fix(ctx: RuleCtx): Patch = { - // println(ctx.index.database) + def replaceNaturalShiffting(ctx: RuleCtx): Patch = + ctx.tree.collect { + case Term.ApplyInfix(lhs, naturalShiffting(_), Nil, List(_)) => + ctx.addRight(lhs, ".toLong") + }.asPatch + override def fix(ctx: RuleCtx): Patch = { replaceToList(ctx) + replaceSymbols(ctx) + replaceTupleZipped(ctx) + @@ -166,6 +180,7 @@ case class Scalacollectioncompat_newcollections(index: SemanticdbIndex) replaceStreamAppend(ctx) + replaceMutableMap(ctx) + replaceMutableSet(ctx) + - replaceSymbolicFold(ctx) + replaceSymbolicFold(ctx) + + replaceNaturalShiffting(ctx) } } diff --git a/scalafix/tests/src/test/scala/fix/Collectionstrawman_Tests.scala b/scalafix/tests/src/test/scala/fix/Collectionstrawman_Tests.scala index ef75d77e..ffe92f45 100644 --- a/scalafix/tests/src/test/scala/fix/Collectionstrawman_Tests.scala +++ b/scalafix/tests/src/test/scala/fix/Collectionstrawman_Tests.scala @@ -1,14 +1,10 @@ package fix import scala.meta._ -import scalafix.testkit._ import scalafix._ +import scalafix.v0._ -class Collectionstrawman_Tests - extends SemanticRuleSuite( - SemanticdbIndex.load(Classpath(AbsolutePath(BuildInfo.inputClassdirectory))), - AbsolutePath(BuildInfo.inputSourceroot), - Seq(AbsolutePath(BuildInfo.outputSourceroot)) - ) { +class Scalafixplayground_Tests + extends scalafix.testkit.SemanticRuleSuite { runAllTests() }