Skip to content

Scalafix v0.9.0

Compare
Choose a tag to compare
@olafurpg olafurpg released this 01 Oct 11:19
18650f5

We are excited to announce the release of Scalafix v0.9.0. Scalafix is a refactoring and linting tool for Scala.

This release includes improvements to documentation, the sbt plugin, better semantic APIs, improved support for custom rules and more.

This release has been under development since January 2018 and includes contributions from 19 contributors. Big thanks to everybody who made it possible!

Documentation 📖

Scalafix has a new website https://scalacenter.github.io/scalafix/

Scalameta v4.0 🔥

The Scalameta dependency has been upgraded to the newly released v4.0.0

New Semantic API 🧙

Semantic rules can now perform more advanced code analysis thanks to improvements in the semantic API:

  • Rules can look up symbol information for any symbol on the classpath, including dependencies. Previously, Scalafix only supported looking up information about symbols that were defined in the project.
  • The SymbolInformation data structure (previously named Denotation) now includes richer information about the symbol's signature, annotations and visibility access.
  • Rules can inspect the SemanticType, which is a sealed data structure describing the type of variables and parameters. Previously, value signatures were represented as strings making them difficult to analyze.
  • Rules can inspect SemanticTree, which is a sealed data structure describing synthetic code that is generated by the compiler from inferred type parameters, implicit arguments, implicit conversions and for comprehensions. Previously, synthetics were encoded as strings making them difficult to analyze.

The new Scalafix semantic API was made possible thanks to recent improvements in SemanticDB.

Improved sbt plugin 🛠

The sbt plugin has been overhauled to address issues with the previous plugin that were reported by our users. The new sbt plugin integrates directly with Scalafix library APIs resulting in an overall more polished user experience.

  • The old scalafix, scalafixTest and scalafixCli tasks have been merged into a single task: scalafix.
    • scalafixTest is now scalafix --check
    • scalafix continues to work as before
    • scalafixCli is no longer needed since scalafix accepts cli flags
  • New scalafixDependencies setting key to install custom rules from Maven Central.
  • Common build mis-configuration such as missing compiler options are reported by Scalafix before compilation starts helping users detect problems as soon as possible.
  • Syntactic rules no longer trigger compilation significantly speeding up usage if you only use syntactic rules.

Check out the installation instructions to learn more how to use the sbt plugin.

Performance 🚀

This release improves the performance of the Scalafix command-line interface and the sbt plugin. A user reported speedups from 65 minutes down to to 2 minutes when running rewrites on a large codebase after upgrading from the previous release.

New build tools API 🔧

There is now an official public API to programmatically invoke Scalafix from build tools or IDEs. The API is available in the module scalafix-interfaces and it's written in Java with zero dependencies weighing a total of 12kb. The API is designed to have a stable binary interface across future releases of Scalafix. This API is used by the new sbt plugin, and is available to users who would like to integrate Scalafix with other build tools like Maven, Gradle.

To learn more about the build tools API, consult the scalafix-interfaces Javadocs.

Breaking changes ⚠️

For end users

  • The v0.5.x API for rules has moved from the scalafix package into scalafix.v0. The scalafix.v0 package will be removed when Scalafix v1.0 is released in the future.
  • The rules Disable and MissingFinal have moved to a separate project https://github.com/vovapolu/scaluzzi
  • The rule ExplicitResultTypes has been removed since it produced incorrect code.
  • The rules DottyKeywords, DottyVarArgPattern and DottyVolatileLazyVal have been removed. Scala 3 migration rewrites will be published as a separate project so that they can evolve at a different pace than the Scalafix core APIs.
  • The sbtfix task in the sbt plugin has been removed, use scalafix --files build.sbt --files project instead.

For tooling integrations

  • The command-line interface requires the --classpath argument to include a full classpath, including dependencies. Dependencies do not have to be compiled with the SemanticDB compiler plugin but sources that Scalafix should analyze must be compiled with SemanticDB.
  • The command-line interface has a new --scalac-options flag to document what compiler options were used to compile the sources. This is required by rules like RemoveUnused to validate the -Ywarn-unused-import is enabled and in the future also to ensure that Scalafix respects SemanticDB options like -P:semanticdb:targetroot and -P:semanticdb:exclude.

For rule authors

Before Now
import scalafix._ import scalafix.v0._
import org.langmeta._ import scala.meta._
import scala.meta.Database import scalafix.v0.Database
import scala.meta.Document import scalafix.v0.Document
import scala.meta.Symbol import scalafix.v0.Symbol
import scala.meta.Denotation import scalafix.v0.Denotation
import scala.meta.ResolvedName import scalafix.v0.ResolvedName
import scala.meta.ResolvedSymbol import scalafix.v0.ResolvedSymbol
import scala.meta.Synthetic import scalafix.v0.Synthetic

It is recommended to migrate rules to use the new scalafix.v1 API, which imposes further changes from scalafix.v0:

v0 v1
object MyRule extends v0.Rule("MyRule")
class MyRule extends v1.SyntacticRule("MyRule")
case class MyRule(index: SemanticdbIndex) extends v0.SemanticRule(index, "MyRule")
class MyRule extends v1.SemanticRule("MyRule")
override def init(conf: metaconfig.Conf): Configured[v0.Rule]
override def withConfiguration(conf: scalafix.v1.Configuration): Configured[v1.Rule]
override def fix(ctx: v0.RuleCtx): Patch
// for syntactic rules
override def fix(implicit doc: v1.SyntacticDoc): Patch
// for semantic rules
override def fix(implicit doc: v1.SemanticDoc): Patch
// Patch operations where `ctx: v0.RuleCtx`
ctx.addRight()
ctx.replaceTree()
ctx.removeImportee()
Patch.addRight()
Patch.replaceTree()
Patch.removeImportee()

Additionally, v1 rules are now loaded using JDK ServiceLoader. To make a custom rule discoverable to Scalafix, create a resource file META-INF/services/scalafix.v1.Rule with the fully qualified name of your rule

// resource file META-INF/services/scalafix.v1.Rule
fully.qualified.MyRule

Contributors ❤️

Big thanks to all 19 contributors who made this release possible

$ git shortlog -sn --no-merges v0.5.10..HEAD
Ólafur Páll Geirsson
vovapolu
Marcelo Cenerino
Guillaume Massé
tanishiking24
Sam Halliday
Eugene Burmako
Shane Delmore
Sean Sullivan
Piotr Galar
Sergii Kyryliuk
Øyvind Raddum Berg
Jimin Hsieh
Per Øyvind Kanestrøm
nicodelpiano
Joan Goyeau
Gabriele Petronella
Eugene Yokota
Andrew Valencik