Skip to content

Commit

Permalink
Merge pull request #364 from 0xced/nullable-reference-types
Browse files Browse the repository at this point in the history
Enable nullable reference types
  • Loading branch information
nblumhardt committed Mar 14, 2023
2 parents 8736256 + 6aa905a commit d4fe8aa
Show file tree
Hide file tree
Showing 32 changed files with 153 additions and 160 deletions.
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)assets/Serilog.snk</AssemblyOriginatorKeyFile>
<ImplicitUsings>enable</ImplicitUsings>
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
6 changes: 3 additions & 3 deletions sample/Sample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ public bool IsEnabled(LogEvent logEvent)

public class LoginData
{
public string Username;
public string? Username;
// ReSharper disable once NotAccessedField.Global
public string Password;
public string? Password;
}

public class CustomPolicy : IDestructuringPolicy
{
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue result)
public bool TryDestructure(object value, ILogEventPropertyValueFactory propertyValueFactory, out LogEventPropertyValue? result)
{
result = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static class ConfigurationLoggerConfigurationExtensions
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
string sectionName,
DependencyContext dependencyContext = null)
DependencyContext? dependencyContext = null)
{
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
if (configuration == null) throw new ArgumentNullException(nameof(configuration));
Expand Down Expand Up @@ -87,7 +87,7 @@ public static class ConfigurationLoggerConfigurationExtensions
public static LoggerConfiguration ConfigurationSection(
this LoggerSettingsConfiguration settingConfiguration,
IConfigurationSection configSection,
DependencyContext dependencyContext = null)
DependencyContext? dependencyContext = null)
{
if (settingConfiguration == null) throw new ArgumentNullException(nameof(settingConfiguration));
if (configSection == null) throw new ArgumentNullException(nameof(configSection));
Expand Down Expand Up @@ -214,7 +214,7 @@ public static class ConfigurationLoggerConfigurationExtensions
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
ConfigurationReaderOptions readerOptions = null)
ConfigurationReaderOptions? readerOptions = null)
{
var configurationReader = readerOptions switch
{
Expand All @@ -225,7 +225,7 @@ public static class ConfigurationLoggerConfigurationExtensions
return settingConfiguration.Settings(configurationReader);
}

static ConfigurationReader GetConfigurationReader(IConfiguration configuration, ConfigurationReaderOptions readerOptions, DependencyContext dependencyContext)
static ConfigurationReader GetConfigurationReader(IConfiguration configuration, ConfigurationReaderOptions readerOptions, DependencyContext? dependencyContext)
{
var assemblyFinder = dependencyContext == null ? AssemblyFinder.Auto() : AssemblyFinder.ForDependencyContext(dependencyContext);
var section = string.IsNullOrWhiteSpace(readerOptions.SectionName) ? configuration : configuration.GetSection(readerOptions.SectionName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ where IsCaseInsensitiveMatch(assemblyFileName, nameToFind)

return query.ToList().AsReadOnly();

static AssemblyName TryGetAssemblyNameFrom(string path)
static AssemblyName? TryGetAssemblyNameFrom(string path)
{
try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ class ConfigurationReader : IConfigurationReader
readonly IConfiguration _section;
readonly IReadOnlyCollection<Assembly> _configurationAssemblies;
readonly ResolutionContext _resolutionContext;
readonly IConfigurationRoot _configurationRoot;
readonly IConfigurationRoot? _configurationRoot;

public ConfigurationReader(IConfiguration configSection, AssemblyFinder assemblyFinder, ConfigurationReaderOptions readerOptions, IConfiguration configuration = null)
public ConfigurationReader(IConfiguration configSection, AssemblyFinder assemblyFinder, ConfigurationReaderOptions readerOptions, IConfiguration? configuration = null)
{
_section = configSection ?? throw new ArgumentNullException(nameof(configSection));
_configurationAssemblies = LoadConfigurationAssemblies(_section, assemblyFinder);
Expand Down Expand Up @@ -145,8 +145,8 @@ void ApplyMinimumLevel(LoggerConfiguration loggerConfiguration)
{
var minimumLevelDirective = _section.GetSection("MinimumLevel");

IConfigurationSection defaultMinLevelDirective = GetDefaultMinLevelDirective();
if (defaultMinLevelDirective.Value != null)
IConfigurationSection? defaultMinLevelDirective = GetDefaultMinLevelDirective();
if (defaultMinLevelDirective?.Value != null)
{
ApplyMinimumLevelConfiguration(defaultMinLevelDirective, (configuration, levelSwitch) => configuration.ControlledBy(levelSwitch));
}
Expand Down Expand Up @@ -189,7 +189,7 @@ void ApplyMinimumLevelConfiguration(IConfigurationSection directive, Action<Logg
SubscribeToLoggingLevelChanges(directive, levelSwitch);
}

IConfigurationSection GetDefaultMinLevelDirective()
IConfigurationSection? GetDefaultMinLevelDirective()
{
var defaultLevelDirective = minimumLevelDirective.GetSection("Default");
if (_configurationRoot != null && minimumLevelDirective.Value != null && defaultLevelDirective.Value != null)
Expand Down Expand Up @@ -439,7 +439,7 @@ object GetImplicitValueForNotSpecifiedKey(ParameterInfo parameter, MethodInfo me
return parameter.DefaultValue;
}

internal static MethodInfo SelectConfigurationMethod(IReadOnlyCollection<MethodInfo> candidateMethods, string name, IReadOnlyCollection<string> suppliedArgumentNames)
internal static MethodInfo? SelectConfigurationMethod(IReadOnlyCollection<MethodInfo> candidateMethods, string name, IReadOnlyCollection<string> suppliedArgumentNames)
{
// Per issue #111, it is safe to use case-insensitive matching on argument names. The CLR doesn't permit this type
// of overloading, and the Microsoft.Extensions.Configuration keys are case-insensitive (case is preserved with some
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public ConfigurationReaderOptions() : this(dependencyContext: null)
/// The dependency context from which sink/enricher packages can be located. If <see langword="null"/>, the platform default will be used.
/// </param>
/// <remarks>Prefer the constructor taking explicit assemblies: <see cref="ConfigurationReaderOptions(System.Reflection.Assembly[])"/>. It's the only one supporting single-file publishing.</remarks>
public ConfigurationReaderOptions(DependencyContext dependencyContext) => DependencyContext = dependencyContext;
public ConfigurationReaderOptions(DependencyContext? dependencyContext) => DependencyContext = dependencyContext;

/// <summary>
/// Initialize a new instance of the <see cref="ConfigurationReaderOptions"/> class.
Expand All @@ -50,12 +50,12 @@ public ConfigurationReaderOptions() : this(dependencyContext: null)
/// <summary>
/// The section name for section which contains a Serilog section. Defaults to <c>Serilog</c>.
/// </summary>
public string SectionName { get; init; } = ConfigurationLoggerConfigurationExtensions.DefaultSectionName;
public string? SectionName { get; init; } = ConfigurationLoggerConfigurationExtensions.DefaultSectionName;

/// <summary>
/// The <see cref="IFormatProvider"/> used when converting strings to other object types. Defaults to the invariant culture.
/// </summary>
public IFormatProvider FormatProvider { get; init; } = CultureInfo.InvariantCulture;
public IFormatProvider? FormatProvider { get; init; } = CultureInfo.InvariantCulture;

/// <summary>
/// Called when a log level switch is created while reading the configuration.
Expand All @@ -65,9 +65,9 @@ public ConfigurationReaderOptions() : this(dependencyContext: null)
/// <item>For minimum level override switches, the switch name is the (partial) namespace or type name of the override.</item>
/// </list>
/// </summary>
public Action<string, LoggingLevelSwitch> OnLevelSwitchCreated { get; init; }
public Action<string, LoggingLevelSwitch>? OnLevelSwitchCreated { get; init; }

internal Assembly[] Assemblies { get; }
internal DependencyContext DependencyContext { get; }
internal Assembly[]? Assemblies { get; }
internal DependencyContext? DependencyContext { get; }
internal ConfigurationAssemblySource? ConfigurationAssemblySource { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

interface IConfigurationArgumentValue
{
object ConvertTo(Type toType, ResolutionContext resolutionContext);
object? ConvertTo(Type toType, ResolutionContext resolutionContext);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

class LoggingFilterSwitchProxy
{
readonly Action<string> _setProxy;
readonly Func<string> _getProxy;
readonly Action<string?> _setProxy;
readonly Func<string?> _getProxy;

LoggingFilterSwitchProxy(object realSwitch)
{
Expand All @@ -12,26 +12,26 @@ class LoggingFilterSwitchProxy
var type = realSwitch.GetType();
var expressionProperty = type.GetProperty("Expression") ?? throw new MissingMemberException(type.FullName, "Expression");

_setProxy = (Action<string>)Delegate.CreateDelegate(
typeof(Action<string>),
_setProxy = (Action<string?>)Delegate.CreateDelegate(
typeof(Action<string?>),
realSwitch,
expressionProperty.GetSetMethod());

_getProxy = (Func<string>)Delegate.CreateDelegate(
typeof(Func<string>),
_getProxy = (Func<string?>)Delegate.CreateDelegate(
typeof(Func<string?>),
realSwitch,
expressionProperty.GetGetMethod());
}

public object RealSwitch { get; }

public string Expression
public string? Expression
{
get => _getProxy();
set => _setProxy(value);
}

public static LoggingFilterSwitchProxy Create(string expression = null)
public static LoggingFilterSwitchProxy? Create(string? expression = null)
{
var filterSwitchType =
Type.GetType("Serilog.Expressions.LoggingFilterSwitch, Serilog.Expressions") ??
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
using System.Reflection;

Expand All @@ -20,7 +21,7 @@ public ObjectArgumentValue(IConfigurationSection section, IReadOnlyCollection<As
_configurationAssemblies = configurationAssemblies ?? throw new ArgumentNullException(nameof(configurationAssemblies));
}

public object ConvertTo(Type toType, ResolutionContext resolutionContext)
public object? ConvertTo(Type toType, ResolutionContext resolutionContext)
{
// return the entire section for internal processing
if (toType == typeof(IConfigurationSection)) return _section;
Expand Down Expand Up @@ -71,7 +72,7 @@ object CreateArray()
return array;
}

bool TryCreateContainer(out object result)
bool TryCreateContainer([NotNullWhen(true)] out object? result)
{
result = null;

Expand All @@ -98,7 +99,7 @@ bool TryCreateContainer(out object result)
}

internal static bool TryBuildCtorExpression(
IConfigurationSection section, Type parameterType, ResolutionContext resolutionContext, out NewExpression ctorExpression)
IConfigurationSection section, Type parameterType, ResolutionContext resolutionContext, [NotNullWhen(true)] out NewExpression? ctorExpression)
{
ctorExpression = null;

Expand Down Expand Up @@ -138,11 +139,11 @@ bool TryCreateContainer(out object result)
from p in c.GetParameters()
let argumentBindResult = suppliedArguments.TryGetValue(p.Name, out var argValue) switch
{
true => new { success = true, hasMatch = true, value = (object)argValue },
true => new { success = true, hasMatch = true, value = (object?)argValue },
false => p.HasDefaultValue switch
{
true => new { success = true, hasMatch = false, value = p.DefaultValue },
false => new { success = false, hasMatch = false, value = (object)null },
true => new { success = true, hasMatch = false, value = (object?)p.DefaultValue },
false => new { success = false, hasMatch = false, value = (object?)null },
},
}
group new { argumentBindResult, p.ParameterType } by c into gr
Expand Down Expand Up @@ -178,7 +179,7 @@ select new
ctorExpression = Expression.New(ctor.ConstructorInfo, ctorArguments);
return true;

static bool TryBindToCtorArgument(object value, Type type, ResolutionContext resolutionContext, out Expression argumentExpression)
static bool TryBindToCtorArgument(object value, Type type, ResolutionContext resolutionContext, [NotNullWhen(true)] out Expression? argumentExpression)
{
argumentExpression = null;

Expand Down Expand Up @@ -217,7 +218,7 @@ static bool TryBindToCtorArgument(object value, Type type, ResolutionContext res
}
}

static bool IsContainer(Type type, out Type elementType)
static bool IsContainer(Type type, [NotNullWhen(true)] out Type? elementType)
{
elementType = null;
foreach (var iface in type.GetInterfaces())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ sealed class ResolutionContext
{
readonly IDictionary<string, LoggingLevelSwitch> _declaredLevelSwitches;
readonly IDictionary<string, LoggingFilterSwitchProxy> _declaredFilterSwitches;
readonly IConfiguration _appConfiguration;
readonly IConfiguration? _appConfiguration;

public ResolutionContext(IConfiguration appConfiguration = null, ConfigurationReaderOptions readerOptions = null)
public ResolutionContext(IConfiguration? appConfiguration = null, ConfigurationReaderOptions? readerOptions = null)
{
_declaredLevelSwitches = new Dictionary<string, LoggingLevelSwitch>();
_declaredFilterSwitches = new Dictionary<string, LoggingFilterSwitchProxy>();
Expand Down Expand Up @@ -51,18 +51,7 @@ public LoggingFilterSwitchProxy LookUpFilterSwitchByName(string switchName)

public bool HasAppConfiguration => _appConfiguration != null;

public IConfiguration AppConfiguration
{
get
{
if (!HasAppConfiguration)
{
throw new InvalidOperationException("AppConfiguration is not available");
}

return _appConfiguration;
}
}
public IConfiguration AppConfiguration => _appConfiguration ?? throw new InvalidOperationException("AppConfiguration is not available");

public string AddLevelSwitch(string levelSwitchName, LoggingLevelSwitch levelSwitch)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Reflection;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Text.RegularExpressions;

using Serilog.Core;
Expand All @@ -23,7 +24,7 @@ public StringArgumentValue(string providedValue)
{ typeof(Type), s => Type.GetType(s, throwOnError:true) },
};

public object ConvertTo(Type toType, ResolutionContext resolutionContext)
public object? ConvertTo(Type toType, ResolutionContext resolutionContext)
{
var argumentValue = Environment.ExpandEnvironmentVariables(_providedValue);

Expand Down Expand Up @@ -158,7 +159,7 @@ public object ConvertTo(Type toType, ResolutionContext resolutionContext)
return Convert.ChangeType(argumentValue, toType, resolutionContext.ReaderOptions.FormatProvider);
}

internal static Type FindType(string typeName)
internal static Type? FindType(string typeName)
{
var type = Type.GetType(typeName);
if (type == null)
Expand All @@ -172,7 +173,7 @@ internal static Type FindType(string typeName)
return type;
}

internal static bool TryParseStaticMemberAccessor(string input, out string accessorTypeName, out string memberName)
internal static bool TryParseStaticMemberAccessor(string input, [NotNullWhen(true)] out string? accessorTypeName, [NotNullWhen(true)] out string? memberName)
{
if (input == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ static class SurrogateConfigurationMethods
LoggerSinkConfiguration loggerSinkConfiguration,
ILogEventSink sink,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
LoggingLevelSwitch levelSwitch = null)
LoggingLevelSwitch? levelSwitch = null)
=> loggerSinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);

static LoggerConfiguration Logger(
LoggerSinkConfiguration loggerSinkConfiguration,
Action<LoggerConfiguration> configureLogger,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
LoggingLevelSwitch levelSwitch = null)
LoggingLevelSwitch? levelSwitch = null)
=> loggerSinkConfiguration.Logger(configureLogger, restrictedToMinimumLevel, levelSwitch);

// .AuditTo...
Expand All @@ -61,14 +61,14 @@ static class SurrogateConfigurationMethods
LoggerAuditSinkConfiguration auditSinkConfiguration,
ILogEventSink sink,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
LoggingLevelSwitch levelSwitch = null)
LoggingLevelSwitch? levelSwitch = null)
=> auditSinkConfiguration.Sink(sink, restrictedToMinimumLevel, levelSwitch);

static LoggerConfiguration Logger(
LoggerAuditSinkConfiguration auditSinkConfiguration,
Action<LoggerConfiguration> configureLogger,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
LoggingLevelSwitch levelSwitch = null)
LoggingLevelSwitch? levelSwitch = null)
=> auditSinkConfiguration.Logger(configureLogger, restrictedToMinimumLevel, levelSwitch);

// .Filter...
Expand Down Expand Up @@ -109,7 +109,7 @@ static LoggerConfiguration AsScalar(LoggerDestructuringConfiguration loggerDestr
LoggerEnrichmentConfiguration loggerEnrichmentConfiguration,
Action<LoggerEnrichmentConfiguration> configureEnricher,
LogEventLevel enrichFromLevel = LevelAlias.Minimum,
LoggingLevelSwitch levelSwitch = null)
LoggingLevelSwitch? levelSwitch = null)
=> levelSwitch != null ? loggerEnrichmentConfiguration.AtLevel(levelSwitch, configureEnricher)
: loggerEnrichmentConfiguration.AtLevel(enrichFromLevel, configureEnricher);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ public void CallableMethodsAreSelected()
var suppliedArgumentNames = new[] { "pathFormat" };

var selected = ConfigurationReader.SelectConfigurationMethod(options, "DummyRollingFile", suppliedArgumentNames);
Assert.Equal(typeof(string), selected.GetParameters()[1].ParameterType);
Assert.Equal(typeof(string), selected?.GetParameters()[1].ParameterType);
}

[Fact]
Expand All @@ -166,7 +166,7 @@ public void MethodsAreSelectedBasedOnCountOfMatchedArguments()
var suppliedArgumentNames = new[] { "pathFormat", "formatter" };

var selected = ConfigurationReader.SelectConfigurationMethod(options, "DummyRollingFile", suppliedArgumentNames);
Assert.Equal(typeof(ITextFormatter), selected.GetParameters()[1].ParameterType);
Assert.Equal(typeof(ITextFormatter), selected?.GetParameters()[1].ParameterType);
}

[Fact]
Expand All @@ -178,7 +178,7 @@ public void MethodsAreSelectedBasedOnCountOfMatchedArgumentsAndThenStringType()
var suppliedArgumentNames = new[] { "pathFormat", "formatter" };

var selected = ConfigurationReader.SelectConfigurationMethod(options, "DummyRollingFile", suppliedArgumentNames);
Assert.Equal(typeof(string), selected.GetParameters()[2].ParameterType);
Assert.Equal(typeof(string), selected?.GetParameters()[2].ParameterType);
}

public static IEnumerable<object[]> FlatMinimumLevel => new List<object[]>
Expand Down

0 comments on commit d4fe8aa

Please sign in to comment.