From 6be0f00671e39a8b744a10bd1d0c91dc8724d4b2 Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 20 Sep 2023 23:03:01 +0000 Subject: Remove api_files property from java_api_library java_api_contribution provides api_surface information, but files directly passed to java_api_library do not possess such information. Currently, the api surface is assumed via naming convention for api files passed via api_files property, but this is fragile. This change removes the api_files property from java_api_library and enforce all api files to be passed via java_api_contribution Test: m nothing --build-from-text-stub Bug: 300964421 Change-Id: If01d9ed978fe469d4ee0d685582a51629ebecc56 --- java/java.go | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) (limited to 'java/java.go') diff --git a/java/java.go b/java/java.go index 4f31af685..aba4faac0 100644 --- a/java/java.go +++ b/java/java.go @@ -1667,11 +1667,6 @@ type JavaApiLibraryProperties struct { // This is a list of Soong modules Api_contributions []string - // list of api.txt files relative to this directory that contribute to the - // API surface. - // This is a list of relative paths - Api_files []string `android:"path"` - // List of flags to be passed to the javac compiler to generate jar file Javacflags []string @@ -1824,7 +1819,7 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { var scopeOrderedSourceFileNames = allApiScopes.Strings( func(s *apiScope) string { return s.apiFilePrefix + "current.txt" }) -func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo, apiFiles android.Paths) android.Paths { +func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) android.Paths { var sortedSrcFiles android.Paths for i, apiScope := range allApiScopes { @@ -1833,20 +1828,14 @@ func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFiles sortedSrcFiles = append(sortedSrcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String())) } } - // TODO: b/300964421 - Remove when api_files property is removed - for _, apiFileName := range apiFiles { - if apiFileName.Base() == scopeOrderedSourceFileNames[i] { - sortedSrcFiles = append(sortedSrcFiles, apiFileName) - } - } } - if len(srcFilesInfo)+len(apiFiles) != len(sortedSrcFiles) { + if len(srcFilesInfo) != len(sortedSrcFiles) { var srcFiles android.Paths for _, srcFileInfo := range srcFilesInfo { srcFiles = append(srcFiles, srcFileInfo.ApiFile) } - ctx.ModuleErrorf("Unrecognizable source file found within %s", append(srcFiles, apiFiles...)) + ctx.ModuleErrorf("Unrecognizable source file found within %s", srcFiles) } return sortedSrcFiles @@ -1892,15 +1881,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { } }) - // Add the api_files inputs - // These are api files in the module subdirectory, which are not provided by - // java_api_contribution but provided directly as module property. - var apiFiles android.Paths - for _, api := range al.properties.Api_files { - apiFiles = append(apiFiles, android.PathForModuleSrc(ctx, api)) - } - - srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo, apiFiles) + srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo) if srcFiles == nil && !ctx.Config().AllowMissingDependencies() { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) -- cgit v1.2.3-59-g8ed1b From a96a7b1e13f04c79831347acc02bedc62cfd954e Mon Sep 17 00:00:00 2001 From: Jihoon Kang Date: Wed, 20 Sep 2023 23:43:32 +0000 Subject: Remove naming conventioned based file sorting in java_api_library With api_files property being removed from java_api_library, all api files are passed to java_api_library via java_api_contribution, which provide api_surface information. Instead of relying on the naming convention of the api files, java_api_library can utilize this information to sort the api files from narrower api scope to the wider api scope. Test: m --build-from-text-stub Bug: 295429988 Change-Id: Idd832778833c072c6b7e9d1f775533e5f4e2af00 --- java/java.go | 41 ++++++++++++++++++----------------------- java/java_test.go | 27 +++++++++++++++++++++++++++ java/sdk_library.go | 11 +++++++++++ 3 files changed, 56 insertions(+), 23 deletions(-) (limited to 'java/java.go') diff --git a/java/java.go b/java/java.go index aba4faac0..7e2366433 100644 --- a/java/java.go +++ b/java/java.go @@ -1814,31 +1814,22 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { } } -// API signature file names sorted from -// the narrowest api scope to the widest api scope -var scopeOrderedSourceFileNames = allApiScopes.Strings( - func(s *apiScope) string { return s.apiFilePrefix + "current.txt" }) - -func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) android.Paths { - var sortedSrcFiles android.Paths - - for i, apiScope := range allApiScopes { - for _, srcFileInfo := range srcFilesInfo { - if srcFileInfo.ApiFile.Base() == scopeOrderedSourceFileNames[i] || srcFileInfo.ApiSurface == apiScope.name { - sortedSrcFiles = append(sortedSrcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String())) - } - } - } - - if len(srcFilesInfo) != len(sortedSrcFiles) { - var srcFiles android.Paths - for _, srcFileInfo := range srcFilesInfo { - srcFiles = append(srcFiles, srcFileInfo.ApiFile) +// Map where key is the api scope name and value is the int value +// representing the order of the api scope, narrowest to the widest +var scopeOrderMap = allApiScopes.MapToIndex( + func(s *apiScope) string { return s.name }) + +func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo { + for _, srcFileInfo := range srcFilesInfo { + if srcFileInfo.ApiSurface == "" { + ctx.ModuleErrorf("Api surface not defined for the associated api file %s", srcFileInfo.ApiFile) } - ctx.ModuleErrorf("Unrecognizable source file found within %s", srcFiles) } + sort.Slice(srcFilesInfo, func(i, j int) bool { + return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface] + }) - return sortedSrcFiles + return srcFilesInfo } func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -1881,7 +1872,11 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { } }) - srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo) + srcFilesInfo = al.sortApiFilesByApiScope(ctx, srcFilesInfo) + var srcFiles android.Paths + for _, srcFileInfo := range srcFilesInfo { + srcFiles = append(srcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String())) + } if srcFiles == nil && !ctx.Config().AllowMissingDependencies() { ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) diff --git a/java/java_test.go b/java/java_test.go index ec6be5c48..b555a9513 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2398,3 +2398,30 @@ func TestJavaApiContributionImport(t *testing.T) { sourceFilesFlag := "--source-files current.txt" android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag) } + +func TestJavaApiLibraryApiFilesSorting(t *testing.T) { + ctx, _ := testJava(t, ` + java_api_library { + name: "foo", + api_contributions: [ + "system-server-api-stubs-docs-non-updatable.api.contribution", + "test-api-stubs-docs-non-updatable.api.contribution", + "system-api-stubs-docs-non-updatable.api.contribution", + "module-lib-api-stubs-docs-non-updatable.api.contribution", + "api-stubs-docs-non-updatable.api.contribution", + ], + } + `) + m := ctx.ModuleForTests("foo", "android_common") + manifest := m.Output("metalava.sbox.textproto") + sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest) + manifestCommand := sboxProto.Commands[0].GetCommand() + + // Api files are sorted from the narrowest api scope to the widest api scope. + // test api and module lib api surface do not have subset/superset relationship, + // but they will never be passed as inputs at the same time. + sourceFilesFlag := "--source-files default/java/api/current.txt " + + "default/java/api/system-current.txt default/java/api/test-current.txt " + + "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt" + android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag) +} diff --git a/java/sdk_library.go b/java/sdk_library.go index 6349d92f5..282379cc4 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -286,6 +286,17 @@ func (scopes apiScopes) Strings(accessor func(*apiScope) string) []string { return list } +// Method that maps the apiScopes properties to the index of each apiScopes elements. +// apiScopes property to be used as the key can be specified with the input accessor. +// Only a string property of apiScope can be used as the key of the map. +func (scopes apiScopes) MapToIndex(accessor func(*apiScope) string) map[string]int { + ret := make(map[string]int) + for i, scope := range scopes { + ret[accessor(scope)] = i + } + return ret +} + var ( scopeByName = make(map[string]*apiScope) allScopeNames []string -- cgit v1.2.3-59-g8ed1b