Skip to content

Commit

Permalink
Add hollow types for deprecated UI controls (#10913)
Browse files Browse the repository at this point in the history
Fixes #3783

Add controls removed in NET3.1 Back to .NET10 for binary compatibility.

None of the re-added types can be constructed, all constructors throw new PlatformNotSupportedException(), default constructors are suppressed by introducing throwing public constructors if needed.
All attributes that have been present on the .NET Framework types, are preserved, as they are accessible by reflection.
All re-introduced types are decorated with [EditorBrowsable(EditorBrowsableState.Never)] attribute that hides them from the intellisense. Type names can be typed in by the developer manually and intellisense would show the same members as it did for .NET Framework projects.
All re-introduced types are decorated with the ObsoleteAttribute that results in a compile time warning. All types share a single deprecation warning Id, to simplify suppression, but have different explanation messages.
All re-introduced types are decorated with [Browsable(false)] attribute to not show custom control properties of these types in the property browser.
All public members are re-introduced with their metadata, except for the private attributes.
Members inherited from the base classes (Control, for example) are not re-introduced even if they had been overridden in the past because they are not required for binary compatibility, unless they are decorated with different attributes.
Members that are re-added to the existing types (Form and Control) are returning defaults or doing nothing.
Non-void public or protected instance members on the restored types throw null, not the PlatformNotSupportedException to save space.
Void public or protected instance members do nothing.
Public or protected fields return default values.
Nullability is disabled for all re-added classes, structs and delegates for compatibility with the .NET Framework.
  • Loading branch information
SimonZhao888 authored Jan 22, 2025
1 parent 2675a00 commit 1142ab5
Show file tree
Hide file tree
Showing 67 changed files with 5,955 additions and 48 deletions.
22 changes: 22 additions & 0 deletions Winforms.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms", "src\System.Windows.Forms\src\System.Windows.Forms.csproj", "{0D23A41B-2626-4703-9E4A-87C07F69B0B2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Tests", "src\System.Windows.Forms\tests\UnitTests\System.Windows.Forms.Tests.csproj", "{AB38E262-F206-4820-8F29-23C5F72A4A16}"
ProjectSection(ProjectDependencies) = postProject
{607E02DD-4256-4E73-B9A4-4CE2673B3703} = {607E02DD-4256-4E73-B9A4-4CE2673B3703}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Windows.Forms.Design.Tests", "src\System.Windows.Forms.Design\tests\UnitTests\System.Windows.Forms.Design.Tests.csproj", "{F977CA8C-FBF9-4D82-80BA-FE5B2F33486E}"
EndProject
Expand Down Expand Up @@ -179,6 +182,8 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "System.Windows.Forms.Analyz
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Private.Windows.Core.Tests", "src\System.Private.Windows.Core\tests\System.Private.Windows.Core.Tests\System.Private.Windows.Core.Tests.csproj", "{B653C860-9B52-4597-9921-24DA79A4E6B1}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnsupportedTypes", "src\System.Windows.Forms\tests\UnsupportedTypes\UnsupportedTypes.csproj", "{607E02DD-4256-4E73-B9A4-4CE2673B3703}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pipelines", "Pipelines", "{656C66A4-59CD-4E14-8AE4-1F5BCEECB553}"
ProjectSection(SolutionItems) = preProject
eng\pipelines\azure-pipelines-codeql.yml = eng\pipelines\azure-pipelines-codeql.yml
Expand Down Expand Up @@ -1086,6 +1091,22 @@ Global
{B653C860-9B52-4597-9921-24DA79A4E6B1}.Release|x64.Build.0 = Release|Any CPU
{B653C860-9B52-4597-9921-24DA79A4E6B1}.Release|x86.ActiveCfg = Release|Any CPU
{B653C860-9B52-4597-9921-24DA79A4E6B1}.Release|x86.Build.0 = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|Any CPU.Build.0 = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|arm64.ActiveCfg = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|arm64.Build.0 = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|x64.ActiveCfg = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|x64.Build.0 = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|x86.ActiveCfg = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Debug|x86.Build.0 = Debug|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|Any CPU.ActiveCfg = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|Any CPU.Build.0 = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|arm64.ActiveCfg = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|arm64.Build.0 = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|x64.ActiveCfg = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|x64.Build.0 = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|x86.ActiveCfg = Release|Any CPU
{607E02DD-4256-4E73-B9A4-4CE2673B3703}.Release|x86.Build.0 = Release|Any CPU
{442C867C-51C0-8CE5-F067-DF065008E3DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{442C867C-51C0-8CE5-F067-DF065008E3DA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{442C867C-51C0-8CE5-F067-DF065008E3DA}.Debug|arm64.ActiveCfg = Debug|Any CPU
Expand Down Expand Up @@ -1172,6 +1193,7 @@ Global
{656C66A4-59CD-4E14-8AE4-1F5BCEECB553} = {8B4B1E09-B3C7-4044-B223-94EDEC1CAA20}
{D4D97D78-D213-45DF-B003-9C4C9F2E5E1C} = {8B4B1E09-B3C7-4044-B223-94EDEC1CAA20}
{442C867C-51C0-8CE5-F067-DF065008E3DA} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7}
{607E02DD-4256-4E73-B9A4-4CE2673B3703} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7B1B0433-F612-4E5A-BE7E-FCF5B9F6E136}
Expand Down
7 changes: 6 additions & 1 deletion docs/list-of-diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ The acceptance criteria for adding an obsoletion includes:
| __`WFDEV005`__ | `Clipboard.GetData(string)` method is obsolete. Use `Clipboard.TryGetData<T>` methods instead. |
| __`WFDEV005`__ | `DataObject.GetData` methods are obsolete. Use the corresponding `DataObject.TryGetData<T>` instead. |
| __`WFDEV005`__ | `ClipboardProxy.GetData(As String)` method is obsolete. Use `ClipboardProxy.TryGetData(Of T)(As String, As T)` instead. |

| __`WFDEV006`__ | `ContextMenu` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `ContextMenuStrip` instead. |
| __`WFDEV006`__ | `DataGrid` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `DataGridView` instead. |
| __`WFDEV006`__ | `MainMenu` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `MenuStrip` instead. |
| __`WFDEV006`__ | `Menu` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `ToolStripDropDown` and `ToolStripDropDownMenu` instead. |
| __`WFDEV006`__ | `StatusBar` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `StatusStrip` instead. |
| __`WFDEV006`__ | `ToolBar` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `ToolStrip` instead. |

## Analyzer Warnings

Expand Down
14 changes: 11 additions & 3 deletions src/Common/src/Obsoletions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,18 @@ internal static class Obsoletions
internal const string FormOnClosingClosedMessage = "Form.OnClosing, Form.OnClosed and the corresponding events are obsolete. Use Form.OnFormClosing, Form.OnFormClosed, Form.FormClosing and Form.FormClosed instead.";
internal const string FormOnClosingClosedDiagnosticId = "WFDEV004";

internal const string DataObjectGetDataMessage = "`DataObject.GetData` methods are obsolete. Use the corresponding `DataObject.TryGetData<T>` instead.";
internal const string ClipboardProxyGetDataMessage = "`ClipboardProxy.GetData(As String)` method is obsolete. Use `ClipboardProxy.TryGetData(Of T)(As String, As T)` instead.";
internal const string ClipboardGetDataMessage = "`Clipboard.GetData(string)` method is obsolete. Use `Clipboard.TryGetData<T>` methods instead.";
internal const string ClipboardGetDataDiagnosticId = "WFDEV005";

internal const string DataObjectGetDataMessage = "`DataObject.GetData` methods are obsolete. Use the corresponding `DataObject.TryGetData<T>` instead.";

internal const string ClipboardProxyGetDataMessage = "`ClipboardProxy.GetData(As String)` method is obsolete. Use `ClipboardProxy.TryGetData(Of T)(As String, As T)` instead.";
#pragma warning disable WFDEV006 // Type or member is obsolete
internal const string ContextMenuMessage = $"`{nameof(ContextMenu)}` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `{nameof(ContextMenuStrip)}` instead.";
internal const string DataGridMessage = $"`{nameof(DataGrid)}` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `{nameof(DataGridView)}` instead.";
internal const string MainMenuMessage = $"`{nameof(MainMenu)}` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `{nameof(MenuStrip)}` instead.";
internal const string MenuMessage = $"`{nameof(Menu)}` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `{nameof(ToolStripDropDown)}` and `{nameof(ToolStripDropDownMenu)}` instead.";
internal const string StatusBarMessage = $"`{nameof(StatusBar)}` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `{nameof(StatusStrip)}` instead.";
internal const string ToolBarMessage = $"`{nameof(ToolBar)}` is provided for binary compatibility with .NET Framework and is not intended to be used directly from your code. Use `{nameof(ToolStrip)}` instead.";
#pragma warning restore WFDEV006
internal const string UnsupportedControlsDiagnosticId = "WFDEV006";
}
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ private static string GetObjectName(object value)

/// <summary>
/// On .NET Framework, this method implements the save part of <see cref="ISerializable"/> interface. On .NET,
/// this interface is implemented only for binary compatibility with the .NET Framework. Formatter deserialization
/// this interface is implemented only for binary compatibility with .NET Framework. Formatter deserialization
/// is disabled .NET by removing the <see cref="SerializableAttribute"/> from this class.
/// This method is used in unit tests only.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace System.Resources.Tools;
/// <remarks>
/// <para>
/// Typically, resources separate code from content within an application. Creating and consuming these resources
/// makes it easier to develop localizable applications. In the .NET Framework, resources are usually consumed by
/// makes it easier to develop localizable applications. In .NET Framework, resources are usually consumed by
/// using the <see cref="ResourceManager"/> class, which contains methods that provide access to culture-specific
/// resources at run time. For more information about creating and consuming resources, see
/// <seealso href="https://docs.microsoft.com/dotnet/core/extensions/resources">Resources in Desktop Apps</seealso>.
Expand Down
3 changes: 3 additions & 0 deletions src/System.Windows.Forms/src/GlobalSuppressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
[assembly: SuppressMessage("Naming", "CA1725:Parameter names should match base declaration", Justification = "Public API", Scope = "member", Target = "~M:System.Windows.Forms.ToolTip.CanExtend(System.Object)~System.Boolean")]
[assembly: SuppressMessage("Naming", "CA1725:Parameter names should match base declaration", Justification = "Public API", Scope = "member", Target = "~M:System.Windows.Forms.TreeNodeCollection.CopyTo(System.Array,System.Int32)")]
[assembly: SuppressMessage("Naming", "CA1725:Parameter names should match base declaration", Justification = "Public API", Scope = "member", Target = "~M:System.Windows.Forms.UpDownBase.OnMouseUp(System.Windows.Forms.MouseEventArgs)")]
[assembly: SuppressMessage("Naming", "CA1725:Parameter names should match base declaration", Justification = "Public API", Scope = "member", Target = "~M:System.Windows.Forms.Menu.MenuItemCollection.CopyTo(System.Array,System.Int32)")]
[assembly: SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "Public API", Scope = "member", Target = "~F:System.Windows.Forms.GridItemCollection.Empty")]
[assembly: SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "Public API", Scope = "member", Target = "~F:System.Windows.Forms.ToolStripRenderer.Offset2X")]
[assembly: SuppressMessage("Usage", "CA2211:Non-constant fields should not be visible", Justification = "Public API", Scope = "member", Target = "~F:System.Windows.Forms.ToolStripRenderer.Offset2Y")]
Expand Down Expand Up @@ -152,6 +153,8 @@
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Public API", Scope = "member", Target = "~F:System.Resources.ResXResourceWriter.Version")]
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Public API", Scope = "member", Target = "~F:System.Resources.ResXResourceWriter.ResourceSchema")]
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Public API", Scope = "member", Target = "~F:System.Windows.Forms.GridItemCollection.Empty")]
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Public API", Scope = "member", Target = "~F:System.Windows.Forms.DataGrid.HitTestInfo.Nowhere")]
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "Public API", Scope = "member", Target = "~F:System.Windows.Forms.DataGridTableStyle.DefaultTableStyle")]
[assembly: SuppressMessage("Performance", "CA1815:Override equals and operator equals on value types", Justification = "Public API", Scope = "type", Target = "~T:System.Windows.Forms.ImeModeConversion")]
[assembly: SuppressMessage("Performance", "CA1821:Remove empty Finalizers", Justification = "Public API", Scope = "member", Target = "~M:System.Windows.Forms.AxHost.ConnectionPointCookie.Finalize")]

Expand Down
Loading

0 comments on commit 1142ab5

Please sign in to comment.