Given the following API definition:
```cs
[Protocol]
public interface Protocol {
[Abstract]
[Export ("requiredMethod")]
void RequiredMethod ();
[Export ("optionalMethod")]
void OptionalMethod ();
}
```
we're now binding it like this:
```cs
[Protocol ("Protocol")]
public interface IProtocol : INativeObject {
[RequiredMember]
[Export ("requiredMethod")]
public void RequiredMethod () { /* default implementation */ }
[OptionalMember]
[Export ("optionalMethod")]
public void OptionalMethod () { /* default implementation */ }
}
```
The main difference from before is that the only difference between required
and optional members is the [RequiredMember]/[OptionalMember] attributes.
This has one major advantage: it's now possible to switch a member from being
required to being optional, or vice versa, without breaking neither source nor
binary compatibility.
It also improves intellisense for optional members. In the past optional
members were implemented using extension methods, which were not very
discoverable when you were supposed to implement a protocol in your own class.
The main downside is that the C# compiler won't enforce developers to
implement required protocol members (which is a necessary side effect of the
fact that we want to be able to switch members between being required and
optional without breaking compatibility). If this turns out to be a problem,
we can implement a custom source analyzer and/or linker step that detects
missing implementations and issue warnings/errors.
This PR also:
* Adds numerous tests.
* Updates the requiredness of a few members in Metal to test that it works as
expected.
* Adds documentation.
* Handles numerous corner cases, which are documented in code and docs.
This PR is probably best reviewed commit-by-commit.
Fixes https://github.com/xamarin/xamarin-macios/issues/13294.
## Description
This PR enables the dedup optimization in FullAOT mode only. The
optimization can only run in FullAOT mode with complete application
context. Without it, the AOT compiler may fail to collect all generic
instances, and the runtime can't find them as they are searched in the
dedup assembly.
## Changes
This PR updates the SDK targets to enable dedup optimization in FullAOT
mode only. This change doesn't depend on any runtime changes.
## Verification
This PR also introduces partial AOT tests. They inspect the bundle for
`aot-instances.dll`, which shouldn't be generated in a partial AOT
compilation setup. Additionally, basic functionality is tested by
asserting at app startup.
## Additional notes
This change should be backported to .NET 8 as well.
Fixes https://github.com/dotnet/runtime/issues/99248
There are now two post build pipelines that run the tests when a new
build has complited building the nuget packages and dependencies. This
allows the project to have a cleaner build pipeline to onboard on the
1ES template.
* The AVSampleCursor type was made available on all platforms two years ago (as
opposed to only macOS before that), so update availability attributes accordingly.
* Also make a few structs used by AVSampleCursor blittable (AVSampleCursorSyncInfo,
AVSampleCursorDependencyInfo, AVSampleCursorChunkInfo, AVSampleCursorAudioDependencyInfo)
This got a bit complicated, because some of the non-blittable members of these structs
are public. This meant a workaround had to be implemented:
* Rename the properties that use these structures - appending "_Blittable" - and
make them internal.
* Create internal "*_Blittable" versions of the structures, and a make the "_Blittable"
properties return these structures.
* Bind the properties again, wrapping the internal versions and manually converting
from the blittable structures to the non-blittable structures.
Note that since some of the properties are new on iOS and tvOS, we don't need the
compatibility workaround for these platforms.
Contributes towards #15684.
Import all the xml documentation for types from https://github.com/xamarin/apple-api-docs.
Some of this documentation should probably be rewritten, and potentially moved
to conceptual documentation, in particular those that contain images (because
images can't be imported into xml documentation).
Note that the documentation hasn't been modified in any way; that's not the purpose of this PR. If documentation should be modified for whatever reason, it can be done in a later PR.
The xml documentation for members will come in a later PR.
Partial fix for https://github.com/xamarin/xamarin-macios/issues/17399.
The steps used to publish build asset information to maestro have been
updated. The post build stage has been disabled for main and .NET 9, as
maestro manifest generation and channel promotion will now run as part
of the "Prepare .NET Release" stage.
With the new `PushToAzureDevOpsArtifacts` task the build pipeline should
now create all of the artifacts required for maestro artifact
publishing.
The `add-build-to-channel` darc command will now trigger a
[Build Promotion Pipeline][0] that pushes build assets to the feed that
corresponds to the maestro channel that is being updated. We should
no longer need to push assets to various NuGet feeds in a separate step.
[0]:
https://dev.azure.com/devdiv/DevDiv/_build/results?buildId=9654802&view=logs&j=ba23343f-f710-5af9-782d-5bd26b102304&t=aec38b44-8611-5dd5-3900-5feff4e06d1b
---------
Co-authored-by: Alex Soto <alex@alexsoto.me>
This is mostly to ensure that in XAMCORE_5_0 we fix all APIs with MarshalAs
attributes, because in order to not break binary compatibility, we can't fix
all of these failures right now.
Additionally it ensures we don't add more APIs with MarshalAs attributes.
Fix BundleStructure when building for only tvOS by detecting whether the
bindings are zipped or not by detecting the presence of the zip file, instead
of computing it based on the current platform (which becomes problematic,
because whether or not a binding project produces a zip file may depend on
whether other platforms are enabled or not).
This test doesn't work when building on iossimulator-arm64 or
tvossimulator-arm64, because we're trying to use a fat framework which doesn't
have that architecture (it contains the device arm64 architecture instead).
So just disable this test on iOS and tvOS - the solution is using an
xcframework, and we already have a different test for that.
---------
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
Call mono_unhandled_exception to raise AppDomain.UnhandledException when
managed exceptions are unhandled.
Partial fix for #15252 (for MonoVM, still pending for CoreCLR, which
needs https://github.com/dotnet/runtime/issues/102730 fixed first).
Include the PR number and title in the commit message.
This makes GitHub emails a bit more descriptive (since there are often
multiple PRs where global.json is bumped).
The logic to update the request's RequestUri is somewhat old:
518ac1bf19
but it makes sense to do so.
Some testing with a console app, also revealed that a plain .NET does this in
case of a redirect:
```cs
async static Task Main ()
{
var client = new HttpClient () { BaseAddress = new Uri("https://httpbin.org") };
var request = new HttpRequestMessage (HttpMethod.Get,
"/redirect-to?url=https%3A%2F%2Fmicrosoft.com&status_code=302&queries[]={}"
);
Console.WriteLine ($"Request uri 1: {request.RequestUri}");
var response = await client.SendAsync(request);
Console.WriteLine ($"Request uri 2: {request.RequestUri}");
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine ((int) response.StatusCode);
Console.WriteLine(content.Length);
}
```
prints:
```
Request uri 1: /redirect-to?url=https%3A%2F%2Fmicrosoft.com&status_code=302&queries[]={}
Request uri 2: https://www.microsoft.com/es-es/
200
201252
```
Further looking into .NET's code, `SocketsHttpHandler` updates RequestUri after
following a redirect:
f5eb26e4da/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/RedirectHandler.cs (L65-L66)
So it seems the expected behavior is to update RequestUri only in case of a
redirect.
Now the question becomes: how to detect whether we're a redirect or not?
Contrary to `SocketsHttpHandler`, we don't do the actual redirect, it's
handled transparently by `NSUrlSession`.
Fortunately `NSUrlSessionTask` has two properties which help:
[`OriginalRequest`][1] and [`CurrentRequest`][2]. According to Apple's
documentation, these are the same, "except when the server has responded to
the initial request with a redirect to a different URL."
This sounds perfect for us, so use these two properties to determine whether a redirect occurred.
Note that we can't use object identity, because these are 'copy' properties,
which means they'll never be the same instances, only at most a copy of
eachother. So instead compare the `AbsoluteString` property to check for
equality. As far as I'm aware, none of the other properties (request body,
headers, cookies, etc.) can be set by the server in a redirect, so there's no
need to compare those.
Fixes https://github.com/xamarin/xamarin-macios/issues/20629.
[1]: https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411572-originalrequest
[2]: https://developer.apple.com/documentation/foundation/nsurlsessiontask/1411649-currentrequest
GCMouse doesn't conform to NSCoding/NSSecureCoding, so fix the API definition.
Since this would be a breaking change, also add compat code to preserve binary
compatibility.
Fixes this test:
Introspection.MacApiSelectorTest
[FAIL] InstanceMethods : 1 errors found in 33428 instance selector validated:
Selector not found for GameController.GCMouse : encodeWithCoder: in Void EncodeTo(Foundation.NSCoder) on GameController.GCMouse
Expected: 0
But was: 1
[FAIL] Selector not found for GameController.GCMouse : encodeWithCoder: in Void EncodeTo(Foundation.NSCoder) on GameController.GCMouse
at Introspection.ApiSelectorTest.InstanceMethods() in /Users/rolf/work/maccore/net9.0/xamarin-macios/tests/introspection/ApiSelectorTest.cs:line 1121
Version the Xamarin.Localization.MSBuild assembly correctly (instead of
hardcoding a 1.0.0 version - implicitly so because no version was set), so
that we can load multiple versions of the assembly into the same process.
Fixes https://github.com/xamarin/xamarin-macios/issues/20062.
In C# there are two ways to specify that a comment is an xml documentation comment:
1. The single-line '///''
2. The multi-line '/** ... **/'
TIL about the second one, when my upcoming tool to migrate API documentation
to xml comments complained that these members already had an xml comment.
This seems entirely accidental, so just remove/rewrite these few comments.
Also fix a few other typos, grammar mistakes, etc.
Add support for binding constructors in protocols.
Given the api definition:
```cs
[Protocol]
public interface Protocol {
[Abstract]
[Export ("init")]
IntPtr Constructor ();
[Export ("initWithValue:")]
IntPtr Constructor (IntPtr value);
[BindAs ("Create")]
[Export ("initWithPlanet:")]
IntPtr Constructor ();
}
```
we're binding it like this:
```cs
[Protocol ("Protocol")]
public interface IProtocol : INativeObject {
[Export ("init")]
public static T CreateInstance<T> () where T: NSObject, IProtocol { /* default implementation */ }
[Export ("initWithValue:")]
public static T CreateInstance<T> () where T: NSObject, IProtocol { /* default implementation */ }
[Export ("initWithPlanet:")]
public static T Create<T> () where T: NSObject, IProtocol { /* default implementation */ }
}
```
Also add documentation and tests.
Fixes https://github.com/xamarin/xamarin-macios/issues/14039.
---------
Co-authored-by: Manuel de la Pena <mandel@microsoft.com>
Co-authored-by: Alex Soto <alex@soto.dev>
The validation verifies that the function pointer for a block callback is the
same the return value from the method's
MethodInfo.MethodHandle.GetFunctionPointer() method.
In actual code, it's equivalent to validating that the following always prints "Equal: true":
```cs
[UnmanagedCallersOnly]
public static void Invoke () {}
static void Test ()
{
delegate* unmanaged<void> fptr1 = &Invoke;
IntPtr fptr2 = GetType ().GetMethod ("Invoke").MethodHandle.GetFunctionPointer ();
Console.WriteLine ($"fptr1: 0x{((IntPtr) fptr1).ToString ("x")}");
Console.WriteLine ($"fptr2: 0x{fptr2.ToString ("x")}");
Console.WriteLine ($"Equal: ((IntPtr) fptr1) == fptr2}"); // prints "Equal: true" for me
}
```
However, this isn't documented, and some feedback indicates it's certainly not
a valid assumption for CoreCLR:
https://discord.com/channels/732297728826277939/732582981163548703/1242473425759633488
And there's also a customer running into this validation, apparently without cause:
https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2054534
So just remove it.
So instead of this:
> Cecil.Tests.Documentation+AssemblyApi: Documented API not found in the platform assembly. This probably indicates that the code to compute the doc name for a given member is incorrect.
we'll get:
> T:Foundation.SomeType: Documented API not found in the platform assembly. This probably indicates that the code to compute the doc name for a given member is incorrect.
Fixes this failure:
> 🔥 Unable to find the contents for the comment: D:\a\1\a\change-detection\results\gh-comment.md does not exist :fire
This is a partial revert of #20601, which broke the API diff.