From cc9a3d1114be6508f972899f23a6abc6f3ea1ffc Mon Sep 17 00:00:00 2001 From: gpetrou Date: Mon, 23 Dec 2024 13:34:50 +0200 Subject: [PATCH] Enable nullability in DesignerActionMethodItem --- .../src/PublicAPI.Shipped.txt | 18 ++-- .../Design/DesignerActionMethodItem.cs | 93 ++++++++++++++++--- .../Forms/Design/DesignerActionVerbItem.cs | 3 +- .../Design/DesignerActionMethodItemTests.cs | 9 +- 4 files changed, 91 insertions(+), 32 deletions(-) diff --git a/src/System.Windows.Forms.Design/src/PublicAPI.Shipped.txt b/src/System.Windows.Forms.Design/src/PublicAPI.Shipped.txt index 71a593e13d1..b015c91dfb0 100644 --- a/src/System.Windows.Forms.Design/src/PublicAPI.Shipped.txt +++ b/src/System.Windows.Forms.Design/src/PublicAPI.Shipped.txt @@ -28,14 +28,14 @@ ~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.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 -~System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList actionList, string memberName, string displayName, string category, bool includeAsDesignerVerb) -> void -~System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList actionList, string memberName, string displayName, string category, string description) -> void -~System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList actionList, string memberName, string displayName, string category, string description, bool includeAsDesignerVerb) -> void -~System.ComponentModel.Design.DesignerActionMethodItem.RelatedComponent.get -> System.ComponentModel.IComponent -~System.ComponentModel.Design.DesignerActionMethodItem.RelatedComponent.set -> 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 +System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList? actionList, string? memberName, string? displayName, string? category, bool includeAsDesignerVerb) -> void +System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList? actionList, string? memberName, string? displayName, string? category, string? description) -> void +System.ComponentModel.Design.DesignerActionMethodItem.DesignerActionMethodItem(System.ComponentModel.Design.DesignerActionList? actionList, string? memberName, string? displayName, string? category, string? description, bool includeAsDesignerVerb) -> void +System.ComponentModel.Design.DesignerActionMethodItem.RelatedComponent.get -> System.ComponentModel.IComponent? +System.ComponentModel.Design.DesignerActionMethodItem.RelatedComponent.set -> void ~System.Drawing.Design.IToolboxService.AddCreator(System.Drawing.Design.ToolboxItemCreatorCallback creator, string format) -> void ~System.Drawing.Design.IToolboxService.AddCreator(System.Drawing.Design.ToolboxItemCreatorCallback creator, string format, System.ComponentModel.Design.IDesignerHost host) -> void ~System.Drawing.Design.IToolboxService.AddLinkedToolboxItem(System.Drawing.Design.ToolboxItem toolboxItem, string category, System.ComponentModel.Design.IDesignerHost host) -> void @@ -83,7 +83,7 @@ ~System.Windows.Forms.Design.ParentControlDesigner.CreateTool(System.Drawing.Design.ToolboxItem tool, System.Drawing.Rectangle bounds) -> void ~System.Windows.Forms.Design.ParentControlDesigner.GetControl(object component) -> System.Windows.Forms.Control ~System.Windows.Forms.Design.ParentControlDesigner.MouseDragTool.get -> System.Drawing.Design.ToolboxItem -~virtual System.ComponentModel.Design.DesignerActionMethodItem.MemberName.get -> string +virtual System.ComponentModel.Design.DesignerActionMethodItem.MemberName.get -> string? ~virtual System.Windows.Forms.Design.ComponentTray.AddComponent(System.ComponentModel.IComponent component) -> void ~virtual System.Windows.Forms.Design.ComponentTray.CanCreateComponentFromTool(System.Drawing.Design.ToolboxItem tool) -> bool ~virtual System.Windows.Forms.Design.ComponentTray.CanDisplayComponent(System.ComponentModel.IComponent component) -> bool diff --git a/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/DesignerActionMethodItem.cs b/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/DesignerActionMethodItem.cs index 4270557c2b4..f0aeb0106bd 100644 --- a/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/DesignerActionMethodItem.cs +++ b/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/DesignerActionMethodItem.cs @@ -1,18 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System.Reflection; namespace System.ComponentModel.Design; public class DesignerActionMethodItem : DesignerActionItem { - private readonly DesignerActionList _actionList; - private MethodInfo _methodInfo; - - public DesignerActionMethodItem(DesignerActionList actionList, string memberName, string displayName, string category, string description, bool includeAsDesignerVerb) + private readonly DesignerActionList? _actionList; + private MethodInfo? _methodInfo; + + public DesignerActionMethodItem( + DesignerActionList? actionList, + string? memberName, + string? displayName, + string? category, + string? description, + bool includeAsDesignerVerb) : base(displayName, category, description) { _actionList = actionList; @@ -20,34 +24,95 @@ public DesignerActionMethodItem(DesignerActionList actionList, string memberName IncludeAsDesignerVerb = includeAsDesignerVerb; } - public DesignerActionMethodItem(DesignerActionList actionList, string memberName, string displayName) : this(actionList, memberName, displayName, null, null, false) + public DesignerActionMethodItem( + DesignerActionList? actionList, + string? memberName, + string? displayName) + : this( + actionList, + memberName, + displayName, + category: null, + description: null, + includeAsDesignerVerb: false) { } - public DesignerActionMethodItem(DesignerActionList actionList, string memberName, string displayName, bool includeAsDesignerVerb) : this(actionList, memberName, displayName, null, null, includeAsDesignerVerb) + public DesignerActionMethodItem( + DesignerActionList? actionList, + string? memberName, + string? displayName, + bool includeAsDesignerVerb) + : this( + actionList, + memberName, + displayName, + category: null, + description: null, + includeAsDesignerVerb) { } - public DesignerActionMethodItem(DesignerActionList actionList, string memberName, string displayName, string category) : this(actionList, memberName, displayName, category, null, false) + public DesignerActionMethodItem( + DesignerActionList? actionList, + string? memberName, + string? displayName, + string? category) + : this( + actionList, + memberName, + displayName, + category, + description: null, + includeAsDesignerVerb: false) { } - public DesignerActionMethodItem(DesignerActionList actionList, string memberName, string displayName, string category, bool includeAsDesignerVerb) : this(actionList, memberName, displayName, category, null, includeAsDesignerVerb) + public DesignerActionMethodItem( + DesignerActionList? actionList, + string? memberName, + string? displayName, + string? category, + bool includeAsDesignerVerb) + : this( + actionList, + memberName, + displayName, + category, + description: null, + includeAsDesignerVerb) { } - public DesignerActionMethodItem(DesignerActionList actionList, string memberName, string displayName, string category, string description) : this(actionList, memberName, displayName, category, description, false) + public DesignerActionMethodItem( + DesignerActionList? actionList, + string? memberName, + string? displayName, + string? category, + string? description) + : this( + actionList, + memberName, + displayName, + category, + description, + includeAsDesignerVerb: false) { } - public virtual string MemberName { get; } + public virtual string? MemberName { get; } - public IComponent RelatedComponent { get; set; } + public IComponent? RelatedComponent { get; set; } public virtual bool IncludeAsDesignerVerb { get; } public virtual void Invoke() { + if (MemberName is null) + { + throw new InvalidOperationException(); + } + _methodInfo ??= _actionList?.GetType()?.GetMethod(MemberName, BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (_methodInfo is null) @@ -61,7 +126,7 @@ public virtual void Invoke() // this is only use for verbs so that a designer action method item can // be converted to a verb. Verbs use an EventHandler to call their invoke // so we need a way to translate the EventHandler Invoke into ou own Invoke - internal void Invoke(object sender, EventArgs args) + internal void Invoke(object? sender, EventArgs args) { Invoke(); } diff --git a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerActionVerbItem.cs b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerActionVerbItem.cs index 95f8b6168cf..27b6d2a0f46 100644 --- a/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerActionVerbItem.cs +++ b/src/System.Windows.Forms.Design/src/System/Windows/Forms/Design/DesignerActionVerbItem.cs @@ -7,7 +7,8 @@ internal class DesignerActionVerbItem : DesignerActionMethodItem { private readonly DesignerVerb _targetVerb; - public DesignerActionVerbItem(DesignerVerb verb) : base(null, null, null) + public DesignerActionVerbItem(DesignerVerb verb) + : base(actionList: null, memberName: null, displayName: null) { Debug.Assert(verb is not null, "All callers check whether the verb is null."); _targetVerb = verb; diff --git a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs index 60c1a7afac2..8022d690733 100644 --- a/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs +++ b/src/System.Windows.Forms.Design/tests/UnitTests/System/ComponentModel/Design/DesignerActionMethodItemTests.cs @@ -209,6 +209,7 @@ public void Invoke_NullActionList_ThrowsInvalidOperationException() } [Theory] + [InlineData(null)] [InlineData("")] [InlineData("NoSuchMember")] [InlineData(nameof(SubDesignerActionList.StaticMethod))] @@ -219,14 +220,6 @@ public void Invoke_NoSuchMemberName_ThrowsInvalidOperationException(string membe Assert.Throws(item.Invoke); } - [Fact] - public void Invoke_NullMemberName_ThrowsArgumentNullException() - { - SubDesignerActionList list = new(); - DesignerActionMethodItem item = new(list, null, "displayName", "category", "description"); - Assert.Throws("name", item.Invoke); - } - [Fact] public void Invoke_MemberWithParameters_ThrowsTargetParameterCountException() {