Skip to content

Commit 1f8e8db

Browse files
authored
chore: Enable nullable for job/characteristics relating code (#2900)
* chore: enable nullable for job/characteristics relating code * chore: fix nullable annotation of AssertHasValue * chore: add additional nullable annotations
1 parent 36fe40d commit 1f8e8db

25 files changed

+163
-112
lines changed

src/BenchmarkDotNet/Characteristics/Characteristic.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Diagnostics.CodeAnalysis;
33
using static BenchmarkDotNet.Characteristics.CharacteristicHelper;
44

5+
#nullable enable
6+
57
namespace BenchmarkDotNet.Characteristics
68
{
79
public abstract class Characteristic
@@ -24,7 +26,7 @@ public abstract class Characteristic
2426
null, fallbackValue,
2527
false);
2628

27-
public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName, Func<CharacteristicObject, T, T> resolver, T fallbackValue, bool ignoreOnApply)
29+
public static Characteristic<T> Create<TOwner, [DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(string memberName, Func<CharacteristicObject, T?, T> resolver, T fallbackValue, bool ignoreOnApply)
2830
where TOwner : CharacteristicObject
2931
=> new Characteristic<T>(
3032
memberName,
@@ -52,7 +54,7 @@ protected Characteristic(
5254
string id,
5355
[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] Type characteristicType,
5456
Type declaringType,
55-
object fallbackValue,
57+
object? fallbackValue,
5658
bool ignoreOnApply,
5759
bool dontShowInSummary = false)
5860
{
@@ -84,7 +86,7 @@ protected Characteristic(
8486

8587
public Type DeclaringType { get; }
8688

87-
private object FallbackValue { get; }
89+
private object? FallbackValue { get; }
8890

8991
public object? this[CharacteristicObject obj]
9092
{
@@ -94,7 +96,7 @@ public object? this[CharacteristicObject obj]
9496

9597
public bool HasChildCharacteristics => IsCharacteristicObjectSubclass(CharacteristicType);
9698

97-
internal virtual object ResolveValueCore(CharacteristicObject obj, object currentValue) =>
99+
internal virtual object? ResolveValueCore(CharacteristicObject obj, object currentValue) =>
98100
ReferenceEquals(currentValue, EmptyValue) ? FallbackValue : currentValue;
99101

100102
public override string ToString() => Id;

src/BenchmarkDotNet/Characteristics/CharacteristicHelper.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Reflection;
77
using JetBrains.Annotations;
88

9+
#nullable enable
10+
911
namespace BenchmarkDotNet.Characteristics
1012
{
1113
public static class CharacteristicHelper
@@ -17,7 +19,7 @@ internal static bool IsCharacteristicObjectSubclass(Type type) =>
1719
private static bool IsCharacteristicSubclass(Type type) =>
1820
type.GetTypeInfo().IsSubclassOf(typeof(Characteristic));
1921

20-
private static Characteristic AssertHasValue(MemberInfo member, Characteristic value)
22+
private static Characteristic AssertHasValue(MemberInfo member, Characteristic? value)
2123
{
2224
if (member?.DeclaringType == null)
2325
throw new NullReferenceException($"{nameof(member.DeclaringType)}");
@@ -54,12 +56,12 @@ private static IReadOnlyList<Characteristic> GetThisTypeCharacteristicsCore(
5456
var fieldValues = characteristicObjectType.GetTypeInfo()
5557
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static)
5658
.Where(f => IsCharacteristicSubclass(f.FieldType))
57-
.Select(f => AssertHasValue(f, (Characteristic)f.GetValue(null)));
59+
.Select(f => AssertHasValue(f, (Characteristic?)f.GetValue(null)));
5860

5961
var propertyValues = characteristicObjectType.GetTypeInfo()
6062
.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Static)
6163
.Where(p => p.GetMethod != null && IsCharacteristicSubclass(p.PropertyType))
62-
.Select(p => AssertHasValue(p, (Characteristic)p.GetValue(null)));
64+
.Select(p => AssertHasValue(p, (Characteristic?)p.GetValue(null)));
6365

6466
// DONTTOUCH: DO NOT change the order of characteristic as it may break logic of some operations.
6567
return fieldValues

src/BenchmarkDotNet/Characteristics/CharacteristicObject.cs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System.Reflection;
66
using JetBrains.Annotations;
77

8+
#nullable enable
9+
810
namespace BenchmarkDotNet.Characteristics
911
{
1012
// TODO: better naming.
@@ -17,15 +19,15 @@ public abstract class CharacteristicObject
1719
DynamicallyAccessedMemberTypes.PublicProperties | DynamicallyAccessedMemberTypes.NonPublicProperties
1820
| DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields;
1921

20-
protected static string ResolveId(CharacteristicObject obj, string actual)
22+
protected static string ResolveId(CharacteristicObject obj, string? actual)
2123
{
2224
if (!string.IsNullOrEmpty(actual) && actual != IdCharacteristic.FallbackValue)
23-
return actual;
25+
return actual!;
2426

2527
string result = CharacteristicSetPresenter.Display.ToPresentation(obj);
2628

2729
if (result.Length == 0)
28-
result = IdCharacteristic.FallbackValue;
30+
result = IdCharacteristic.FallbackValue!;
2931

3032
return result;
3133
}
@@ -44,7 +46,7 @@ protected CharacteristicObject()
4446
sharedValues = new Dictionary<Characteristic, object>();
4547
}
4648

47-
protected CharacteristicObject(string? id) : this()
49+
protected CharacteristicObject(string id) : this()
4850
{
4951
if (!string.IsNullOrEmpty(id))
5052
{
@@ -79,7 +81,7 @@ private void AssertIsNonFrozenRoot()
7981
AssertIsRoot();
8082
}
8183

82-
private static void AssertIsAssignable(Characteristic characteristic, object value)
84+
private static void AssertIsAssignable(Characteristic characteristic, object? value)
8385
{
8486
if (ReferenceEquals(value, Characteristic.EmptyValue) || ReferenceEquals(value, null))
8587
{
@@ -140,53 +142,53 @@ public bool HasValue(Characteristic characteristic)
140142
return false;
141143
}
142144

143-
internal T GetValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic)
145+
internal T? GetValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic)
144146
{
145-
return (T)GetValue((Characteristic)characteristic);
147+
return (T?)GetValue((Characteristic)characteristic);
146148
}
147149

148-
internal object GetValue(Characteristic characteristic)
150+
internal object? GetValue(Characteristic characteristic)
149151
{
150152
if (!sharedValues.TryGetValue(characteristic, out var result))
151153
result = Characteristic.EmptyValue;
152154

153155
return ResolveCore(characteristic, result);
154156
}
155157

156-
private object ResolveCore(Characteristic characteristic, object result)
158+
private object? ResolveCore(Characteristic characteristic, object result)
157159
{
158160
return characteristic.ResolveValueCore(this, result);
159161
}
160162
#endregion
161163

162164
#region Resolve
163-
public T ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver)
165+
public T? ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver)
164166
{
165167
return resolver.Resolve(this, characteristic);
166168
}
167169

168-
public T ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver, T defaultValue)
170+
public T? ResolveValue<[DynamicallyAccessedMembers(CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, IResolver resolver, T defaultValue)
169171
{
170172
return resolver.Resolve(this, characteristic, defaultValue);
171173
}
172174

173-
public object ResolveValue(Characteristic characteristic, IResolver resolver)
175+
public object? ResolveValue(Characteristic characteristic, IResolver resolver)
174176
{
175177
return resolver.Resolve(this, characteristic);
176178
}
177179

178-
public object ResolveValue(Characteristic characteristic, IResolver resolver, object defaultValue)
180+
public object? ResolveValue(Characteristic characteristic, IResolver resolver, object defaultValue)
179181
{
180182
return resolver.Resolve(this, characteristic, defaultValue);
181183
}
182184

183-
public T ResolveValue<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, T defaultValue)
185+
public T? ResolveValue<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T>(Characteristic<T> characteristic, T defaultValue)
184186
{
185-
return HasValue(characteristic) ? GetValue(characteristic) : (T)characteristic.ResolveValueCore(this, defaultValue);
187+
return HasValue(characteristic) ? GetValue(characteristic) : (T?)characteristic.ResolveValueCore(this, defaultValue!);
186188
}
187189

188190
[PublicAPI]
189-
public object ResolveValue(Characteristic characteristic, object defaultValue)
191+
public object? ResolveValue(Characteristic characteristic, object defaultValue)
190192
{
191193
return HasValue(characteristic) ? GetValue(characteristic) : characteristic.ResolveValueCore(this, defaultValue);
192194
}
@@ -203,16 +205,16 @@ public object ResolveValue(Characteristic characteristic, object defaultValue)
203205
SetValue((Characteristic)characteristic, value);
204206
}
205207

206-
internal void SetValue(Characteristic characteristic, object value)
208+
internal void SetValue(Characteristic characteristic, object? value)
207209
{
208210
AssertNotFrozen();
209211

210212
if (characteristic.HasChildCharacteristics)
211213
{
212214
AssertIsAssignable(characteristic, value);
213215

214-
var oldObjectValue = (CharacteristicObject)GetValue(characteristic);
215-
var newObjectValue = (CharacteristicObject)ResolveCore(characteristic, value);
216+
var oldObjectValue = (CharacteristicObject?)GetValue(characteristic);
217+
var newObjectValue = (CharacteristicObject?)ResolveCore(characteristic, value!);
216218

217219
if (!ReferenceEquals(oldObjectValue, newObjectValue))
218220
{
@@ -226,7 +228,7 @@ internal void SetValue(Characteristic characteristic, object value)
226228
}
227229
}
228230

229-
private void SetValueCore(Characteristic characteristic, object value)
231+
private void SetValueCore(Characteristic characteristic, object? value)
230232
{
231233
AssertIsAssignable(characteristic, value);
232234

@@ -243,7 +245,7 @@ private void SetValueCore(Characteristic characteristic, object value)
243245
$"The current node {this} has value for {characteristic} already.",
244246
nameof(characteristic));
245247

246-
var characteristicObject = (CharacteristicObject)ResolveCore(characteristic, value);
248+
var characteristicObject = (CharacteristicObject)ResolveCore(characteristic, value!)!;
247249
characteristicObject.SetOwnerCore(OwnerOrSelf);
248250

249251
sharedValues[characteristic] = characteristicObject;
@@ -321,7 +323,7 @@ private void SetValueOnAttach(Characteristic characteristic, object value)
321323
if (characteristic.HasChildCharacteristics)
322324
{
323325
// DONTTOUCH: workaround on case there were no parent characteristic.
324-
var characteristicObject = (CharacteristicObject)GetValue(characteristic);
326+
var characteristicObject = (CharacteristicObject?)GetValue(characteristic);
325327
characteristicObject?.DetachFromOwner(characteristic);
326328
}
327329

@@ -358,13 +360,13 @@ private CharacteristicObject ApplyCore(
358360
{
359361
if (!HasValue(characteristic))
360362
{
361-
var characteristicObject = (CharacteristicObject)ResolveCore(characteristic, value);
363+
var characteristicObject = (CharacteristicObject?)ResolveCore(characteristic, value);
362364
if (characteristicObject != null)
363365
{
364366
value = Activator.CreateInstance(characteristicObject.GetType());
365367
}
366368

367-
SetValueCore(characteristic, value);
369+
SetValueCore(characteristic, value!);
368370
}
369371
}
370372
else
@@ -399,20 +401,20 @@ protected CharacteristicObject UnfreezeCopyCore()
399401
{
400402
AssertIsRoot();
401403

402-
var newRoot = (CharacteristicObject)Activator.CreateInstance(GetType());
404+
var newRoot = (CharacteristicObject)Activator.CreateInstance(GetType())!;
403405
newRoot.ApplyCore(this);
404406

405407
// Preserve the IdCharacteristic of the original object
406408
if (this.HasValue(IdCharacteristic))
407409
{
408-
newRoot.SetValue(IdCharacteristic, this.GetValue(IdCharacteristic));
410+
newRoot.SetValue(IdCharacteristic, this.GetValue(IdCharacteristic)!);
409411
}
410412

411413
return newRoot;
412414
}
413415
#endregion
414416

415-
public string Id => IdCharacteristic[this];
417+
public string Id => IdCharacteristic[this]!;
416418

417419
public override string ToString() => Id;
418420
}

src/BenchmarkDotNet/Characteristics/CharacteristicObject`1.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public abstract class CharacteristicObject<T> : CharacteristicObject
88
{
99
protected CharacteristicObject() { }
1010

11-
protected CharacteristicObject(string? id) : base(id) { }
11+
protected CharacteristicObject(string id) : base(id) { }
1212

1313
public new T Apply(CharacteristicObject other) => (T)ApplyCore(other);
1414

src/BenchmarkDotNet/Characteristics/CharacteristicPresenter.cs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using BenchmarkDotNet.Helpers;
66
using BenchmarkDotNet.Jobs;
77

8+
#nullable enable
9+
810
namespace BenchmarkDotNet.Characteristics
911
{
1012
public abstract class CharacteristicPresenter
@@ -16,7 +18,7 @@ public abstract class CharacteristicPresenter
1618

1719
public abstract string ToPresentation(CharacteristicObject obj, Characteristic characteristic);
1820

19-
public abstract string ToPresentation(object characteristicValue, Characteristic characteristic);
21+
public abstract string ToPresentation(object? characteristicValue, Characteristic characteristic);
2022

2123
private class DefaultCharacteristicPresenter : CharacteristicPresenter
2224
{
@@ -26,11 +28,11 @@ public override string ToPresentation(CharacteristicObject obj, Characteristic c
2628
return job.ResolvedId;
2729

2830
return obj.HasValue(characteristic)
29-
? ToPresentation(characteristic[obj], characteristic)
31+
? ToPresentation(characteristic[obj]!, characteristic)
3032
: "Default";
3133
}
3234

33-
public override string ToPresentation(object value, Characteristic characteristic)
35+
public override string ToPresentation(object? value, Characteristic characteristic)
3436
{
3537
if (!(value is string) && value is IEnumerable collection)
3638
return ToPresentation(collection);
@@ -64,7 +66,7 @@ private static string ToPresentation(IEnumerable collection)
6466
return buffer.ToString();
6567
}
6668

67-
private static string ToPresentation(object value)
69+
private static string ToPresentation(object? value)
6870
=> (value as IFormattable)?.ToString(null, DefaultCultureInfo.Instance)
6971
?? value?.ToString()
7072
?? "";
@@ -77,11 +79,11 @@ private class SourceCodeCharacteristicPresenter : CharacteristicPresenter
7779
public override string ToPresentation(CharacteristicObject obj, Characteristic characteristic)
7880
=> ToPresentation(characteristic[obj], characteristic);
7981

80-
public override string ToPresentation(object characteristicValue, Characteristic characteristic)
82+
public override string ToPresentation(object? characteristicValue, Characteristic characteristic)
8183
{
8284
// TODO: DO NOT hardcode Characteristic suffix
8385
string id = characteristic.Id;
84-
string type = characteristic.DeclaringType.FullName;
86+
string type = characteristic.DeclaringType.FullName!;
8587
string value = SourceCodeHelper.ToSourceCode(characteristicValue);
8688
return $"{type}.{id}Characteristic[job] = {value}";
8789
}
@@ -94,7 +96,7 @@ public override string ToPresentation(CharacteristicObject obj, Characteristic c
9496
? ToPresentation(characteristic[obj], characteristic)
9597
: "Default";
9698

97-
public override string ToPresentation(object characteristicValue, Characteristic characteristic)
99+
public override string ToPresentation(object? characteristicValue, Characteristic characteristic)
98100
=> FolderNameHelper.ToFolderName(characteristicValue);
99101
}
100102
}
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
using System;
22
using System.Diagnostics.CodeAnalysis;
33

4+
#nullable enable
5+
46
namespace BenchmarkDotNet.Characteristics
57
{
68
public class Characteristic<[DynamicallyAccessedMembers(CharacteristicObject.CharacteristicMemberTypes)] T> : Characteristic
79
{
810
internal Characteristic(
911
string id,
1012
Type declaringType,
11-
Func<CharacteristicObject, T, T>? resolver,
12-
T fallbackValue,
13+
Func<CharacteristicObject, T?, T>? resolver,
14+
T? fallbackValue,
1315
bool ignoreOnApply,
1416
bool dontShowInSummary = false)
1517
: base(id, typeof(T), declaringType, fallbackValue, ignoreOnApply, dontShowInSummary)
@@ -18,22 +20,22 @@ internal Characteristic(
1820
FallbackValue = fallbackValue;
1921
}
2022

21-
private Func<CharacteristicObject, T, T>? Resolver { get; }
23+
private Func<CharacteristicObject, T?, T>? Resolver { get; }
2224

23-
public T FallbackValue { get; }
25+
public T? FallbackValue { get; }
2426

25-
public new T this[CharacteristicObject obj]
27+
public new T? this[CharacteristicObject obj]
2628
{
2729
get { return obj.GetValue(this); }
2830
set { obj.SetValue(this, value); }
2931
}
3032

31-
internal override object ResolveValueCore(CharacteristicObject obj, object currentValue)
33+
internal override object? ResolveValueCore(CharacteristicObject obj, object currentValue)
3234
{
3335
if (Resolver == null)
34-
return (T)base.ResolveValueCore(obj, currentValue);
36+
return (T?)base.ResolveValueCore(obj, currentValue);
3537

36-
return Resolver(obj, (T)base.ResolveValueCore(obj, currentValue));
38+
return Resolver(obj, (T?)base.ResolveValueCore(obj, currentValue));
3739
}
3840
}
3941
}

0 commit comments

Comments
 (0)