Skip to content

Commit fe48078

Browse files
authored
Merge pull request scala#126 from MasseGuillaume/traversable-to-cc
Refactor Traversable and .to[CC] rules
2 parents 7713c76 + 2934852 commit fe48078

File tree

11 files changed

+183
-122
lines changed

11 files changed

+183
-122
lines changed

build.sbt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,14 +223,13 @@ lazy val `scalafix-tests` = project
223223
.settings(
224224
scalaVersion := scalafixScala212,
225225
libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full,
226-
buildInfoPackage := "fix",
226+
buildInfoPackage := "build",
227227
buildInfoKeys := Seq[BuildInfoKey](
228228
"inputSourceroot" -> sourceDirectory.in(`scalafix-input`, Compile).value,
229229
"outputSourceroot" -> (baseDirectory in ThisBuild).value / "scalafix/output/src/main",
230230
"output212Sourceroot" -> output212.value,
231231
"output212PlusSourceroot" -> output212Plus.value,
232232
"output213Sourceroot" -> output213.value,
233-
"output212PlusSourceroot" -> output212Plus.value,
234233
"output213FailureSourceroot" -> sourceDirectory.in(`scalafix-output213-failure`, Compile).value,
235234
"inputClassdirectory" -> classDirectory.in(`scalafix-input`, Compile).value
236235
),
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
rule = "scala:fix.CrossCompat"
3+
*/
4+
package fix
5+
6+
import scala.collection.immutable
7+
import scala.collection.mutable
8+
9+
object CompanionSrc {
10+
11+
(null: collection.IndexedSeq[Int]).companion
12+
(null: collection.Iterable[Int]).companion
13+
(null: collection.Seq[Int]).companion
14+
(null: collection.Traversable[Int]).companion
15+
16+
(null: immutable.HashSet[Int]).companion
17+
(null: immutable.IndexedSeq[Int]).companion
18+
(null: immutable.Iterable[Int]).companion
19+
(null: immutable.LinearSeq[Int]).companion
20+
(null: immutable.List[Int]).companion
21+
(null: immutable.ListSet[Int]).companion
22+
(null: immutable.Queue[Int]).companion
23+
(null: immutable.Seq[Int]).companion
24+
(null: immutable.Set[Int]).companion
25+
(null: immutable.Stream[Int]).companion
26+
(null: immutable.Traversable[Int]).companion
27+
(null: immutable.Vector[Int]).companion
28+
29+
(null: mutable.ArrayBuffer[Int]).companion
30+
(null: mutable.ArraySeq[Int]).companion
31+
(null: mutable.ArrayStack[Int]).companion
32+
(null: mutable.Buffer[Int]).companion
33+
(null: mutable.HashSet[Int]).companion
34+
(null: mutable.IndexedSeq[Int]).companion
35+
(null: mutable.Iterable[Int]).companion
36+
(null: mutable.LinearSeq[Int]).companion
37+
(null: mutable.LinkedHashSet[Int]).companion
38+
(null: mutable.Queue[Int]).companion
39+
(null: mutable.Seq[Int]).companion
40+
(null: mutable.Set[Int]).companion
41+
(null: mutable.Traversable[Int]).companion
42+
}

scalafix/input/src/main/scala/fix/CompanionSrc212.scala

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,10 @@ import scala.collection.{immutable => i, mutable => m}
77
import scala.{collection => c}
88

99
object CompanionSrc212 {
10-
11-
(null: c.IndexedSeq[Int]).companion
12-
(null: c.Iterable[Int]).companion
13-
(null: c.Seq[Int]).companion
14-
(null: c.Traversable[Int]).companion
15-
16-
(null: i.HashSet[Int]).companion
17-
(null: i.IndexedSeq[Int]).companion
18-
(null: i.Iterable[Int]).companion
19-
(null: i.LinearSeq[Int]).companion
20-
(null: i.List[Int]).companion
21-
(null: i.ListSet[Int]).companion
22-
(null: i.Queue[Int]).companion
23-
(null: i.Seq[Int]).companion
24-
(null: i.Set[Int]).companion
2510
(null: i.Stack[Int]).companion
26-
(null: i.Stream[Int]).companion
27-
(null: i.Traversable[Int]).companion
28-
(null: i.Vector[Int]).companion
29-
30-
(null: m.ArrayBuffer[Int]).companion
31-
(null: m.ArraySeq[Int]).companion
32-
(null: m.ArrayStack[Int]).companion
33-
(null: m.Buffer[Int]).companion
3411
(null: m.DoubleLinkedList[Int]).companion
35-
(null: m.HashSet[Int]).companion
36-
(null: m.IndexedSeq[Int]).companion
37-
(null: m.Iterable[Int]).companion
38-
(null: m.LinearSeq[Int]).companion
39-
(null: m.LinkedHashSet[Int]).companion
4012
(null: m.LinkedList[Int]).companion
4113
(null: m.MutableList[Int]).companion
42-
(null: m.Queue[Int]).companion
4314
(null: m.ResizableArray[Int]).companion
44-
(null: m.Seq[Int]).companion
45-
(null: m.Set[Int]).companion
46-
(null: m.Traversable[Int]).companion
4715
}
16+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
rule = "scala:fix.CrossCompat"
3+
*/
4+
package fix
5+
6+
object ReplaceToSrc {
7+
List(1).to[Set]
8+
Set(1).to[List]
9+
10+
def m1(xs: Set[Int]): List[Int] =
11+
xs.to
12+
13+
List[Int]() // unrelated matching brackets
14+
15+
def m2(xs: List[Int]): Iterable[Int] =
16+
xs.to
17+
}

scalafix/input/src/main/scala/fix/TraversableSrc.scala

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ rule = "scala:fix.CrossCompat"
33
*/
44
package fix
55

6-
object TraversableSrc {
7-
def foo(xs: Traversable[(Int, String)], ys: List[Int]): Unit = {
8-
xs.to[List]
9-
xs.to[Set]
10-
xs.toIterator
11-
ys.iterator
12-
}
6+
import scala.collection.immutable
7+
import scala.collection.mutable
138

14-
def m1(xs: TraversableOnce[Int]): List[Int] =
15-
xs.to
9+
trait TraversableSrc {
10+
val to: TraversableOnce[Int]
11+
val cto: collection.TraversableOnce[Int]
1612

17-
List[Int]() // unrelated matching brackets
13+
val t: Traversable[Int]
14+
val ct: collection.Traversable[Int]
15+
val it: immutable.Traversable[Int]
16+
val mt: mutable.Traversable[Int]
1817
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
2+
3+
4+
package fix
5+
6+
import scala.collection.immutable
7+
import scala.collection.mutable
8+
import scala.collection.compat._
9+
10+
object CompanionSrc {
11+
12+
(null: collection.IndexedSeq[Int]).iterableFactory
13+
(null: collection.Iterable[Int]).iterableFactory
14+
(null: collection.Seq[Int]).iterableFactory
15+
(null: collection.Iterable[Int]).iterableFactory
16+
17+
(null: immutable.HashSet[Int]).iterableFactory
18+
(null: immutable.IndexedSeq[Int]).iterableFactory
19+
(null: immutable.Iterable[Int]).iterableFactory
20+
(null: immutable.LinearSeq[Int]).iterableFactory
21+
(null: immutable.List[Int]).iterableFactory
22+
(null: immutable.ListSet[Int]).iterableFactory
23+
(null: immutable.Queue[Int]).iterableFactory
24+
(null: immutable.Seq[Int]).iterableFactory
25+
(null: immutable.Set[Int]).iterableFactory
26+
(null: immutable.Stream[Int]).iterableFactory
27+
(null: immutable.Iterable[Int]).iterableFactory
28+
(null: immutable.Vector[Int]).iterableFactory
29+
30+
(null: mutable.ArrayBuffer[Int]).iterableFactory
31+
(null: mutable.ArraySeq[Int]).iterableFactory
32+
(null: mutable.ArrayStack[Int]).iterableFactory
33+
(null: mutable.Buffer[Int]).iterableFactory
34+
(null: mutable.HashSet[Int]).iterableFactory
35+
(null: mutable.IndexedSeq[Int]).iterableFactory
36+
(null: mutable.Iterable[Int]).iterableFactory
37+
(null: mutable.LinearSeq[Int]).iterableFactory
38+
(null: mutable.LinkedHashSet[Int]).iterableFactory
39+
(null: mutable.Queue[Int]).iterableFactory
40+
(null: mutable.Seq[Int]).iterableFactory
41+
(null: mutable.Set[Int]).iterableFactory
42+
(null: mutable.Iterable[Int]).iterableFactory
43+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
3+
4+
package fix
5+
6+
import scala.collection.compat._
7+
object ReplaceToSrc {
8+
List(1).to(Set)
9+
Set(1).to(List)
10+
11+
def m1(xs: Set[Int]): List[Int] =
12+
xs.to(scala.collection.immutable.List)
13+
14+
List[Int]() // unrelated matching brackets
15+
16+
def m2(xs: List[Int]): Iterable[Int] =
17+
xs.to(scala.collection.immutable.IndexedSeq)
18+
}

scalafix/output/src/main/scala/fix/TraversableSrc.scala

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@
33

44
package fix
55

6+
import scala.collection.immutable
7+
import scala.collection.mutable
68
import scala.collection.compat._
7-
object TraversableSrc {
8-
def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = {
9-
xs.to(List)
10-
xs.to(Set)
11-
xs.iterator
12-
ys.iterator
13-
}
149

15-
def m1(xs: IterableOnce[Int]): List[Int] =
16-
xs.to(scala.collection.immutable.List)
10+
trait TraversableSrc {
11+
val to: IterableOnce[Int]
12+
val cto: IterableOnce[Int]
1713

18-
List[Int]() // unrelated matching brackets
14+
val t: Iterable[Int]
15+
val ct: collection.Iterable[Int]
16+
val it: immutable.Iterable[Int]
17+
val mt: mutable.Iterable[Int]
1918
}

scalafix/output212/src/main/scala/fix/CompanionSrc212.scala

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,9 @@ import scala.{collection => c}
88
import scala.collection.compat._
99

1010
object CompanionSrc212 {
11-
12-
(null: c.IndexedSeq[Int]).iterableFactory
13-
(null: c.Iterable[Int]).iterableFactory
14-
(null: c.Seq[Int]).iterableFactory
15-
(null: collection.Iterable[Int]).iterableFactory
16-
17-
(null: i.HashSet[Int]).iterableFactory
18-
(null: i.IndexedSeq[Int]).iterableFactory
19-
(null: i.Iterable[Int]).iterableFactory
20-
(null: i.LinearSeq[Int]).iterableFactory
21-
(null: i.List[Int]).iterableFactory
22-
(null: i.ListSet[Int]).iterableFactory
23-
(null: i.Queue[Int]).iterableFactory
24-
(null: i.Seq[Int]).iterableFactory
25-
(null: i.Set[Int]).iterableFactory
2611
(null: i.Stack[Int]).iterableFactory
27-
(null: i.Stream[Int]).iterableFactory
28-
(null: i.Traversable[Int]).iterableFactory
29-
(null: i.Vector[Int]).iterableFactory
30-
31-
(null: m.ArrayBuffer[Int]).iterableFactory
32-
(null: m.ArraySeq[Int]).iterableFactory
33-
(null: m.ArrayStack[Int]).iterableFactory
34-
(null: m.Buffer[Int]).iterableFactory
3512
(null: m.DoubleLinkedList[Int]).iterableFactory
36-
(null: m.HashSet[Int]).iterableFactory
37-
(null: m.IndexedSeq[Int]).iterableFactory
38-
(null: m.Iterable[Int]).iterableFactory
39-
(null: m.LinearSeq[Int]).iterableFactory
40-
(null: m.LinkedHashSet[Int]).iterableFactory
4113
(null: m.LinkedList[Int]).iterableFactory
4214
(null: m.MutableList[Int]).iterableFactory
43-
(null: m.Queue[Int]).iterableFactory
4415
(null: m.ResizableArray[Int]).iterableFactory
45-
(null: m.Seq[Int]).iterableFactory
46-
(null: m.Set[Int]).iterableFactory
47-
(null: m.Traversable[Int]).iterableFactory
4816
}

scalafix/rules/src/main/scala/fix/Stable212Base.scala

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
3131
val foldLeftSymbol = foldSymbol(isLeft = true)
3232
val foldRightSymbol = foldSymbol(isLeft = false)
3333

34-
val iterator = normalized("_root_.scala.collection.TraversableLike.toIterator.")
34+
3535
val toTpe = normalized(
3636
"_root_.scala.collection.TraversableLike.to.",
3737
"_root_.scala.collection.TraversableOnce.to.",
@@ -73,10 +73,9 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
7373
"_root_.scala.collection.immutable.TreeSet#until(Ljava/lang/Object;)Lscala/collection/immutable/TreeSet;."
7474
)
7575

76-
val traversable = exact(
77-
"_root_.scala.collection.Traversable#",
76+
val `TraversableLike.toIterator` = normalized("_root_.scala.collection.TraversableLike.toIterator.")
77+
val traversableOnce = exact(
7878
"_root_.scala.collection.TraversableOnce#",
79-
"_root_.scala.package.Traversable#",
8079
"_root_.scala.package.TraversableOnce#"
8180
)
8281

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

102-
def replaceSymbols0(ctx: RuleCtx): Patch = {
101+
def replaceTraversable(ctx: RuleCtx): Patch = {
102+
103+
val traversableIterator =
104+
ctx.tree.collect {
105+
case `TraversableLike.toIterator`(t: Name) =>
106+
ctx.replaceTree(t, "iterator")
107+
}.asPatch
108+
103109
val traversableToIterable =
104110
ctx.replaceSymbols(
105-
"scala.Traversable" -> "scala.Iterable",
106-
"scala.collection.Traversable" -> "scala.collection.Iterable",
107-
"scala.TraversableOnce" -> "scala.IterableOnce",
108-
"scala.collection.TraversableOnce" -> "scala.collection.IterableOnce"
111+
"scala.Traversable" -> "scala.Iterable",
112+
"scala.collection.Traversable" -> "scala.collection.Iterable",
113+
"scala.collection.immutable.Traversable" -> "scala.collection.immutable.Iterable",
114+
"scala.collection.mutable.Traversable" -> "scala.collection.mutable.Iterable",
109115
)
110116

111-
import scala.meta.contrib._
112-
val hasTraversable =
113-
ctx.tree.exists {
114-
case traversable(_) => true
115-
case _ => false
117+
val traversableOnceToIterableOnce =
118+
ctx.tree.collect {
119+
case Type.Apply(sel @ Type.Select(chain, traversableOnce(n: Name)), _) =>
120+
val dot = chain.tokens.toList.reverse.drop(1)
121+
122+
ctx.removeTokens(chain.tokens) +
123+
ctx.removeTokens(dot) +
124+
ctx.replaceTree(sel, "IterableOnce")
116125

117-
}
126+
case Type.Apply(traversableOnce(n: Name), _) =>
127+
ctx.replaceTree(n, "IterableOnce")
128+
129+
130+
}.asPatch
118131

119132
val compatImport =
120-
if (hasTraversable) addCompatImport(ctx)
133+
if (traversableOnceToIterableOnce.nonEmpty || traversableIterator.nonEmpty) addCompatImport(ctx)
121134
else Patch.empty
122135

123-
traversableToIterable + compatImport
136+
traversableOnceToIterableOnce + traversableToIterable + traversableIterator + compatImport
124137
}
125138

126139
def replaceSymbolicFold(ctx: RuleCtx): Patch = {
@@ -251,14 +264,8 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
251264
}
252265
}
253266

254-
def replaceToList(ctx: RuleCtx): Patch = {
255-
val replaceToIterator =
256-
ctx.tree.collect {
257-
case iterator(t: Name) =>
258-
ctx.replaceTree(t, "iterator")
259-
}.asPatch
260-
261-
val replaceTo =
267+
def replaceTo(ctx: RuleCtx): Patch = {
268+
val patch =
262269
ctx.tree.collect {
263270
case Term.ApplyType(Term.Select(_, t @ toTpe(n: Name)), _) if !handledTo.contains(n) =>
264271
trailingBrackets(n, ctx).map { case (open, close) =>
@@ -286,10 +293,10 @@ trait Stable212Base extends CrossCompatibility { self: SemanticRule =>
286293
}.asPatch
287294

288295
val compatImport =
289-
if (replaceTo.nonEmpty) addCompatImport(ctx)
296+
if (patch.nonEmpty) addCompatImport(ctx)
290297
else Patch.empty
291298

292-
compatImport + replaceToIterator + replaceTo
299+
compatImport + patch
293300
}
294301

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

568575
override def fix(ctx: RuleCtx): Patch = {
569-
replaceSymbols0(ctx) +
576+
replaceTraversable(ctx) +
570577
replaceCanBuildFrom(ctx) +
571-
replaceToList(ctx) +
578+
replaceTo(ctx) +
572579
replaceCopyToBuffer(ctx) +
573580
replaceSymbolicFold(ctx) +
574581
replaceSetMapPlus2(ctx) +

0 commit comments

Comments
 (0)