Using Scala Compiler Plugins From Gradle
The Scala compiler like just about every other modern programming language compiler has a plugin/extensibility story. It universally accepted that sbt is the default build tool for Scala. So users of sbt benefit from sbt’s first class support of Scala compiler plugins.
For those of us who choose (or are forced to use) other build tools, life is a little more difficult. It is more likely than not, that the ReadMe of your favorite compiler plugin does not include instructions on how to use the plugin outside of sbt. Alas, all hope is not gone. Repeat after me, “Yes we can!” You too can join in with the cool kids, and use compiler plugins.
NewType
The scalamacro.paradise
plugin is a fairly popular plugin that many other plugins leverage. In this post, we are going to use macro paradise to enable scala-newtype
macro expansion. The scala-newtype
package includes a @newtype
annotation that leverages scalamacro.paradise
to allow you to generate new types that map to a wrapped type with zero runtime overhead.
import io.estatico.newtype.macros.newtype
package object types {
@newtype case class OrderId(value: String)
}
This is similar to the newtype
keyword in Haskell, from which the library derives its name.
-- Haskell newtype examplenewtype OrderId = OrderId String
The scala-newtype
package/library is also very similar to theopaque type alias
feature which is coming in Scala 3.0.
//Scala 3.0 / Dotty opaque typeopaque type OrderId = String
Gradle Paradise
I’m going to outline how you would go about enabling macro-paradise
so you can use newtype
in all its glory.
First, lets add a custom configuration to our gradle file.
We can achieve this by simply adding the following:
configurations {
scalaCompilerPlugin
}
With that configuration in place, we can now add the macro paradise compiler plugin.
dependencies {
...
compile 'org.scala-lang:scala-library:2.12.6'
compile 'io.estatico:newtype_2.12:0.4.2'
scalaCompilerPlugin 'org.scalamacros:paradise_2.12.6:2.1.1'
...
}
At this point you should have something that looks like below:
Okay, we now have the plugin available, but that’s not enough. Now we need to make the Scala compiler aware of the scalamacro.paradise
plugin by adding it to the scalaCompileOptions
of the ScalaCompile
task.
With this in place, you should now be able to use scala-newtype
in anger with successful macro generation.
Wrapping Up
Once done you should have a build.gradle file that looks something like below:
Though this post outlined adding the scalamacro.paradise
plugin, you can use this same procedure to include other Scala compiler plugins. Enjoy!
You can also take a look at the corresponding repository for this post on GitHub.