java_sdk_library: Path extraction from deps depend on tag
Previously, the information that the java_sdk_library extracted from
its child dependencies was determined purely by the type of the
dependency and whether it had a tag of the appropriate type. The actual
tag itself was ignored. That worked but was a little fragile as it
relied on there being no overlap between the types of the dependencies
or if there was overlap on the order in which the dependencies were
processed and the dependency types were checked to ensure that the
correct information was collected.
This change makes the information that is extracted dependent on the
tag that is used. That makes the behavior much more robust and also
simplifes the follow up change which may get the stubs source and API
files from separate droidstubs invocations.
Changes:
* A func field is added to the scopeDependencyTag that is supplied with
a dependency from which to extract the information and scopePaths
into which the information will be stored.
* Each scopeDependencyTag instance supplies its own function.
* Various items are renamed to more closely reflect what they actually
do. e.g. the apiFileTag is renamed to stubsSourceAndApiTag field
because if provides access to both api file and stubs source.
Test: m checkapi
Bug: 155164730
Change-Id: I4e1861ea67f441f2948a0d7d7053ab0b1169955f
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 361ac71..a9e5b85 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -60,6 +60,17 @@
blueprint.BaseDependencyTag
name string
apiScope *apiScope
+
+ // Function for extracting appropriate path information from the dependency.
+ depInfoExtractor func(paths *scopePaths, dep android.Module) error
+}
+
+// Extract tag specific information from the dependency.
+func (tag scopeDependencyTag) extractDepInfo(ctx android.ModuleContext, dep android.Module, paths *scopePaths) {
+ err := tag.depInfoExtractor(paths, dep)
+ if err != nil {
+ ctx.ModuleErrorf("has an invalid {scopeDependencyTag: %s} dependency on module %s: %s", tag.name, ctx.OtherModuleName(dep), err.Error())
+ }
}
// Provides information about an api scope, e.g. public, system, test.
@@ -88,8 +99,8 @@
// The tag to use to depend on the stubs library module.
stubsTag scopeDependencyTag
- // The tag to use to depend on the stubs
- apiFileTag scopeDependencyTag
+ // The tag to use to depend on the stubs source and API module.
+ stubsSourceAndApiTag scopeDependencyTag
// The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
apiFilePrefix string
@@ -112,14 +123,17 @@
// Initialize a scope, creating and adding appropriate dependency tags
func initApiScope(scope *apiScope) *apiScope {
- scope.fieldName = proptools.FieldNameForProperty(scope.name)
+ name := scope.name
+ scope.fieldName = proptools.FieldNameForProperty(name)
scope.stubsTag = scopeDependencyTag{
- name: scope.name + "-stubs",
- apiScope: scope,
+ name: name + "-stubs",
+ apiScope: scope,
+ depInfoExtractor: (*scopePaths).extractStubsLibraryInfoFromDependency,
}
- scope.apiFileTag = scopeDependencyTag{
- name: scope.name + "-api",
- apiScope: scope,
+ scope.stubsSourceAndApiTag = scopeDependencyTag{
+ name: name + "-stubs-source-and-api",
+ apiScope: scope,
+ depInfoExtractor: (*scopePaths).extractStubsSourceAndApiInfoFromApiStubsProvider,
}
return scope
}
@@ -128,7 +142,7 @@
return baseName + sdkStubsLibrarySuffix + scope.moduleSuffix
}
-func (scope *apiScope) docsModuleName(baseName string) string {
+func (scope *apiScope) stubsSourceModuleName(baseName string) string {
return baseName + sdkStubsSourceSuffix + scope.moduleSuffix
}
@@ -349,6 +363,27 @@
stubsSrcJar android.Path
}
+func (paths *scopePaths) extractStubsLibraryInfoFromDependency(dep android.Module) error {
+ if lib, ok := dep.(Dependency); ok {
+ paths.stubsHeaderPath = lib.HeaderJars()
+ paths.stubsImplPath = lib.ImplementationJars()
+ return nil
+ } else {
+ return fmt.Errorf("expected module that implements Dependency, e.g. java_library")
+ }
+}
+
+func (paths *scopePaths) extractStubsSourceAndApiInfoFromApiStubsProvider(dep android.Module) error {
+ if provider, ok := dep.(ApiStubsProvider); ok {
+ paths.currentApiFilePath = provider.ApiFilePath()
+ paths.removedApiFilePath = provider.RemovedApiFilePath()
+ paths.stubsSrcJar = provider.StubsSrcJar()
+ return nil
+ } else {
+ return fmt.Errorf("expected module that implements ApiStubsProvider, e.g. droidstubs")
+ }
+}
+
// Common code between sdk library and sdk library import
type commonToSdkLibraryAndImport struct {
scopePaths map[*apiScope]*scopePaths
@@ -447,8 +482,8 @@
// Add dependencies to the stubs library
ctx.AddVariationDependencies(nil, apiScope.stubsTag, module.stubsName(apiScope))
- // And the api file
- ctx.AddVariationDependencies(nil, apiScope.apiFileTag, module.docsName(apiScope))
+ // And the stubs source and api files
+ ctx.AddVariationDependencies(nil, apiScope.stubsSourceAndApiTag, module.stubsSourceName(apiScope))
}
if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
@@ -469,27 +504,16 @@
// When this java_sdk_library is depended upon from others via "libs" property,
// the recorded paths will be returned depending on the link type of the caller.
ctx.VisitDirectDeps(func(to android.Module) {
- otherName := ctx.OtherModuleName(to)
tag := ctx.OtherModuleDependencyTag(to)
- if lib, ok := to.(Dependency); ok {
- if scopeTag, ok := tag.(scopeDependencyTag); ok {
- apiScope := scopeTag.apiScope
- scopePaths := module.getScopePaths(apiScope)
- scopePaths.stubsHeaderPath = lib.HeaderJars()
- scopePaths.stubsImplPath = lib.ImplementationJars()
- }
- }
- if doc, ok := to.(ApiStubsProvider); ok {
- if scopeTag, ok := tag.(scopeDependencyTag); ok {
- apiScope := scopeTag.apiScope
- scopePaths := module.getScopePaths(apiScope)
- scopePaths.currentApiFilePath = doc.ApiFilePath()
- scopePaths.removedApiFilePath = doc.RemovedApiFilePath()
- scopePaths.stubsSrcJar = doc.StubsSrcJar()
- } else {
- ctx.ModuleErrorf("depends on module %q of unknown tag %q", otherName, tag)
- }
+ // Extract information from any of the scope specific dependencies.
+ if scopeTag, ok := tag.(scopeDependencyTag); ok {
+ apiScope := scopeTag.apiScope
+ scopePaths := module.getScopePaths(apiScope)
+
+ // Extract information from the dependency. The exact information extracted
+ // is determined by the nature of the dependency which is determined by the tag.
+ scopeTag.extractDepInfo(ctx, to, scopePaths)
}
})
}
@@ -504,14 +528,15 @@
return entriesList
}
-// Module name of the stubs library
+// Name of the java_library module that compiles the stubs source.
func (module *SdkLibrary) stubsName(apiScope *apiScope) string {
return apiScope.stubsModuleName(module.BaseModuleName())
}
-// Module name of the docs
-func (module *SdkLibrary) docsName(apiScope *apiScope) string {
- return apiScope.docsModuleName(module.BaseModuleName())
+// // Name of the droidstubs module that generates the stubs source and
+// generates/checks the API.
+func (module *SdkLibrary) stubsSourceName(apiScope *apiScope) string {
+ return apiScope.stubsSourceModuleName(module.BaseModuleName())
}
// Module name of the runtime implementation library
@@ -597,7 +622,7 @@
props.Visibility = visibility
// sources are generated from the droiddoc
- props.Srcs = []string{":" + module.docsName(apiScope)}
+ props.Srcs = []string{":" + module.stubsSourceName(apiScope)}
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
props.Sdk_version = proptools.StringPtr(sdkVersion)
props.System_modules = module.Library.Module.deviceProperties.System_modules
@@ -633,8 +658,8 @@
}
// Creates a droidstubs module that creates stubs source files from the given full source
-// files
-func (module *SdkLibrary) createStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope) {
+// files and also updates and checks the API specification files.
+func (module *SdkLibrary) createStubsSourcesAndApi(mctx android.DefaultableHookContext, apiScope *apiScope) {
props := struct {
Name *string
Visibility []string
@@ -670,7 +695,7 @@
// * system_modules
// * libs (static_libs/libs)
- props.Name = proptools.StringPtr(module.docsName(apiScope))
+ props.Name = proptools.StringPtr(module.stubsSourceName(apiScope))
// If stubs_source_visibility is not set then the created module will use the
// visibility of this module.
@@ -934,7 +959,7 @@
for _, scope := range generatedScopes {
module.createStubsLibrary(mctx, scope)
- module.createStubsSources(mctx, scope)
+ module.createStubsSourcesAndApi(mctx, scope)
}
if !proptools.Bool(module.sdkLibraryProperties.Api_only) {
@@ -1001,7 +1026,7 @@
// List of shared java libs that this module has dependencies to
Libs []string
- // The stub sources.
+ // The stubs source.
Stub_srcs []string `android:"path"`
// The current.txt
@@ -1161,7 +1186,7 @@
Name *string
Srcs []string
}{}
- props.Name = proptools.StringPtr(apiScope.docsModuleName(module.BaseModuleName()))
+ props.Name = proptools.StringPtr(apiScope.stubsSourceModuleName(module.BaseModuleName()))
props.Srcs = scopeProperties.Stub_srcs
mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
}