Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Xamarin.Android.Build.Tasks] Add support for 'AndroidEnableRestrictToAttributes'. #7990

Merged
merged 2 commits into from
May 2, 2023

Conversation

jpobst
Copy link
Contributor

@jpobst jpobst commented Apr 25, 2023

Context: dotnet/java-interop#1081
Context: dotnet/java-interop#1094

Adds support for emitting [Obsolete] warnings for API marked with androidx.annotation.RestrictTo. These warnings inform the user that the package owner does not consider an API to be "public". These warnings have a custom warning code (XAOBS001) that can be suppressed if desired.

This is enabled by default with the value obsolete, but can be disabled by setting $(AndroidEnableRestrictToAttributes) to disable.

<AndroidEnableRestrictToAttributes>disable</AndroidEnableRestrictToAttributes>

@jpobst jpobst marked this pull request as ready for review April 26, 2023 15:54

Support for this property was added in .NET 8.

This property is `True` by default.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also add:

If you would instead prefer to *remove* members that have the `@RestrictTo` annotation *or* are in non-exported Java packages, you can use [Transform files](https://learn.microsoft.com/xamarin/android/platform/binding-java-library/customizing-bindings/java-bindings-metadata#metadataxml-transform-file) to prevent these types from being bound:

            <attr path="//class[@annotated-visibility]"
                name="visibility">kotlin-internal</attr>
            <attr path="//interface[@annotated-visibility]"
                name="visibility">kotlin-internal</attr>

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…formatted properly to use XML block formatting, as appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated using <remove-node>.

@jpobst jpobst force-pushed the enable-restrict-to branch from f1355ef to 0f30f6a Compare May 1, 2023 19:40
@jonpryor
Copy link
Member

jonpryor commented May 2, 2023

We're gonna change the boolean MSBuild property to an "enum" property.

@jonpryor
Copy link
Member

jonpryor commented May 2, 2023

WIP commit message (will need updating for enum semantics):

Context: https://github.com/xamarin/java.interop/issues/1081
Context: https://github.com/xamarin/java.interop/commit/b274a67f38e2f4012ab8414cba2c778f53f0b13c
Context: https://github.com/xamarin/AndroidX/issues/690

Android libraries may use the [`androidx.annotation.RestrictTo`][0]
annotation to mark a `public` Java type as "not public":

	// Java
	@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
	public class DrawableWrapper extends Drawable {
	}

Unfortunately, .NET Android didn't know about this annotation, so all
such annotated types were bound as *`public`* types:

	// C# binding
	public class DrawableWrapper : Drawable {
	}

This is a problem because Google doesn't maintain API compatibility
for types with the `@RestrictTo` annotation.  This can result in
undesirable API breakage; see also xamarin/AndroidX#690.

xamarin/java.interop#b274a67f updated `class-parse` to know about the
`@RestrictTo` annotation; when present, an `//*/@annotated-visibility`
attribute is present within `api.xml`:

	<class
	    name="DrawableWrapper"
	
	    annotated-visibility="LIBRARY_GROUP_PREFIX"
	/>

xamarin/java.interop#b274a67f also updated `generator` to support a
`generator --lang-features=restrict-to-attributes`; when present,
types with an `//*/@annotated-visibility` attribute will be marked
as `[Obsolete]` (*not* removed!), in order to maintain API
compatibility with existing ("broken") bindings, so that customers
can migrate away from these types:

	// C# binding
	[Obsolete
	    "While this type is 'public', Google considers it internal API and reserves the right to modify or delete it in the future. Use at your own risk.",
	    DiagnosticId = "XAOBS001")
	partial class DrawableWrapper : Drawable {
	}

The new `[Obsolete]` usage also specifies a custom warning code of
`XAOBS001` so that the warning can be suppressed if desired.

Add support for a new `$(AndroidEnableRestrictToAttributes)` MSBuild
"enum-style" property.  Supported values include:

  * `obsolete`: `generator --lang-features=restrict-to-attributes`
    will be used and the `[Obsolete]` custom attribute will be placed
    on bindings of Java types which have a `@RestrictTo` annotation.

    This is the default value.

  * `disable`: Java types with a `@RestrictTo` annotation
    will *not* be marked as `[Obsolete]`, and will be bound as a
    "normal" Java `public` type.

        <AndroidEnableRestrictToAttributes>disable</AndroidEnableRestrictToAttributes>

If you would instead prefer that types with `@RestrictTo` not be
bound at all, this can be achieved via Metadata, e.g.

	<remove-node path="//*[@annotated-visibility]" />

[0]: https://developer.android.com/reference/androidx/annotation/RestrictTo

@jpobst jpobst force-pushed the enable-restrict-to branch from 18092d7 to 9e30ada Compare May 2, 2023 16:13
@jonpryor jonpryor merged commit 50521d9 into main May 2, 2023
@jonpryor jonpryor deleted the enable-restrict-to branch May 2, 2023 18:51
grendello added a commit to grendello/xamarin-android that referenced this pull request May 4, 2023
* main:
  Bump to dotnet/installer@0ce891843a 8.0.100-preview.5.23228.7 (dotnet#7994)
  [ci] Automatically retry failed emulator tests. (dotnet#7997)
  [xaprepare] Combine 'AndroidTestDependencies' and 'EmulatorTestDependencies' scenarios. (dotnet#8006)
  [xaprepare] Provision 'platform-33_r02' (dotnet#8004)
  [Xamarin.Android.Build.Tasks] Add AndroidEnableRestrictToAttributes (dotnet#7990)
  [ci] Remove plots-to-appinsights. (dotnet#8002)
  [Xamarin.Android.Build.Tasks] remove NuGet dependencies (dotnet#8000)
  Bump to 33.0.56 $(AndroidNet7Version) (dotnet#7998)
  $(AndroidPackVersionSuffix)=preview.5; net8 is 34.0.0-preview.5 (dotnet#7996)
jonathanpeppers pushed a commit that referenced this pull request Aug 15, 2023
…7990)

Context: dotnet/java-interop#1081
Context: dotnet/java-interop@b274a67
Context: dotnet/android-libraries#690

Android libraries may use the [`androidx.annotation.RestrictTo`][0]
annotation to mark a `public` Java type as "not public":

	// Java
	@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
	public class DrawableWrapper extends Drawable {
	}

Unfortunately, .NET Android didn't know about this annotation, so all
such annotated types were bound as *`public`* types:

	// C# binding
	public class DrawableWrapper : Drawable {
	}

This is a problem because Google doesn't maintain API compatibility
for types with the `@RestrictTo` annotation.  This can result in
undesirable API breakage; see also dotnet/android-libraries#690.

xamarin/java.interop#b274a67f updated `class-parse` to know about the
`@RestrictTo` annotation; when present, an `//*/@annotated-visibility`
attribute is present within `api.xml`:

	<class
	    name="DrawableWrapper"
	    …
	    annotated-visibility="LIBRARY_GROUP_PREFIX"
	/>

xamarin/java.interop#b274a67f also updated `generator` to support a
`generator --lang-features=restrict-to-attributes`; when present,
types with an `//*/@annotated-visibility` attribute will be marked
as `[Obsolete]` (*not* removed!), in order to maintain API
compatibility with existing ("broken") bindings, so that customers
can migrate away from these types:

	// C# binding
	[Obsolete
	    "While this type is 'public', Google considers it internal API and reserves the right to modify or delete it in the future. Use at your own risk.",
	    DiagnosticId = "XAOBS001")
	partial class DrawableWrapper : Drawable {
	}

The new `[Obsolete]` usage also specifies a custom warning code of
`XAOBS001` so that the warning can be suppressed if desired.

Add support for a new `$(AndroidEnableRestrictToAttributes)` MSBuild
"enum-style" property.  Supported values include:

  * `obsolete`: `generator --lang-features=restrict-to-attributes`
    will be used and the `[Obsolete]` custom attribute will be placed
    on bindings of Java types which have a `@RestrictTo` annotation.

    This is the default value.

  * `disable`: Java types with a `@RestrictTo` annotation
    will *not* be marked as `[Obsolete]`, and will be bound as a
    "normal" Java `public` type.

        <AndroidEnableRestrictToAttributes>disable</AndroidEnableRestrictToAttributes>

If you would instead prefer that types with `@RestrictTo` not be
bound at all, this can be achieved via Metadata, e.g.

	<remove-node path="//*[@annotated-visibility]" />

[0]: https://developer.android.com/reference/androidx/annotation/RestrictTo
@github-actions github-actions bot locked and limited conversation to collaborators Jan 22, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants