Add error-prone support
Add support for compiling java sources with the error-prone tool.
Test: m -j checkbuild
Change-Id: Ieb4ee0e05f8f34a52ed7bcf1c7cbacf1c9c4d0b5
diff --git a/java/builder.go b/java/builder.go
index efe0a6b..b7ff3ab 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -49,6 +49,25 @@
},
"javacFlags", "bootClasspath", "classpath", "outDir", "annoDir", "javaVersion")
+ errorprone = pctx.AndroidStaticRule("errorprone",
+ blueprint.RuleParams{
+ Command: `rm -rf "$outDir" "$annoDir" && mkdir -p "$outDir" "$annoDir" && ` +
+ `${config.ErrorProneCmd}` +
+ `$javacFlags $bootClasspath $classpath ` +
+ `-source $javaVersion -target $javaVersion ` +
+ `-d $outDir -s $annoDir @$out.rsp && ` +
+ `find $outDir -type f | sort | ${config.JarArgsCmd} $outDir > $out`,
+ CommandDeps: []string{
+ "${config.JavaCmd}",
+ "${config.ErrorProneJavacJar}",
+ "${config.ErrorProneJar}",
+ "${config.JarArgsCmd}",
+ },
+ Rspfile: "$out.rsp",
+ RspfileContent: "$in",
+ },
+ "javacFlags", "bootClasspath", "classpath", "outDir", "annoDir", "javaVersion")
+
jar = pctx.AndroidStaticRule("jar",
blueprint.RuleParams{
Command: `${config.JarCmd} $operation ${out}.tmp $manifest $jarArgs && ${config.Zip2ZipCmd} -t -i ${out}.tmp -o ${out} && rm ${out}.tmp`,
@@ -144,12 +163,41 @@
return jarSpec{classFileList}
}
+func RunErrorProne(ctx android.ModuleContext, srcFiles android.Paths, srcFileLists android.Paths,
+ flags javaBuilderFlags, deps android.Paths) android.Path {
+
+ classDir := android.PathForModuleOut(ctx, "classes-errorprone")
+ annoDir := android.PathForModuleOut(ctx, "anno-errorprone")
+ classFileList := android.PathForModuleOut(ctx, "classes-errorprone.list")
+
+ javacFlags := flags.javacFlags + android.JoinWithPrefix(srcFileLists.Strings(), "@")
+
+ deps = append(deps, srcFileLists...)
+
+ ctx.ModuleBuild(pctx, android.ModuleBuildParams{
+ Rule: errorprone,
+ Description: "errorprone",
+ Output: classFileList,
+ Inputs: srcFiles,
+ Implicits: deps,
+ Args: map[string]string{
+ "javacFlags": javacFlags,
+ "bootClasspath": flags.bootClasspath,
+ "classpath": flags.classpath,
+ "outDir": classDir.String(),
+ "annoDir": annoDir.String(),
+ "javaVersion": flags.javaVersion,
+ },
+ })
+
+ return classFileList
+}
+
func TransformClassesToJar(ctx android.ModuleContext, classes []jarSpec,
- manifest android.OptionalPath) android.Path {
+ manifest android.OptionalPath, deps android.Paths) android.Path {
outputFile := android.PathForModuleOut(ctx, "classes-full-debug.jar")
- deps := android.Paths{}
jarArgs := []string{}
for _, j := range classes {
diff --git a/java/config/errorprone.go b/java/config/errorprone.go
new file mode 100644
index 0000000..da9b775
--- /dev/null
+++ b/java/config/errorprone.go
@@ -0,0 +1,97 @@
+// Copyright 2017 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package config
+
+import (
+ "strings"
+)
+
+func init() {
+ pctx.SourcePathVariable("ErrorProneJavacJar", "external/error_prone/javac/javac-9-dev-r3297-4.jar")
+ pctx.SourcePathVariable("ErrorProneJar", "external/error_prone/error_prone/error_prone_core-2.0.19-with-dependencies.jar")
+ pctx.SourcePathsVariable("ErrorProneClasspath", ":",
+ "external/error_prone/error_prone/error_prone_annotations-2.0.19.jar",
+ "external/error_prone/checkerframework/dataflow-1.8.10.jar",
+ "external/error_prone/checkerframework/javacutil-1.8.10.jar",
+ "external/error_prone/jFormatString/jFormatString-3.0.0.jar")
+
+ // The checks that are fatal to the build.
+ pctx.StaticVariable("ErrorProneChecksError", strings.Join([]string{
+ "-Xep:AsyncCallableReturnsNull:ERROR",
+ "-Xep:AsyncFunctionReturnsNull:ERROR",
+ "-Xep:BundleDeserializationCast:ERROR",
+ "-Xep:CompatibleWithAnnotationMisuse:ERROR",
+ "-Xep:CompileTimeConstant:ERROR",
+ "-Xep:DaggerProvidesNull:ERROR",
+ "-Xep:DoNotCall:ERROR",
+ "-Xep:ForOverride:ERROR",
+ "-Xep:FunctionalInterfaceMethodChanged:ERROR",
+ "-Xep:FuturesGetCheckedIllegalExceptionType:ERROR",
+ "-Xep:GuiceAssistedInjectScoping:ERROR",
+ "-Xep:GuiceAssistedParameters:ERROR",
+ "-Xep:GuiceInjectOnFinalField:ERROR",
+ "-Xep:Immutable:ERROR",
+ "-Xep:ImmutableModification:ERROR",
+ "-Xep:IncompatibleArgumentType:ERROR",
+ "-Xep:IndexOfChar:ERROR",
+ "-Xep:InjectMoreThanOneScopeAnnotationOnClass:ERROR",
+ "-Xep:JavaxInjectOnAbstractMethod:ERROR",
+ "-Xep:JUnit4SetUpNotRun:ERROR",
+ "-Xep:JUnit4TearDownNotRun:ERROR",
+ "-Xep:JUnit4TestNotRun:ERROR",
+ "-Xep:JUnitAssertSameCheck:ERROR",
+ "-Xep:LiteByteStringUtf8:ERROR",
+ "-Xep:LoopConditionChecker:ERROR",
+ "-Xep:MockitoCast:ERROR",
+ "-Xep:MockitoUsage:ERROR",
+ "-Xep:MoreThanOneInjectableConstructor:ERROR",
+ "-Xep:MustBeClosedChecker:ERROR",
+ "-Xep:NonCanonicalStaticImport:ERROR",
+ "-Xep:NonFinalCompileTimeConstant:ERROR",
+ "-Xep:OptionalEquality:ERROR",
+ "-Xep:OverlappingQualifierAndScopeAnnotation:ERROR",
+ "-Xep:PackageInfo:ERROR",
+ "-Xep:PreconditionsCheckNotNull:ERROR",
+ "-Xep:PreconditionsCheckNotNullPrimitive:ERROR",
+ "-Xep:ProtoFieldNullComparison:ERROR",
+ "-Xep:ProvidesMethodOutsideOfModule:ERROR",
+ "-Xep:RestrictedApiChecker:ERROR",
+ "-Xep:SelfAssignment:ERROR",
+ "-Xep:StreamToString:ERROR",
+ "-Xep:SuppressWarningsDeprecated:ERROR",
+ "-Xep:ThrowIfUncheckedKnownChecked:ERROR",
+ "-Xep:ThrowNull:ERROR",
+ "-Xep:TypeParameterQualifier:ERROR",
+ "-Xep:UnnecessaryTypeArgument:ERROR",
+ "-Xep:UnusedAnonymousClass:ERROR",
+ }, " "))
+
+ pctx.StaticVariable("ErrorProneFlags", strings.Join([]string{
+ "com.google.errorprone.ErrorProneCompiler",
+ "-Xdiags:verbose",
+ "-XDcompilePolicy=simple",
+ "-XDallowBetterNullChecks=false",
+ "-XDusePolyAttribution=true",
+ "-XDuseStrictMethodClashCheck=true",
+ "-XDuseStructuralMostSpecificResolution=true",
+ "-XDuseGraphInference=true",
+ "-Xmaxwarns 100000",
+ "-XDandroidCompatible=true",
+ "-XepAllErrorsAsWarnings",
+ }, " "))
+
+ pctx.StaticVariable("ErrorProneCmd",
+ "${JavaCmd} -Xbootclasspath/p:${ErrorProneJavacJar} -cp ${ErrorProneJar}:${ErrorProneClasspath} ${ErrorProneFlags} ${ErrorProneChecksError}")
+}
diff --git a/java/java.go b/java/java.go
index ac88020..e2e15d4 100644
--- a/java/java.go
+++ b/java/java.go
@@ -330,6 +330,8 @@
srcFileLists = append(srcFileLists, j.ExtraSrcLists...)
+ var extraJarDeps android.Paths
+
if len(srcFiles) > 0 {
// Compile java sources into .class files
classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, deps)
@@ -337,6 +339,17 @@
return
}
+ if ctx.AConfig().IsEnvTrue("RUN_ERROR_PRONE") {
+ // If error-prone is enabled, add an additional rule to compile the java files into
+ // a separate set of classes (so that they don't overwrite the normal ones and require
+ // a rebuild when error-prone is turned off). Add the classes as a dependency to
+ // the jar command so the two compiles can run in parallel.
+ // TODO(ccross): Once we always compile with javac9 we may be able to conditionally
+ // enable error-prone without affecting the output class files.
+ errorprone := RunErrorProne(ctx, srcFiles, srcFileLists, flags, deps)
+ extraJarDeps = append(extraJarDeps, errorprone)
+ }
+
classJarSpecs = append([]jarSpec{classes}, classJarSpecs...)
}
@@ -349,7 +362,7 @@
allJarSpecs = append(allJarSpecs, resourceJarSpecs...)
// Combine classes + resources into classes-full-debug.jar
- outputFile := TransformClassesToJar(ctx, allJarSpecs, manifest)
+ outputFile := TransformClassesToJar(ctx, allJarSpecs, manifest, extraJarDeps)
if ctx.Failed() {
return
}
@@ -575,7 +588,7 @@
j.resourceJarSpecs = append(j.resourceJarSpecs, resourceJarSpec)
}
- j.combinedClasspathFile = TransformClassesToJar(ctx, j.classJarSpecs, android.OptionalPath{})
+ j.combinedClasspathFile = TransformClassesToJar(ctx, j.classJarSpecs, android.OptionalPath{}, nil)
ctx.InstallFileName(android.PathForModuleInstall(ctx, "framework"),
ctx.ModuleName()+".jar", j.combinedClasspathFile)