Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions tests/common/AppDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,17 @@
using MonoTouch.NUnit.UI;
using NUnit.Framework.Internal;

// Disable until we get around to enable + fix any issues.
#nullable disable
#nullable enable

[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate {

static internal UIWindow MainWindow;
public static TouchRunner Runner { get; set; }
static internal UIWindow? MainWindow;
public static TouchRunner? Runner { get; set; }

partial void PostFinishedLaunching ();

public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
public override bool FinishedLaunching (UIApplication application, NSDictionary? launchOptions)
{
#if __MACCATALYST__ || __MACOS__
TestRuntime.NotifyLaunchCompleted ();
Expand Down Expand Up @@ -61,7 +60,7 @@ public override UISceneConfiguration GetConfiguration (UIApplication application
public partial class SceneDelegate : UIResponder, IUIWindowSceneDelegate {

[Export ("window")]
public UIWindow Window { get; set; }
public UIWindow? Window { get; set; }

[Export ("scene:willConnectToSession:options:")]
public void WillConnect (UIScene scene, UISceneSession session, UISceneConnectionOptions connectionOptions)
Expand Down
71 changes: 36 additions & 35 deletions tests/common/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@
using System.Threading;
using Xamarin.Utils;

#nullable disable // until we get around to fixing this file
#nullable enable

namespace Xamarin.Tests {
static partial class Configuration {
public const string XI_ProductName = "MonoTouch";
public const string XM_ProductName = "Xamarin.Mac";

public static string DotNetBclDir;
public static string DotNetCscCommand;
public static string? DotNetBclDir;
public static string? DotNetCscCommand;
public static string DotNetExecutable;
public static string DotNetTfm;
public static string mt_src_root;
public static string? mt_src_root;
public static string sdk_version;
public static string tvos_sdk_version;
public static string macos_sdk_version;
public static string xcode_root;
public static string XcodeVersionString;
public static string? XcodeVersionString;
public static string xcode83_root;
public static string xcode94_root;
#if MONOMAC
Expand All @@ -37,12 +37,12 @@ static partial class Configuration {
public static bool XcodeIsStable;
public static string DOTNET_DIR;

static Version xcode_version;
static Version? xcode_version;

public static Version XcodeVersion {
get {
if (xcode_version is null)
xcode_version = Version.Parse (XcodeVersionString);
xcode_version = Version.Parse (XcodeVersionString!);
return xcode_version;
}
}
Expand Down Expand Up @@ -101,11 +101,11 @@ public static string XcodeLocation {
}

// This is the location of an Xcode which is older than the recommended one.
public static string GetOldXcodeRoot (Version min_version = null)
public static string? GetOldXcodeRoot (Version? min_version = null)
{
var with_versions = new List<Tuple<Version, string>> ();

var max_version = Version.Parse (XcodeVersionString);
var max_version = Version.Parse (XcodeVersionString!);
foreach (var xcode in GetAllXcodes ()) {
var path = xcode.Path;
var version = xcode.Version;
Expand Down Expand Up @@ -153,16 +153,16 @@ static void ParseConfigFiles ()
if (!test_config.Any () && Environment.OSVersion.Platform != PlatformID.Win32NT) {
// Run 'make test.config' in the tests/ directory
// First find the tests/ directory
var dir = TestAssemblyDirectory;
string tests_dir = null;
var dir = TestAssemblyDirectory!;
string? tests_dir = null;
while (dir.Length > 1) {
var file = Path.Combine (dir, "tests");
if (Directory.Exists (file)) {
tests_dir = file;
break;
}

dir = Path.GetDirectoryName (dir);
dir = Path.GetDirectoryName (dir)!;
}

if (tests_dir is null)
Expand Down Expand Up @@ -202,7 +202,8 @@ static void ParseConfigFile (string file)
}
}

internal static string GetVariable (string variable, string @default)
[return: NotNullIfNotNull (nameof (@default))]
internal static string? GetVariable (string variable, string? @default)
{
var result = Environment.GetEnvironmentVariable (variable);
if (string.IsNullOrEmpty (result))
Expand Down Expand Up @@ -239,7 +240,7 @@ public static string EvaluateVariable (string variable)
return result.Substring (variable.Length + 1);
}

static string GetXcodeVersion (string xcode_path)
static string? GetXcodeVersion (string xcode_path)
{
var version_plist = Path.Combine (xcode_path, "..", "version.plist");
if (!File.Exists (version_plist))
Expand All @@ -248,23 +249,23 @@ static string GetXcodeVersion (string xcode_path)
return GetPListStringValue (version_plist, "CFBundleShortVersionString");
}

public static string GetPListStringValue (string plist, string key)
public static string? GetPListStringValue (string plist, string key)
{
var settings = new System.Xml.XmlReaderSettings ();
settings.DtdProcessing = System.Xml.DtdProcessing.Ignore;
var doc = new System.Xml.XmlDocument ();
using (var fs = new StringReader (ReadPListAsXml (plist))) {
using (var reader = System.Xml.XmlReader.Create (fs, settings)) {
doc.Load (reader);
return doc.DocumentElement
.SelectSingleNode ($"//dict/key[text()='{key}']/following-sibling::string[1]/text()").Value;
return doc.DocumentElement!
.SelectSingleNode ($"//dict/key[text()='{key}']/following-sibling::string[1]/text()")!.Value;
}
}
}

public static string ReadPListAsXml (string path)
{
string tmpfile = null;
string? tmpfile = null;
try {
tmpfile = Path.GetTempFileName ();
File.Copy (path, tmpfile, true);
Expand Down Expand Up @@ -297,8 +298,8 @@ static Configuration ()
include_maccatalyst = !string.IsNullOrEmpty (GetVariable ("INCLUDE_MACCATALYST", ""));
DotNetBclDir = GetVariable ("DOTNET_BCL_DIR", null);
DotNetCscCommand = GetVariable ("DOTNET_CSC_COMMAND", null)?.Trim ('\'');
DotNetExecutable = GetVariable ("DOTNET", null);
DotNetTfm = GetVariable ("DOTNET_TFM", null);
DotNetExecutable = GetVariable ("DOTNET", "");
DotNetTfm = GetVariable ("DOTNET_TFM", "");
XcodeIsStable = string.Equals (GetVariable ("XCODE_IS_STABLE", ""), "true",
StringComparison.OrdinalIgnoreCase);
DOTNET_DIR = GetVariable ("DOTNET_DIR", "");
Expand Down Expand Up @@ -359,7 +360,7 @@ public static string RootPath {
}
}

public static bool TryGetRootPath (out string rootPath)
public static bool TryGetRootPath ([NotNullWhen (true)] out string? rootPath)
{
try {
rootPath = RootPath;
Expand Down Expand Up @@ -643,7 +644,7 @@ public static string CloneTestDirectory (string directory)
foreach (var file in files) {
var src = Path.Combine (directory, file);
var tgt = Path.Combine (testsTemporaryDirectory, file);
var tgtDir = Path.GetDirectoryName (tgt);
var tgtDir = Path.GetDirectoryName (tgt)!;
Directory.CreateDirectory (tgtDir);
File.Copy (src, tgt);
if (tgt.EndsWith (".csproj", StringComparison.OrdinalIgnoreCase)) {
Expand Down Expand Up @@ -681,19 +682,19 @@ public static void FixupTestFiles (string directory, string mode)
}
}

public static Dictionary<string, string> GetBuildEnvironment (ApplePlatform platform)
public static Dictionary<string, string?> GetBuildEnvironment (ApplePlatform platform)
{
var environment = new Dictionary<string, string> ();
var environment = new Dictionary<string, string?> ();
SetBuildVariables (platform, ref environment);
return environment;
}

public static void SetBuildVariables (ApplePlatform platform, ref Dictionary<string, string> environment)
public static void SetBuildVariables (ApplePlatform platform, ref Dictionary<string, string?> environment)
{
if (environment is null)
environment = new Dictionary<string, string> ();
environment = new Dictionary<string, string?> ();

environment ["MD_APPLE_SDK_ROOT"] = Path.GetDirectoryName (Path.GetDirectoryName (xcode_root));
environment ["MD_APPLE_SDK_ROOT"] = Path.GetDirectoryName (Path.GetDirectoryName (xcode_root)!)!;

// This is set by `dotnet test` and can cause building legacy projects to fail to build with:
// Microsoft.NET.Build.Extensions.ConflictResolution.targets(30,5):
Expand All @@ -713,13 +714,13 @@ public static string GetTestLibraryDirectory (ApplePlatform platform, bool? simu

switch (platform) {
case ApplePlatform.iOS:
dir = simulator.Value ? "iphonesimulator" : "iphoneos";
dir = simulator == true ? "iphonesimulator" : "iphoneos";
break;
case ApplePlatform.MacOSX:
dir = "macos";
break;
case ApplePlatform.TVOS:
dir = simulator.Value ? "tvsimulator" : "tvos";
dir = simulator == true ? "tvsimulator" : "tvos";
break;
case ApplePlatform.MacCatalyst:
dir = "maccatalyst";
Expand Down Expand Up @@ -751,7 +752,7 @@ static bool IsAPFS {
} else {
var exit_code = ExecutionHelper.Execute ("/bin/df", new string [] { "-t", "apfs", "/" },
out var output, TimeSpan.FromSeconds (10));
is_apfs = exit_code == 0 && output.Trim ().Split ('\n').Length >= 2;
is_apfs = exit_code == 0 && output!.Trim ().Split ('\n').Length >= 2;
}
}

Expand Down Expand Up @@ -790,7 +791,7 @@ public static bool CanRunArm64 {
[DllImport ("libc")]
static extern int sysctlbyname (string name, ref int value, ref IntPtr size, IntPtr zero, IntPtr zeroAgain);

public static IEnumerable<string> CallNM (string file, string nmArguments, string arch = null)
public static IEnumerable<string> CallNM (string file, string nmArguments, string? arch = null)
{
var arguments = new List<string> (new [] { nmArguments, file });
if (!string.IsNullOrEmpty (arch)) {
Expand All @@ -809,12 +810,12 @@ public static IEnumerable<string> CallNM (string file, string nmArguments, strin
});
}

public static IEnumerable<string> GetNativeSymbols (string file, string arch = null)
public static IEnumerable<string> GetNativeSymbols (string file, string? arch = null)
{
return CallNM (file, "-gUjA", arch);
}

public static IEnumerable<string> GetUndefinedNativeSymbols (string file, string arch = null)
public static IEnumerable<string> GetUndefinedNativeSymbols (string file, string? arch = null)
{
return CallNM (file, "-gujA", arch);
}
Expand All @@ -829,7 +830,7 @@ public static bool IsStableRelease {
}

public static bool TryGetApiDefinitionRsp (TargetFramework framework,
[NotNullWhen (true)] out string rspPath)
[NotNullWhen (true)] out string? rspPath)
{
rspPath = null;
var platform = framework.Platform switch {
Expand All @@ -846,7 +847,7 @@ public static bool TryGetApiDefinitionRsp (TargetFramework framework,
}

public static bool TryGetPlatformPreprocessorSymbolsRsp (TargetFramework framework,
[NotNullWhen (true)] out string rspPath)
[NotNullWhen (true)] out string? rspPath)
{
rspPath = null;
var platform = framework.Platform switch {
Expand Down
2 changes: 1 addition & 1 deletion tests/common/ConfigurationNUnit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

using Xamarin.Utils;

#nullable disable // until we get around to fixing this file
#nullable enable

namespace Xamarin.Tests {
static partial class Configuration {
Expand Down
28 changes: 14 additions & 14 deletions tests/common/ExecutionHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.Text;
using Xamarin.Utils;

#nullable disable // until we get around to fixing this file
#nullable enable

namespace Xamarin.Tests {
class XBuild {
Expand All @@ -12,17 +12,17 @@ public static string ToolPath {
}
}

public static string BuildXM (string project, string configuration = "Debug", string platform = "x86", string verbosity = null, TimeSpan? timeout = null, string [] arguments = null, string targets = "Clean,Build")
public static string BuildXM (string project, string configuration = "Debug", string platform = "x86", string? verbosity = null, TimeSpan? timeout = null, string []? arguments = null, string targets = "Clean,Build")
{
return Build (project, ApplePlatform.MacOSX, configuration, platform, verbosity, timeout, arguments, targets);
}

public static string BuildXI (string project, string configuration = "Debug", string platform = "iPhoneSimulator", string verbosity = null, TimeSpan? timeout = null, string [] arguments = null, string targets = "Clean,Build")
public static string BuildXI (string project, string configuration = "Debug", string platform = "iPhoneSimulator", string? verbosity = null, TimeSpan? timeout = null, string []? arguments = null, string targets = "Clean,Build")
{
return Build (project, ApplePlatform.iOS, configuration, platform, verbosity, timeout, arguments, targets);
}

static string Build (string project, ApplePlatform applePlatform, string configuration = "Debug", string platform = "iPhoneSimulator", string verbosity = null, TimeSpan? timeout = null, string [] arguments = null, string targets = "Clean,Build")
static string Build (string project, ApplePlatform applePlatform, string configuration = "Debug", string platform = "iPhoneSimulator", string? verbosity = null, TimeSpan? timeout = null, string []? arguments = null, string targets = "Clean,Build")
{
return ExecutionHelper.Execute (ToolPath,
new string [] {
Expand Down Expand Up @@ -50,7 +50,7 @@ public static int Execute (string fileName, IList<string> arguments, TimeSpan? t
return Execute (fileName, arguments, null, null, null, timeout);
}

public static int Execute (string fileName, IList<string> arguments, string working_directory = null, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
public static int Execute (string fileName, IList<string> arguments, string? working_directory = null, Action<string>? stdout_callback = null, Action<string>? stderr_callback = null, TimeSpan? timeout = null)
{
return Execute (fileName, arguments, timed_out: out var _, workingDirectory: working_directory, stdout_callback: stdout_callback, stderr_callback: stderr_callback, timeout: timeout);
}
Expand All @@ -60,19 +60,19 @@ public static int Execute (string fileName, IList<string> arguments, out StringB
return Execute (fileName, arguments, out output, null, null);
}

public static int Execute (string fileName, IList<string> arguments, out StringBuilder output, string working_directory, TimeSpan? timeout = null)
public static int Execute (string fileName, IList<string> arguments, out StringBuilder output, string? working_directory, TimeSpan? timeout = null)
{
output = new StringBuilder ();
return Execute (fileName, arguments, out var _, workingDirectory: working_directory, stdout: output, stderr: output, timeout: timeout);
}

public static int Execute (string fileName, IList<string> arguments, out StringBuilder output, string working_directory, Dictionary<string, string> environment_variables, TimeSpan? timeout = null)
public static int Execute (string fileName, IList<string> arguments, out StringBuilder output, string? working_directory, Dictionary<string, string?>? environment_variables, TimeSpan? timeout = null)
{
output = new StringBuilder ();
return Execute (fileName, arguments, out var _, workingDirectory: working_directory, stdout: output, stderr: output, timeout: timeout, environment_variables: environment_variables);
}

public static int Execute (string fileName, IList<string> arguments, out bool timed_out, string workingDirectory = null, Dictionary<string, string> environment_variables = null, StringBuilder stdout = null, StringBuilder stderr = null, TimeSpan? timeout = null)
public static int Execute (string fileName, IList<string> arguments, out bool timed_out, string? workingDirectory = null, Dictionary<string, string?>? environment_variables = null, StringBuilder? stdout = null, StringBuilder? stderr = null, TimeSpan? timeout = null)
{
var rv = Execution.RunAsync (fileName, arguments, workingDirectory: workingDirectory, environment: environment_variables, timeout: timeout).Result;
if (stdout is not null)
Expand All @@ -81,11 +81,11 @@ public static int Execute (string fileName, IList<string> arguments, out bool ti
stderr.Append (rv.Output.StandardError);
timed_out = rv.TimedOut;
if (rv.TimedOut)
Console.WriteLine ($"Command '{fileName} {StringUtils.FormatArguments (arguments)}' didn't finish in {timeout.Value.TotalMilliseconds} ms, and was killed.", timeout.Value.TotalMinutes);
Console.WriteLine ($"Command '{fileName} {StringUtils.FormatArguments (arguments)}' didn't finish in {timeout!.Value.TotalMilliseconds} ms, and was killed.", timeout!.Value.TotalMinutes);
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

This Console.WriteLine call passes an extra argument (timeout!.Value.TotalMinutes) that isn’t used by the interpolated string, and it also null-forgives timeout. Either include the value in the message (add a placeholder/text) or remove the extra argument, and avoid timeout! by handling the timeout is null case.

Copilot uses AI. Check for mistakes.
return rv.ExitCode;
}

public static int Execute (string fileName, IList<string> arguments, out bool timed_out, string workingDirectory = null, Dictionary<string, string> environment_variables = null, Action<string> stdout_callback = null, Action<string> stderr_callback = null, TimeSpan? timeout = null)
public static int Execute (string fileName, IList<string> arguments, out bool timed_out, string? workingDirectory = null, Dictionary<string, string?>? environment_variables = null, Action<string>? stdout_callback = null, Action<string>? stderr_callback = null, TimeSpan? timeout = null)
{
if (stdout_callback is null)
stdout_callback = Console.WriteLine;
Expand All @@ -95,24 +95,24 @@ public static int Execute (string fileName, IList<string> arguments, out bool ti
var rv = Execution.RunWithCallbacksAsync (fileName, arguments, workingDirectory: workingDirectory, environment: environment_variables, standardOutput: stdout_callback, standardError: stderr_callback, timeout: timeout).Result;
timed_out = rv.TimedOut;
if (rv.TimedOut)
Console.WriteLine ($"Command '{fileName} {StringUtils.FormatArguments (arguments)}' didn't finish in {timeout.Value.TotalMilliseconds} ms, and was killed.", timeout.Value.TotalMinutes);
Console.WriteLine ($"Command '{fileName} {StringUtils.FormatArguments (arguments)}' didn't finish in {timeout!.Value.TotalMilliseconds} ms, and was killed.", timeout!.Value.TotalMinutes);
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

This Console.WriteLine call passes an extra argument (timeout!.Value.TotalMinutes) that isn’t used by the interpolated string, and it also null-forgives timeout. Either include the value in the message (add a placeholder/text) or remove the extra argument, and avoid timeout! by handling the timeout is null case.

Copilot uses AI. Check for mistakes.
return rv.ExitCode;
}

public static int Execute (string fileName, IList<string> arguments, out string output, TimeSpan? timeout = null)
public static int Execute (string fileName, IList<string> arguments, out string? output, TimeSpan? timeout = null)
{
var sb = new StringBuilder ();
var rv = Execute (fileName, arguments, timed_out: out var _, stdout: sb, stderr: sb, timeout: timeout);
output = sb.ToString ();
return rv;
}

public static int Execute (string fileName, IList<string> arguments, Dictionary<string, string> environmentVariables, StringBuilder stdout, StringBuilder stderr, TimeSpan? timeout = null, string workingDirectory = null)
public static int Execute (string fileName, IList<string> arguments, Dictionary<string, string?>? environmentVariables, StringBuilder? stdout, StringBuilder? stderr, TimeSpan? timeout = null, string? workingDirectory = null)
{
return Execute (fileName, arguments, timed_out: out var _, workingDirectory: workingDirectory, environment_variables: environmentVariables, stdout: stdout, stderr: stderr, timeout: timeout);
}

public static string Execute (string fileName, IList<string> arguments, bool throwOnError = true, Dictionary<string, string> environmentVariables = null, bool hide_output = false, TimeSpan? timeout = null)
public static string Execute (string fileName, IList<string> arguments, bool throwOnError = true, Dictionary<string, string?>? environmentVariables = null, bool hide_output = false, TimeSpan? timeout = null)
{
var rv = Execution.RunAsync (fileName, arguments, environment: environmentVariables, timeout: timeout).Result;
var output = rv.Output.MergedOutput;
Expand Down
1 change: 1 addition & 0 deletions tests/common/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

global using System;
global using System.Collections.Generic;
global using System.Diagnostics.CodeAnalysis;
global using System.Runtime.InteropServices;

global using CoreFoundation;
Expand Down
Loading
Loading