forked from com-lihaoyi/mill
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ErrorProne plugin (com-lihaoyi#3460)
This adds a new `ErrorProne` plugin to the `contrib` section of Mill. It provides the `ErrorProneModule` `trait`, which can be mixed into `JavaModule`s. Derived modules like `ScalaModule` are also supported, as long as they support the `javacOptions` task to configure the Java compiler. We use the [Error Prone](https://errorprone.info/index) project as a compiler plugin. Although this is a simple javac compiler plugin, it's usage isn't trivial. Fetching the correct classpath and supplying options can be tricky, since they need to be provided in a special form. Also using with JVMs starting from version 16 requires special options handling due to the new more restrictive module classpath. This plugin is handling all of the known issues and make its use easy for the user. Additional configuration options are supported via the `errorProneOptions` target. Here is a usage example: ```scala package build import mill._, javalib._ import mill.contrib.errorprone._ import $ivy.`com.lihaoyi::mill-contrib-errorprone:` object `package` extends RootModule with JavaModule with ErrorProneModule { def errorProneOptions = Seq("-XepAllErrorsAsWarnings") } ``` Fix com-lihaoyi#3447 Pull request: com-lihaoyi#3460 --------- Co-authored-by: Li Haoyi <[email protected]>
- Loading branch information
Showing
11 changed files
with
252 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
= Mill ErrorProne Plugin | ||
:page-aliases: Plugin_ErrorProne.adoc | ||
|
||
https://errorprone.info/index[Error Prone] augments the Java compiler's type checker and detect common mistakes at compile time. | ||
|
||
You just need to mix the `ErrorProneModule` into your `JavaModule` and it will automatically run with every compilation. | ||
|
||
.`build.mill.sc`: Enable `ErrorProne` in a module | ||
[source,scala] | ||
---- | ||
package build | ||
import mill._, scalalib._ | ||
import $ivy.`com.lihaoyi::mill-contrib-errorprone:` | ||
import mill.contrib.errorprone.ErrorProneModule | ||
object foo extends JavaModule with ErrorProneModule { | ||
} | ||
---- | ||
|
||
== Configuration | ||
|
||
The following configuration options exist: | ||
|
||
`def errorProneVersion: T[String]`:: | ||
The `error-prone` version to use. Defaults to [[BuildInfo.errorProneVersion]], the version used to build and test the module. | ||
Find the latest at https://mvnrepository.com/artifact/com.google.errorprone/error_prone_core[mvnrepository.com] | ||
|
||
`def errorProneOptions: T[Seq[String]]`:: | ||
Options directly given to the `error-prone` processor. | ||
Those are documented as "flags" at https://errorprone.info/docs/flags |
81 changes: 81 additions & 0 deletions
81
contrib/errorprone/src/mill/contrib/errorprone/ErrorProneModule.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package mill.contrib.errorprone | ||
|
||
import mill.api.PathRef | ||
import mill.{Agg, T} | ||
import mill.scalalib.{Dep, DepSyntax, JavaModule} | ||
|
||
import java.io.File | ||
|
||
/** | ||
* Integrated Error Prone into a [[JavaModule]]. | ||
* | ||
* See https://errorprone.info/index | ||
*/ | ||
trait ErrorProneModule extends JavaModule { | ||
|
||
/** The `error-prone` version to use. Defaults to [[BuildInfo.errorProneVersion]]. */ | ||
def errorProneVersion: T[String] = T.input { | ||
BuildInfo.errorProneVersion | ||
} | ||
|
||
/** | ||
* The dependencies of the `error-prone` compiler plugin. | ||
*/ | ||
def errorProneDeps: T[Agg[Dep]] = T { | ||
Agg( | ||
ivy"com.google.errorprone:error_prone_core:${errorProneVersion()}" | ||
) | ||
} | ||
|
||
/** | ||
* The classpath of the `error-prone` compiler plugin. | ||
*/ | ||
def errorProneClasspath: T[Agg[PathRef]] = T { | ||
resolveDeps(T.task { errorProneDeps().map(bindDependency()) })() | ||
} | ||
|
||
/** | ||
* Options used to enable and configure the `eror-prone` plugin in the Java compiler. | ||
*/ | ||
def errorProneJavacEnableOptions: T[Seq[String]] = T { | ||
val processorPath = errorProneClasspath().map(_.path).mkString(File.pathSeparator) | ||
val enableOpts = Seq( | ||
"-XDcompilePolicy=simple", | ||
"-processorpath", | ||
processorPath, | ||
(Seq("-Xplugin:ErrorProne") ++ errorProneOptions()).mkString(" ") | ||
) | ||
val java17Options = Option.when(scala.util.Properties.isJavaAtLeast(16))(Seq( | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED", | ||
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED", | ||
"--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED", | ||
"--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED" | ||
).map(o => s"-J${o}")).toSeq.flatten | ||
java17Options ++ enableOpts | ||
} | ||
|
||
/** | ||
* Options directly given to the `error-prone` processor. | ||
* | ||
* Those are documented as "flags" at https://errorprone.info/docs/flags | ||
*/ | ||
def errorProneOptions: T[Seq[String]] = T { Seq.empty[String] } | ||
|
||
/** | ||
* Appends the [[errorProneJavacEnableOptions]] to the Java compiler options. | ||
*/ | ||
override def javacOptions: T[Seq[String]] = T { | ||
val supOpts = super.javacOptions() | ||
val enableOpts = Option | ||
.when(!supOpts.exists(o => o.startsWith("-Xplugin:ErrorProne")))( | ||
errorProneJavacEnableOptions() | ||
) | ||
supOpts ++ enableOpts.toSeq.flatten | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
contrib/errorprone/test/resources/simple/src/ShortSet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package simple.src; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
public class ShortSet { | ||
public static void main (String[] args) { | ||
Set<Short> s = new HashSet<>(); | ||
for (short i = 0; i < 100; i++) { | ||
s.add(i); | ||
s.remove(i - 1); | ||
} | ||
System.out.println(s.size()); | ||
} | ||
} | ||
|
44 changes: 44 additions & 0 deletions
44
contrib/errorprone/test/src/mill/contrib/errorprone/ErrorProneTests.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package mill.contrib.errorprone | ||
|
||
import mill.T | ||
import mill.scalalib.JavaModule | ||
import mill.testkit.{TestBaseModule, UnitTester} | ||
import os.Path | ||
import utest._ | ||
|
||
object ErrorProneTests extends TestSuite { | ||
|
||
object noErrorProne extends TestBaseModule with JavaModule {} | ||
object errorProne extends TestBaseModule with JavaModule with ErrorProneModule {} | ||
object errorProneCustom extends TestBaseModule with JavaModule with ErrorProneModule { | ||
override def errorProneOptions: T[Seq[String]] = T(Seq( | ||
"-XepAllErrorsAsWarnings" | ||
)) | ||
} | ||
|
||
val testModuleSourcesPath: Path = os.Path(sys.env("MILL_TEST_RESOURCE_FOLDER")) / "simple" | ||
|
||
def tests = Tests { | ||
test("reference") { | ||
test("compile") { | ||
val eval = UnitTester(noErrorProne, testModuleSourcesPath) | ||
val res = eval(noErrorProne.compile) | ||
assert(res.isRight) | ||
} | ||
} | ||
test("errorprone") { | ||
test("compileFail") { | ||
val eval = UnitTester(errorProne, testModuleSourcesPath) | ||
val res = eval(errorProne.compile) | ||
assert(res.isLeft) | ||
} | ||
test("compileWarn") { | ||
val eval = UnitTester(errorProneCustom, testModuleSourcesPath, debugEnabled = true) | ||
val Right(opts) = eval(errorProneCustom.javacOptions) | ||
assert(opts.value.exists(_.contains("-XepAllErrorsAsWarnings"))) | ||
val res = eval(errorProneCustom.compile) | ||
assert(res.isRight) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// When adding the `ErrorPromeModule` to your `JavaModule`, | ||
// the `error-prone` compiler plugin automatically detects various kind of programming errors. | ||
|
||
package build | ||
import mill._, javalib._ | ||
import mill.contrib.errorprone._ | ||
|
||
import $ivy.`com.lihaoyi::mill-contrib-errorprone:` | ||
|
||
object `package` extends RootModule with JavaModule with ErrorProneModule { | ||
def errorProneOptions = Seq("-XepAllErrorsAsWarnings") | ||
} | ||
|
||
/** See Also: src/example/ShortSet.java */ | ||
|
||
/** Usage | ||
|
||
> ./mill show errorProneOptions | ||
[ | ||
"-XepAllErrorsAsWarnings" | ||
] | ||
|
||
> ./mill compile | ||
[warn] .../src/example/ShortSet.java:11:15: [CollectionIncompatibleType] Argument 'i - 1' should not be passed to this method; its type int is not compatible with its collection's type argument Short | ||
[warn] s.remove(i - 1); | ||
[warn] ^ (see https://errorprone.info/bugpattern/CollectionIncompatibleType) | ||
[warn] 1 warning | ||
[warn] ^ | ||
*/ | ||
|
||
|
16 changes: 16 additions & 0 deletions
16
example/javalib/module/14-error-prone/src/example/ShortSet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package example; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
public class ShortSet { | ||
public static void main (String[] args) { | ||
Set<Short> s = new HashSet<>(); | ||
for (short i = 0; i < 100; i++) { | ||
s.add(i); | ||
s.remove(i - 1); | ||
} | ||
System.out.println(s.size()); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters