summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jihoon Kang <jihoonkang@google.com> 2024-01-31 23:27:26 +0000
committer Paul Duffin <paulduffin@google.com> 2024-04-19 10:56:32 +0100
commit5623e5425ab8c9f7be114c1229fede4af9b5fbf2 (patch)
tree4a8d55169e605234561de59de12f4febed916b83
parentd3b020a8c301b76791dbb0aa25b3a0e5e33d13fb (diff)
Support passing multiple last api files to metalava in droidstubs
This change supports passing multiple last api files to metalava, instead of emitting an error when multiple files are passed as inputs. The last api file providing modules are filegroups or genrule modules that output exactly one output file. This change modifies that behavior so that the filegroups can output multiple api files. The last api file providing modules are (mostly) generated from the `prebuilt_apis` sdk module. However, these modules only provide a single api scope txt files (e.g. system api scope last api file filegroup would only provide last system api file, not system + public). This change modifies `prebuilt_apis` by generating "combine" filegroup modules, that include api files of the subset api scopes as well. The ordering of the files are handled when generating the combined api filegroup modules, and droidstubs module does not check whether the passed api files are in order from the narrowest api scope to the widest api scope. Submission of this change will be done once metalava fully supports handling multiple api files input for api lint and nullness migration. Test: m nothing Bug: 321827591 Change-Id: I2066e7ceb7ee7c6d0fd87cd43bfd08db906d4b8f
-rw-r--r--java/droidstubs.go21
-rw-r--r--java/prebuilt_apis.go15
-rw-r--r--java/sdk_library.go33
3 files changed, 43 insertions, 26 deletions
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 02b81a4fe..870c6438e 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -532,8 +532,8 @@ func (d *Droidstubs) annotationsFlags(ctx android.ModuleContext, cmd *android.Ru
cmd.Flag(config.MetalavaAnnotationsFlags)
if params.migratingNullability {
- previousApi := android.PathForModuleSrc(ctx, String(d.properties.Previous_api))
- cmd.FlagWithInput("--migrate-nullness ", previousApi)
+ previousApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Previous_api)})
+ cmd.FlagForEachInput("--migrate-nullness ", previousApiFiles)
}
if s := String(d.properties.Validate_nullability_from_list); s != "" {
@@ -692,11 +692,11 @@ func (d *Droidstubs) apiCompatibilityFlags(ctx android.ModuleContext, cmd *andro
ctx.PropertyErrorf("out", "out property may not be combined with check_api")
}
- apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
- removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
+ apiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Api_file)})
+ removedApiFiles := android.PathsForModuleSrc(ctx, []string{String(d.properties.Check_api.Last_released.Removed_api_file)})
- cmd.FlagWithInput("--check-compatibility:api:released ", apiFile)
- cmd.FlagWithInput("--check-compatibility:removed:released ", removedApiFile)
+ cmd.FlagForEachInput("--check-compatibility:api:released ", apiFiles)
+ cmd.FlagForEachInput("--check-compatibility:removed:released ", removedApiFiles)
baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
if baselineFile.Valid() {
@@ -950,9 +950,12 @@ func (d *Droidstubs) everythingOptionalCmd(ctx android.ModuleContext, cmd *andro
// Add API lint options.
if doApiLint {
- newSince := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Api_lint.New_since)
- if newSince.Valid() {
- cmd.FlagWithInput("--api-lint ", newSince.Path())
+ var newSince android.Paths
+ if d.properties.Check_api.Api_lint.New_since != nil {
+ newSince = android.PathsForModuleSrc(ctx, []string{proptools.String(d.properties.Check_api.Api_lint.New_since)})
+ }
+ if len(newSince) > 0 {
+ cmd.FlagForEachInput("--api-lint ", newSince)
} else {
cmd.Flag("--api-lint")
}
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 6a79e5883..00613eee3 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -367,10 +367,23 @@ func prebuiltApiFiles(mctx android.LoadHookContext, p *prebuiltApis) {
info := latest[k]
name := PrebuiltApiCombinedModuleName(info.module, info.scope, "latest")
+ // Iterate until the currentApiScope does not extend any other api scopes
+ // i.e. is not a superset of any other api scopes
+ // the relationship between the api scopes is defined in java/sdk_library.go
var srcs []string
currentApiScope := scopeByName[info.scope]
- srcs = append(srcs, PrebuiltApiModuleName(info.module, currentApiScope.name, "latest"))
+ for currentApiScope != nil {
+ if _, ok := latest[fmt.Sprintf("%s.%s", info.module, currentApiScope.name)]; ok {
+ srcs = append(srcs, PrebuiltApiModuleName(info.module, currentApiScope.name, "latest"))
+ }
+ currentApiScope = currentApiScope.extends
+ }
+ // srcs is currently listed in the order from the widest api scope to the narrowest api scopes
+ // e.g. module lib -> system -> public
+ // In order to pass the files in metalava from the narrowest api scope to the widest api scope,
+ // the list has to be reversed.
+ android.ReverseSliceInPlace(srcs)
createCombinedApiFilegroupModule(mctx, name, srcs)
}
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 56b1d399d..bb5730db1 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -705,10 +705,10 @@ type scopePaths struct {
annotationsZip android.OptionalPath
// The path to the latest API file.
- latestApiPath android.OptionalPath
+ latestApiPaths android.Paths
// The path to the latest removed API file.
- latestRemovedApiPath android.OptionalPath
+ latestRemovedApiPaths android.Paths
}
func (paths *scopePaths) extractStubsLibraryInfoFromDependency(ctx android.ModuleContext, dep android.Module) error {
@@ -829,28 +829,25 @@ func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(ctx an
})
}
-func extractSingleOptionalOutputPath(dep android.Module) (android.OptionalPath, error) {
+func extractOutputPaths(dep android.Module) (android.Paths, error) {
var paths android.Paths
if sourceFileProducer, ok := dep.(android.SourceFileProducer); ok {
paths = sourceFileProducer.Srcs()
+ return paths, nil
} else {
- return android.OptionalPath{}, fmt.Errorf("module %q does not produce source files", dep)
+ return nil, fmt.Errorf("module %q does not produce source files", dep)
}
- if len(paths) != 1 {
- return android.OptionalPath{}, fmt.Errorf("expected one path from %q, got %q", dep, paths)
- }
- return android.OptionalPathForPath(paths[0]), nil
}
func (paths *scopePaths) extractLatestApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPath, err := extractSingleOptionalOutputPath(dep)
- paths.latestApiPath = outputPath
+ outputPaths, err := extractOutputPaths(dep)
+ paths.latestApiPaths = outputPaths
return err
}
func (paths *scopePaths) extractLatestRemovedApiPath(ctx android.ModuleContext, dep android.Module) error {
- outputPath, err := extractSingleOptionalOutputPath(dep)
- paths.latestRemovedApiPath = outputPath
+ outputPaths, err := extractOutputPaths(dep)
+ paths.latestRemovedApiPaths = outputPaths
return err
}
@@ -1625,11 +1622,15 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
scopes[scope.name] = scopeInfo
scopeInfo["current_api"] = scope.snapshotRelativeCurrentApiTxtPath(baseModuleName)
scopeInfo["removed_api"] = scope.snapshotRelativeRemovedApiTxtPath(baseModuleName)
- if p := scopePaths.latestApiPath; p.Valid() {
- scopeInfo["latest_api"] = p.Path().String()
+ if p := scopePaths.latestApiPaths; len(p) > 0 {
+ // The last path in the list is the one that applies to this scope, the
+ // preceding ones, if any, are for the scope(s) that it extends.
+ scopeInfo["latest_api"] = p[len(p)-1].String()
}
- if p := scopePaths.latestRemovedApiPath; p.Valid() {
- scopeInfo["latest_removed_api"] = p.Path().String()
+ if p := scopePaths.latestRemovedApiPaths; len(p) > 0 {
+ // The last path in the list is the one that applies to this scope, the
+ // preceding ones, if any, are for the scope(s) that it extends.
+ scopeInfo["latest_removed_api"] = p[len(p)-1].String()
}
}
android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo})