You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[class-parse] support Module AttributeInfo (#1097)
Fixes: #1096
Context: https://stackoverflow.com/questions/57358750/module-info-class-file-is-different-in-the-module-jar-file-and-compiled-module-i
Context: 678c4bd
Context: b274a67
JDK 9 adds support for [modules][0], which are (kinda sorta) like
.NET Assemblies: modules can depend upon other modules, export
packages, etc.
In particular:
> **exports and exports…to.** An exports module directive specifies
> one of the module’s packages whose `public` types (and their nested
> `public` and `protected` types) should be accessible to code in all
> other modules.
This allows an equivalent to the [C# `internal` access modifier][1]:
`public` types in a *non-`export`ed package* should be treated as
"internal", while `public` types in an `export`ed package are
"fully public".
Update `Xamarin.Android.Tools.Bytecode.dll` to extract the module-
related information, then update `ClassPath` so that it updates all
`public` types *outside* of the "exported" packages to have an
`//*/@annotated-visibility` attribute value of `module-info`.
(See also commit b274a67, which added `//*/@@annotated-visibility`.)
If there is *already* an `//*/@annotated-visibility` value, then we
*append* ` module-info` to the attribute value.
We use `//*/@annotated-visibility` because we are concerned about
introducing an ABI break into AndroidX-related bindings because of
type visibility changes. If this isn't a concern, it should be
possible to use Metadata to remove those types:
<attr path="//class[@annotated-visibility]"
name="visibility">kotlin-internal</attr>
<attr path="//interface[@annotated-visibility]"
name="visibility">kotlin-internal</attr>
`class-parse` command-line parsing has been altered. There is now a
"global `ClassPath`", which will be used to hold `.class` files
provided on the command-line. `.jar` and `.jmod` files provided on
the command-line will be given their own `ClassPath` instances, and
`module-info.class`-based annotated-visibility fixups are specific to
each `ClassPath` instance. Global files are processed together.
There is thus no way for `module-info.class` visibility changes from
`a.jar` to impact `b.jar`. After visibilities are fixed up, we then
merge everything into the "global" `ClassPath` instance before
transforming to XML.
Additionally, `class-parse --dump` can now accept `.jar` files,
and will dump out *all* `.class` filers within the `.jar` file.
To make this output easier, each "entry" starts with a "header" of
`-- Begin {ClassFile.FullJniName}`, and a blank link will be printed
between each entry.
`tests/Xamarin.Android.Tools.Bytecode-Tests` has been updated to:
1. Contain a `module-info.java`, which declares a `com.xamarin`
module.
2. Add a new `com.xamarin.internal.PublicClassNotInModuleExports`
type which is *not* in the `com.xamarin` package, but instead
a *nested* package. The type is `public`.
3. Build a `xatb.jar` artifact
This makes for a simple one-off test:
% dotnet build tests/Xamarin.Android.Tools.Bytecode-Tests/*.csproj
% dotnet build tools/class-parse/*.csproj
% dotnet bin/Debug-net7.0/class-parse.dll \
tests/Xamarin.Android.Tools.Bytecode-Tests/obj/Debug-net7.0/xatb.jar
…
<class
name="PublicClassNotInModuleExports"
…
annotated-visibility="module-info" />
Note that `com.xamarin.internal.PublicClassNotInModuleExports` now
has an XML attribute `annotated-visibility="module-info"`.
Aside: the commit message of 678c4bd sadly overlooked this
[clarification][2] for why `kotlin-internal` was introduced:
> Note: we introduce and use a new `//*/@visibility` value of
> `kotlin-internal` because `internal` is an *existing* value that may
> be used in `Metadata.xml` files, e.g. making `public` API `internal`
> so that it can still be used in the binding, but isn't *public*.
Aside: a discovered oddity: `jar cf …` *modifies* `module-info.class`,
adding a `ModulePackages` attribute! (Specifically, if you compare
the "on-disk" `module-info.class` to the one within
`tests/Xamarin.Android.Tools.Bytecode-Tests/obj/$(Configuration)/xatb.jar`,
they differ in size!)
[0]: https://www.oracle.com/corporate/features/understanding-java-9-modules.html
[1]: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/internal
[2]: #793 (comment)
0 commit comments