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
[api-compat] Provide API diffs around API breakage
Context: #4356
Context: 54beb90
Context: a20be39
The use of `Microsoft.DotNet.ApiCompat.exe` added in 07e7477 has one
major deficiency:
The error messages reported by `Microsoft.DotNet.ApiCompat.exe` are
*awful* and borderline useless or misleading.
For example, consider commit PR #4356, which attempts to bring sanity
and consistency around `$(AndroidPlatformId)` and `Mono.Android.dll`
builds. It contains an API break, which we'll hand wave away and
accept for preview release purposes, in which the property type for
`Android.Telephony.CellInfoGsm.CellIdentity` changes from
`CellIdentityGsm` to `CellIdentity`:
// API-29
namespace Android.Telephony {
public sealed partial class CellInfoGsm: Android.Telephony.CellInfo, Android.OS.IParcelable {
public unsafe Android.Telephony.CellIdentityGsm CellIdentity {
}
}
// API-R
namespace Android.Telephony {
public sealed partial class CellInfoGsm : Android.Telephony.CellInfo, Android.OS.IParcelable {
public unsafe Android.Telephony.CellIdentity CellIdentity {
}
}
This is clearly a break. How does `Microsoft.DotNet.ApiCompat.exe`
report the breakage?
error : MembersMustExist : Member 'Android.Telephony.CellInfoGsm.CellIdentity.get()' does not exist in the implementation but it does exist in the contract.
Which is infuriatingly terrible. The message *implies* that
`Android.Telephony.CellInfoGsm.get_CellIdentity()` doesn't exist, but
it *does* exist. The problem is that the return type changed!
Or consider 54beb90, in which we now emit a slew of default interface
members within the `Mono.Android.dll` binding, which *should* be API
compatible. `Microsoft.DotNet.ApiCompat.exe` complains as well:
InterfacesShouldHaveSameMembers : Interface member 'Java.Util.Functions.IUnaryOperator.Identity()' is present in the implementation but not in the contract.
What these messages have in common is that they provide no context,
lack important types, and in no way suggest how to *fix* the error
other than to just ignore it.
Overhaul this infrastructure so that crucial context is provided.
The context is provided by using "reference assembly source":
the [`Microsoft.DotNet.GenAPI.exe` utility][0] can be run on an
assembly to generate C# source code that shows the same API but no
implementation:
namespace Android.Accounts
{
[Android.Runtime.RegisterAttribute("android/accounts/AbstractAccountAuthenticator", DoNotGenerateAcw=true, ApiSince=5)]
public abstract partial class AbstractAccountAuthenticator : Java.Lang.Object
{
[Android.Runtime.RegisterAttribute("KEY_CUSTOM_TOKEN_EXPIRY", ApiSince=23)]
public const string KeyCustomTokenExpiry = "android.accounts.expiry";
[Android.Runtime.RegisterAttribute(".ctor", "(Landroid/content/Context;)V", "")]
public AbstractAccountAuthenticator(Android.Content.Context context) { }
Update the `src/Mono.Android` build so that after every build, after
running `Microsoft.DotNet.ApiCompat.exe` we *also* run
`Microsoft.DotNet.GenAPI.exe` on the generated assembly, then run
`diff -u` against the recently created assembly and the reference
assembly source for the contract assembly. This allows us to get
*useful diffs* in the API:
Task "Exec" (TaskId:570)
Task Parameter:Command=diff -u "../../tests/api-compatibility/reference/Mono.Android.dll.cs" "/Volumes/Xamarin-Work/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll.cs" (TaskId:570)
diff -u "../../tests/api-compatibility/reference/Mono.Android.dll.cs" "/Volumes/Xamarin-Work/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll.cs" (TaskId:570)
--- ../../tests/api-compatibility/reference/Mono.Android.dll.cs 2020-03-05 13:20:59.000000000 -0500 (TaskId:570)
+++ /Volumes/Xamarin-Work/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll.cs 2020-03-05 13:40:12.000000000 -0500 (TaskId:570)
@@ -27,7 +27,7 @@ (TaskId:570)
{ (TaskId:570)
[Android.Runtime.RegisterAttribute("ACCEPT_HANDOVER", ApiSince=28)] (TaskId:570)
public const string AcceptHandover = "android.permission.ACCEPT_HANDOVER"; (TaskId:570)
- [Android.Runtime.RegisterAttribute("ACCESS_BACKGROUND_LOCATION")] (TaskId:570)
+ [Android.Runtime.RegisterAttribute("ACCESS_BACKGROUND_LOCATION", ApiSince=29)] (TaskId:570)
(The above is courtesy commmit 4cd2060, which added
`RegisterAttribute.ApiSince` on a large number of members.)
Finally, how do we update the "contract" `Mono.Android.dll` assembly?
Add a new `tests/api-compatibility/api-compatibility.targets` file
which contains a `UpdateMonoAndroidContract` target which will update
`tests/api-compatibility/reference/Mono.Android.zip` with the contents
of a `cil-strip`'d `Mono.Android.dll` and updated "reference assembly
source".
`Mono.Android.zip` contains a contract from Xamarin.Android 10.2.0.100
for `$(TargetFrameworkVersion)` v10.0.
Note: The `diff -u` invocation and `UpdateMonoAndroidContract` targets
currently only work on non-Windows platforms, due to the use of the
**diff**(1) and **zip**(1L) utilities.
[0]: https://github.com/dotnet/arcade/tree/bc4fa8e7149769db4efd466f160417a32b11f0bf/src/Microsoft.DotNet.GenAPI
0 commit comments