Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable nullability in ArrayEditor #12675

Merged
merged 3 commits into from
Feb 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/System.Windows.Forms.Design/src/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#nullable enable
~override System.ComponentModel.Design.ArrayEditor.CreateCollectionItemType() -> System.Type
~override System.ComponentModel.Design.ArrayEditor.GetItems(object editValue) -> object[]
~override System.ComponentModel.Design.ArrayEditor.SetItems(object editValue, object[] value) -> object
override System.ComponentModel.Design.ArrayEditor.CreateCollectionItemType() -> System.Type!
override System.ComponentModel.Design.ArrayEditor.GetItems(object? editValue) -> object![]!
override System.ComponentModel.Design.ArrayEditor.SetItems(object? editValue, object![]? value) -> object?
~override System.Windows.Forms.Design.ComponentTray.GetService(System.Type serviceType) -> object
~override System.Windows.Forms.Design.ComponentTray.OnDragDrop(System.Windows.Forms.DragEventArgs de) -> void
~override System.Windows.Forms.Design.ComponentTray.OnDragEnter(System.Windows.Forms.DragEventArgs de) -> void
Expand Down Expand Up @@ -31,7 +31,7 @@
~override System.Windows.Forms.Design.ParentControlDesigner.SnapLines.get -> System.Collections.IList
~override System.Windows.Forms.Design.WindowsFormsDesignerOptionService.PopulateOptionCollection(System.ComponentModel.Design.DesignerOptionService.DesignerOptionCollection options) -> void
~static System.Windows.Forms.Design.ParentControlDesigner.InvokeCreateTool(System.Windows.Forms.Design.ParentControlDesigner toInvoke, System.Drawing.Design.ToolboxItem tool) -> void
~System.ComponentModel.Design.ArrayEditor.ArrayEditor(System.Type type) -> void
System.ComponentModel.Design.ArrayEditor.ArrayEditor(System.Type! type) -> void
~System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList actionList, string memberName, string displayName) -> void
~System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList actionList, string memberName, string displayName, bool includeAsDesignerVerb) -> void
~System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList actionList, string memberName, string displayName, string category) -> void
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable

namespace System.ComponentModel.Design;

/// <summary>
Expand All @@ -22,12 +20,16 @@ public ArrayEditor(Type type) : base(type)
/// Gets or sets the data type this collection contains.
/// </summary>
protected override Type CreateCollectionItemType()
=> CollectionType?.GetElementType();
{
Type? type = CollectionType.GetElementType();

return type is null ? throw new InvalidOperationException() : type;
}

/// <summary>
/// Gets the items in the array.
/// </summary>
protected override object[] GetItems(object editValue)
protected override object[] GetItems(object? editValue)
{
if (editValue is Array valueArray)
{
Expand All @@ -42,7 +44,7 @@ protected override object[] GetItems(object editValue)
/// <summary>
/// Sets the items in the array.
/// </summary>
protected override object SetItems(object editValue, object[] value)
protected override object? SetItems(object? editValue, object[]? value)
{
if (editValue is not null and not Array)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public partial class CollectionEditor : UITypeEditor
/// <summary>
/// Initializes a new instance of the <see cref="CollectionEditor"/> class using the specified collection type.
/// </summary>
public CollectionEditor(Type type) => CollectionType = type;
public CollectionEditor(Type type) => CollectionType = type.OrThrowIfNull();

/// <summary>
/// Gets the data type of each item in the collection.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,8 @@ namespace System.ComponentModel.Design.Tests;
public class ArrayEditorTests
{
[Theory]
[InlineData(typeof(object), null)]
[InlineData(typeof(string), null)]
[InlineData(typeof(string[]), typeof(string))]
[InlineData(typeof(int[]), typeof(int))]
[InlineData(typeof(IList<int>), null)]
[InlineData(typeof(IList), null)]
[InlineData(typeof(ClassWithItem), null)]
[InlineData(typeof(ClassWithPrivateItem), null)]
[InlineData(typeof(ClassWithStaticItem), null)]
[InlineData(typeof(ClassWithItems), null)]
[InlineData(typeof(ClassWithPrivateItems), null)]
[InlineData(typeof(ClassWithStaticItems), null)]
public void ArrayEditor_Ctor_Type(Type type, Type expectedItemType)
{
SubArrayEditor editor = new(type);
Expand All @@ -34,16 +25,27 @@ public void ArrayEditor_Ctor_Type(Type type, Type expectedItemType)
Assert.Equal([expectedItemType], editor.NewItemTypes);
}

[Theory]
[InlineData(typeof(object))]
[InlineData(typeof(string))]
[InlineData(typeof(IList<int>))]
[InlineData(typeof(IList))]
[InlineData(typeof(ClassWithItem))]
[InlineData(typeof(ClassWithPrivateItem))]
[InlineData(typeof(ClassWithStaticItem))]
[InlineData(typeof(ClassWithItems))]
[InlineData(typeof(ClassWithPrivateItems))]
[InlineData(typeof(ClassWithStaticItems))]
public void ArrayEditor_Ctor_Invalid_Type(Type type)
{
SubArrayEditor editor = new(type);
Assert.Throws<InvalidOperationException>(() => editor.CollectionItemType);
}

[Fact]
public void ArrayEditor_Ctor_NullType()
public void ArrayEditor_Ctor_NullType_ThrowsArgumentNullException()
{
SubArrayEditor editor = new(null);
Assert.Null(editor.CollectionItemType);
Assert.Null(editor.CollectionType);
Assert.Null(editor.Context);
Assert.Equal("net.ComponentModel.CollectionEditor", editor.HelpTopic);
Assert.False(editor.IsDropDownResizable);
Assert.Equal([null], editor.NewItemTypes);
Assert.Throws<ArgumentNullException>(() => new SubArrayEditor(null));
}

public static IEnumerable<object[]> CanRemoveInstance_TestData()
Expand All @@ -58,7 +60,7 @@ public static IEnumerable<object[]> CanRemoveInstance_TestData()
[MemberData(nameof(CanRemoveInstance_TestData))]
public void ArrayEditor_CanRemoveInstance_Invoke_ReturnsExpected(object value)
{
SubArrayEditor editor = new(null);
SubArrayEditor editor = new(typeof(string[]));
Assert.True(editor.CanRemoveInstance(value));
}

Expand All @@ -77,29 +79,19 @@ public void ArrayEditor_CanRemoveInstance_InheritanceAttribute_ReturnsExpected(I
{
using Component component = new();
TypeDescriptor.AddAttributes(component, attribute);
SubArrayEditor editor = new(null);
SubArrayEditor editor = new(typeof(string[]));
Assert.Equal(expected, editor.CanRemoveInstance(component));
}

[Fact]
public void ArrayEditor_CanSelectMultipleInstances_Invoke_ReturnsFalse()
{
SubArrayEditor editor = new(null);
SubArrayEditor editor = new(typeof(string[]));
Assert.True(editor.CanSelectMultipleInstances());
}

public static IEnumerable<object[]> GetDisplayText_TestData()
{
yield return new object[] { null, null, string.Empty };
yield return new object[] { null, string.Empty, "String" };
yield return new object[] { null, "string", "string" };

yield return new object[] { null, new ClassWithStringName { Name = "CustomName" }, "CustomName" };
yield return new object[] { null, new ClassWithStringName { Name = string.Empty }, "ClassWithStringName" };
yield return new object[] { null, new ClassWithStringName { Name = null }, "ClassWithStringName" };
yield return new object[] { null, new ClassWithNonStringName { Name = 1 }, "ClassWithNonStringName" };
yield return new object[] { null, new ClassWithNullToString(), "ClassWithNullToString" };

yield return new object[] { typeof(int), null, string.Empty };
yield return new object[] { typeof(int), "", "String" };
yield return new object[] { typeof(int), "value", "value" };
Expand Down Expand Up @@ -135,7 +127,7 @@ public void ArrayEditor_GetDisplayText_ValueDoesNotMatchCollectionType_ThrowsTar
[CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))]
public void ArrayEditor_GetEditStyle_Invoke_ReturnsModal(ITypeDescriptorContext context)
{
ArrayEditor editor = new(null);
ArrayEditor editor = new(typeof(string[]));
Assert.Equal(UITypeEditorEditStyle.Modal, editor.GetEditStyle(context));
}

Expand All @@ -151,7 +143,7 @@ public static IEnumerable<object[]> GetItems_TestData()
[MemberData(nameof(GetItems_TestData))]
public void ArrayEditor_GetItems_Invoke_ReturnsExpected(object editValue, object[] expected)
{
SubArrayEditor editor = new(null);
SubArrayEditor editor = new(typeof(string[]));
object[] items = editor.GetItems(editValue);
Assert.Equal(expected, items);
Assert.IsType(expected.GetType(), items);
Expand All @@ -162,7 +154,7 @@ public void ArrayEditor_GetItems_Invoke_ReturnsExpected(object editValue, object
[CommonMemberData(typeof(CommonTestHelperEx), nameof(CommonTestHelperEx.GetITypeDescriptorContextTestData))]
public void ArrayEditor_GetPaintValueSupported_Invoke_ReturnsFalse(ITypeDescriptorContext context)
{
ArrayEditor editor = new(null);
ArrayEditor editor = new(typeof(string[]));
Assert.False(editor.GetPaintValueSupported(context));
}

Expand Down Expand Up @@ -202,17 +194,6 @@ public void ArrayEditor_SetItems_InvokeNonArrayValue_ReturnsExpected(object edit
Assert.Same(expected, editor.SetItems(editValue, value));
}

[Theory]
[InlineData(typeof(object))]
[InlineData(null)]
public void ArrayEditor_SetItems_NullCollectionItemType_ThrowsArgumentNullException(Type type)
{
SubArrayEditor editor = new(type);
Assert.Null(editor.CollectionItemType);
Assert.Throws<ArgumentNullException>("elementType", () => editor.SetItems(null, Array.Empty<object>()));
Assert.Throws<ArgumentNullException>("elementType", () => editor.SetItems(Array.Empty<object>(), Array.Empty<object>()));
}

private class SubArrayEditor : ArrayEditor
{
public SubArrayEditor(Type type) : base(type)
Expand Down
Loading