Skip to content

Commit

Permalink
Merge pull request #771 from unoplatform/dev/dr/genDiff
Browse files Browse the repository at this point in the history
Improve collection analyzer
  • Loading branch information
dr1rrb authored Sep 27, 2022
2 parents d257d1a + d7a588b commit 0bc9052
Show file tree
Hide file tree
Showing 32 changed files with 1,268 additions and 282 deletions.
33 changes: 33 additions & 0 deletions src/Uno.Extensions.Core/_Compat/MemberNotNullWhenAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;

namespace System.Diagnostics.CodeAnalysis
{
/// <summary>Specifies that the method or property will ensure that the listed field and property members have non-null values when returning with the specified return value condition.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public sealed class MemberNotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
/// <param name="returnValue">The return value condition. If the method returns this value, the associated parameter will not be <see langword="null" />.</param>
/// <param name="member">The field or property member that is promised to be non-null.</param>
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}

/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
/// <param name="returnValue">The return value condition. If the method returns this value, the associated parameter will not be <see langword="null" />.</param>
/// <param name="members">The list of field and property members that are promised to be non-null.</param>
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}

/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }

/// <summary>Gets field or property member names.</summary>
public string[] Members { get; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ internal record CompatibilityTypesGenerationContext(

[ContextType("System.Diagnostics.CodeAnalysis.NotNullIfNotNullAttribute?")] INamedTypeSymbol? NotNullIfNotNullAttribute, // .net std 2.1 and above
[ContextType("System.Diagnostics.CodeAnalysis.NotNullWhenAttribute?")] INamedTypeSymbol? NotNullWhenAttribute, // .net std 2.1 and above
[ContextType("System.Diagnostics.CodeAnalysis.MemberNotNullWhenAttribute?")] INamedTypeSymbol? MemberNotNullWhenAttribute, // .net std 2.1 and above

[ContextType("System.Runtime.CompilerServices.IsExternalInit?")] INamedTypeSymbol? IsExternalInit, // .net 5 and above only
[ContextType("System.Runtime.CompilerServices.ModuleInitializerAttribute?")] INamedTypeSymbol? ModuleInitializerAttribute // .net 5 and above only
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ public CompatibilityTypesGenerationTool(CompatibilityTypesGenerationContext cont
{
yield return (nameof(_context.NotNullWhenAttribute), GetNotNullWhenAttribute());
}
if (_context.MemberNotNullWhenAttribute is null && !GetIsDisabled("UnoExtensionsGeneration_DisableMemberNotNullWhenAttribute"))
{
yield return (nameof(_context.MemberNotNullWhenAttribute), GetMemberNotNullWhenAttribute());
}
if (_context.IsExternalInit is null && !GetIsDisabled("UnoExtensionsGeneration_DisableIsExternalInit"))
{
yield return (nameof(_context.IsExternalInit), GetIsExternalInit());
Expand Down Expand Up @@ -110,6 +114,44 @@ public NotNullIfNotNullAttribute(string parameterName)
}}
".Align(0);

private string GetMemberNotNullWhenAttribute()
=> $@"{this.GetFileHeader(3)}
using global::System;
namespace System.Diagnostics.CodeAnalysis
{{
/// <summary>Specifies that the method or property will ensure that the listed field and property members have non-null values when returning with the specified return value condition.</summary>
[global::System.AttributeUsage(global::System.AttributeTargets.Method | global::System.AttributeTargets.Property, AllowMultiple = true, Inherited = false)]
public sealed class MemberNotNullWhenAttribute : global::System.Attribute
{{
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
/// <param name=""returnValue"">The return value condition. If the method returns this value, the associated parameter will not be <see langword=""null"" />.</param>
/// <param name=""member"">The field or property member that is promised to be non-null.</param>
public MemberNotNullWhenAttribute(bool returnValue, string member)
{{
ReturnValue = returnValue;
Members = new string[1] {{ member }};
}}
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
/// <param name=""returnValue"">The return value condition. If the method returns this value, the associated parameter will not be <see langword=""null"" />.</param>
/// <param name=""members"">The list of field and property members that are promised to be non-null.</param>
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{{
ReturnValue = returnValue;
Members = members;
}}
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue {{ get; }}
/// <summary>Gets field or property member names.</summary>
public string[] Members {{ get; }}
}}
}}
".Align(0);

public string GetNotNullWhenAttribute()
=> $@"{this.GetFileHeader(3)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<ItemGroup>
<CompilerVisibleProperty Include="UnoExtensionsGeneration_DisableNotNullIfNotNullAttribute" />
<CompilerVisibleProperty Include="UnoExtensionsGeneration_DisableNotNullWhenAttribute" />
<CompilerVisibleProperty Include="UnoExtensionsGeneration_DisableMemberNotNullWhenAttribute" />
<CompilerVisibleProperty Include="UnoExtensionsGeneration_DisableIsExternalInit" />
<CompilerVisibleProperty Include="UnoExtensionsGeneration_DisableModuleInitializerAttribute" />
</ItemGroup>
Expand Down
22 changes: 11 additions & 11 deletions src/Uno.Extensions.Reactive.Testing/ConstraintParts/ItemsChanged.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,34 @@ public sealed class ItemsChanged : ChangesConstraint
public static ItemsChanged Empty { get; } = new();

public static ItemsChanged Add<T>(int index, params T[] items)
=> new(RichNotifyCollectionChangedEventArgs.AddSome(items, index));
=> new(RichNotifyCollectionChangedEventArgs.AddSome<T>(items, index));

public static ItemsChanged Add<T>(int index, IEnumerable<T> items)
=> new(RichNotifyCollectionChangedEventArgs.AddSome(items.ToList(), index));
=> new(RichNotifyCollectionChangedEventArgs.AddSome<T>(items.ToList(), index));

public static ItemsChanged Remove<T>(int index, params T[] items)
=> new(RichNotifyCollectionChangedEventArgs.RemoveSome(items, index));
=> new(RichNotifyCollectionChangedEventArgs.RemoveSome<T>(items, index));

public static ItemsChanged Remove<T>(int index, IEnumerable<T> items)
=> new(RichNotifyCollectionChangedEventArgs.RemoveSome(items.ToList(), index));
=> new(RichNotifyCollectionChangedEventArgs.RemoveSome<T>(items.ToList(), index));

public static ItemsChanged Replace<T>(int index, IEnumerable<T> oldItems, IEnumerable<T> newItems)
=> new(RichNotifyCollectionChangedEventArgs.ReplaceSome(oldItems.ToList(), newItems.ToList(), index));
=> new(RichNotifyCollectionChangedEventArgs.ReplaceSome<T>(oldItems.ToList(), newItems.ToList(), index));

public static ItemsChanged Replace<T>(int index, T oldItem, T newItem)
=> new(RichNotifyCollectionChangedEventArgs.Replace(oldItem, newItem, index));
=> new(RichNotifyCollectionChangedEventArgs.Replace<T>(oldItem, newItem, index));

public static ItemsChanged Move<T>(int oldIndex, int newIndex, params T[] items)
=> new(RichNotifyCollectionChangedEventArgs.MoveSome(items.ToList(), oldIndex, newIndex));
=> new(RichNotifyCollectionChangedEventArgs.MoveSome<T>(items.ToList(), oldIndex, newIndex));

public static ItemsChanged Move<T>(int oldIndex, int newIndex, IEnumerable<T> items)
=> new(RichNotifyCollectionChangedEventArgs.MoveSome(items.ToList(), oldIndex, newIndex));
=> new(RichNotifyCollectionChangedEventArgs.MoveSome<T>(items.ToList(), oldIndex, newIndex));

public static ItemsChanged Reset<T>(IEnumerable<T> oldItems, IEnumerable<T> newItems)
=> new(RichNotifyCollectionChangedEventArgs.Reset(oldItems.ToList(), newItems.ToList()));
=> new(RichNotifyCollectionChangedEventArgs.Reset<T>(oldItems.ToList(), newItems.ToList()));

public static ItemsChanged Reset<T>(IEnumerable<T> newItems)
=> new(RichNotifyCollectionChangedEventArgs.Reset(null, newItems.ToList()));
=> new(RichNotifyCollectionChangedEventArgs.Reset<T>(null, newItems.ToList()));

public static ItemsChanged operator &(ItemsChanged left, ItemsChanged right)
=> new(left._expectedArgs.Concat(right._expectedArgs).ToImmutableList());
Expand All @@ -64,7 +64,7 @@ public override void Assert(ChangeCollection actual)
{
AssertionScope.Current.Fail("is not set, but the collection of items was expected to have been updated.");
}
changeSet.Should().BeOfType<CollectionChangeSet>();
changeSet.Should().BeAssignableTo<CollectionChangeSet>();

if (changeSet is CollectionChangeSet changes)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.Extensions.Collections.Tracking;
using Uno.Extensions.Reactive.Collections;
using Uno.Extensions.Reactive.Tests._Utils;
using static Uno.Extensions.Collections.CollectionChanged;

Expand Down Expand Up @@ -2215,7 +2216,11 @@ protected override IEnumerable<T> AsEnumerable(IImmutableList<T> collection)
=> collection;

/// <inheritdoc />
protected override CollectionUpdater GetUpdater(CollectionAnalyzer<T> analyzer, IImmutableList<T> previous, IImmutableList<T> updated, ICollectionUpdaterVisitor visitor)
=> analyzer.GetUpdater(previous, updated, visitor);
protected override CollectionUpdater GetUpdater(ItemComparer<T> comparer, IImmutableList<T> previous, IImmutableList<T> updated, ICollectionUpdaterVisitor visitor)
=> new CollectionAnalyzer<T>(comparer).GetUpdater(previous, updated, visitor);

/// <inheritdoc />
protected override CollectionChangeSet<T> GetChanges(ItemComparer<T> comparer, IImmutableList<T> previous, IImmutableList<T> updated)
=> new CollectionAnalyzer<T>(comparer).GetChanges(previous, updated);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.Extensions.Collections.Tracking;
using Uno.Extensions.Reactive.Collections;
using Uno.Extensions.Reactive.Tests._Utils;
using static Uno.Extensions.Collections.CollectionChanged;

Expand Down Expand Up @@ -2215,8 +2216,12 @@ protected override IEnumerable<T> AsEnumerable(ImmutableListWhichIsNotIList<T> c
=> collection;

/// <inheritdoc />
protected override CollectionUpdater GetUpdater(CollectionAnalyzer<T> analyzer, ImmutableListWhichIsNotIList<T> previous, ImmutableListWhichIsNotIList<T> updated, ICollectionUpdaterVisitor visitor)
=> analyzer.GetUpdater(previous, updated, visitor);
protected override CollectionUpdater GetUpdater(ItemComparer<T> comparer, ImmutableListWhichIsNotIList<T> previous, ImmutableListWhichIsNotIList<T> updated, ICollectionUpdaterVisitor visitor)
=> new CollectionAnalyzer<T>(comparer).GetUpdater(previous, updated, visitor);

/// <inheritdoc />
protected override CollectionChangeSet<T> GetChanges(ItemComparer<T> comparer, ImmutableListWhichIsNotIList<T> previous, ImmutableListWhichIsNotIList<T> updated)
=> new CollectionAnalyzer<T>(comparer).GetChanges(previous, updated);
}

private class ImmutableListWhichIsNotIList<T> : IImmutableList<T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.Extensions.Collections.Tracking;
using Uno.Extensions.Equality;
using Uno.Extensions.Reactive.Collections;
using Uno.Extensions.Reactive.Tests._Utils;
using Uno.Extensions.Reactive.Utils;
using static Uno.Extensions.Collections.CollectionChanged;
Expand Down Expand Up @@ -2220,8 +2221,12 @@ protected override IList Create(object?[] items)
=> new ArrayList(items.Select(_cast).ToArray()); // Make sure to lost the IList<object?>

/// <inheritdoc />
protected override CollectionUpdater GetUpdater(CollectionAnalyzer<object?> analyzer, IList previous, IList updated, ICollectionUpdaterVisitor visitor)
=> analyzer.GetUpdater(previous, updated, visitor);
protected override CollectionUpdater GetUpdater(ItemComparer<object?> comparer, IList previous, IList updated, ICollectionUpdaterVisitor visitor)
=> new CollectionAnalyzer(new(comparer.Entity?.ToEqualityComparer(), comparer.Version?.ToEqualityComparer())).GetUpdater(previous, updated, visitor);

/// <inheritdoc />
protected override CollectionChangeSet GetChanges(ItemComparer<object?> comparer, IList previous, IList updated)
=> new CollectionAnalyzer(new(comparer.Entity?.ToEqualityComparer(), comparer.Version?.ToEqualityComparer())).GetChanges(previous, updated);

/// <inheritdoc />
protected override IEnumerable<object?> AsEnumerable(IList collection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Uno.Extensions.Collections.Tracking;
using Uno.Extensions.Reactive.Collections;
using Uno.Extensions.Reactive.Tests._Utils;
using Uno.Extensions.Reactive.Utils;
using static Uno.Extensions.Collections.CollectionChanged;
Expand Down Expand Up @@ -2210,8 +2211,12 @@ protected override IList<T> Create(T[] items)
=> items;

/// <inheritdoc />
protected override CollectionUpdater GetUpdater(CollectionAnalyzer<T> analyzer, IList<T> previous, IList<T> updated, ICollectionUpdaterVisitor visitor)
=> analyzer.GetUpdater(previous, updated, visitor);
protected override CollectionUpdater GetUpdater(ItemComparer<T> comparer, IList<T> previous, IList<T> updated, ICollectionUpdaterVisitor visitor)
=> new CollectionAnalyzer<T>(comparer).GetUpdater(previous, updated, visitor);

/// <inheritdoc />
protected override CollectionChangeSet<T> GetChanges(ItemComparer<T> comparer, IList<T> previous, IList<T> updated)
=> new CollectionAnalyzer<T>(comparer).GetChanges(previous, updated);

/// <inheritdoc />
protected override IEnumerable<T> AsEnumerable(IList<T> collection)
Expand Down
Loading

0 comments on commit 0bc9052

Please sign in to comment.