Skip to content

Refactor Traversable and .to[CC] rules #126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -223,14 +223,13 @@ lazy val `scalafix-tests` = project
.settings(
scalaVersion := scalafixScala212,
libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full,
buildInfoPackage := "fix",
buildInfoPackage := "build",
buildInfoKeys := Seq[BuildInfoKey](
"inputSourceroot" -> sourceDirectory.in(`scalafix-input`, Compile).value,
"outputSourceroot" -> (baseDirectory in ThisBuild).value / "scalafix/output/src/main",
"output212Sourceroot" -> output212.value,
"output212PlusSourceroot" -> output212Plus.value,
"output213Sourceroot" -> output213.value,
"output212PlusSourceroot" -> output212Plus.value,
"output213FailureSourceroot" -> sourceDirectory.in(`scalafix-output213-failure`, Compile).value,
"inputClassdirectory" -> classDirectory.in(`scalafix-input`, Compile).value
),
Expand Down
42 changes: 42 additions & 0 deletions scalafix/input/src/main/scala/fix/CompanionSrc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
rule = "scala:fix.CrossCompat"
*/
package fix

import scala.collection.immutable
import scala.collection.mutable

object CompanionSrc {

(null: collection.IndexedSeq[Int]).companion
(null: collection.Iterable[Int]).companion
(null: collection.Seq[Int]).companion
(null: collection.Traversable[Int]).companion

(null: immutable.HashSet[Int]).companion
(null: immutable.IndexedSeq[Int]).companion
(null: immutable.Iterable[Int]).companion
(null: immutable.LinearSeq[Int]).companion
(null: immutable.List[Int]).companion
(null: immutable.ListSet[Int]).companion
(null: immutable.Queue[Int]).companion
(null: immutable.Seq[Int]).companion
(null: immutable.Set[Int]).companion
(null: immutable.Stream[Int]).companion
(null: immutable.Traversable[Int]).companion
(null: immutable.Vector[Int]).companion

(null: mutable.ArrayBuffer[Int]).companion
(null: mutable.ArraySeq[Int]).companion
(null: mutable.ArrayStack[Int]).companion
(null: mutable.Buffer[Int]).companion
(null: mutable.HashSet[Int]).companion
(null: mutable.IndexedSeq[Int]).companion
(null: mutable.Iterable[Int]).companion
(null: mutable.LinearSeq[Int]).companion
(null: mutable.LinkedHashSet[Int]).companion
(null: mutable.Queue[Int]).companion
(null: mutable.Seq[Int]).companion
(null: mutable.Set[Int]).companion
(null: mutable.Traversable[Int]).companion
}
33 changes: 1 addition & 32 deletions scalafix/input/src/main/scala/fix/CompanionSrc212.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,10 @@ import scala.collection.{immutable => i, mutable => m}
import scala.{collection => c}

object CompanionSrc212 {

(null: c.IndexedSeq[Int]).companion
(null: c.Iterable[Int]).companion
(null: c.Seq[Int]).companion
(null: c.Traversable[Int]).companion

(null: i.HashSet[Int]).companion
(null: i.IndexedSeq[Int]).companion
(null: i.Iterable[Int]).companion
(null: i.LinearSeq[Int]).companion
(null: i.List[Int]).companion
(null: i.ListSet[Int]).companion
(null: i.Queue[Int]).companion
(null: i.Seq[Int]).companion
(null: i.Set[Int]).companion
(null: i.Stack[Int]).companion
(null: i.Stream[Int]).companion
(null: i.Traversable[Int]).companion
(null: i.Vector[Int]).companion

(null: m.ArrayBuffer[Int]).companion
(null: m.ArraySeq[Int]).companion
(null: m.ArrayStack[Int]).companion
(null: m.Buffer[Int]).companion
(null: m.DoubleLinkedList[Int]).companion
(null: m.HashSet[Int]).companion
(null: m.IndexedSeq[Int]).companion
(null: m.Iterable[Int]).companion
(null: m.LinearSeq[Int]).companion
(null: m.LinkedHashSet[Int]).companion
(null: m.LinkedList[Int]).companion
(null: m.MutableList[Int]).companion
(null: m.Queue[Int]).companion
(null: m.ResizableArray[Int]).companion
(null: m.Seq[Int]).companion
(null: m.Set[Int]).companion
(null: m.Traversable[Int]).companion
}

17 changes: 17 additions & 0 deletions scalafix/input/src/main/scala/fix/ReplaceToSrc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
rule = "scala:fix.CrossCompat"
*/
package fix

object ReplaceToSrc {
List(1).to[Set]
Set(1).to[List]

def m1(xs: Set[Int]): List[Int] =
xs.to

List[Int]() // unrelated matching brackets

def m2(xs: List[Int]): Iterable[Int] =
xs.to
}
19 changes: 9 additions & 10 deletions scalafix/input/src/main/scala/fix/TraversableSrc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ rule = "scala:fix.CrossCompat"
*/
package fix

object TraversableSrc {
def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = {
xs.to[List]
xs.to[Set]
xs.toIterator
ys.iterator
}
import scala.collection.immutable
import scala.collection.mutable

def m1(xs: TraversableOnce[Int]): List[Int] =
xs.to
trait TraversableSrc {
val to: TraversableOnce[Int]
val cto: collection.TraversableOnce[Int]

List[Int]() // unrelated matching brackets
val t: Traversable[Int]
val ct: collection.Traversable[Int]
val it: immutable.Traversable[Int]
val mt: mutable.Traversable[Int]
}
43 changes: 43 additions & 0 deletions scalafix/output/src/main/scala/fix/CompanionSrc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@



package fix

import scala.collection.immutable
import scala.collection.mutable
import scala.collection.compat._

object CompanionSrc {

(null: collection.IndexedSeq[Int]).iterableFactory
(null: collection.Iterable[Int]).iterableFactory
(null: collection.Seq[Int]).iterableFactory
(null: collection.Iterable[Int]).iterableFactory

(null: immutable.HashSet[Int]).iterableFactory
(null: immutable.IndexedSeq[Int]).iterableFactory
(null: immutable.Iterable[Int]).iterableFactory
(null: immutable.LinearSeq[Int]).iterableFactory
(null: immutable.List[Int]).iterableFactory
(null: immutable.ListSet[Int]).iterableFactory
(null: immutable.Queue[Int]).iterableFactory
(null: immutable.Seq[Int]).iterableFactory
(null: immutable.Set[Int]).iterableFactory
(null: immutable.Stream[Int]).iterableFactory
(null: immutable.Iterable[Int]).iterableFactory
(null: immutable.Vector[Int]).iterableFactory

(null: mutable.ArrayBuffer[Int]).iterableFactory
(null: mutable.ArraySeq[Int]).iterableFactory
(null: mutable.ArrayStack[Int]).iterableFactory
(null: mutable.Buffer[Int]).iterableFactory
(null: mutable.HashSet[Int]).iterableFactory
(null: mutable.IndexedSeq[Int]).iterableFactory
(null: mutable.Iterable[Int]).iterableFactory
(null: mutable.LinearSeq[Int]).iterableFactory
(null: mutable.LinkedHashSet[Int]).iterableFactory
(null: mutable.Queue[Int]).iterableFactory
(null: mutable.Seq[Int]).iterableFactory
(null: mutable.Set[Int]).iterableFactory
(null: mutable.Iterable[Int]).iterableFactory
}
18 changes: 18 additions & 0 deletions scalafix/output/src/main/scala/fix/ReplaceToSrc.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@



package fix

import scala.collection.compat._
object ReplaceToSrc {
List(1).to(Set)
Set(1).to(List)

def m1(xs: Set[Int]): List[Int] =
xs.to(scala.collection.immutable.List)

List[Int]() // unrelated matching brackets

def m2(xs: List[Int]): Iterable[Int] =
xs.to(scala.collection.immutable.IndexedSeq)
}
19 changes: 9 additions & 10 deletions scalafix/output/src/main/scala/fix/TraversableSrc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@

package fix

import scala.collection.immutable
import scala.collection.mutable
import scala.collection.compat._
object TraversableSrc {
def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = {
xs.to(List)
xs.to(Set)
xs.iterator
ys.iterator
}

def m1(xs: IterableOnce[Int]): List[Int] =
xs.to(scala.collection.immutable.List)
trait TraversableSrc {
val to: IterableOnce[Int]
val cto: IterableOnce[Int]

List[Int]() // unrelated matching brackets
val t: Iterable[Int]
val ct: collection.Iterable[Int]
val it: immutable.Iterable[Int]
val mt: mutable.Iterable[Int]
}
32 changes: 0 additions & 32 deletions scalafix/output212/src/main/scala/fix/CompanionSrc212.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,41 +8,9 @@ import scala.{collection => c}
import scala.collection.compat._

object CompanionSrc212 {

(null: c.IndexedSeq[Int]).iterableFactory
(null: c.Iterable[Int]).iterableFactory
(null: c.Seq[Int]).iterableFactory
(null: collection.Iterable[Int]).iterableFactory

(null: i.HashSet[Int]).iterableFactory
(null: i.IndexedSeq[Int]).iterableFactory
(null: i.Iterable[Int]).iterableFactory
(null: i.LinearSeq[Int]).iterableFactory
(null: i.List[Int]).iterableFactory
(null: i.ListSet[Int]).iterableFactory
(null: i.Queue[Int]).iterableFactory
(null: i.Seq[Int]).iterableFactory
(null: i.Set[Int]).iterableFactory
(null: i.Stack[Int]).iterableFactory
(null: i.Stream[Int]).iterableFactory
(null: i.Traversable[Int]).iterableFactory
(null: i.Vector[Int]).iterableFactory

(null: m.ArrayBuffer[Int]).iterableFactory
(null: m.ArraySeq[Int]).iterableFactory
(null: m.ArrayStack[Int]).iterableFactory
(null: m.Buffer[Int]).iterableFactory
(null: m.DoubleLinkedList[Int]).iterableFactory
(null: m.HashSet[Int]).iterableFactory
(null: m.IndexedSeq[Int]).iterableFactory
(null: m.Iterable[Int]).iterableFactory
(null: m.LinearSeq[Int]).iterableFactory
(null: m.LinkedHashSet[Int]).iterableFactory
(null: m.LinkedList[Int]).iterableFactory
(null: m.MutableList[Int]).iterableFactory
(null: m.Queue[Int]).iterableFactory
(null: m.ResizableArray[Int]).iterableFactory
(null: m.Seq[Int]).iterableFactory
(null: m.Set[Int]).iterableFactory
(null: m.Traversable[Int]).iterableFactory
}
65 changes: 36 additions & 29 deletions scalafix/rules/src/main/scala/fix/Stable212Base.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
val foldLeftSymbol = foldSymbol(isLeft = true)
val foldRightSymbol = foldSymbol(isLeft = false)

val iterator = normalized("_root_.scala.collection.TraversableLike.toIterator.")

val toTpe = normalized(
"_root_.scala.collection.TraversableLike.to.",
"_root_.scala.collection.TraversableOnce.to.",
Expand Down Expand Up @@ -73,10 +73,9 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
"_root_.scala.collection.immutable.TreeSet#until(Ljava/lang/Object;)Lscala/collection/immutable/TreeSet;."
)

val traversable = exact(
"_root_.scala.collection.Traversable#",
val `TraversableLike.toIterator` = normalized("_root_.scala.collection.TraversableLike.toIterator.")
val traversableOnce = exact(
"_root_.scala.collection.TraversableOnce#",
"_root_.scala.package.Traversable#",
"_root_.scala.package.TraversableOnce#"
)

Expand All @@ -99,28 +98,42 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
sameElements + compatImport
}

def replaceSymbols0(ctx: RuleCtx): Patch = {
def replaceTraversable(ctx: RuleCtx): Patch = {

val traversableIterator =
ctx.tree.collect {
case `TraversableLike.toIterator`(t: Name) =>
ctx.replaceTree(t, "iterator")
}.asPatch

val traversableToIterable =
ctx.replaceSymbols(
"scala.Traversable" -> "scala.Iterable",
"scala.collection.Traversable" -> "scala.collection.Iterable",
"scala.TraversableOnce" -> "scala.IterableOnce",
"scala.collection.TraversableOnce" -> "scala.collection.IterableOnce"
"scala.Traversable" -> "scala.Iterable",
"scala.collection.Traversable" -> "scala.collection.Iterable",
"scala.collection.immutable.Traversable" -> "scala.collection.immutable.Iterable",
"scala.collection.mutable.Traversable" -> "scala.collection.mutable.Iterable",
)

import scala.meta.contrib._
val hasTraversable =
ctx.tree.exists {
case traversable(_) => true
case _ => false
val traversableOnceToIterableOnce =
ctx.tree.collect {
case Type.Apply(sel @ Type.Select(chain, traversableOnce(n: Name)), _) =>
val dot = chain.tokens.toList.reverse.drop(1)

ctx.removeTokens(chain.tokens) +
ctx.removeTokens(dot) +
ctx.replaceTree(sel, "IterableOnce")

}
case Type.Apply(traversableOnce(n: Name), _) =>
ctx.replaceTree(n, "IterableOnce")


}.asPatch

val compatImport =
if (hasTraversable) addCompatImport(ctx)
if (traversableOnceToIterableOnce.nonEmpty || traversableIterator.nonEmpty) addCompatImport(ctx)
else Patch.empty

traversableToIterable + compatImport
traversableOnceToIterableOnce + traversableToIterable + traversableIterator + compatImport
}

def replaceSymbolicFold(ctx: RuleCtx): Patch = {
Expand Down Expand Up @@ -251,14 +264,8 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
}
}

def replaceToList(ctx: RuleCtx): Patch = {
val replaceToIterator =
ctx.tree.collect {
case iterator(t: Name) =>
ctx.replaceTree(t, "iterator")
}.asPatch

val replaceTo =
def replaceTo(ctx: RuleCtx): Patch = {
val patch =
ctx.tree.collect {
case Term.ApplyType(Term.Select(_, t @ toTpe(n: Name)), _) if !handledTo.contains(n) =>
trailingBrackets(n, ctx).map { case (open, close) =>
Expand Down Expand Up @@ -286,10 +293,10 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
}.asPatch

val compatImport =
if (replaceTo.nonEmpty) addCompatImport(ctx)
if (patch.nonEmpty) addCompatImport(ctx)
else Patch.empty

compatImport + replaceToIterator + replaceTo
compatImport + patch
}

def replaceFuture(ctx: RuleCtx): Patch = {
Expand Down Expand Up @@ -566,9 +573,9 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
}

override def fix(ctx: RuleCtx): Patch = {
replaceSymbols0(ctx) +
replaceTraversable(ctx) +
replaceCanBuildFrom(ctx) +
replaceToList(ctx) +
replaceTo(ctx) +
replaceCopyToBuffer(ctx) +
replaceSymbolicFold(ctx) +
replaceSetMapPlus2(ctx) +
Expand Down
Loading