Conversation
Sprinkle nullability information in a number of places where it makes sense.
There was a problem hiding this comment.
Pull request overview
This PR adds/adjusts C# nullable annotations across XHarness shared iOS and common components to better model where values may legitimately be absent (e.g., platform/configuration and environment variables), improving static null-safety across the codebase.
Changes:
- Made many
platform/configurationparameters nullable inProjectFileExtensionsAPIs. - Updated process execution APIs to allow environment variable values to be nullable (
Dictionary<string, string?>), enabling explicit removal of variables. - Updated logging and simulator-selection APIs with additional nullability annotations.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Microsoft.DotNet.XHarness.iOS.Shared/Utilities/ProjectFileExtensions.cs | Marks platform/configuration inputs as nullable across project XML helpers. |
| src/Microsoft.DotNet.XHarness.iOS.Shared/IResultParser.cs | Updates result parser API to allow nullable variation. |
| src/Microsoft.DotNet.XHarness.iOS.Shared/Hardware/SimulatorLoader.cs | Adjusts simulator selection enumerable nullability. |
| src/Microsoft.DotNet.XHarness.iOS.Shared/Execution/MlaunchProcessManager.cs | Allows nullable env-var values in mlaunch process execution APIs. |
| src/Microsoft.DotNet.XHarness.iOS.Shared/Execution/IMlaunchProcessManager.cs | Keeps interface in sync with mlaunch manager env-var nullability changes. |
| src/Microsoft.DotNet.XHarness.Common/Logging/NullLog.cs | Accepts nullable strings/args in the no-op logger implementation. |
| src/Microsoft.DotNet.XHarness.Common/Logging/Log.cs | Broadens logger write APIs and WriteImpl nullability. |
| src/Microsoft.DotNet.XHarness.Common/Logging/ILog.cs | Broadens logger interface to accept nullable strings/args. |
| src/Microsoft.DotNet.XHarness.Common/Execution/ProcessManager.cs | Allows nullable env-var values (with removal behavior when null). |
| src/Microsoft.DotNet.XHarness.Common/Execution/IProcessManager.cs | Keeps interface in sync with ProcessManager env-var nullability changes. |
| src/Microsoft.DotNet.XHarness.Apple/AppOperations/AppRunnerBase.cs | Allows passing nullable env-var dictionary into Mac Catalyst app runner. |
Comments suppressed due to low confidence (1)
src/Microsoft.DotNet.XHarness.Common/Logging/Log.cs:27
Write(string? value)can pass null through toWriteImpl(e.g., whenTimestampis false andvalueis null). Many existingWriteImploverrides currently take a non-nullstringand may warn (nullability mismatch) or throw if they start receiving null. Consider coalescingvaluetostring.Emptybefore callingWriteImpl(and keepWriteImplnon-nullable), or update all overrides to accept/handlestring?safely.
public void Write(string? value)
{
if (Timestamp)
{
value = "[" + DateTime.Now.ToString("HH:mm:ss.fffffff") + "] " + value;
| private static string? GetElementValue(this XmlDocument csproj, string? platform, string? configuration, string elementName, bool throwIfNotFound = true) | ||
| { | ||
| var nodes = csproj.SelectNodes($"/*/*/*[local-name() = '{elementName}']"); | ||
| foreach (XmlNode? n in nodes) |
There was a problem hiding this comment.
GetElementValue now allows platform/configuration to be null, but the method body later uses these values in string replacements (e.g., Replace("$(Platform)", platform) / Replace("$(Configuration)", configuration)) which will throw if the replacement value is null. Update the implementation to only replace when the corresponding value is non-null (or coalesce to empty) so callers can safely pass null.
| public static void SetMtouchUseLlvm(this XmlDocument csproj, bool value, string? platform, string? configuration) => SetNode(csproj, "MtouchUseLlvm", true ? "true" : "false", platform, configuration); | ||
|
|
||
| public static void SetMtouchUseBitcode(this XmlDocument csproj, bool value, string platform, string configuration) => SetNode(csproj, "MtouchEnableBitcode", true ? "true" : "false", platform, configuration); | ||
| public static void SetMtouchUseBitcode(this XmlDocument csproj, bool value, string? platform, string? configuration) => SetNode(csproj, "MtouchEnableBitcode", true ? "true" : "false", platform, configuration); |
There was a problem hiding this comment.
Both SetMtouchUseLlvm and SetMtouchUseBitcode ignore the value parameter and always write "true" because they use true ? "true" : "false". This makes it impossible to set these properties to false. Use the value parameter when selecting the string to write.
| public IEnumerable<ISimulatorDevice> SelectDevices(TestTarget target, ILog log, bool minVersion, CancellationToken cancellationToken = default) | ||
| => new SimulatorEnumerable(this, target, minVersion, log, cancellationToken); | ||
| public IEnumerable<ISimulatorDevice?> SelectDevices(TestTargetOs target, ILog log, bool minVersion, CancellationToken cancellationToken = default) | ||
| public IEnumerable<ISimulatorDevice> SelectDevices(TestTargetOs target, ILog log, bool minVersion, CancellationToken cancellationToken = default) | ||
| => new SimulatorEnumerable(this, target, minVersion, log, cancellationToken); |
There was a problem hiding this comment.
SimulatorLoader.SelectDevices return type was changed to IEnumerable<ISimulatorDevice>, but ISimulatorLoader.SelectDevices still declares IEnumerable<ISimulatorDevice?>. This will break the interface implementation (compile error) unless the interface signature is updated too (or the implementation keeps the nullable return type).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sprinkle nullability information in a number of places where it makes sense.