Skip to content

Commit cab6275

Browse files
committed
Write blog post about scalafix and scala.meta semantic api
1 parent 1e96e8d commit cab6275

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Refactor with scalafix
2+
3+
We are happy to announce the release of [scalafix v0.3][scalafix].
4+
This release introduces a new `Rewrite` and `Patch` API powered by the [scala.meta semantic API][meta-1.6].
5+
We are excited about this release because we believe it enables a number promising tooling applications.
6+
7+
This first release of the scala.meta semantic API enables rewrites to query for the "symbol" of a name that appears in a Scala source file.
8+
A symbol is a unique identifier of a definition such as a class, val, def or trait.
9+
This ability to query for symbols opens possibilities for a great number of refactorings including imports management and identifier renaming.
10+
To demonstrate what rewrites can be implemented with scalafix v0.3, let's take one example.
11+
12+
## Example: Xor to Either
13+
14+
The functional programming library [cats][cats] migrated recently from its `Xor` data type to `Either` from the standard library.
15+
It requires a few mechanical steps to migrate code to use `Either` instead of `Xor`.
16+
For example, below is a diff that's taken from [circe][xor-cire]'s migration to `Either`.
17+
18+
```diff
19+
- final def either: Xor[HCursor, HCursor] = if (succeeded) Xor.right(any) else Xor.left(any)
20+
+ final def either: Either[HCursor, HCursor] = if (succeeded) Right(any) else Left(any)
21+
```
22+
23+
Scalafix rewrites are composed of so-called "patches".
24+
A patch describes a single refactoring operation.
25+
`Replace` is one patch that can be used to rename identifiers
26+
27+
```scala
28+
Replace(Symbol("_root_.cats.data.Xor."), q"Either")
29+
Replace(Symbol("_root_.cats.data.Xor.Left."), q"Left")
30+
Replace(Symbol("_root_.cats.data.Xor.Right."), q"Right")
31+
```
32+
33+
To introduce new imports on renmae, it's possible to pass in `additionalImports`
34+
```scala
35+
Replace(Symbol("_root_.cats.data.XorT."), q"EitherT",
36+
additionalImports = List(importer"cats.data.EitherT")),
37+
```
38+
39+
Imports can be removed with the `RemoveGlobalImport` patch
40+
41+
```scala
42+
RemoveGlobalImport(importer"cats.data.Xor")
43+
```
44+
Nothing happens if the import does not appear in the source file.
45+
Likewise, it's OK to add the same import twice, scalafix will de-duplicate it.
46+
47+
The full `Xor` to `Either` scalafix rewrite can be found [here][xor2either] and its accompanying test
48+
suite [here][xor2either-test].
49+
50+
To learn more about how to start with scalafix, visit the [installation docs][install]!
51+
52+
## Cross-building
53+
54+
TODO: Shane
55+
56+
## Custom rewrites
57+
You can write your own custom rewrites.
58+
59+
[xor2either-test]: https://github.com/scalacenter/scalafix/blob/f61136fad79afcdbb03528ce78c7928afc6eafd6/scalafix-nsc/src/test/resources/syntactic/Xor2Either.source
60+
[xor2either]: https://github.com/scalacenter/scalafix/blob/f61136fad79afcdbb03528ce78c7928afc6eafd6/core/src/main/scala/scalafix/rewrite/Xor2Either.scala
61+
[xor-circe]: https://github.com/circe/circe/pull/343/files
62+
[cats]: http://github.com/typelevel/cats
63+
[ghpages]: http://github.com/scalacenter/scalafix
64+
[prevpost]: http://scala-lang.org/blog/2016/10/24/scalafix.html
65+
[scalafix]: https://scalacenter.github.io/scalafix/#0.3.0
66+
[install]: https://scalacenter.github.io/scalafix/#Installation
67+
[meta-1.6]: https://github.com/scalameta/scalameta/blob/master/changelog/1.6.0.md#semantic-api

0 commit comments

Comments
 (0)