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

[coremidi] Add nullability to (generated and manual) bindings #15098

Merged
merged 7 commits into from
Jun 6, 2022

Conversation

tj-devel709
Copy link
Member

This PR aims to bring nullability changes to CoreMidi.
Following the steps here:

  1. I am adding nullable enable to all manual files that are not "API_SOURCES" in src/frameworks.sources and making the required nullability changes
  2. Changing all throw new ArgumentNullException ("object")); to ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (object)); for size saving optimization as well to mark that this framework contains nullability changes
  3. Changing any == null or != null to is null and is not null

@tj-devel709 tj-devel709 added the not-notes-worthy Ignore for release notes label May 23, 2022
@tj-devel709 tj-devel709 added this to the Future milestone May 23, 2022
get {
return GetData (kMIDIPropertyConnectionUniqueID);
}
set {
if (value is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (value));
Copy link
Member Author

Choose a reason for hiding this comment

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

While I realize that I added a good amount of these and that SetData () throws an exception if the value arg is null, I thought it would be better to explicitly add the exceptions here and not use a !, but I am open to opinions!

Copy link
Member

Choose a reason for hiding this comment

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

Explicit over implicit, I like it.

connectionParams.NumSources = (uint)Sources.Length;
for (int i = 0; i < Sources.Length; i++)
connectionParams.Sources[i] = Sources[i];
connectionParams.Sources [i] = Sources [i];
}
Copy link
Member Author

Choose a reason for hiding this comment

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

I could possibly see this being a change in behavior since now it's possible that the connectionParams.NumSources could not be set if the connectionParams.Sources is null. I don't think that we want it to be set in that scenario anyways so either this is negligible, I can add a conditional around the for loop (but it looks messy), or I can just add an ! saying the connectionParams.Sources is not null.

Same thing with the connectionParams.NumDestinations a few lines below.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is a breaking change:

  1. If Sources.Length is 0, then if NumSources isn't assigned there's no difference (because 0 is the default value)
  2. If Sources.Length > 0, then we'd run into a NullReferenceException in the loop.

So yes, there's a change in behavior, but from a NullReferenceException to no exception, which I think is fine in this scenario.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

connectionParams.NumSources = (uint)Sources.Length;
for (int i = 0; i < Sources.Length; i++)
connectionParams.Sources[i] = Sources[i];
connectionParams.Sources [i] = Sources [i];
}
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this is a breaking change:

  1. If Sources.Length is 0, then if NumSources isn't assigned there's no difference (because 0 is the default value)
  2. If Sources.Length > 0, then we'd run into a NullReferenceException in the loop.

So yes, there's a change in behavior, but from a NullReferenceException to no exception, which I think is fine in this scenario.

@@ -758,7 +761,7 @@ public class MidiPacket
#if !COREBUILD
public long TimeStamp;
IntPtr byteptr;
byte [] bytes;
byte []? bytes;
Copy link
Member

Choose a reason for hiding this comment

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

Setting this to Array.Empty will remove a few things.

Comment on lines 1023 to 1025
using (var args = new MidiPacketsEventArgs (packetList)) {
e (port, args);
}
Copy link
Member

Choose a reason for hiding this comment

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

For the future, you can use using without the {} since it is small.

get {
return GetData (kMIDIPropertyConnectionUniqueID);
}
set {
if (value is null)
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (value));
Copy link
Member

Choose a reason for hiding this comment

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

Explicit over implicit, I like it.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2
Copy link
Collaborator

📋 [PR Build] API Diff 📋

API diff (for current PR)

ℹ️ API Diff (from PR only) (please review changes)

API diff: vsdrops gist

Xamarin
.NET
Xamarin vs .NET
iOS vs Mac Catalyst (.NET)

API diff (vs stable)

✅ API Diff from stable

API diff: vsdrops gist

Xamarin
.NET
Xamarin vs .NET
iOS vs Mac Catalyst (.NET)

Generator diff

Generator Diff (no change)

Pipeline on Agent XAMBOT-1033.Monterey'
Hash: a7d838cf5b1640f212cba6b3ccb508a53d060dcc

@vs-mobiletools-engineering-service2
Copy link
Collaborator

📚 [PR Build] Artifacts 📚

Packages generated

View packages

Pipeline on Agent XAMBOT-1103.Monterey
Hash: a7d838cf5b1640f212cba6b3ccb508a53d060dcc

@vs-mobiletools-engineering-service2
Copy link
Collaborator

💻 [PR Build] Tests on macOS Mac Catalina (10.15) passed 💻

All tests on macOS Mac Catalina (10.15) passed.

Pipeline on Agent
Hash: a7d838cf5b1640f212cba6b3ccb508a53d060dcc

@vs-mobiletools-engineering-service2
Copy link
Collaborator

❌ [CI Build] Tests failed on VSTS: simulator tests iOS ❌

Tests failed on VSTS: simulator tests iOS.

Test results

1 tests failed, 147 tests passed.

Failed tests

  • xcframework-test/watchOS 32-bits - simulator/Debug: Crashed

Pipeline on Agent XAMBOT-1170.Monterey'
Merge a7d838c into 9822cbc

if (e != null) {
using (var args = new MidiPacketsEventArgs (packetList)) {
e (port, args);
if (gch.Target is MidiPort port) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is subtly different, as before a null gch.Target (or one of the wrong type) would throw, where this will silently no-op.

I think that is fine however.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah yes that is a good point!

Comment on lines +1023 to +1024
using (var args = new MidiPacketsEventArgs (packetList))
e (port, args);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
using (var args = new MidiPacketsEventArgs (packetList))
e (port, args);
using (var args = new MidiPacketsEventArgs (packetList)) {
e (port, args);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I think style wise we want braces for using blocks, but maybe I'm wrong?

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed this block style as a request from Manuel

var e = port.MessageReceived;
if (e != null)
e (port, new MidiPacketsEventArgs (packetList));
if (gch.Target is MidiEndpoint port) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto comment above.

@tj-devel709
Copy link
Member Author

@tj-devel709 tj-devel709 merged commit a2768dd into dotnet:main Jun 6, 2022
rolfbjarne pushed a commit that referenced this pull request Dec 12, 2022
. (#16992)

Closes #16979

The only `MidiPacket` constructor ever used internally is the one accepting an `IntPtr` argument. Therefore `bytes` will always have the default empty array value. Because of this, in the `Bytes` get accessor `bytes` is not null, but empty and indexing into `bytes` on line 848 throws the exception. The other option would have been to remove the empty array default value that was added in #15098, but the length check seemed like the safer, although maybe slightly less performant, option.
rolfbjarne pushed a commit that referenced this pull request Dec 13, 2022
…ception. Fixes #16979. (#17022)

Closes #16979

The only `MidiPacket` constructor ever used internally is the one accepting an `IntPtr` argument. Therefore `bytes` will always have the default empty array value. Because of this, in the `Bytes` get accessor `bytes` is not null, but empty and indexing into `bytes` on line 848 throws the exception. The other option would have been to remove the empty array default value that was added in #15098, but the length check seemed like the safer, although maybe slightly less performant, option.


Backport of #16992

Co-authored-by: Reid Kirkpatrick <[email protected]>
rolfbjarne pushed a commit that referenced this pull request Dec 13, 2022
Fixes #16979. (#17021)

Closes #16979

The only `MidiPacket` constructor ever used internally is the one accepting an `IntPtr` argument. Therefore `bytes` will always have the default empty array value. Because of this, in the `Bytes` get accessor `bytes` is not null, but empty and indexing into `bytes` on line 848 throws the exception. The other option would have been to remove the empty array default value that was added in #15098, but the length check seemed like the safer, although maybe slightly less performant, option.

Backport of #16992

Co-authored-by: Reid Kirkpatrick <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not-notes-worthy Ignore for release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants