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

Nullability context and code refactor #11

Merged
merged 8 commits into from
Dec 12, 2023

Conversation

AgentFire
Copy link

Added #nullable-context:enable to main projects.
Added #lang-version:latest to main projects.
Updated NuGet packages on the main projects.

Refactoring:
Added braces to code blocks.
Converted to file-scope namespaces.
Added nullability modifiers where required
Added missing null checks
Other minor one-click IDE refactors to bring the code base to be more consistent.

Added #nullable-context:enable to main projects.
Added #lang-version:latest to main projects.
Updated NuGet packages on the main projects.

Refactoring:
Added braces to code blocks.
Converted to file-scope namespaces.
Added nullability modifiers where required
Added missing null checks
Other minor one-click IDE refactors to bring the code base to be more consistent.
Copy link
Member

@PJB3005 PJB3005 left a comment

Choose a reason for hiding this comment

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

Doing everything in a single commit like this is a no-go. I can't possibly review these changes.

Doing something like enabling nullability is good.

Completely restyling all the lines in the project has little benefit and is not worth the churn it creates. Even if it were a separate commit I still don't want to bother for various reasons.

@AgentFire AgentFire marked this pull request as draft November 14, 2023 19:47
@AgentFire AgentFire marked this pull request as ready for review November 14, 2023 19:51
@AgentFire
Copy link
Author

Understandable, here is a downgraded version 😊

@AgentFire AgentFire requested a review from PJB3005 November 14, 2023 22:26
Copy link
Member

@PJB3005 PJB3005 left a comment

Choose a reason for hiding this comment

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

All in all there's still more stylistic changes than I'd prefer, but the biggest review task was still the nullables.

Comment on lines 8 to 9
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
Copy link
Member

Choose a reason for hiding this comment

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

This is indented wrong. Also don't set LangVersion to latest, set it to a fixed version.

Comment on lines 6 to 7
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>
Copy link
Member

Choose a reason for hiding this comment

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

Same issues as other csproj.

Comment on lines 1134 to 1137
if (zVal == null || yAccum == null)
{
throw new InvalidOperationException("both zVal and yAccum should not be null");
}
Copy link
Member

Choose a reason for hiding this comment

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

I'd just make this an assert instead. It should mute nullability warnings.

Copy link
Author

Choose a reason for hiding this comment

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

It doesn't mute any warning unfortunately, so I'll add another helper method based on AgumentNullException.ThrowIfNull.

Comment on lines 17 to 26
internal byte[] BufferData => m_data ?? throw new InvalidOperationException($"{nameof(m_data)} is null");

internal byte[]? m_data;
internal int m_bitLength;
internal int m_readPosition;

/// <summary>
/// Gets or sets the internal data buffer
/// </summary>
public byte[] Data
public byte[]? Data
Copy link
Member

Choose a reason for hiding this comment

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

As far as I can tell, m_data can only be null if the message is currently pooled. I'd just make Data throw in that case (as it's kind of an invalid state to be doing stuff with it, you shouldn't have a handle) so it doesn't need to be nullable.

{
lock (m_connections)
{
if (m_connections.Count > 0)
{
LogWarning("Connect attempt failed; Already connected");
return null;
throw new InvalidOperationException("Connect attempt failed; Already connected");
Copy link
Member

Choose a reason for hiding this comment

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

Not sure it's a good idea to change behavior like this.

Comment on lines 282 to 288
public static string MakeCommaDelimitedList<T>(IReadOnlyList<T> list)
{
var cnt = list.Count;
StringBuilder bdr = new StringBuilder(cnt * 5); // educated guess
for(int i=0;i<cnt;i++)
for (int i = 0; i < cnt; i++)
{
bdr.Append(list[i].ToString());
bdr.Append(list[i]?.ToString());
Copy link
Member

Choose a reason for hiding this comment

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

Annotate the function with T : notnull instead, don't change the behavior.

{
var defaultAddress = ProbeDefaultRouteAddress();
IPAddress? defaultAddress = ProbeDefaultRouteAddress();
Copy link
Member

Choose a reason for hiding this comment

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

This change shouldn't be necessary.

@@ -71,7 +72,7 @@ private static IPAddress ProbeDefaultRouteAddress()
// This basically gets us the network interface address "that goes to the router".
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(new IPAddress(new byte[] { 1, 1, 1, 1 }), 12345);
return ((IPEndPoint)socket.LocalEndPoint).Address;
return (socket.LocalEndPoint as IPEndPoint)?.Address;
Copy link
Member

Choose a reason for hiding this comment

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

LocalEndPoint is expected to be set by the connect call, this should be an assert if anything at all.

@@ -51,7 +51,7 @@ public void TestResolveEndPointBasic()
var addr = NetUtility.Resolve("example.com", 55555);

Assert.That(addr, Is.Not.Null);
Assert.That(addr.Port, Is.EqualTo(55555));
Assert.That(addr?.Port, Is.EqualTo(55555));
Copy link
Member

Choose a reason for hiding this comment

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

This doesn't make sense, the address is null checked right above.

@@ -88,7 +88,7 @@ public async Task TestResolveEndPointAsyncBasic()
var addr = await NetUtility.ResolveAsync("example.com", 55555);

Assert.That(addr, Is.Not.Null);
Assert.That(addr.Port, Is.EqualTo(55555));
Assert.That(addr?.Port, Is.EqualTo(55555));
Copy link
Member

Choose a reason for hiding this comment

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

Ditto.

@AgentFire
Copy link
Author

I believe I've worked out all your comments.

@AgentFire AgentFire requested a review from PJB3005 November 18, 2023 00:33
@AgentFire
Copy link
Author

@PJB3005 I believe there is a workflow button to be pressed?..

Copy link
Member

@PJB3005 PJB3005 left a comment

Choose a reason for hiding this comment

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

I'll just fix the last couple issues myself.

Comment on lines 75 to 92
/// <summary>Returns the passed <paramref name="argument"/>, but throws an <see cref="NetException"/> if the <paramref name="argument"/> is null.</summary>
/// <param name="argument">The reference type argument to validate as non-null.</param>
/// <param name="paramName">The name of the parameter with which <paramref name="argument"/> corresponds.</param>
#if !DEBUG
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T ThrowIfNull<T>(T argument, string? paramName = null)
{
return argument;
}
#else
#if NET5_0_OR_GREATER
public static T ThrowIfNull<T>([NotNull] T? argument, [CallerArgumentExpression(nameof(argument))] string? paramName = null) where T : class
#else
public static T ThrowIfNull<T>([NotNull] T? argument, string? paramName = null) where T : class
#endif
{
return argument ?? throw new NetException($"{paramName ?? "argument"} is null");
}
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 like these methods for a few reasons:

  1. They should be internal, not public.
  2. They're used interchangeably as asserts and ArgumentNullExceptions, which is confusing.

@@ -19,7 +19,7 @@ public void DiscoverLocalPeers(int serverPort)
um.m_messageType = NetMessageType.Discovery;
Interlocked.Increment(ref um.m_recyclingCount);

m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(new NetEndPoint(NetUtility.GetBroadcastAddress() ?? throw new InvalidOperationException(), serverPort), um));
m_unsentUnconnectedMessages.Enqueue(new NetTuple<NetEndPoint, NetOutgoingMessage>(new NetEndPoint(NetException.ThrowIfNull(NetUtility.GetBroadcastAddress()), serverPort), um));
Copy link
Member

Choose a reason for hiding this comment

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

This isn't great because it doesn't further explain why the exception happened.

Comment on lines 331 to 336
public T?[] ToArray()
{
m_lock.EnterReadLock();
try
{
T[] retval = new T[m_size];
T?[] retval = new T[m_size];
Copy link
Member

Choose a reason for hiding this comment

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

It shouldn't be possible for the queue to contain null entries within the actual valid range, so these shouldn't be nullable.

Remove NetException.ThrowIfNull in favor of NetException.Assert, ArgumentNullException and InvalidOperationException.

NetException.Assert now has [DoesNotReturnIf(false)] on its bool parameter. This makes the C# compiler understand it for NRT analysis.
@PJB3005
Copy link
Member

PJB3005 commented Dec 12, 2023

Because you made this PR from your wizards branch I can't push to it, I made a PR to your fork: AgentFire#1

@AgentFire
Copy link
Author

Merged. A nice touch with the DoesNotReturnIf.

@PJB3005 PJB3005 merged commit e2a5762 into space-wizards:wizards Dec 12, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants