Add check_nullability_warnings support to droidstubs.

This takes the warnings file written by metalava and diffs it against
the expected (checked-in) file, in a manner similar to the checking
and updating of the signature files. This makes it possible for a
developer adding a large API surface (e.g. by moving to a new version
of upstream sources for ojluni) to do so without being blocked on
adding the annotations, while ensuring that at all times there is an
up-to-date record of the API surface which is missing annotations.

Bug: 73448108
Test: See the other change in this topic.
Change-Id: If9ed470ef3355a0d713bb556b5561fb255e4e277
This commit is contained in:
Pete Gillin
2018-10-22 15:55:04 +01:00
parent 115934e883
commit 581d608468
2 changed files with 69 additions and 15 deletions

View File

@@ -454,6 +454,14 @@ func (dstubs *Droidstubs) AndroidMk() android.AndroidMkData {
fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:", fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
dstubs.checkLastReleasedApiTimestamp.String()) dstubs.checkLastReleasedApiTimestamp.String())
} }
if dstubs.checkNullabilityWarningsTimestamp != nil {
fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-nullability-warnings")
fmt.Fprintln(w, dstubs.Name()+"-check-nullability-warnings:",
dstubs.checkNullabilityWarningsTimestamp.String())
fmt.Fprintln(w, ".PHONY:", "droidcore")
fmt.Fprintln(w, "droidcore: ", dstubs.Name()+"-check-nullability-warnings")
}
apiFilePrefix := "INTERNAL_PLATFORM_" apiFilePrefix := "INTERNAL_PLATFORM_"
if String(dstubs.properties.Api_tag_name) != "" { if String(dstubs.properties.Api_tag_name) != "" {
apiFilePrefix += String(dstubs.properties.Api_tag_name) + "_" apiFilePrefix += String(dstubs.properties.Api_tag_name) + "_"

View File

@@ -106,6 +106,12 @@ var (
}, },
"srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg") "srcJarDir", "srcJars", "javaVersion", "bootclasspathArgs", "classpathArgs", "sourcepathArgs", "opts", "msg")
nullabilityWarningsCheck = pctx.AndroidStaticRule("nullabilityWarningsCheck",
blueprint.RuleParams{
Command: `( diff $expected $actual && touch $out ) || ( echo -e "$msg" ; exit 38 )`,
},
"expected", "actual", "msg")
dokka = pctx.AndroidStaticRule("dokka", dokka = pctx.AndroidStaticRule("dokka",
blueprint.RuleParams{ blueprint.RuleParams{
Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` + Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && ` +
@@ -354,6 +360,9 @@ type DroidstubsProperties struct {
// a list of top-level directories containing Java stub files to merge show/hide annotations from. // a list of top-level directories containing Java stub files to merge show/hide annotations from.
Merge_inclusion_annotations_dirs []string Merge_inclusion_annotations_dirs []string
// a file containing expected warnings produced by validation of nullability annotations.
Check_nullability_warnings *string
// if set to true, allow Metalava to generate doc_stubs source files. Defaults to false. // if set to true, allow Metalava to generate doc_stubs source files. Defaults to false.
Create_doc_stubs *bool Create_doc_stubs *bool
@@ -1211,23 +1220,26 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
type Droidstubs struct { type Droidstubs struct {
Javadoc Javadoc
properties DroidstubsProperties properties DroidstubsProperties
apiFile android.WritablePath apiFile android.WritablePath
apiXmlFile android.WritablePath apiXmlFile android.WritablePath
lastReleasedApiXmlFile android.WritablePath lastReleasedApiXmlFile android.WritablePath
dexApiFile android.WritablePath dexApiFile android.WritablePath
privateApiFile android.WritablePath privateApiFile android.WritablePath
privateDexApiFile android.WritablePath privateDexApiFile android.WritablePath
removedApiFile android.WritablePath removedApiFile android.WritablePath
removedDexApiFile android.WritablePath removedDexApiFile android.WritablePath
apiMappingFile android.WritablePath apiMappingFile android.WritablePath
exactApiFile android.WritablePath exactApiFile android.WritablePath
proguardFile android.WritablePath proguardFile android.WritablePath
nullabilityWarningsFile android.WritablePath
checkCurrentApiTimestamp android.WritablePath checkCurrentApiTimestamp android.WritablePath
updateCurrentApiTimestamp android.WritablePath updateCurrentApiTimestamp android.WritablePath
checkLastReleasedApiTimestamp android.WritablePath checkLastReleasedApiTimestamp android.WritablePath
checkNullabilityWarningsTimestamp android.WritablePath
annotationsZip android.WritablePath annotationsZip android.WritablePath
apiVersionsXml android.WritablePath apiVersionsXml android.WritablePath
@@ -1290,6 +1302,10 @@ func (d *Droidstubs) DepsMutator(ctx android.BottomUpMutatorContext) {
} }
} }
if String(d.properties.Check_nullability_warnings) != "" {
android.ExtractSourceDeps(ctx, d.properties.Check_nullability_warnings)
}
if len(d.properties.Api_levels_annotations_dirs) != 0 { if len(d.properties.Api_levels_annotations_dirs) != 0 {
for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs { for _, apiLevelsAnnotationsDir := range d.properties.Api_levels_annotations_dirs {
ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir) ctx.AddDependency(ctx.Module(), metalavaAPILevelsAnnotationsDirTag, apiLevelsAnnotationsDir)
@@ -1407,9 +1423,9 @@ func (d *Droidstubs) collectAnnotationsFlags(ctx android.ModuleContext,
flags += " --migrate-nullness " + previousApi.String() flags += " --migrate-nullness " + previousApi.String()
} }
if validatingNullability { if validatingNullability {
nullabilityWarningsTxt := android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt") d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
*implicitOutputs = append(*implicitOutputs, nullabilityWarningsTxt) *implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
flags += " --nullability-warnings-txt " + nullabilityWarningsTxt.String() flags += " --nullability-warnings-txt " + d.nullabilityWarningsFile.String()
} }
d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip") d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
@@ -1685,6 +1701,36 @@ func (d *Droidstubs) GenerateAndroidBuildActions(ctx android.ModuleContext) {
d.checkLastReleasedApiTimestamp) d.checkLastReleasedApiTimestamp)
} }
if String(d.properties.Check_nullability_warnings) != "" {
if d.nullabilityWarningsFile == nil {
ctx.PropertyErrorf("check_nullability_warnings",
"Cannot specify check_nullability_warnings unless validating nullability")
}
checkNullabilityWarnings := ctx.ExpandSource(String(d.properties.Check_nullability_warnings),
"check_nullability_warnings")
d.checkNullabilityWarningsTimestamp = android.PathForModuleOut(ctx, "check_nullability_warnings.timestamp")
msg := fmt.Sprintf(`\n******************************\n`+
`The warnings encountered during nullability annotation validation did\n`+
`not match the checked in file of expected warnings. The diffs are shown\n`+
`above. You have two options:\n`+
` 1. Resolve the differences by editing the nullability annotations.\n`+
` 2. Update the file of expected warnings by running:\n`+
` cp %s %s\n`+
` and submitting the updated file as part of your change.`,
d.nullabilityWarningsFile, checkNullabilityWarnings)
ctx.Build(pctx, android.BuildParams{
Rule: nullabilityWarningsCheck,
Description: "Nullability Warnings Check",
Output: d.checkNullabilityWarningsTimestamp,
Implicits: android.Paths{checkNullabilityWarnings, d.nullabilityWarningsFile},
Args: map[string]string{
"expected": checkNullabilityWarnings.String(),
"actual": d.nullabilityWarningsFile.String(),
"msg": msg,
},
})
}
if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() { if Bool(d.properties.Jdiff_enabled) && !ctx.Config().IsPdkBuild() {
// Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below // Please sync with android-api-council@ before making any changes for the name of jdiffDocZip below