Browse Source

Added nullable annotations to Avalonia.Styling.

pull/7240/head
Steven Kirk 4 years ago
parent
commit
328199b2d2
  1. 1
      src/Avalonia.Styling/Avalonia.Styling.csproj
  2. 12
      src/Avalonia.Styling/Controls/ChildNameScope.cs
  3. 4
      src/Avalonia.Styling/Controls/INameScope.cs
  4. 30
      src/Avalonia.Styling/Controls/NameScope.cs
  5. 28
      src/Avalonia.Styling/Controls/NameScopeExtensions.cs
  6. 8
      src/Avalonia.Styling/Controls/NameScopeLocator.cs
  7. 2
      src/Avalonia.Styling/Controls/PseudoClassesExtensions.cs
  8. 2
      src/Avalonia.Styling/Controls/ResourceDictionary.cs
  9. 6
      src/Avalonia.Styling/Controls/ResourceNodeExtensions.cs
  10. 2
      src/Avalonia.Styling/INamed.cs
  11. 16
      src/Avalonia.Styling/LogicalTree/ControlLocator.cs
  12. 6
      src/Avalonia.Styling/LogicalTree/ILogical.cs
  13. 26
      src/Avalonia.Styling/LogicalTree/LogicalExtensions.cs
  14. 7
      src/Avalonia.Styling/LogicalTree/LogicalTreeAttachmentEventArgs.cs
  15. 18
      src/Avalonia.Styling/StyledElement.cs
  16. 2
      src/Avalonia.Styling/Styling/Activators/NthChildActivator.cs
  17. 2
      src/Avalonia.Styling/Styling/Activators/StyleClassActivator.cs
  18. 6
      src/Avalonia.Styling/Styling/ChildSelector.cs
  19. 2
      src/Avalonia.Styling/Styling/OrSelector.cs
  20. 2
      src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs
  21. 50
      src/Avalonia.Styling/Styling/Selectors.cs
  22. 14
      src/Avalonia.Styling/Styling/Styles.cs
  23. 6
      src/Avalonia.Styling/Styling/TemplateSelector.cs
  24. 2
      src/Avalonia.Visuals/Visual.cs
  25. 6
      src/Markup/Avalonia.Markup/Markup/Parsers/SelectorParser.cs

1
src/Avalonia.Styling/Avalonia.Styling.csproj

@ -9,4 +9,5 @@
<ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
</ItemGroup>
<Import Project="..\..\build\ApiDiff.props" />
<Import Project="..\..\build\NullableEnable.props" />
</Project>

12
src/Avalonia.Styling/Controls/ChildNameScope.cs

@ -15,20 +15,20 @@ namespace Avalonia.Controls
public void Register(string name, object element) => _inner.Register(name, element);
public SynchronousCompletionAsyncResult<object> FindAsync(string name)
public SynchronousCompletionAsyncResult<object?> FindAsync(string name)
{
var found = Find(name);
if (found != null)
return new SynchronousCompletionAsyncResult<object>(found);
return new SynchronousCompletionAsyncResult<object?>(found);
// Not found and both current and parent scope are in completed state
if(IsCompleted)
return new SynchronousCompletionAsyncResult<object>(null);
return new SynchronousCompletionAsyncResult<object?>(null);
return DoFindAsync(name);
}
public SynchronousCompletionAsyncResult<object> DoFindAsync(string name)
public SynchronousCompletionAsyncResult<object?> DoFindAsync(string name)
{
var src = new SynchronousCompletionAsyncResultSource<object>();
var src = new SynchronousCompletionAsyncResultSource<object?>();
void ParentSearch()
{
@ -56,7 +56,7 @@ namespace Avalonia.Controls
return src.AsyncResult;
}
public object Find(string name)
public object? Find(string name)
{
var found = _inner.Find(name);
if (found != null)

4
src/Avalonia.Styling/Controls/INameScope.cs

@ -22,14 +22,14 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="name">The name.</param>
/// <returns>The element, or null if the name was not found.</returns>
SynchronousCompletionAsyncResult<object> FindAsync(string name);
SynchronousCompletionAsyncResult<object?> FindAsync(string name);
/// <summary>
/// Finds a named element in the name scope, returns immediately, doesn't traverse the name scope stack
/// </summary>
/// <param name="name">The name.</param>
/// <returns>The element, or null if the name was not found.</returns>
object Find(string name);
object? Find(string name);
/// <summary>
/// Marks the name scope as completed, no further registrations will be allowed

30
src/Avalonia.Styling/Controls/NameScope.cs

@ -22,8 +22,8 @@ namespace Avalonia.Controls
private readonly Dictionary<string, object> _inner = new Dictionary<string, object>();
private readonly Dictionary<string, SynchronousCompletionAsyncResultSource<object>> _pendingSearches =
new Dictionary<string, SynchronousCompletionAsyncResultSource<object>>();
private readonly Dictionary<string, SynchronousCompletionAsyncResultSource<object?>> _pendingSearches =
new Dictionary<string, SynchronousCompletionAsyncResultSource<object?>>();
/// <summary>
/// Gets the value of the attached <see cref="NameScopeProperty"/> on a styled element.
@ -32,7 +32,7 @@ namespace Avalonia.Controls
/// <returns>The value of the NameScope attached property.</returns>
public static INameScope GetNameScope(StyledElement styled)
{
Contract.Requires<ArgumentNullException>(styled != null);
_ = styled ?? throw new ArgumentNullException(nameof(styled));
return styled.GetValue(NameScopeProperty);
}
@ -44,7 +44,7 @@ namespace Avalonia.Controls
/// <param name="value">The value to set.</param>
public static void SetNameScope(StyledElement styled, INameScope value)
{
Contract.Requires<ArgumentNullException>(styled != null);
_ = styled ?? throw new ArgumentNullException(nameof(styled));
styled.SetValue(NameScopeProperty, value);
}
@ -54,12 +54,11 @@ namespace Avalonia.Controls
{
if (IsCompleted)
throw new InvalidOperationException("NameScope is completed, no further registrations are allowed");
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentNullException>(element != null);
object existing;
_ = name ?? throw new ArgumentNullException(nameof(name));
_ = element ?? throw new ArgumentNullException(nameof(element));
if (_inner.TryGetValue(name, out existing))
if (_inner.TryGetValue(name, out var existing))
{
if (existing != element)
{
@ -77,27 +76,26 @@ namespace Avalonia.Controls
}
}
public SynchronousCompletionAsyncResult<object> FindAsync(string name)
public SynchronousCompletionAsyncResult<object?> FindAsync(string name)
{
var found = Find(name);
if (found != null)
return new SynchronousCompletionAsyncResult<object>(found);
return new SynchronousCompletionAsyncResult<object?>(found);
if (IsCompleted)
return new SynchronousCompletionAsyncResult<object>((object)null);
return new SynchronousCompletionAsyncResult<object?>(null);
if (!_pendingSearches.TryGetValue(name, out var tcs))
// We are intentionally running continuations synchronously here
_pendingSearches[name] = tcs = new SynchronousCompletionAsyncResultSource<object>();
_pendingSearches[name] = tcs = new SynchronousCompletionAsyncResultSource<object?>();
return tcs.AsyncResult;
}
/// <inheritdoc />
public object Find(string name)
public object? Find(string name)
{
Contract.Requires<ArgumentNullException>(name != null);
_ = name ?? throw new ArgumentNullException(nameof(name));
object result;
_inner.TryGetValue(name, out result);
_inner.TryGetValue(name, out var result);
return result;
}

28
src/Avalonia.Styling/Controls/NameScopeExtensions.cs

@ -17,11 +17,11 @@ namespace Avalonia.Controls
/// <param name="nameScope">The name scope.</param>
/// <param name="name">The name.</param>
/// <returns>The named element or null if not found.</returns>
public static T Find<T>(this INameScope nameScope, string name)
public static T? Find<T>(this INameScope nameScope, string name)
where T : class
{
Contract.Requires<ArgumentNullException>(nameScope != null);
Contract.Requires<ArgumentNullException>(name != null);
_ = nameScope ?? throw new ArgumentNullException(nameof(nameScope));
_ = name ?? throw new ArgumentNullException(nameof(name));
var result = nameScope.Find(name);
@ -31,7 +31,7 @@ namespace Avalonia.Controls
$"Expected control '{name}' to be '{typeof(T)} but it was '{result.GetType()}'.");
}
return (T)result;
return (T?)result;
}
/// <summary>
@ -41,11 +41,11 @@ namespace Avalonia.Controls
/// <param name="anchor">The control to take the name scope from.</param>
/// <param name="name">The name.</param>
/// <returns>The named element or null if not found.</returns>
public static T Find<T>(this ILogical anchor, string name)
public static T? Find<T>(this ILogical anchor, string name)
where T : class
{
Contract.Requires<ArgumentNullException>(anchor != null);
Contract.Requires<ArgumentNullException>(name != null);
_ = anchor ?? throw new ArgumentNullException(nameof(anchor));
_ = name ?? throw new ArgumentNullException(nameof(name));
var styledAnchor = anchor as StyledElement;
if (styledAnchor == null)
return null;
@ -64,8 +64,8 @@ namespace Avalonia.Controls
public static T Get<T>(this INameScope nameScope, string name)
where T : class
{
Contract.Requires<ArgumentNullException>(nameScope != null);
Contract.Requires<ArgumentNullException>(name != null);
_ = nameScope ?? throw new ArgumentNullException(nameof(nameScope));
_ = name ?? throw new ArgumentNullException(nameof(name));
var result = nameScope.Find(name);
@ -94,9 +94,9 @@ namespace Avalonia.Controls
public static T Get<T>(this ILogical anchor, string name)
where T : class
{
Contract.Requires<ArgumentNullException>(anchor != null);
Contract.Requires<ArgumentNullException>(name != null);
_ = anchor ?? throw new ArgumentNullException(nameof(anchor));
_ = name ?? throw new ArgumentNullException(nameof(name));
var nameScope = (anchor as INameScope) ?? NameScope.GetNameScope((StyledElement)anchor);
if (nameScope == null)
throw new InvalidOperationException(
@ -105,9 +105,9 @@ namespace Avalonia.Controls
return nameScope.Get<T>(name);
}
public static INameScope FindNameScope(this ILogical control)
public static INameScope? FindNameScope(this ILogical control)
{
Contract.Requires<ArgumentNullException>(control != null);
_ = control ?? throw new ArgumentNullException(nameof(control));
var scope = control.GetSelfAndLogicalAncestors()
.OfType<StyledElement>()

8
src/Avalonia.Styling/Controls/NameScopeLocator.cs

@ -11,9 +11,9 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="scope">The scope relative from which the object should be resolved.</param>
/// <param name="name">The name of the object to find.</param>
public static IObservable<object> Track(INameScope scope, string name)
public static IObservable<object?> Track(INameScope scope, string name)
{
return new NeverEndingSynchronousCompletionAsyncResultObservable<object>(scope.FindAsync(name));
return new NeverEndingSynchronousCompletionAsyncResultObservable<object?>(scope.FindAsync(name));
}
// This class is implemented in such weird way because for some reason
@ -22,7 +22,7 @@ namespace Avalonia.Controls
private class NeverEndingSynchronousCompletionAsyncResultObservable<T> : IObservable<T>
{
private T _value;
private T? _value;
private SynchronousCompletionAsyncResult<T>? _asyncResult;
public NeverEndingSynchronousCompletionAsyncResultObservable(SynchronousCompletionAsyncResult<T> task)
@ -47,7 +47,7 @@ namespace Avalonia.Controls
observer.OnNext(_asyncResult.Value.GetResult());
});
else
observer.OnNext(_value);
observer.OnNext(_value!);
return Disposable.Empty;
}

2
src/Avalonia.Styling/Controls/PseudoClassesExtensions.cs

@ -12,7 +12,7 @@ namespace Avalonia.Controls
/// <param name="value">True to add the pseudoclass or false to remove.</param>
public static void Set(this IPseudoClasses classes, string name, bool value)
{
Contract.Requires<ArgumentNullException>(classes != null);
_ = classes ?? throw new ArgumentNullException(nameof(classes));
if (value)
{

2
src/Avalonia.Styling/Controls/ResourceDictionary.cs

@ -177,7 +177,7 @@ namespace Avalonia.Controls
}
}
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
Owner?.NotifyHostedResourcesChanged(ResourcesChangedEventArgs.Empty);
}

6
src/Avalonia.Styling/Controls/ResourceNodeExtensions.cs

@ -109,7 +109,7 @@ namespace Avalonia.Controls
observer.OnNext(Convert(_target.FindResource(_key)));
}
private void ResourcesChanged(object sender, ResourcesChangedEventArgs e)
private void ResourcesChanged(object? sender, ResourcesChangedEventArgs e)
{
PublishNext(Convert(_target.FindResource(_key)));
}
@ -159,7 +159,7 @@ namespace Avalonia.Controls
}
}
private void OwnerChanged(object sender, EventArgs e)
private void OwnerChanged(object? sender, EventArgs e)
{
if (_owner is object)
{
@ -176,7 +176,7 @@ namespace Avalonia.Controls
PublishNext();
}
private void ResourcesChanged(object sender, ResourcesChangedEventArgs e)
private void ResourcesChanged(object? sender, ResourcesChangedEventArgs e)
{
PublishNext();
}

2
src/Avalonia.Styling/INamed.cs

@ -8,6 +8,6 @@ namespace Avalonia
/// <summary>
/// Gets the element name.
/// </summary>
string Name { get; }
string? Name { get; }
}
}

16
src/Avalonia.Styling/LogicalTree/ControlLocator.cs

@ -9,19 +9,19 @@ namespace Avalonia.LogicalTree
/// </summary>
public static class ControlLocator
{
public static IObservable<ILogical> Track(ILogical relativeTo, int ancestorLevel, Type ancestorType = null)
public static IObservable<ILogical?> Track(ILogical relativeTo, int ancestorLevel, Type? ancestorType = null)
{
return new ControlTracker(relativeTo, ancestorLevel, ancestorType);
}
private class ControlTracker : LightweightObservableBase<ILogical>
private class ControlTracker : LightweightObservableBase<ILogical?>
{
private readonly ILogical _relativeTo;
private readonly int _ancestorLevel;
private readonly Type _ancestorType;
private ILogical _value;
private readonly Type? _ancestorType;
private ILogical? _value;
public ControlTracker(ILogical relativeTo, int ancestorLevel, Type ancestorType)
public ControlTracker(ILogical relativeTo, int ancestorLevel, Type? ancestorType)
{
_relativeTo = relativeTo;
_ancestorLevel = ancestorLevel;
@ -43,18 +43,18 @@ namespace Avalonia.LogicalTree
_value = null;
}
protected override void Subscribed(IObserver<ILogical> observer, bool first)
protected override void Subscribed(IObserver<ILogical?> observer, bool first)
{
observer.OnNext(_value);
}
private void Attached(object sender, LogicalTreeAttachmentEventArgs e)
private void Attached(object? sender, LogicalTreeAttachmentEventArgs e)
{
Update();
PublishNext(_value);
}
private void Detached(object sender, LogicalTreeAttachmentEventArgs e)
private void Detached(object? sender, LogicalTreeAttachmentEventArgs e)
{
_value = null;
PublishNext(null);

6
src/Avalonia.Styling/LogicalTree/ILogical.cs

@ -12,12 +12,12 @@ namespace Avalonia.LogicalTree
/// <summary>
/// Raised when the control is attached to a rooted logical tree.
/// </summary>
event EventHandler<LogicalTreeAttachmentEventArgs> AttachedToLogicalTree;
event EventHandler<LogicalTreeAttachmentEventArgs>? AttachedToLogicalTree;
/// <summary>
/// Raised when the control is detached from a rooted logical tree.
/// </summary>
event EventHandler<LogicalTreeAttachmentEventArgs> DetachedFromLogicalTree;
event EventHandler<LogicalTreeAttachmentEventArgs>? DetachedFromLogicalTree;
/// <summary>
/// Gets a value indicating whether the element is attached to a rooted logical tree.
@ -27,7 +27,7 @@ namespace Avalonia.LogicalTree
/// <summary>
/// Gets the logical parent.
/// </summary>
ILogical LogicalParent { get; }
ILogical? LogicalParent { get; }
/// <summary>
/// Gets the logical children.

26
src/Avalonia.Styling/LogicalTree/LogicalExtensions.cs

@ -15,14 +15,14 @@ namespace Avalonia.LogicalTree
/// <returns>The logical's ancestors.</returns>
public static IEnumerable<ILogical> GetLogicalAncestors(this ILogical logical)
{
Contract.Requires<ArgumentNullException>(logical != null);
_ = logical ?? throw new ArgumentNullException(nameof(logical));
logical = logical.LogicalParent;
ILogical? l = logical.LogicalParent;
while (logical != null)
while (l != null)
{
yield return logical;
logical = logical.LogicalParent;
yield return l;
l = l.LogicalParent;
}
}
@ -48,14 +48,14 @@ namespace Avalonia.LogicalTree
/// <param name="logical">The logical.</param>
/// <param name="includeSelf">If given logical should be included in search.</param>
/// <returns>First ancestor of given type.</returns>
public static T FindLogicalAncestorOfType<T>(this ILogical logical, bool includeSelf = false) where T : class
public static T? FindLogicalAncestorOfType<T>(this ILogical logical, bool includeSelf = false) where T : class
{
if (logical is null)
{
return null;
}
ILogical parent = includeSelf ? logical : logical.LogicalParent;
var parent = includeSelf ? logical : logical.LogicalParent;
while (parent != null)
{
@ -120,7 +120,7 @@ namespace Avalonia.LogicalTree
/// <param name="logical">The logical.</param>
/// <param name="includeSelf">If given logical should be included in search.</param>
/// <returns>First descendant of given type.</returns>
public static T FindLogicalDescendantOfType<T>(this ILogical logical, bool includeSelf = false) where T : class
public static T? FindLogicalDescendantOfType<T>(this ILogical logical, bool includeSelf = false) where T : class
{
if (logical is null)
{
@ -140,7 +140,7 @@ namespace Avalonia.LogicalTree
/// </summary>
/// <param name="logical">The logical.</param>
/// <returns>The parent, or null if the logical is unparented.</returns>
public static ILogical GetLogicalParent(this ILogical logical)
public static ILogical? GetLogicalParent(this ILogical logical)
{
return logical.LogicalParent;
}
@ -153,7 +153,7 @@ namespace Avalonia.LogicalTree
/// <returns>
/// The parent, or null if the logical is unparented or its parent is not of type <typeparamref name="T"/>.
/// </returns>
public static T GetLogicalParent<T>(this ILogical logical) where T : class
public static T? GetLogicalParent<T>(this ILogical logical) where T : class
{
return logical.LogicalParent as T;
}
@ -165,7 +165,7 @@ namespace Avalonia.LogicalTree
/// <returns>The logical siblings.</returns>
public static IEnumerable<ILogical> GetLogicalSiblings(this ILogical logical)
{
ILogical parent = logical.LogicalParent;
var parent = logical.LogicalParent;
if (parent != null)
{
@ -187,7 +187,7 @@ namespace Avalonia.LogicalTree
/// </returns>
public static bool IsLogicalAncestorOf(this ILogical logical, ILogical target)
{
ILogical current = target?.LogicalParent;
var current = target?.LogicalParent;
while (current != null)
{
@ -202,7 +202,7 @@ namespace Avalonia.LogicalTree
return false;
}
private static T FindDescendantOfTypeCore<T>(ILogical logical) where T : class
private static T? FindDescendantOfTypeCore<T>(ILogical logical) where T : class
{
var logicalChildren = logical.LogicalChildren;
var logicalChildrenCount = logicalChildren.Count;

7
src/Avalonia.Styling/LogicalTree/LogicalTreeAttachmentEventArgs.cs

@ -19,11 +19,8 @@ namespace Avalonia.LogicalTree
ILogical source,
ILogical parent)
{
Contract.Requires<ArgumentNullException>(root != null);
Contract.Requires<ArgumentNullException>(source != null);
Root = root;
Source = source;
Root = root ?? throw new ArgumentNullException(nameof(root));
Source = source ?? throw new ArgumentNullException(nameof(source));
Parent = parent;
}

18
src/Avalonia.Styling/StyledElement.cs

@ -427,7 +427,7 @@ namespace Avalonia
if (_logicalRoot != null)
{
var e = new LogicalTreeAttachmentEventArgs(_logicalRoot, this, old);
var e = new LogicalTreeAttachmentEventArgs(_logicalRoot, this, old!);
OnDetachedFromLogicalTreeCore(e);
}
@ -435,7 +435,7 @@ namespace Avalonia
if (newRoot is object)
{
var e = new LogicalTreeAttachmentEventArgs(newRoot, this, parent);
var e = new LogicalTreeAttachmentEventArgs(newRoot, this, parent!);
OnAttachedToLogicalTreeCore(e);
}
else if (parent is null)
@ -495,21 +495,21 @@ namespace Avalonia
DetachStylesFromThisAndDescendents(allStyles);
}
protected virtual void LogicalChildrenCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
protected virtual void LogicalChildrenCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
SetLogicalParent(e.NewItems);
SetLogicalParent(e.NewItems!);
break;
case NotifyCollectionChangedAction.Remove:
ClearLogicalParent(e.OldItems);
ClearLogicalParent(e.OldItems!);
break;
case NotifyCollectionChangedAction.Replace:
ClearLogicalParent(e.OldItems);
SetLogicalParent(e.NewItems);
ClearLogicalParent(e.OldItems!);
SetLogicalParent(e.NewItems!);
break;
case NotifyCollectionChangedAction.Reset:
@ -729,7 +729,7 @@ namespace Avalonia
for (var i = 0; i < count; i++)
{
var logical = (ILogical) children[i];
var logical = (ILogical) children[i]!;
if (logical.LogicalParent is null)
{
@ -744,7 +744,7 @@ namespace Avalonia
for (var i = 0; i < count; i++)
{
var logical = (ILogical) children[i];
var logical = (ILogical) children[i]!;
if (logical.LogicalParent == this)
{

2
src/Avalonia.Styling/Styling/Activators/NthChildActivator.cs

@ -37,7 +37,7 @@ namespace Avalonia.Styling.Activators
_provider.ChildIndexChanged -= ChildIndexChanged;
}
private void ChildIndexChanged(object sender, ChildIndexChangedEventArgs e)
private void ChildIndexChanged(object? sender, ChildIndexChangedEventArgs e)
{
// Run matching again if:
// 1. Selector is reversed, so other item insertion/deletion might affect total count without changing subscribed item index.

2
src/Avalonia.Styling/Styling/Activators/StyleClassActivator.cs

@ -66,7 +66,7 @@ namespace Avalonia.Styling.Activators
_classes.CollectionChanged -= ClassesChangedHandler;
}
private void ClassesChanged(object sender, NotifyCollectionChangedEventArgs e)
private void ClassesChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action != NotifyCollectionChangedAction.Move)
{

6
src/Avalonia.Styling/Styling/ChildSelector.cs

@ -6,7 +6,7 @@ namespace Avalonia.Styling
internal class ChildSelector : Selector
{
private readonly Selector _parent;
private string _selectorString;
private string? _selectorString;
public ChildSelector(Selector parent)
{
@ -25,7 +25,7 @@ namespace Avalonia.Styling
public override bool IsCombinator => true;
/// <inheritdoc/>
public override Type TargetType => null;
public override Type? TargetType => null;
public override string ToString()
{
@ -64,6 +64,6 @@ namespace Avalonia.Styling
}
}
protected override Selector MovePrevious() => null;
protected override Selector? MovePrevious() => null;
}
}

2
src/Avalonia.Styling/Styling/OrSelector.cs

@ -120,7 +120,7 @@ namespace Avalonia.Styling
}
else
{
while (!result.IsAssignableFrom(selector.TargetType))
while (result is not null && !result.IsAssignableFrom(selector.TargetType))
{
result = result.BaseType;
}

2
src/Avalonia.Styling/Styling/PropertyEqualsSelector.cs

@ -109,7 +109,7 @@ namespace Avalonia.Styling
var converter = TypeDescriptor.GetConverter(propertyType);
if (converter?.CanConvertFrom(valueType) == true)
{
return Equals(propertyValue, converter.ConvertFrom(null, CultureInfo.InvariantCulture, value));
return Equals(propertyValue, converter.ConvertFrom(null, CultureInfo.InvariantCulture, value!));
}
return false;

50
src/Avalonia.Styling/Styling/Selectors.cs

@ -25,10 +25,14 @@ namespace Avalonia.Styling
/// <param name="previous">The previous selector.</param>
/// <param name="name">The name of the style class.</param>
/// <returns>The selector.</returns>
public static Selector Class(this Selector previous, string name)
public static Selector Class(this Selector? previous, string name)
{
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(name));
_ = name ?? throw new ArgumentNullException(nameof(name));
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Name may not be empty", nameof(name));
}
var tac = previous as TypeNameAndClassSelector;
@ -48,7 +52,7 @@ namespace Avalonia.Styling
/// </summary>
/// <param name="previous">The previous selector.</param>
/// <returns>The selector.</returns>
public static Selector Descendant(this Selector previous)
public static Selector Descendant(this Selector? previous)
{
return new DescendantSelector(previous);
}
@ -59,9 +63,9 @@ namespace Avalonia.Styling
/// <param name="previous">The previous selector.</param>
/// <param name="type">The type.</param>
/// <returns>The selector.</returns>
public static Selector Is(this Selector previous, Type type)
public static Selector Is(this Selector? previous, Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
return TypeNameAndClassSelector.Is(previous, type);
}
@ -72,7 +76,7 @@ namespace Avalonia.Styling
/// <typeparam name="T">The type.</typeparam>
/// <param name="previous">The previous selector.</param>
/// <returns>The selector.</returns>
public static Selector Is<T>(this Selector previous) where T : IStyleable
public static Selector Is<T>(this Selector? previous) where T : IStyleable
{
return previous.Is(typeof(T));
}
@ -83,10 +87,14 @@ namespace Avalonia.Styling
/// <param name="previous">The previous selector.</param>
/// <param name="name">The name.</param>
/// <returns>The selector.</returns>
public static Selector Name(this Selector previous, string name)
public static Selector Name(this Selector? previous, string name)
{
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(name));
_ = name ?? throw new ArgumentNullException(nameof(name));
if (string.IsNullOrWhiteSpace(name))
{
throw new ArgumentException("Name may not be empty", nameof(name));
}
var tac = previous as TypeNameAndClassSelector;
@ -107,7 +115,7 @@ namespace Avalonia.Styling
/// <param name="previous">The previous selector.</param>
/// <param name="argument">The selector to be not-ed.</param>
/// <returns>The selector.</returns>
public static Selector Not(this Selector previous, Func<Selector, Selector> argument)
public static Selector Not(this Selector? previous, Func<Selector?, Selector> argument)
{
return new NotSelector(previous, argument(null));
}
@ -118,7 +126,7 @@ namespace Avalonia.Styling
/// <param name="previous">The previous selector.</param>
/// <param name="argument">The selector to be not-ed.</param>
/// <returns>The selector.</returns>
public static Selector Not(this Selector previous, Selector argument)
public static Selector Not(this Selector? previous, Selector argument)
{
return new NotSelector(previous, argument);
}
@ -126,7 +134,7 @@ namespace Avalonia.Styling
/// <inheritdoc cref="NthChildSelector"/>
/// <inheritdoc cref="NthChildSelector(Selector?, int, int)"/>
/// <returns>The selector.</returns>
public static Selector NthChild(this Selector previous, int step, int offset)
public static Selector NthChild(this Selector? previous, int step, int offset)
{
return new NthChildSelector(previous, step, offset);
}
@ -134,7 +142,7 @@ namespace Avalonia.Styling
/// <inheritdoc cref="NthLastChildSelector"/>
/// <inheritdoc cref="NthLastChildSelector(Selector?, int, int)"/>
/// <returns>The selector.</returns>
public static Selector NthLastChild(this Selector previous, int step, int offset)
public static Selector NthLastChild(this Selector? previous, int step, int offset)
{
return new NthLastChildSelector(previous, step, offset);
}
@ -145,9 +153,9 @@ namespace Avalonia.Styling
/// <param name="previous">The previous selector.</param>
/// <param name="type">The type.</param>
/// <returns>The selector.</returns>
public static Selector OfType(this Selector previous, Type type)
public static Selector OfType(this Selector? previous, Type type)
{
Contract.Requires<ArgumentNullException>(type != null);
_ = type ?? throw new ArgumentNullException(nameof(type));
return TypeNameAndClassSelector.OfType(previous, type);
}
@ -158,7 +166,7 @@ namespace Avalonia.Styling
/// <typeparam name="T">The type.</typeparam>
/// <param name="previous">The previous selector.</param>
/// <returns>The selector.</returns>
public static Selector OfType<T>(this Selector previous) where T : IStyleable
public static Selector OfType<T>(this Selector? previous) where T : IStyleable
{
return previous.OfType(typeof(T));
}
@ -191,9 +199,9 @@ namespace Avalonia.Styling
/// <param name="property">The property.</param>
/// <param name="value">The property value.</param>
/// <returns>The selector.</returns>
public static Selector PropertyEquals<T>(this Selector previous, AvaloniaProperty<T> property, object value)
public static Selector PropertyEquals<T>(this Selector? previous, AvaloniaProperty<T> property, object? value)
{
Contract.Requires<ArgumentNullException>(property != null);
_ = property ?? throw new ArgumentNullException(nameof(property));
return new PropertyEqualsSelector(previous, property, value);
}
@ -205,9 +213,9 @@ namespace Avalonia.Styling
/// <param name="property">The property.</param>
/// <param name="value">The property value.</param>
/// <returns>The selector.</returns>
public static Selector PropertyEquals(this Selector previous, AvaloniaProperty property, object value)
public static Selector PropertyEquals(this Selector? previous, AvaloniaProperty property, object? value)
{
Contract.Requires<ArgumentNullException>(property != null);
_ = property ?? throw new ArgumentNullException(nameof(property));
return new PropertyEqualsSelector(previous, property, value);
}

14
src/Avalonia.Styling/Styling/Styles.cs

@ -262,7 +262,7 @@ namespace Avalonia.Styling
}
}
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
private void OnCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
static IReadOnlyList<T> ToReadOnlyList<T>(IList list)
{
@ -282,7 +282,7 @@ namespace Avalonia.Styling
{
for (var i = 0; i < items.Count; ++i)
{
var style = (IStyle)items[i];
var style = (IStyle)items[i]!;
if (Owner is object && style is IResourceProvider resourceProvider)
{
@ -299,7 +299,7 @@ namespace Avalonia.Styling
{
for (var i = 0; i < items.Count; ++i)
{
var style = (IStyle)items[i];
var style = (IStyle)items[i]!;
if (Owner is object && style is IResourceProvider resourceProvider)
{
@ -315,14 +315,14 @@ namespace Avalonia.Styling
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
Add(e.NewItems);
Add(e.NewItems!);
break;
case NotifyCollectionChangedAction.Remove:
Remove(e.OldItems);
Remove(e.OldItems!);
break;
case NotifyCollectionChangedAction.Replace:
Remove(e.OldItems);
Add(e.NewItems);
Remove(e.OldItems!);
Add(e.NewItems!);
break;
case NotifyCollectionChangedAction.Reset:
throw new InvalidOperationException("Reset should not be called on Styles.");

6
src/Avalonia.Styling/Styling/TemplateSelector.cs

@ -5,7 +5,7 @@ namespace Avalonia.Styling
internal class TemplateSelector : Selector
{
private readonly Selector _parent;
private string _selectorString;
private string? _selectorString;
public TemplateSelector(Selector parent)
{
@ -24,7 +24,7 @@ namespace Avalonia.Styling
public override bool IsCombinator => true;
/// <inheritdoc/>
public override Type TargetType => null;
public override Type? TargetType => null;
public override string ToString()
{
@ -48,6 +48,6 @@ namespace Avalonia.Styling
return _parent.Match(templatedParent, subscribe);
}
protected override Selector MovePrevious() => null;
protected override Selector? MovePrevious() => null;
}
}

2
src/Avalonia.Visuals/Visual.cs

@ -377,7 +377,7 @@ namespace Avalonia
}
}
protected override void LogicalChildrenCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
protected override void LogicalChildrenCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
base.LogicalChildrenCollectionChanged(sender, e);
VisualRoot?.Renderer?.RecalculateChildren(this);

6
src/Markup/Avalonia.Markup/Markup/Parsers/SelectorParser.cs

@ -138,16 +138,16 @@ namespace Avalonia.Markup.Parsers
break;
case SelectorGrammar.ChildSyntax child:
result = result.Child();
result = result!.Child();
break;
case SelectorGrammar.DescendantSyntax descendant:
result = result.Descendant();
break;
case SelectorGrammar.TemplateSyntax template:
result = result.Template();
result = result!.Template();
break;
case SelectorGrammar.NotSyntax not:
result = result.Not(x => Create(not.Argument));
result = result.Not(x => Create(not.Argument)!);
break;
case SelectorGrammar.NthChildSyntax nth:
result = result.NthChild(nth.Step, nth.Offset);

Loading…
Cancel
Save