java_sdk_library: Add redirection to module-lib stubs

Previously, when using sdk_version: "module_current" any direct
reference to an sdk library would use the public not module-lib stubs.
This change corrects that.

Prior to the addition of the module-lib api scope almost all
java_sdk_library instances supported all the scopes to which a request
for jars could be redirected, i.e. public, system and test. The
exceptions to that are a few special instances that were used with
sdk_version: "none" and so were either caught by the java_sdk_library
special cases or dropped through to public.

The addition of module-lib, plus the flexible control over which scopes
are generated means that is no longer true. It is possible for a
java_sdk_library to be requested for a scope it does not have which
would have resulted in an empty set of paths being returned leading to
confusing compilation errors.

To avoid that this change also adds support for using the inheritance
hierarchy defined by the apiScope.extends field to fall back to the
closest available surface.

Test: m nothing
Bug: 155164730
Change-Id: I6aab75a772433ee0a36b6f1758a4aec4be2f9a49
This commit is contained in:
Paul Duffin 2020-05-20 11:52:25 +01:00
parent b05d4295de
commit 803a9565cd
2 changed files with 83 additions and 5 deletions

View File

@ -1261,6 +1261,45 @@ func TestJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) {
`)
}
func TestJavaSdkLibrary_MissingScope(t *testing.T) {
testJavaError(t, `requires api scope module-lib from foo but it only has \[\] available`, `
java_sdk_library {
name: "foo",
srcs: ["a.java"],
public: {
enabled: false,
},
}
java_library {
name: "baz",
srcs: ["a.java"],
libs: ["foo"],
sdk_version: "module_current",
}
`)
}
func TestJavaSdkLibrary_FallbackScope(t *testing.T) {
testJava(t, `
java_sdk_library {
name: "foo",
srcs: ["a.java"],
system: {
enabled: true,
},
}
java_library {
name: "baz",
srcs: ["a.java"],
libs: ["foo"],
// foo does not have module-lib scope so it should fallback to system
sdk_version: "module_current",
}
`)
}
var compilerFlagsTestCases = []struct {
in string
out bool

View File

@ -551,7 +551,7 @@ func (c *commonToSdkLibraryAndImport) apiModuleName(apiScope *apiScope) string {
return c.namingScheme.apiModuleName(apiScope, c.moduleBase.BaseModuleName())
}
func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths {
func (c *commonToSdkLibraryAndImport) getScopePathsCreateIfNeeded(scope *apiScope) *scopePaths {
if c.scopePaths == nil {
c.scopePaths = make(map[*apiScope]*scopePaths)
}
@ -564,6 +564,28 @@ func (c *commonToSdkLibraryAndImport) getScopePaths(scope *apiScope) *scopePaths
return paths
}
func (c *commonToSdkLibraryAndImport) findScopePaths(scope *apiScope) *scopePaths {
if c.scopePaths == nil {
return nil
}
return c.scopePaths[scope]
}
// If this does not support the requested api scope then find the closest available
// scope it does support. Returns nil if no such scope is available.
func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths {
for s := scope; s != nil; s = s.extends {
if paths := c.findScopePaths(s); paths != nil {
return paths
}
}
// This should never happen outside tests as public should be the base scope for every
// scope and is enabled by default.
return nil
}
func (c *commonToSdkLibraryAndImport) sdkJarsCommon(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
// If a specific numeric version has been requested then use prebuilt versions of the sdk.
@ -575,13 +597,26 @@ func (c *commonToSdkLibraryAndImport) sdkJarsCommon(ctx android.BaseModuleContex
switch sdkVersion.kind {
case sdkSystem:
apiScope = apiScopeSystem
case sdkModule:
apiScope = apiScopeModuleLib
case sdkTest:
apiScope = apiScopeTest
default:
apiScope = apiScopePublic
}
paths := c.getScopePaths(apiScope)
paths := c.findClosestScopePath(apiScope)
if paths == nil {
var scopes []string
for _, s := range allApiScopes {
if c.findScopePaths(s) != nil {
scopes = append(scopes, s.name)
}
}
ctx.ModuleErrorf("requires api scope %s from %s but it only has %q available", apiScope.name, c.moduleBase.BaseModuleName(), scopes)
return nil
}
if headerJars {
return paths.stubsHeaderPath
} else {
@ -704,7 +739,7 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
// Extract information from any of the scope specific dependencies.
if scopeTag, ok := tag.(scopeDependencyTag); ok {
apiScope := scopeTag.apiScope
scopePaths := module.getScopePaths(apiScope)
scopePaths := module.getScopePathsCreateIfNeeded(apiScope)
// Extract information from the dependency. The exact information extracted
// is determined by the nature of the dependency which is determined by the tag.
@ -1455,7 +1490,7 @@ func (module *sdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo
if lib, ok := to.(Dependency); ok {
if scopeTag, ok := tag.(scopeDependencyTag); ok {
apiScope := scopeTag.apiScope
scopePaths := module.getScopePaths(apiScope)
scopePaths := module.getScopePathsCreateIfNeeded(apiScope)
scopePaths.stubsHeaderPath = lib.HeaderJars()
}
}
@ -1640,7 +1675,11 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe
s.Scopes = make(map[*apiScope]scopeProperties)
for _, apiScope := range allApiScopes {
paths := sdk.getScopePaths(apiScope)
paths := sdk.findScopePaths(apiScope)
if paths == nil {
continue
}
jars := paths.stubsImplPath
if len(jars) > 0 {
properties := scopeProperties{}