Skip to content

Commit 864b71d

Browse files
authored
Merge pull request #15 from julienrf/add-scalafix
Move migration rules here
2 parents 6e954b2 + 00cbc8f commit 864b71d

15 files changed

+423
-2
lines changed

CONTRIBUTING.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Contributing
2+
3+
## Build
4+
5+
### Sbt Projects
6+
7+
- `scala-collection-compat` project (in the root directory): implementation of the compatibility library ;
8+
- In directory `scalafix/` there is an independent build containing the implementation of the migration tool.
9+
10+
## Migration tool
11+
12+
Several levels of contribution are possible!
13+
14+
### Report a missing case
15+
16+
Create an issue tagged with the
17+
[migration](https://github.com/scala/collection-strawman/labels/migration) label.
18+
Embrace `diff`s to describe differences between the standard collections and
19+
the strawman:
20+
21+
~~~ diff
22+
- xs.toIterator
23+
+ xs.iterator()
24+
~~~
25+
26+
### Add a missing test case
27+
28+
Even better, instead of providing a diff, you can directly add it as a test case!
29+
30+
1. Fork this repository and create a separate branch;
31+
32+
2. Add a file in the `scalafix/input/src/main/scala/fix/` directory with code
33+
that uses the standard collections:
34+
35+
~~~ scala
36+
class toIteratorVsIterator(xs: Iterable[Int]) {
37+
xs.toIterator
38+
}
39+
~~~
40+
41+
3. Add a corresponding file in the `scalafix/output/src/main/scala/fix/` directory
42+
with the same code but using the strawman:
43+
44+
~~~ scala
45+
import strawman.collection.Iterable
46+
47+
class toIteratorVsIterator(xs: Iterable[Int]) {
48+
xs.iterator()
49+
}
50+
~~~
51+
52+
4. Check that your code example compiles
53+
- run sbt from the `scalafix/` directory
54+
and then run the following tasks `; input/compile ; output/compile`;
55+
56+
5. Commit your changes, push your branch to your fork and create a pull request.
57+
58+
Then maybe someone will take over and implement your use case… or maybe you will
59+
(see next section)!
60+
61+
### Implement a missing case
62+
63+
Even better, complete the migration tool implementation to support the missing case!
64+
65+
After you have added the missing case (see previous section), run the following
66+
sbt task (with sbt started from the `scalafix/` directory) to run the
67+
migration tool on the input files and check whether the result matches the
68+
expected output files:
69+
70+
~~~
71+
> tests/test
72+
~~~
73+
74+
Fix the implementation of the rule (in the
75+
`rules/src/main/scala/fix/Scalacollectioncompat_v0.scala` file) until the
76+
tests are green. You can find more help about the scalafix API in its
77+
[documentation](https://scalacenter.github.io/scalafix/docs/rule-authors/setup).

README.md

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
[![Build Status](https://travis-ci.org/scala/scala-collection-compat.svg?branch=master)](https://travis-ci.org/scala/scala-collection-compat)
22

3-
Scala 2.13 Collection Compatibility Library
4-
===========================================
3+
Scala 2.13 Collection Compatibility Library And Migration Tool
4+
==============================================================
5+
6+
## Compatibility Library
57

68
This library for Scala 2.12 provides limited compatibility with the new collection library in 2.13. We try to keep the
79
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
2426
empty `scala.collection.compat` package object that allows you to write `import scala.collection.compat._` in 2.13.
2527
The 2.13 version has the compatibility extensions in this package. It also adds backported version of some new collection
2628
types to other `scala.collection` subpackages.
29+
30+
## Migration Tool
31+
32+
A tool is being developed to automatically migrate code that uses the standard
33+
collection to use the strawman.
34+
35+
To use it, add the [scalafix](https://scalacenter.github.io/scalafix/) sbt plugin
36+
to your build, as explained in
37+
[its documentation](https://scalacenter.github.io/scalafix/#Installation).
38+
39+
The migration tool is not exhaustive and we will continue to improve
40+
it over time. If you encounter a use case that’s not supported, please
41+
report it as described in the
42+
[contributing documentation](CONTRIBUTING.md#migration-tool).
43+
44+
### Migrating a 2.12 code base to 2.13
45+
46+
Run the following sbt task on your project:
47+
48+
~~~
49+
> scalafix github:scala/scala-collection-compat/v0
50+
~~~

scalafix/build.sbt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
def scalafixVersion = _root_.scalafix.Versions.version
2+
inScope(Global)(
3+
List(
4+
scalaVersion := _root_.scalafix.Versions.scala212
5+
)
6+
)
7+
8+
lazy val root = project
9+
.in(file("."))
10+
.aggregate(
11+
rules, input, output, tests
12+
)
13+
14+
lazy val rules = project.settings(
15+
libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % scalafixVersion
16+
)
17+
18+
lazy val input = project
19+
.settings(
20+
scalafixSourceroot := sourceDirectory.in(Compile).value
21+
)
22+
23+
lazy val output = project
24+
.settings(
25+
resolvers += "scala-pr" at "https://scala-ci.typesafe.com/artifactory/scala-integration/",
26+
scalaVersion := "2.13.0-M4-pre-20d3c21"
27+
)
28+
29+
lazy val tests = project
30+
.settings(
31+
libraryDependencies += "ch.epfl.scala" % "scalafix-testkit" % scalafixVersion % Test cross CrossVersion.full,
32+
buildInfoPackage := "fix",
33+
buildInfoKeys := Seq[BuildInfoKey](
34+
"inputSourceroot" ->
35+
sourceDirectory.in(input, Compile).value,
36+
"outputSourceroot" ->
37+
sourceDirectory.in(output, Compile).value,
38+
"inputClassdirectory" ->
39+
classDirectory.in(input, Compile).value
40+
)
41+
)
42+
.dependsOn(input, rules)
43+
.enablePlugins(BuildInfoPlugin)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
rule = "scala:fix.Collectionstrawman_v0"
3+
*/
4+
package fix
5+
6+
object Collectionstrawman_v0_Stream {
7+
val s = Stream(1, 2, 3)
8+
s.append(List(4, 5, 6))
9+
1 #:: 2 #:: 3 #:: Stream.Empty
10+
val isEmpty: Stream[_] => Boolean = {
11+
case Stream.Empty => true
12+
case x #:: xs => false
13+
}
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
rule = "scala:fix.Collectionstrawman_v0"
3+
*/
4+
package fix
5+
6+
object Collectionstrawman_v0_Traversable {
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+
}
13+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
rule = "scala:fix.Collectionstrawman_v0"
3+
*/
4+
package fix
5+
6+
import scala.language.postfixOps
7+
object Collectionstrawman_v0_Tuple2Zipped {
8+
def zipped(xs: List[Int], ys: List[Int]): Unit = {
9+
(xs, ys).zipped
10+
(xs,ys).zipped
11+
((xs, ys) zipped)
12+
(((xs) , (ys)).zipped)
13+
(xs, // foo
14+
ys).zipped
15+
/* a */(/* b */ xs /* c */, /* d */ ys /* e */)/* f */./* g */zipped/* h */
16+
(coll(1), coll(2)).zipped
17+
(List(1, 2, 3), Stream.from(1)).zipped
18+
}
19+
def coll(x: Int): List[Int] = ???
20+
}
21+
22+
object Collectionstrawman_v0_Tuple3Zipped {
23+
def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = {
24+
(xs, ys, zs).zipped
25+
(xs,ys,zs).zipped
26+
((xs, ys, zs) zipped)
27+
(((xs) , (ys) , (zs)).zipped)
28+
(xs, // foo
29+
ys, // bar
30+
zs).zipped
31+
/* a */(/* b */ xs /* c */, /* d */ ys /* e */, /* f */ zs /* g */)/* h */./* i */zipped/* j */
32+
(coll(1), coll(2), coll(3)).zipped
33+
(List(1, 2, 3), Set(1, 2, 3), Stream.from(1)).zipped
34+
}
35+
def coll(x: Int): List[Int] = ???
36+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
rule = "scala:fix.Collectionstrawman_v0"
3+
*/
4+
package fix
5+
6+
import scala.collection.mutable
7+
8+
class Collectionstrawman_v0_copyToBuffer(xs: List[Int], b: mutable.Buffer[Int]) {
9+
10+
xs.copyToBuffer(b)
11+
(xs ++ xs).copyToBuffer(b)
12+
13+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package fix
2+
3+
object Collectionstrawman_v0_Stream {
4+
val s = LazyList(1, 2, 3)
5+
s.lazyAppendAll(List(4, 5, 6))
6+
1 #:: 2 #:: 3 #:: LazyList.Empty
7+
val isEmpty: LazyList[_] => Boolean = {
8+
case LazyList.Empty => true
9+
case x #:: xs => false
10+
}
11+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package fix
2+
3+
object Collectionstrawman_v0_Traversable {
4+
def foo(xs: Iterable[(Int, String)], ys: List[Int]): Unit = {
5+
xs.to(List)
6+
xs.to(Set)
7+
xs.iterator()
8+
ys.iterator()
9+
}
10+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package fix
2+
3+
import scala.language.postfixOps
4+
object Collectionstrawman_v0_Tuple2Zipped {
5+
def zipped(xs: List[Int], ys: List[Int]): Unit = {
6+
xs.lazyZip(ys)
7+
xs.lazyZip(ys)
8+
(xs.lazyZip(ys) )
9+
((xs).lazyZip((ys)))
10+
xs.lazyZip(// foo
11+
ys)
12+
/* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */)/* f *//* g *//* h */
13+
coll(1).lazyZip(coll(2))
14+
List(1, 2, 3).lazyZip(LazyList.from(1))
15+
}
16+
def coll(x: Int): List[Int] = ???
17+
}
18+
19+
object Collectionstrawman_v0_Tuple3Zipped {
20+
def zipped(xs: List[Int], ys: List[Int], zs: List[Int]): Unit = {
21+
xs.lazyZip(ys).lazyZip(zs)
22+
xs.lazyZip(ys).lazyZip(zs)
23+
(xs.lazyZip(ys).lazyZip(zs) )
24+
((xs).lazyZip((ys)).lazyZip((zs)))
25+
xs.lazyZip(// foo
26+
ys).lazyZip(// bar
27+
zs)
28+
/* a *//* b */ xs /* c */.lazyZip(/* d */ ys /* e */).lazyZip(/* f */ zs /* g */)/* h *//* i *//* j */
29+
coll(1).lazyZip(coll(2)).lazyZip(coll(3))
30+
List(1, 2, 3).lazyZip(Set(1, 2, 3)).lazyZip(LazyList.from(1))
31+
}
32+
def coll(x: Int): List[Int] = ???
33+
}

0 commit comments

Comments
 (0)