diff --git a/src/NServiceBus.Core.Tests/API/NullabilityWarnings.cs b/src/NServiceBus.Core.Tests/API/NullabilityWarnings.cs new file mode 100644 index 0000000000..a2f73e53aa --- /dev/null +++ b/src/NServiceBus.Core.Tests/API/NullabilityWarnings.cs @@ -0,0 +1,149 @@ +namespace NServiceBus.Core.Tests.API; + +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using Particular.Approvals; + +// As part of the nullable reference type migration effort, individual folders are annotated with +// #nullable enable one at a time (tracked in NullableEnable.CompletedFolders.approved.txt and +// NullableEnable.IncompleteFolders.approved.txt). This test previews what would happen if nullable +// reference types were force-enabled for the whole project: files that already opt in via +// #nullable enable are unaffected, but any file without an explicit directive picks up the +// project-wide default instead of staying oblivious. This test captures the current set of +// resulting warnings so that any new regressions are immediately visible. The goal is to keep the +// list shrinking over time. Once all warnings are resolved +// and the approved file empty, this test can be deleted and enable can be set +// directly in the NServiceBus.Core.csproj. +// +// Only warnings matching the hardcoded set of nullable reference type diagnostic IDs below are captured +// (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/nullable-warnings), +// +// See https://learn.microsoft.com/en-us/dotnet/csharp/nullable-references for more details. +[TestFixture] +public partial class NullabilityWarnings +{ + [Test] + [CancelAfter(30_000)] + public async Task ApproveNullabilityWarnings(CancellationToken cancellationToken = default) + { + var projectPath = Path.GetFullPath(Path.Combine( + TestContext.CurrentContext.TestDirectory, + "..", "..", "..", "..", + "NServiceBus.Core", + "NServiceBus.Core.csproj")); + + var binlogPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "out.binlog"); + + try + { + var warnings = await BuildWithNullableEnabled(projectPath, binlogPath, cancellationToken); + + Approver.Verify(warnings); + } + finally + { + if (File.Exists(binlogPath)) + { + File.Delete(binlogPath); + } + } + } + + static async Task BuildWithNullableEnabled(string projectPath, string binlogPath, CancellationToken cancellationToken = default) + { + var startInfo = new ProcessStartInfo + { + FileName = "dotnet", + UseShellExecute = false, + RedirectStandardOutput = true, + RedirectStandardError = true, + CreateNoWindow = true, + }; + + startInfo.ArgumentList.Add("build"); + startInfo.ArgumentList.Add(projectPath); + startInfo.ArgumentList.Add("-p:Nullable=enable"); + startInfo.ArgumentList.Add("-p:TreatWarningsAsErrors=false"); + startInfo.ArgumentList.Add("-p:IsPackable=false"); + startInfo.ArgumentList.Add($"-bl:{binlogPath}"); + + using var process = Process.Start(startInfo)!; + + var outputTask = process.StandardOutput.ReadToEndAsync(cancellationToken); + var errorTask = process.StandardError.ReadToEndAsync(cancellationToken); + + await process.WaitForExitAsync(cancellationToken); + + var output = await outputTask; + var error = await errorTask; + + Assert.That(process.ExitCode, Is.Zero, $"Build failed:{Environment.NewLine}{error}{Environment.NewLine}{output}"); + + var warnings = NullableWarningRegex().Matches(output) + .Select(m => ScrubLine(m.Value.Trim())) + .Distinct() + .OrderBy(w => w, StringComparer.Ordinal) + .ToList(); + + var grouped = warnings + .GroupBy(w => FileRegex().Match(w).Groups["file"].Value) + .OrderBy(g => g.Key, StringComparer.Ordinal); + + var result = new StringBuilder() + .AppendLine("The following nullable warnings are present in NServiceBus.Core.") + .AppendLine("Changes that make this list longer should not be approved.") + .AppendLine("-----"); + + foreach (var group in grouped) + { + _ = result.AppendLine().AppendLine(group.Key); + foreach (var warning in group) + { + _ = result.AppendLine($" {MessageRegex().Match(warning).Groups["msg"].Value}"); + } + } + + return result.ToString(); + } + + static string ScrubLine(string line) + { + line = PathPrefixRegex().Replace(line, "", 1); + line = line.Replace('\\', '/'); + line = LineNumbersRegex().Replace(line, ""); + line = ProjectPathSuffixRegex().Replace(line, ""); + return line; + } + + [GeneratedRegex(@"^.+?(?=src[\\/])", RegexOptions.IgnoreCase)] + private static partial Regex PathPrefixRegex(); + + [GeneratedRegex(@"\(\d+,\d+\)")] + private static partial Regex LineNumbersRegex(); + + [GeneratedRegex(@"\s*\[[^\]]+[/\\][^\]]+\]$")] + private static partial Regex ProjectPathSuffixRegex(); + + [GeneratedRegex($@".+: warning CS({NullableWarningCodes}):.+")] + private static partial Regex NullableWarningRegex(); + + [GeneratedRegex(@"^(?src/[^\s:]+)")] + private static partial Regex FileRegex(); + + [GeneratedRegex($@": warning (?CS({NullableWarningCodes}):.+)$")] + private static partial Regex MessageRegex(); + + // Sourced from https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/nullable-warnings + const string NullableWarningCodes = + "8597|8598|8600|8601|8602|8603|8604|8605|8607|8608|8609|8610|8611|8612|8613|8614|" + + "8615|8616|8617|8618|8619|8620|8621|8622|8623|8624|8625|8628|8629|8631|8632|8633|" + + "8634|8636|8637|8639|8643|8644|8645|8650|8651|8655|8667|8668|8669|8670|8714|8762|" + + "8763|8764|8765|8766|8767|8768|8769|8770|8774|8775|8776|8777|8819|8824|8825|8847"; +} diff --git a/src/NServiceBus.Core.Tests/API/NullableEnabledDirectories.cs b/src/NServiceBus.Core.Tests/API/NullableEnabledDirectories.cs new file mode 100644 index 0000000000..66384a8f0b --- /dev/null +++ b/src/NServiceBus.Core.Tests/API/NullableEnabledDirectories.cs @@ -0,0 +1,139 @@ +namespace NServiceBus.Core.Tests.API; + +using System; +using System.IO; +using System.Linq; +using System.Text; +using NUnit.Framework; + +[TestFixture] +public class NullableEnabledDirectories +{ + [Test] + public void EnsureFilesInCompletedDirectoriesAreAnnotated() + { + var sourceRoot = FindSourceRoot(); + var completedDirectories = ReadCompletedDirectories(sourceRoot); + + var violations = new StringBuilder(); + + foreach (var relativeDirectory in completedDirectories) + { + var directory = Path.Combine(sourceRoot, relativeDirectory); + + if (!Directory.Exists(directory)) + { + violations.AppendLine($"{relativeDirectory} (directory listed in {ApprovedFileName} no longer exists)"); + continue; + } + + foreach (var file in Directory.EnumerateFiles(directory, "*.cs", SearchOption.TopDirectoryOnly)) + { + if (!IsAnnotated(file)) + { + violations.AppendLine(Path.GetRelativePath(sourceRoot, file).Replace('\\', '/')); + } + } + } + + if (violations.Length > 0) + { + Assert.Fail( + $"The following files are missing the '#nullable enable' annotation, followed by a blank line, " + + $"even though they live in a directory listed as fully migrated in {ApprovedFileName}. Either fix " + + $"the file or, if the directory is no longer fully migrated, remove it from {ApprovedFileName}:{Environment.NewLine}{violations}"); + } + } + + [Test] + [Explicit("Run this test to generate a report of directories that are not fully annotated with '#nullable enable'.")] + public void GenerateIncompleteDirectoriesReport() + { + var sourceRoot = FindSourceRoot(); + var approvalFilesDirectory = Path.Combine(sourceRoot, "NServiceBus.Core.Tests", "ApprovalFiles"); + var incompleteReportFilePath = Path.Combine(approvalFilesDirectory, IncompleteReceivedFileName); + + var incompleteReport = BuildIncompleteDirectoriesReport(sourceRoot); + + if (Path.Exists(incompleteReport)) + { + File.Delete(incompleteReportFilePath); + } + + File.WriteAllText(incompleteReportFilePath, incompleteReport); + } + + static string BuildIncompleteDirectoriesReport(string sourceRoot) + { + var builder = new StringBuilder() + .AppendLine("The following directories have at least one .cs file that is NOT annotated with #nullable enable.") + .AppendLine("Format: directoryannotated/total files.") + .AppendLine("-----") + .AppendLine("This file is for analysis purposes only and should not be committed."); + + var directories = Directory.EnumerateFiles(sourceRoot, "*.cs", SearchOption.AllDirectories) + .Where(file => !IsBinOrObj(file)) + .GroupBy(file => Path.GetDirectoryName(file)!) + .Select(group => new + { + Directory = Path.GetRelativePath(sourceRoot, group.Key).Replace('\\', '/'), + Total = group.Count(), + Annotated = group.Count(IsAnnotated) + }) + .Where(entry => entry.Annotated < entry.Total) + .OrderBy(entry => entry.Directory, StringComparer.Ordinal); + + foreach (var entry in directories) + { + builder.AppendLine($"{entry.Directory}\t{entry.Annotated}/{entry.Total}"); + } + + return builder.ToString(); + } + + static bool IsAnnotated(string file) + { + var firstTwoLines = File.ReadLines(file).Take(2).ToArray(); + var firstLine = firstTwoLines.ElementAtOrDefault(0); + var secondLine = firstTwoLines.ElementAtOrDefault(1); + + return firstLine == "#nullable enable" && secondLine == ""; + } + + static bool IsBinOrObj(string path) + { + var normalized = path.Replace('\\', '/'); + return normalized.Contains("/bin/") || normalized.Contains("/obj/"); + } + + static string[] ReadCompletedDirectories(string sourceRoot) + { + var approvedFilePath = Path.Combine(sourceRoot, "NServiceBus.Core.Tests", "ApprovalFiles", ApprovedFileName); + + return File.ReadAllLines(approvedFilePath) + .SkipWhile(line => line != "-----") + .Skip(1) + .Where(line => !string.IsNullOrWhiteSpace(line)) + .ToArray(); + } + + static string FindSourceRoot() + { + var directory = TestContext.CurrentContext.TestDirectory; + + while (directory != null) + { + if (Directory.GetFiles(directory, "*.csproj").Length == 1) + { + return Directory.GetParent(directory)!.FullName; + } + + directory = Directory.GetParent(directory)?.FullName; + } + + throw new InvalidOperationException("Could not find the src directory."); + } + + const string ApprovedFileName = "NullableEnable.CompletedFolders.approved.txt"; + const string IncompleteReceivedFileName = "NullableEnable.IncompleteFolders.txt"; +} diff --git a/src/NServiceBus.Core.Tests/ApprovalFiles/NullabilityWarnings.ApproveNullabilityWarnings.approved.txt b/src/NServiceBus.Core.Tests/ApprovalFiles/NullabilityWarnings.ApproveNullabilityWarnings.approved.txt new file mode 100644 index 0000000000..2205efbced --- /dev/null +++ b/src/NServiceBus.Core.Tests/ApprovalFiles/NullabilityWarnings.ApproveNullabilityWarnings.approved.txt @@ -0,0 +1,362 @@ +The following nullable warnings are present in NServiceBus.Core. +Changes that make this list longer should not be approved. +----- + +src/NServiceBus.Core.Analyzer/FeatureDefaultsEnableFeatureAnalyzer.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core.Analyzer/ForwardCancellationTokenAnalyzer.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'genericTaskType' in 'void ForwardCancellationTokenAnalyzer.Analyze(SyntaxNodeAnalysisContext context, INamedTypeSymbol cancellableContextInterface, INamedTypeSymbol cancellationTokenType, INamedTypeSymbol genericTaskType, INamedTypeSymbol genericValueTaskType)'. + CS8604: Possible null reference argument for parameter 'genericValueTaskType' in 'void ForwardCancellationTokenAnalyzer.Analyze(SyntaxNodeAnalysisContext context, INamedTypeSymbol cancellableContextInterface, INamedTypeSymbol cancellationTokenType, INamedTypeSymbol genericTaskType, INamedTypeSymbol genericValueTaskType)'. + CS8604: Possible null reference argument for parameter 'symbol' in 'SymbolExtensions.extension(ISymbol)'. + CS8620: Argument of type 'ImmutableDictionary' cannot be used for parameter 'properties' of type 'ImmutableDictionary' in 'Diagnostic Diagnostic.Create(DiagnosticDescriptor descriptor, Location? location, ImmutableDictionary? properties, params object?[]? messageArgs)' due to differences in the nullability of reference types. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core.Analyzer/MethodSymbolExtensions.cs + CS8602: Dereference of a possibly null reference. + +src/NServiceBus.Core.Analyzer/Sagas/AddSagaInterceptor.cs + CS8604: Possible null reference argument for parameter 'knownTypes' in 'InterceptableSagaSpec? Parser.Parse(InvocationExpressionSyntax invocation, SemanticModel semanticModel, HandlerKnownTypes knownTypes, CancellationToken cancellationToken = default(CancellationToken))'. + +src/NServiceBus.Core.Analyzer/Sagas/FindSagaByDataSymbolVisitor.cs + CS8618: Non-nullable property 'FoundSaga' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core.Analyzer/Sagas/SagaAnalyzer.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8601: Possible null reference assignment. + CS8602: Dereference of a possibly null reference. + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'expression' in 'TypeInfo CSharpExtensions.GetTypeInfo(SemanticModel? semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken = default(CancellationToken))'. + CS8604: Possible null reference argument for parameter 'interfaceType' in 'SagaHandlerDeclaration.SagaHandlerDeclaration(BaseTypeSyntax syntax, INamedTypeSymbol interfaceType)'. + CS8620: Argument of type 'ImmutableDictionary' cannot be used for parameter 'properties' of type 'ImmutableDictionary' in 'Diagnostic Diagnostic.Create(DiagnosticDescriptor descriptor, Location? location, IEnumerable? additionalLocations, ImmutableDictionary? properties, params object?[]? messageArgs)' due to differences in the nullability of reference types. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core.Analyzer/Sagas/SagaDetails.cs + CS8618: Non-nullable property 'MapperParameterSyntax' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core.Analyzer/Sagas/SagaHandlerDeclaration.cs + CS8601: Possible null reference assignment. + CS8618: Non-nullable property 'MessageType' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'MessageTypeSyntax' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core.Analyzer/Sagas/SagaMessageMapping.cs + CS8601: Possible null reference assignment. + CS8618: Non-nullable property 'CorrelationId' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'MessageMappingExpression' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'MessageType' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'MessageTypeSyntax' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'ToSagaSyntax' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core.Analyzer/SymbolExtensions.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core.Analyzer/TypeSymbolExtensions.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/EndpointConfiguration.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8604: Possible null reference argument for parameter 'obj' in 'void Action.Invoke(TInitializationExtension obj)'. + +src/NServiceBus.Core/EndpointCreator.cs + CS8618: Non-nullable field 'envelopeComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'featureComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'hostingComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'pipelineComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'receiveComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'recoverabilityComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'sendComponent' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'transportSeam' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable property 'MessageSession' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Hosting/HostingComponent.Settings.cs + CS8604: Possible null reference argument for parameter 'value' in 'void SettingsHolder.Set(string key, object value)'. + +src/NServiceBus.Core/Licensing/LicenseReminder.cs + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Pipeline/Incoming/DeserializeMessageConnector.cs + CS8604: Possible null reference argument for parameter 'messageTypes' in 'object[] IMessageSerializer.Deserialize(ReadOnlyMemory body, IList messageTypes = null)'. + +src/NServiceBus.Core/Pipeline/Incoming/LogicalMessageFactory.cs + CS8604: Possible null reference argument for parameter 'messageType' in 'MessageMetadata MessageMetadataRegistry.GetMessageMetadata(Type messageType)'. + +src/NServiceBus.Core/Pipeline/Incoming/TransportReceiveToPhysicalMessageConnector.cs + CS8604: Possible null reference argument for parameter 'messageType' in 'MulticastAddressTag.MulticastAddressTag(Type messageType)'. + +src/NServiceBus.Core/Pipeline/Outgoing/SerializeMessageConnector.cs + CS8604: Possible null reference argument for parameter 'messageType' in 'MessageMetadata MessageMetadataRegistry.GetMessageMetadata(Type messageType)'. + +src/NServiceBus.Core/Reliability/Outbox/NoOpOutboxStorage.cs + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Reliability/SynchronizedStorage/SynchronizedStorage.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Routing/AutomaticSubscriptions/AutoSubscribe.cs + CS8602: Dereference of a possibly null reference. + +src/NServiceBus.Core/Routing/EndpointInstance.cs + CS8625: Cannot convert null literal to non-nullable reference type. + CS8765: Nullability of type of parameter 'obj' doesn't match overridden member (possibly because of nullability attributes). + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/MessageDrivenSubscribeTerminator.cs + CS8597: Thrown value may be null. + CS8601: Possible null reference assignment. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MessageDrivenSubscribeTerminator.SendSubscribeMessageWithRetries(string destination, OutgoingMessage subscriptionMessage, string messageType, ContextBag context, int retriesCount, CancellationToken cancellationToken)'. + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/MessageDrivenSubscriptionsConfigExtensions.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8604: Possible null reference argument for parameter 'messageNamespace' in 'NamespacePublisherSource.NamespacePublisherSource(Assembly messageAssembly, string messageNamespace, PublisherAddress address)'. + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/MessageDrivenUnsubscribeTerminator.cs + CS8601: Possible null reference assignment. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MessageDrivenUnsubscribeTerminator.SendUnsubscribeMessageWithRetries(string destination, OutgoingMessage unsubscribeMessage, string messageType, ContextBag context, int retriesCount, CancellationToken cancellationToken)'. + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/MessageType.cs + CS8601: Possible null reference assignment. + CS8618: Non-nullable property 'TypeName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'Version' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8765: Nullability of type of parameter 'obj' doesn't match overridden member (possibly because of nullability attributes). + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/PublisherAddress.cs + CS8602: Dereference of a possibly null reference. + CS8618: Non-nullable field 'addresses' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'endpoint' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'instances' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8765: Nullability of type of parameter 'obj' doesn't match overridden member (possibly because of nullability attributes). + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/SubscriptionReceiverBehavior.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'endpoint' in 'Subscriber.Subscriber(string transportAddress, string endpoint)'. + +src/NServiceBus.Core/Routing/MessageDrivenSubscriptions/SubscriptionRouter.cs + CS8600: Converting null literal or possible null value to non-nullable type. + +src/NServiceBus.Core/Routing/RoutingComponent.cs + CS8604: Possible null reference argument for parameter 'instanceSpecificQueue' in 'UnicastSendRouter.UnicastSendRouter(bool isSendOnly, string receiveQueueName, QueueAddress instanceSpecificQueue, IDistributionPolicy defaultDistributionPolicy, UnicastRoutingTable unicastRoutingTable, EndpointInstances endpointInstances, ITransportAddressResolver transportAddressResolver)'. + +src/NServiceBus.Core/Routing/RoutingSettings.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8604: Possible null reference argument for parameter 'messageNamespace' in 'NamespaceRouteSource.NamespaceRouteSource(Assembly messageAssembly, string messageNamespace, UnicastRoute route)'. + +src/NServiceBus.Core/Routing/SingleInstanceRoundRobinDistributionStrategy.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Routing/SubscriptionMigrationMode/MigrationSubscribeTerminator.cs + CS8597: Thrown value may be null. + CS8601: Possible null reference assignment. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MigrationSubscribeTerminator.SendSubscribeMessageWithRetries(string destination, OutgoingMessage subscriptionMessage, string messageType, ContextBag context, int retriesCount, CancellationToken cancellationToken)'. + +src/NServiceBus.Core/Routing/SubscriptionMigrationMode/MigrationUnsubscribeTerminator.cs + CS8601: Possible null reference assignment. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MigrationUnsubscribeTerminator.SendUnsubscribeMessageWithRetries(string destination, OutgoingMessage unsubscribeMessage, string messageType, ContextBag context, int retriesCount, CancellationToken cancellationToken)'. + +src/NServiceBus.Core/Routing/SubscriptionMigrationMode/SubscriptionMigrationModeSettings.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8604: Possible null reference argument for parameter 'messageNamespace' in 'NamespacePublisherSource.NamespacePublisherSource(Assembly messageAssembly, string messageNamespace, PublisherAddress address)'. + +src/NServiceBus.Core/Routing/UnicastPublishRouter.cs + CS8600: Converting null literal or possible null value to non-nullable type. + +src/NServiceBus.Core/Routing/UnicastRoute.cs + CS8618: Non-nullable property 'Endpoint' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'Instance' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'PhysicalAddress' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Routing/UnicastRoutingTable.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Routing/UnicastSendRouter.cs + CS8618: Non-nullable field 'instanceSpecificQueue' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable property 'ExplicitDestination' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'SpecificInstance' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Sagas/ActiveSagaInstance.cs + CS8604: Possible null reference argument for parameter 'InitialValue' in 'CorrelationPropertyInfo.CorrelationPropertyInfo(string Name, Type Type, object InitialValue, bool HasInitialValue)'. + CS8604: Possible null reference argument for parameter 'currentCorrelationPropertyValue' in 'void ActiveSagaInstance.ValidateCorrelationPropertyHaveValue(object currentCorrelationPropertyValue)'. + CS8604: Possible null reference argument for parameter 'currentCorrelationPropertyValue' in 'void ActiveSagaInstance.ValidateCorrelationPropertyNotModified(object currentCorrelationPropertyValue)'. + CS8618: Non-nullable field 'correlationProperty' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable property 'SagaId' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Sagas/CustomFinderAdapter.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Sagas/Saga.cs + CS8604: Possible null reference argument for parameter 'message' in 'Task IPipelineContext.Send(object message, SendOptions options)'. + +src/NServiceBus.Core/Sagas/SagaCorrelationProperty.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Sagas/SagaFinderDefinition.cs + CS8618: Non-nullable property 'MessageTypeName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'Properties' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Sagas/SagaLookupValues.cs + CS8601: Possible null reference assignment. + +src/NServiceBus.Core/Sagas/SagaPersistenceBehavior.cs + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'messageType' in 'bool SagaMetadata.TryGetFinder(string messageType, out SagaFinderDefinition? finderDefinition)'. + CS8604: Possible null reference argument for parameter 'value' in 'SagaCorrelationProperty.SagaCorrelationProperty(string name, object value)'. + CS8619: Nullability of reference types in value of type 'Task' doesn't match target type 'Task'. + +src/NServiceBus.Core/Serialization/IMessageSerializer.cs + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Serializers/XML/XmlDeserialization.cs + CS8600: Converting null literal or possible null value to non-nullable type. + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'fields' in 'FieldInfo XmlDeserialization.GetField(FieldInfo[] fields, string name)'. + CS8604: Possible null reference argument for parameter 'node' in 'object XmlDeserialization.Process(XmlNode node, object parent, Type nodeType = null)'. + CS8604: Possible null reference argument for parameter 'properties' in 'PropertyInfo XmlDeserialization.GetProperty(PropertyInfo[] properties, string name)'. + CS8618: Non-nullable field 'defaultNamespace' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Serializers/XML/XmlMessageSerializer.cs + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'messageType' in 'XmlSerialization.XmlSerialization(Type messageType, Stream stream, object message, Conventions conventions, XmlSerializerCache cache, bool skipWrappingRawXml, string @namespace = "http://tempuri.net")'. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Serializers/XML/XmlSanitizingStream.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Serializers/XML/XmlSerialization.cs + CS8604: Possible null reference argument for parameter 'elem' in 'void XmlSerialization.WriteObject(XElement elem, string name, Type type, object value, bool useNS = false)'. + CS8604: Possible null reference argument for parameter 'item' in 'bool List.Contains(string item)'. + CS8604: Possible null reference argument for parameter 'value' in 'void XmlSerialization.WriteObject(XElement elem, string name, Type type, object value, bool useNS = false)'. + +src/NServiceBus.Core/Serializers/XML/XmlSerializerCache.cs + CS8604: Possible null reference argument for parameter 'typeArguments' in 'Type Type.MakeGenericType(params Type[] typeArguments)'. + +src/NServiceBus.Core/ServicePlatform/Retries/RetryAcknowledgementBehavior.cs + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Settings/SettingsHolder.cs + CS8601: Possible null reference assignment. + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'key' in 'T SettingsHolder.GetOrDefault(string key)'. + CS8604: Possible null reference argument for parameter 'key' in 'bool SettingsHolder.HasExplicitValue(string key)'. + CS8604: Possible null reference argument for parameter 'key' in 'bool SettingsHolder.HasSetting(string key)'. + CS8604: Possible null reference argument for parameter 'key' in 'bool SettingsHolder.TryGet(string key, out T val)'. + CS8604: Possible null reference argument for parameter 'key' in 'object SettingsHolder.Get(string key)'. + CS8604: Possible null reference argument for parameter 'key' in 'void SettingsHolder.Set(string key, object value)'. + CS8604: Possible null reference argument for parameter 'key' in 'void SettingsHolder.SetDefault(string key, object value)'. + CS8604: Possible null reference argument for parameter 'value' in 'void SettingsHolder.Set(string key, object value)'. + CS8604: Possible null reference argument for parameter 'value' in 'void SettingsHolder.SetDefault(string key, object value)'. + +src/NServiceBus.Core/StartableEndpoint.cs + CS8618: Non-nullable field 'stoppingTokenSource' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'transportInfrastructure' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + +src/NServiceBus.Core/Transports/DispatchProperties.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Transports/IncomingMessageExtensions.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Transports/Learning/DelayedMessagePoller.cs + CS8618: Non-nullable field 'polling' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + +src/NServiceBus.Core/Transports/Learning/DirectoryBasedTransaction.cs + CS8618: Non-nullable property 'FileToProcess' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Transports/Learning/HeaderSerializer.cs + CS8603: Possible null reference return. + +src/NServiceBus.Core/Transports/Learning/LearningTransport.cs + CS8618: Non-nullable property 'StorageDirectory' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Transports/Learning/LearningTransportDispatcher.cs + CS8604: Possible null reference argument for parameter 'path3' in 'string Path.Combine(string path1, string path2, string path3)'. + +src/NServiceBus.Core/Transports/Learning/LearningTransportInfrastructure.cs + CS8604: Possible null reference argument for parameter 'subscriptionManager' in 'LearningTransportMessagePump.LearningTransportMessagePump(string id, string receiveAddress, string basePath, Action criticalErrorAction, ISubscriptionManager subscriptionManager, ReceiveSettings receiveSettings, TransportTransactionMode transactionMode)'. + +src/NServiceBus.Core/Transports/Learning/LearningTransportMessagePump.cs + CS8618: Non-nullable field 'bodyDir' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'committedTransactionDir' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'concurrencyLimiter' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'delayedDir' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'delayedMessagePoller' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'messageProcessingCancellationTokenSource' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'messagePumpBasePath' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'messagePumpCancellationTokenSource' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'messagePumpTask' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'onError' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'onMessage' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'pendingTransactionDir' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Transports/Learning/LearningTransportSubscriptionManager.cs + CS8604: Possible null reference argument for parameter 'path2' in 'string Path.Combine(string path1, string path2)'. + +src/NServiceBus.Core/Transports/Learning/NoTransaction.cs + CS8618: Non-nullable property 'FileToProcess' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Transports/QueueAddress.cs + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Transports/TransportInfrastructure.cs + CS8618: Non-nullable property 'Dispatcher' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'Receivers' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Transports/TransportOperation.cs + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Transports/TransportSeam.cs + CS8618: Non-nullable field 'receiverSettings' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'transportInfrastructure' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + +src/NServiceBus.Core/Unicast/MessageOperations.cs + CS8604: Possible null reference argument for parameter 'message' in 'Task MessageOperations.Publish(IBehaviorContext context, Type messageType, object message, PublishOptions options)'. + CS8604: Possible null reference argument for parameter 'message' in 'Task MessageOperations.ReplyMessage(IBehaviorContext context, Type messageType, object message, ReplyOptions options)'. + CS8604: Possible null reference argument for parameter 'message' in 'Task MessageOperations.SendMessage(IBehaviorContext context, Type messageType, object message, SendOptions options)'. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MessageOperations.Publish(IBehaviorContext context, Type messageType, object message, PublishOptions options)'. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MessageOperations.ReplyMessage(IBehaviorContext context, Type messageType, object message, ReplyOptions options)'. + CS8604: Possible null reference argument for parameter 'messageType' in 'Task MessageOperations.SendMessage(IBehaviorContext context, Type messageType, object message, SendOptions options)'. + +src/NServiceBus.Core/Unicast/Messages/MessageMetadata.cs + CS8604: Possible null reference argument for parameter 'item' in 'bool ICollection.Contains(string item)'. + CS8625: Cannot convert null literal to non-nullable reference type. + +src/NServiceBus.Core/Unicast/Messages/MessageMetadataRegistry.cs + CS8601: Possible null reference assignment. + CS8603: Possible null reference return. + CS8604: Possible null reference argument for parameter 'key' in 'bool ConcurrentDictionary.TryAdd(string key, Type value)'. + CS8618: Non-nullable field 'isMessageType' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + +src/NServiceBus.Core/Unicast/Queuing/QueueNotFoundException.cs + CS8618: Non-nullable property 'Queue' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/Utils/FileVersionRetriever.cs + CS8602: Dereference of a possibly null reference. + +src/NServiceBus.Core/Utils/Reflection/DelegateFactory.cs + CS8602: Dereference of a possibly null reference. + CS8604: Possible null reference argument for parameter 'meth' in 'void ILGenerator.Emit(OpCode opcode, MethodInfo meth)'. + CS8604: Possible null reference argument for parameter 'type' in 'UnaryExpression Expression.Convert(Expression expression, Type type)'. + +src/NServiceBus.Core/Utils/Reflection/TypeExtensionMethods.cs + CS8601: Possible null reference assignment. + CS8603: Possible null reference return. + +src/NServiceBus.Core/VersionInformation.cs + CS8601: Possible null reference assignment. + CS8618: Non-nullable property 'MajorMinorPatch' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + +src/NServiceBus.Core/obsoletes-v10.cs + CS8618: Non-nullable field 'isMessageType' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable field 'sagaFinders' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the field as nullable. + CS8618: Non-nullable property 'AssociatedMessages' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'EntityName' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'Loader' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'NotFoundHandler' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'SagaDataFactory' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'SagaEntityType' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. + CS8618: Non-nullable property 'SagaType' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable. diff --git a/src/NServiceBus.Core.Tests/ApprovalFiles/NullableEnable.CompletedFolders.approved.txt b/src/NServiceBus.Core.Tests/ApprovalFiles/NullableEnable.CompletedFolders.approved.txt new file mode 100644 index 0000000000..97aa7ee44f --- /dev/null +++ b/src/NServiceBus.Core.Tests/ApprovalFiles/NullableEnable.CompletedFolders.approved.txt @@ -0,0 +1,54 @@ +The following directories have every .cs file annotated with #nullable enable. +Changes that remove a directory from this list, or add a directory whose files are not +all annotated, should not be approved. New files added to a listed directory must also +be annotated with #nullable enable. +----- +NServiceBus.AcceptanceTests/Core/LoggingIntegration +NServiceBus.Core.Analyzer/Features +NServiceBus.Core.Tests/Receiving +NServiceBus.Core.Tests/Utils +NServiceBus.Core/Audit +NServiceBus.Core/Causation +NServiceBus.Core/CircuitBreakers +NServiceBus.Core/Conventions +NServiceBus.Core/Correlation +NServiceBus.Core/CriticalError +NServiceBus.Core/DelayedDelivery +NServiceBus.Core/Envelopes +NServiceBus.Core/Extensibility +NServiceBus.Core/Features +NServiceBus.Core/Hosting +NServiceBus.Core/Hosting/Helpers +NServiceBus.Core/Hosting/KeyedServices +NServiceBus.Core/Hosting/StartupDiagnostics +NServiceBus.Core/IdGeneration +NServiceBus.Core/Installation +NServiceBus.Core/Licensing +NServiceBus.Core/Logging +NServiceBus.Core/MessageInterfaces +NServiceBus.Core/MessageInterfaces/MessageMapper +NServiceBus.Core/MessageInterfaces/MessageMapper/Reflection +NServiceBus.Core/MessageMutators +NServiceBus.Core/MessageMutators/MutateInstanceMessage +NServiceBus.Core/MessageMutators/MutateTransportMessage +NServiceBus.Core/Notifications +NServiceBus.Core/OpenTelemetry +NServiceBus.Core/OpenTelemetry/Metrics +NServiceBus.Core/OpenTelemetry/Tracing +NServiceBus.Core/Performance/MessageProcessingOptimizations +NServiceBus.Core/Performance/Statistics +NServiceBus.Core/Performance/TimeToBeReceived +NServiceBus.Core/Persistence +NServiceBus.Core/Persistence/Learning +NServiceBus.Core/Persistence/Learning/SagaPersister +NServiceBus.Core/Pipeline +NServiceBus.Core/Pipeline/Incoming +NServiceBus.Core/Pipeline/Outgoing +NServiceBus.Core/Receiving +NServiceBus.Core/Recoverability +NServiceBus.Core/Recoverability/DelayedRetries +NServiceBus.Core/Recoverability/ImmediateRetries +NServiceBus.Core/Recoverability/Settings +NServiceBus.Core/Serializers/SystemJson +NServiceBus.Core/Support +NServiceBus.Core/Unicast/Config