From dee1a7419f6d28451500a3e2a9b49440fce4c8f9 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 9 Aug 2024 17:37:25 +0000 Subject: [PATCH 1/2] Add .internal modules to IDEInfo.deps of top-level java_sdk_library libraries and apps can depend on the top-level java_sdk_library like such ``` java_library { name: "mylib", libs: ["somesdklib"], } ``` and soong will automatically resolve mylib's classpath to either the stub or impl library based on the api container these libraries are in. Since the top-level java_sdk_library has no compilation actions, code completion of `mylib` is not feasible today via `module_bp_java_deps.json`. This CL adds support for this code completion by registering the .impl (or public stubs) as a transtive dependency of `mylib`. The implication of this change is that implementation symbols of the sdk library will be surfaced during code-completion of mylib, even when mylib is in a different container. Long term, this should go away when all the library dependencies are made explicit in Android.bp files. Test: go build ./java Test: verified that symbols of android.car.builtin (a java_sdk_library) can be resolved with the repro instructions in b/356572093#comment5 Bug: 356572093 Bug: 358613520 Change-Id: Ia3887bae34bbd25b8c6346f43602835da32af84a --- java/sdk_library.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/java/sdk_library.go b/java/sdk_library.go index a8cc1b81f..4f95a997d 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -3602,3 +3602,19 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo propertySet.AddProperty("doctag_files", dests) } } + +// TODO(b/358613520): This can be removed when modules are no longer allowed to depend on the top-level library. +func (s *SdkLibrary) IDEInfo(dpInfo *android.IdeInfo) { + s.Library.IDEInfo(dpInfo) + if s.implLibraryModule != nil { + dpInfo.Deps = append(dpInfo.Deps, s.implLibraryModule.Name()) + } else { + // This java_sdk_library does not have an implementation (it sets `api_only` to true). + // Examples of this are `art.module.intra.core.api` (IntraCore api surface). + // Return the "public" stubs for these. + stubPaths := s.findClosestScopePath(apiScopePublic) + if len(stubPaths.stubsHeaderPath) > 0 { + dpInfo.Jars = append(dpInfo.Jars, stubPaths.stubsHeaderPath[0].String()) + } + } +} From b4cd5df5736b0561471d0861a2d8a6b0d1cdf118 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 8 Aug 2024 21:57:22 +0000 Subject: [PATCH 2/2] Make IdeInfo aware of jarjar-ing jarjar can be used to repackage a java_library. e.g. Foo.java in package com.android might get repackaged to prefix.com.android.Foo in the resultant jar. To allow code completion of rdeps, we should use the repackaged jar instead of the src files. This CL sets dpInfo.Jars to the header jar _only_ when jarjar_rules is not empty. We could probably set `Jars` to the header jar even for non jarjar-d libraries and get rid of `Srcs`, `SrcJars` altogether, but that would likely slow down any tools that index out/soong/module_bp_java_deps.json for code completion. Test: go test ./java Bug: 356572093 Change-Id: Ib45810799a479cb315aed011a34351d386a21357 --- java/base.go | 14 +++++++++----- java/jdeps_test.go | 21 ++++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/java/base.go b/java/base.go index f820629e9..49ff22f93 100644 --- a/java/base.go +++ b/java/base.go @@ -2027,16 +2027,20 @@ func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { // Collect information for opening IDE project files in java/jdeps.go. func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { - dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) - dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) - dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) - dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) + // jarjar rules will repackage the sources. To prevent misleading results, IdeInfo should contain the + // repackaged jar instead of the input sources. if j.expandJarjarRules != nil { dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) + dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String()) + } else { + dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) + dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) } + dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) + dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...) dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...) - dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) } func (j *Module) CompilerDeps() []string { diff --git a/java/jdeps_test.go b/java/jdeps_test.go index 47bfac16c..ff54da92a 100644 --- a/java/jdeps_test.go +++ b/java/jdeps_test.go @@ -91,16 +91,23 @@ func TestCollectJavaLibraryPropertiesAddAidlIncludeDirs(t *testing.T) { } } -func TestCollectJavaLibraryPropertiesAddJarjarRules(t *testing.T) { - expected := "Jarjar_rules.txt" - module := LibraryFactory().(*Library) - module.expandJarjarRules = android.PathForTesting(expected) +func TestCollectJavaLibraryWithJarJarRules(t *testing.T) { + ctx, _ := testJava(t, + ` + java_library { + name: "javalib", + srcs: ["foo.java"], + jarjar_rules: "jarjar_rules.txt", + } + `) + module := ctx.ModuleForTests("javalib", "android_common").Module().(*Library) dpInfo := &android.IdeInfo{} module.IDEInfo(dpInfo) - - if dpInfo.Jarjar_rules[0] != expected { - t.Errorf("Library.IDEInfo() Jarjar_rules = %v, want %v", dpInfo.Jarjar_rules[0], expected) + android.AssertBoolEquals(t, "IdeInfo.Srcs of repackaged library should be empty", true, len(dpInfo.Srcs) == 0) + android.AssertStringEquals(t, "IdeInfo.Jar_rules of repackaged library should not be empty", "jarjar_rules.txt", dpInfo.Jarjar_rules[0]) + if !android.SubstringInList(dpInfo.Jars, "soong/.intermediates/javalib/android_common/jarjar/turbine/javalib.jar") { + t.Errorf("IdeInfo.Jars of repackaged library should contain the output of jarjar-ing. All outputs: %v\n", dpInfo.Jars) } }