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
Fixes: dotnet#1096
Context: https://stackoverflow.com/questions/57358750/module-info-class-file-is-different-in-the-module-jar-file-and-compiled-module-i
Context: 678c4bd
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, the update `XmlClassDeclarationBuilder` so that
it updates all `public` types *outside* of the "exported" packages to
have a visibility of `kotlin-internal`.
Why a `//*/@visibility` value of `kotlin-internal`? From a
[suggestion][2] for the commit message of 678c4bd, which was sadly
overlooked in the final merge:
> 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*.
If we use `internal`, *those types are still bound*, it's just that
the bound types have C# `internal` visibility, while we *want* them
to be *skipped entirely*. A visibility value of `kotlin-internal`
allows us to skip them, which is desired.
`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"
…
visibility="kotlin-internal" />
Note that `com.xamarin.internal.PublicClassNotInModuleExports` is now
shown as `kotlin-internal` instead of `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]: dotnet#793 (comment)
0 commit comments