Skip to content

Commit e4b0a79

Browse files
maxkatz6danwalmsley
authored andcommitted
Merge pull request #7179 from AvaloniaUI/fixes/avalonia-base-nullability
Finished adding nullable annotations to Avalonia.Base.
1 parent 6ce4079 commit e4b0a79

File tree

182 files changed

+422
-601
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

182 files changed

+422
-601
lines changed

src/Avalonia.Base/AttachedProperty.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
22

3-
#nullable enable
4-
53
namespace Avalonia
64
{
75
/// <summary>

src/Avalonia.Base/Avalonia.Base.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
<Import Project="..\..\build\JetBrains.Annotations.props" />
1212
<Import Project="..\..\build\System.Memory.props" />
1313
<Import Project="..\..\build\ApiDiff.props" />
14+
<Import Project="..\..\build\NullableEnable.props" />
1415
</Project>

src/Avalonia.Base/AvaloniaInternalException.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
22

3-
#nullable enable
4-
53
namespace Avalonia
64
{
75
/// <summary>

src/Avalonia.Base/AvaloniaLocator.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ namespace Avalonia
77
{
88
public class AvaloniaLocator : IAvaloniaDependencyResolver
99
{
10-
private readonly IAvaloniaDependencyResolver _parentScope;
10+
private readonly IAvaloniaDependencyResolver? _parentScope;
1111
public static IAvaloniaDependencyResolver Current { get; set; }
1212
public static AvaloniaLocator CurrentMutable { get; set; }
13-
private readonly Dictionary<Type, Func<object>> _registry = new Dictionary<Type, Func<object>>();
13+
private readonly Dictionary<Type, Func<object?>> _registry = new Dictionary<Type, Func<object?>>();
1414

1515
static AvaloniaLocator()
1616
{
@@ -27,10 +27,9 @@ public AvaloniaLocator(IAvaloniaDependencyResolver parentScope)
2727
_parentScope = parentScope;
2828
}
2929

30-
public object GetService(Type t)
30+
public object? GetService(Type t)
3131
{
32-
Func<object> rv;
33-
return _registry.TryGetValue(t, out rv) ? rv() : _parentScope?.GetService(t);
32+
return _registry.TryGetValue(t, out var rv) ? rv() : _parentScope?.GetService(t);
3433
}
3534

3635
public class RegistrationHelper<TService>
@@ -57,7 +56,7 @@ public AvaloniaLocator ToFunc<TImlp>(Func<TImlp> func) where TImlp : TService
5756
public AvaloniaLocator ToLazy<TImlp>(Func<TImlp> func) where TImlp : TService
5857
{
5958
var constructed = false;
60-
TImlp instance = default;
59+
TImlp? instance = default;
6160
_locator._registry[typeof (TService)] = () =>
6261
{
6362
if (!constructed)
@@ -73,7 +72,7 @@ public AvaloniaLocator ToLazy<TImlp>(Func<TImlp> func) where TImlp : TService
7372

7473
public AvaloniaLocator ToSingleton<TImpl>() where TImpl : class, TService, new()
7574
{
76-
TImpl instance = null;
75+
TImpl? instance = null;
7776
return ToFunc(() => instance ?? (instance = new TImpl()));
7877
}
7978

@@ -117,14 +116,14 @@ public static IDisposable EnterScope()
117116

118117
public interface IAvaloniaDependencyResolver
119118
{
120-
object GetService(Type t);
119+
object? GetService(Type t);
121120
}
122121

123122
public static class LocatorExtensions
124123
{
125-
public static T GetService<T>(this IAvaloniaDependencyResolver resolver)
124+
public static T? GetService<T>(this IAvaloniaDependencyResolver resolver)
126125
{
127-
return (T) resolver.GetService(typeof (T));
126+
return (T?) resolver.GetService(typeof (T));
128127
}
129128
}
130129
}

src/Avalonia.Base/AvaloniaObject.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
using Avalonia.PropertyStore;
88
using Avalonia.Threading;
99

10-
#nullable enable
11-
1210
namespace Avalonia
1311
{
1412
/// <summary>
@@ -47,7 +45,7 @@ public event EventHandler<AvaloniaPropertyChangedEventArgs>? PropertyChanged
4745
/// <summary>
4846
/// Raised when a <see cref="AvaloniaProperty"/> value changes on this object.
4947
/// </summary>
50-
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
48+
event PropertyChangedEventHandler? INotifyPropertyChanged.PropertyChanged
5149
{
5250
add { _inpcChanged += value; }
5351
remove { _inpcChanged -= value; }
@@ -857,7 +855,7 @@ private void SetDirectValueUnchecked<T>(DirectPropertyBase<T> property, BindingV
857855
private string GetDescription(object o)
858856
{
859857
var description = o as IDescription;
860-
return description?.Description ?? o.ToString();
858+
return description?.Description ?? o.ToString() ?? o.GetType().Name;
861859
}
862860

863861
/// <summary>

src/Avalonia.Base/AvaloniaObjectExtensions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
using Avalonia.Data;
77
using Avalonia.Reactive;
88

9-
#nullable enable
10-
119
namespace Avalonia
1210
{
1311
/// <summary>

src/Avalonia.Base/AvaloniaProperty.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
using Avalonia.Data.Core;
55
using Avalonia.Utilities;
66

7-
#nullable enable
8-
97
namespace Avalonia
108
{
119
/// <summary>
@@ -544,12 +542,12 @@ private AvaloniaPropertyMetadata GetMetadataWithOverrides(Type type)
544542
throw new ArgumentNullException(nameof(type));
545543
}
546544

547-
if (_metadataCache.TryGetValue(type, out AvaloniaPropertyMetadata result))
545+
if (_metadataCache.TryGetValue(type, out var result))
548546
{
549547
return result;
550548
}
551549

552-
Type currentType = type;
550+
Type? currentType = type;
553551

554552
while (currentType != null)
555553
{

src/Avalonia.Base/AvaloniaPropertyChangedEventArgs.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System;
22
using Avalonia.Data;
33

4-
#nullable enable
5-
64
namespace Avalonia
75
{
86
/// <summary>

src/Avalonia.Base/AvaloniaPropertyChangedEventArgs`1.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using Avalonia.Data;
22

3-
#nullable enable
4-
53
namespace Avalonia
64
{
75
/// <summary>

src/Avalonia.Base/AvaloniaPropertyMetadata.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using Avalonia.Data;
22

3-
#nullable enable
4-
53
namespace Avalonia
64
{
75
/// <summary>

src/Avalonia.Base/AvaloniaPropertyRegistry.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
using System.Collections.Generic;
33
using System.Runtime.CompilerServices;
44

5-
#nullable enable
6-
75
namespace Avalonia
86
{
97
/// <summary>

src/Avalonia.Base/AvaloniaProperty`1.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
using Avalonia.Data;
44
using Avalonia.Utilities;
55

6-
#nullable enable
7-
86
namespace Avalonia
97
{
108
/// <summary>
@@ -84,15 +82,15 @@ internal void NotifyChanged(AvaloniaPropertyChangedEventArgs<TValue> e)
8482

8583
protected override IObservable<AvaloniaPropertyChangedEventArgs> GetChanged() => Changed;
8684

87-
protected BindingValue<object> TryConvert(object? value)
85+
protected BindingValue<object?> TryConvert(object? value)
8886
{
8987
if (value == UnsetValue)
9088
{
91-
return BindingValue<object>.Unset;
89+
return BindingValue<object?>.Unset;
9290
}
9391
else if (value == BindingOperations.DoNothing)
9492
{
95-
return BindingValue<object>.DoNothing;
93+
return BindingValue<object?>.DoNothing;
9694
}
9795

9896
if (!TypeUtilities.TryConvertImplicit(PropertyType, value, out var converted))
@@ -102,7 +100,7 @@ protected BindingValue<object> TryConvert(object? value)
102100
Name,
103101
value,
104102
value?.GetType().FullName ?? "(null)"));
105-
return BindingValue<object>.BindingError(error);
103+
return BindingValue<object?>.BindingError(error);
106104
}
107105

108106
return converted;

src/Avalonia.Base/Collections/AvaloniaDictionary.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
using System.Collections.Generic;
44
using System.Collections.Specialized;
55
using System.ComponentModel;
6+
using System.Diagnostics.CodeAnalysis;
67
using System.Linq;
78
using Avalonia.Data.Core;
89

9-
#nullable enable
10-
1110
namespace Avalonia.Collections
1211
{
1312
/// <summary>
@@ -19,6 +18,7 @@ public class AvaloniaDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
1918
IDictionary,
2019
INotifyCollectionChanged,
2120
INotifyPropertyChanged
21+
where TKey : notnull
2222
{
2323
private Dictionary<TKey, TValue> _inner;
2424

@@ -76,8 +76,7 @@ public TValue this[TKey key]
7676

7777
set
7878
{
79-
TValue old;
80-
bool replace = _inner.TryGetValue(key, out old);
79+
bool replace = _inner.TryGetValue(key, out var old);
8180
_inner[key] = value;
8281

8382
if (replace)
@@ -89,7 +88,7 @@ public TValue this[TKey key]
8988
var e = new NotifyCollectionChangedEventArgs(
9089
NotifyCollectionChangedAction.Replace,
9190
new KeyValuePair<TKey, TValue>(key, value),
92-
new KeyValuePair<TKey, TValue>(key, old));
91+
new KeyValuePair<TKey, TValue>(key, old!));
9392
CollectionChanged(this, e);
9493
}
9594
}
@@ -100,7 +99,7 @@ public TValue this[TKey key]
10099
}
101100
}
102101

103-
object IDictionary.this[object key] { get => ((IDictionary)_inner)[key]; set => ((IDictionary)_inner)[key] = value; }
102+
object? IDictionary.this[object key] { get => ((IDictionary)_inner)[key]; set => ((IDictionary)_inner)[key] = value; }
104103

105104
/// <inheritdoc/>
106105
public void Add(TKey key, TValue value)
@@ -145,7 +144,7 @@ public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
145144
/// <inheritdoc/>
146145
public bool Remove(TKey key)
147146
{
148-
if (_inner.TryGetValue(key, out TValue value))
147+
if (_inner.TryGetValue(key, out var value))
149148
{
150149
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Count)));
151150
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs($"Item[{key}]"));
@@ -168,8 +167,7 @@ public bool Remove(TKey key)
168167
}
169168

170169
/// <inheritdoc/>
171-
public bool TryGetValue(TKey key, out TValue value) => _inner.TryGetValue(key, out value);
172-
170+
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) => _inner.TryGetValue(key, out value);
173171
/// <inheritdoc/>
174172
IEnumerator IEnumerable.GetEnumerator() => _inner.GetEnumerator();
175173

@@ -195,7 +193,7 @@ bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> i
195193
}
196194

197195
/// <inheritdoc/>
198-
void IDictionary.Add(object key, object value) => Add((TKey)key, (TValue)value);
196+
void IDictionary.Add(object key, object? value) => Add((TKey)key, (TValue)value!);
199197

200198
/// <inheritdoc/>
201199
bool IDictionary.Contains(object key) => ((IDictionary) _inner).Contains(key);

src/Avalonia.Base/Collections/AvaloniaList.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
using System.Linq;
77
using Avalonia.Diagnostics;
88

9-
#nullable enable
10-
119
namespace Avalonia.Collections
1210
{
1311
/// <summary>
@@ -95,7 +93,7 @@ public AvaloniaList(params T[] items)
9593
/// <summary>
9694
/// Raised when a change is made to the collection's items.
9795
/// </summary>
98-
public event NotifyCollectionChangedEventHandler CollectionChanged
96+
public event NotifyCollectionChangedEventHandler? CollectionChanged
9997
{
10098
add => _collectionChanged += value;
10199
remove => _collectionChanged -= value;
@@ -135,7 +133,7 @@ public event NotifyCollectionChangedEventHandler CollectionChanged
135133
bool ICollection.IsSynchronized => false;
136134

137135
/// <inheritdoc/>
138-
object? ICollection.SyncRoot => null;
136+
object ICollection.SyncRoot => this;
139137

140138
/// <inheritdoc/>
141139
bool ICollection<T>.IsReadOnly => false;

src/Avalonia.Base/Collections/AvaloniaListConverter.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,33 @@
33
using System.Globalization;
44
using Avalonia.Utilities;
55

6-
#nullable enable
7-
86
namespace Avalonia.Collections
97
{
108
/// <summary>
119
/// Creates an <see cref="AvaloniaList{T}"/> from a string representation.
1210
/// </summary>
1311
public class AvaloniaListConverter<T> : TypeConverter
1412
{
15-
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
13+
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
1614
{
1715
return sourceType == typeof(string);
1816
}
1917

20-
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
18+
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object? value)
2119
{
20+
if (value is not string stringValue)
21+
return null;
22+
2223
var result = new AvaloniaList<T>();
2324

2425
// TODO: Use StringTokenizer here.
25-
var values = ((string)value).Split(',');
26+
var values = stringValue.Split(',');
2627

2728
foreach (var s in values)
2829
{
2930
if (TypeUtilities.TryConvert(typeof(T), s, culture, out var v))
3031
{
31-
result.Add((T)v);
32+
result.Add((T)v!);
3233
}
3334
else
3435
{

0 commit comments

Comments
 (0)