Add error-prone support
Add support for compiling java sources with the error-prone tool. Test: m -j checkbuild Change-Id: Ieb4ee0e05f8f34a52ed7bcf1c7cbacf1c9c4d0b5
This commit is contained in:
@@ -222,6 +222,7 @@ bootstrap_go_package {
|
|||||||
],
|
],
|
||||||
srcs: [
|
srcs: [
|
||||||
"java/config/config.go",
|
"java/config/config.go",
|
||||||
|
"java/config/errorprone.go",
|
||||||
"java/config/makevars.go",
|
"java/config/makevars.go",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,7 @@ package android
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
"github.com/google/blueprint/pathtools"
|
"github.com/google/blueprint/pathtools"
|
||||||
@@ -75,6 +76,25 @@ func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.V
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SourcePathsVariable returns a Variable whose value is the source directory
|
||||||
|
// appended with the supplied paths, joined with separator. It may only be
|
||||||
|
// called during a Go package's initialization - either from the init()
|
||||||
|
// function or as part of a package-scoped variable's initialization.
|
||||||
|
func (p AndroidPackageContext) SourcePathsVariable(name, separator string, paths ...string) blueprint.Variable {
|
||||||
|
return p.VariableFunc(name, func(config interface{}) (string, error) {
|
||||||
|
ctx := &configErrorWrapper{p, config.(Config), []error{}}
|
||||||
|
var ret []string
|
||||||
|
for _, path := range paths {
|
||||||
|
p := safePathForSource(ctx, path)
|
||||||
|
if len(ctx.errors) > 0 {
|
||||||
|
return "", ctx.errors[0]
|
||||||
|
}
|
||||||
|
ret = append(ret, p.String())
|
||||||
|
}
|
||||||
|
return strings.Join(ret, separator), nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SourcePathVariableWithEnvOverride returns a Variable whose value is the source directory
|
// SourcePathVariableWithEnvOverride returns a Variable whose value is the source directory
|
||||||
// appended with the supplied path, or the value of the given environment variable if it is set.
|
// appended with the supplied path, or the value of the given environment variable if it is set.
|
||||||
// The environment variable is not required to point to a path inside the source tree.
|
// The environment variable is not required to point to a path inside the source tree.
|
||||||
|
@@ -49,6 +49,25 @@ var (
|
|||||||
},
|
},
|
||||||
"javacFlags", "bootClasspath", "classpath", "outDir", "annoDir", "javaVersion")
|
"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",
|
jar = pctx.AndroidStaticRule("jar",
|
||||||
blueprint.RuleParams{
|
blueprint.RuleParams{
|
||||||
Command: `${config.JarCmd} $operation ${out}.tmp $manifest $jarArgs && ${config.Zip2ZipCmd} -t -i ${out}.tmp -o ${out} && rm ${out}.tmp`,
|
Command: `${config.JarCmd} $operation ${out}.tmp $manifest $jarArgs && ${config.Zip2ZipCmd} -t -i ${out}.tmp -o ${out} && rm ${out}.tmp`,
|
||||||
@@ -144,12 +163,41 @@ func TransformJavaToClasses(ctx android.ModuleContext, srcFiles android.Paths, s
|
|||||||
return jarSpec{classFileList}
|
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,
|
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")
|
outputFile := android.PathForModuleOut(ctx, "classes-full-debug.jar")
|
||||||
|
|
||||||
deps := android.Paths{}
|
|
||||||
jarArgs := []string{}
|
jarArgs := []string{}
|
||||||
|
|
||||||
for _, j := range classes {
|
for _, j := range classes {
|
||||||
|
97
java/config/errorprone.go
Normal file
97
java/config/errorprone.go
Normal file
@@ -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}")
|
||||||
|
}
|
17
java/java.go
17
java/java.go
@@ -330,6 +330,8 @@ func (j *Module) compile(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
srcFileLists = append(srcFileLists, j.ExtraSrcLists...)
|
srcFileLists = append(srcFileLists, j.ExtraSrcLists...)
|
||||||
|
|
||||||
|
var extraJarDeps android.Paths
|
||||||
|
|
||||||
if len(srcFiles) > 0 {
|
if len(srcFiles) > 0 {
|
||||||
// Compile java sources into .class files
|
// Compile java sources into .class files
|
||||||
classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, deps)
|
classes := TransformJavaToClasses(ctx, srcFiles, srcFileLists, flags, deps)
|
||||||
@@ -337,6 +339,17 @@ func (j *Module) compile(ctx android.ModuleContext) {
|
|||||||
return
|
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...)
|
classJarSpecs = append([]jarSpec{classes}, classJarSpecs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,7 +362,7 @@ func (j *Module) compile(ctx android.ModuleContext) {
|
|||||||
allJarSpecs = append(allJarSpecs, resourceJarSpecs...)
|
allJarSpecs = append(allJarSpecs, resourceJarSpecs...)
|
||||||
|
|
||||||
// Combine classes + resources into classes-full-debug.jar
|
// Combine classes + resources into classes-full-debug.jar
|
||||||
outputFile := TransformClassesToJar(ctx, allJarSpecs, manifest)
|
outputFile := TransformClassesToJar(ctx, allJarSpecs, manifest, extraJarDeps)
|
||||||
if ctx.Failed() {
|
if ctx.Failed() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -575,7 +588,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
j.resourceJarSpecs = append(j.resourceJarSpecs, resourceJarSpec)
|
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.InstallFileName(android.PathForModuleInstall(ctx, "framework"),
|
||||||
ctx.ModuleName()+".jar", j.combinedClasspathFile)
|
ctx.ModuleName()+".jar", j.combinedClasspathFile)
|
||||||
|
Reference in New Issue
Block a user