Browse Source

Merge branch 'v2_develop' into v2_2489_scroll-scrollbar-new

BDisp 1 year ago
parent
commit
9ed6cf7034
100 changed files with 1972 additions and 3868 deletions
  1. 37 0
      .filenesting.json
  2. 1 1
      .github/workflows/api-docs.yml
  3. 2 2
      .github/workflows/codeql-analysis.yml
  4. 69 26
      .github/workflows/dotnet-core.yml
  5. 1 2
      .github/workflows/publish.yml
  6. 46 12
      .gitignore
  7. 33 0
      .vsconfig
  8. 0 23
      Analyzers/Directory.Build.props
  9. 0 21
      Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Program.cs
  10. 0 25
      Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Terminal.Gui.Analyzers.Internal.Debugging.csproj
  11. 0 48
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/EnumMemberValues.cs
  12. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum.cs
  13. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt.cs
  14. 0 50
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt_NoFastIsDefined.cs
  15. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt.cs
  16. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt_NoFastIsDefined.cs
  17. 0 49
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_NoFastIsDefined.cs
  18. 0 50
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum.cs
  19. 0 51
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitInt.cs
  20. 0 50
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitUInt.cs
  21. 0 46
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum.cs
  22. 0 48
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitInt.cs
  23. 0 46
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitUint.cs
  24. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum.cs
  25. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitInt.cs
  26. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitUInt.cs
  27. 0 329
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGeneratorTests.cs
  28. 0 111
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/IndentedTextWriterExtensionsTests.cs
  29. 0 47
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj
  30. 0 3
      Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj.DotSettings
  31. 0 20
      Analyzers/Terminal.Gui.Analyzers.Internal/AccessibilityExtensions.cs
  32. 0 8
      Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Shipped.md
  33. 0 4
      Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Unshipped.md
  34. 0 117
      Analyzers/Terminal.Gui.Analyzers.Internal/Analyzers/GenerateEnumExtensionMethodsAttributeAnalyzer.cs
  35. 0 3
      Analyzers/Terminal.Gui.Analyzers.Internal/ApiCompatExcludedAttributes.txt
  36. 0 27
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/AssemblyExtendedEnumTypeAttribute.cs
  37. 0 37
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/ExtensionsForEnumTypeAttribute.cs
  38. 0 110
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/GenerateEnumExtensionMethodsAttribute.cs
  39. 0 14
      Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/IExtensionsForEnumTypeAttribute.cs
  40. 0 11
      Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IEqualityOperators.cs
  41. 0 6
      Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IntrinsicAttribute.cs
  42. 0 43
      Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/NumericExtensions.cs
  43. 0 204
      Analyzers/Terminal.Gui.Analyzers.Internal/Constants/Strings.cs
  44. 0 235
      Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/CodeWriter.cs
  45. 0 443
      Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsGenerationInfo.cs
  46. 0 452
      Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGenerator.cs
  47. 0 38
      Analyzers/Terminal.Gui.Analyzers.Internal/IGeneratedTypeMetadata.cs
  48. 0 28
      Analyzers/Terminal.Gui.Analyzers.Internal/IStandardCSharpCodeGenerator.cs
  49. 0 71
      Analyzers/Terminal.Gui.Analyzers.Internal/IndentedTextWriterExtensions.cs
  50. 0 8
      Analyzers/Terminal.Gui.Analyzers.Internal/Properties/launchSettings.json
  51. 0 63
      Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj
  52. 0 4
      Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj.DotSettings
  53. 4 0
      CommunityToolkitExample/CommunityToolkitExample.csproj
  54. 1 1
      Directory.Build.props
  55. 3 0
      Example/Example.csproj
  56. 25 17
      GitVersion.yml
  57. 10 0
      NoSamples.slnf
  58. 4 1
      ReactiveExample/ReactiveExample.csproj
  59. 10 0
      Release.slnf
  60. 0 117
      Scripts/Terminal.Gui.PowerShell.Analyzers.psd1
  61. 0 96
      Scripts/Terminal.Gui.PowerShell.Analyzers.psm1
  62. 0 6
      Scripts/Terminal.Gui.PowerShell.Core.psm1
  63. 1 1
      Scripts/Terminal.Gui.PowerShell.psd1
  64. 65 4
      Terminal.Gui/Application/Application.cs
  65. 2 0
      Terminal.Gui/Configuration/ConfigurationManager.cs
  66. 3 0
      Terminal.Gui/Configuration/SettingsScope.cs
  67. 1 3
      Terminal.Gui/Drawing/Alignment.cs
  68. 1 2
      Terminal.Gui/Drawing/AlignmentModes.cs
  69. 5 4
      Terminal.Gui/Drawing/Cell.cs
  70. 21 0
      Terminal.Gui/Drawing/Color.cs
  71. 41 0
      Terminal.Gui/Drawing/FillPair.cs
  72. 23 3
      Terminal.Gui/Drawing/Glyphs.cs
  73. 255 0
      Terminal.Gui/Drawing/Gradient.cs
  74. 42 0
      Terminal.Gui/Drawing/GradientFill.cs
  75. 14 0
      Terminal.Gui/Drawing/IFill.cs
  76. 24 14
      Terminal.Gui/Drawing/LineCanvas.cs
  77. 24 0
      Terminal.Gui/Drawing/SolidFill.cs
  78. 43 38
      Terminal.Gui/Drawing/StraightLine.cs
  79. 71 95
      Terminal.Gui/Drawing/Thickness.cs
  80. 0 16
      Terminal.Gui/Drawing/ThicknessEventArgs.cs
  81. 51 0
      Terminal.Gui/EnumExtensions/AddOrSubtractExtensions.cs
  82. 53 0
      Terminal.Gui/EnumExtensions/AlignmentExtensions.cs
  83. 90 0
      Terminal.Gui/EnumExtensions/AlignmentModesExtensions.cs
  84. 89 0
      Terminal.Gui/EnumExtensions/BorderSettingsExtensions.cs
  85. 89 0
      Terminal.Gui/EnumExtensions/DimAutoStyleExtensions.cs
  86. 51 0
      Terminal.Gui/EnumExtensions/DimPercentModeExtensions.cs
  87. 51 0
      Terminal.Gui/EnumExtensions/DimensionExtensions.cs
  88. 93 0
      Terminal.Gui/EnumExtensions/KeyBindingScopeExtensions.cs
  89. 53 0
      Terminal.Gui/EnumExtensions/SideExtensions.cs
  90. 93 0
      Terminal.Gui/EnumExtensions/ViewDiagnosticFlagsExtensions.cs
  91. 2 2
      Terminal.Gui/Input/KeyBindingScope.cs
  92. 1 2
      Terminal.Gui/Input/ShortcutHelper.cs
  93. 1 1
      Terminal.Gui/Resources/Strings.pt-PT.resx
  94. 7 3
      Terminal.Gui/Resources/config.json
  95. 37 37
      Terminal.Gui/Terminal.Gui.csproj
  96. 0 26
      Terminal.Gui/Text/StringEventArgs.cs
  97. 13 13
      Terminal.Gui/View/Adornment/Adornment.cs
  98. 98 53
      Terminal.Gui/View/Adornment/Border.cs
  99. 26 0
      Terminal.Gui/View/Adornment/BorderSettings.cs
  100. 192 2
      Terminal.Gui/View/Adornment/Margin.cs

+ 37 - 0
.filenesting.json

@@ -0,0 +1,37 @@
+{
+  "help": "https://go.microsoft.com/fwlink/?linkid=866610",
+  "root": true,
+
+  "dependentFileProviders": {
+    "add": {
+      "addedExtension": {},
+      "pathSegment": {
+        "add": {
+          ".*": [
+            ".config",
+            ".cs",
+            ".json",
+            ".resx"
+          ]
+        }
+      },
+      "extensionToExtension": {
+        "add": {
+          ".designer.cs": [
+            ".resx"
+          ],
+          ".cs.d.ts": [
+            ".cs"
+          ]
+        }
+      },
+      "fileToFile": {
+        "add": {
+          "package-lock.json": [
+            "package.json"
+          ]
+        }
+      }
+    }
+  }
+}

+ 1 - 1
.github/workflows/api-docs.yml

@@ -2,7 +2,7 @@ name: Build and publish API docs
 
 on:
   push:
-    branches: [main, develop, v2_develop]
+    branches: [main, v2_develop]
 
 permissions:
   id-token: write 

+ 2 - 2
.github/workflows/codeql-analysis.yml

@@ -4,7 +4,7 @@ name: "Code scanning"
 
 on:
   push:
-    branches: [main]
+    branches: [main, v2_release]
     paths-ignore:
       - '**/*.md'
       - '**/*.txt'
@@ -12,7 +12,7 @@ on:
       - docs
       - docfx
   pull_request:
-    branches: [main]
+    branches: [main, v2_release]
     paths-ignore:
       - '**/*.md'
       - '**/*.txt'

+ 69 - 26
.github/workflows/dotnet-core.yml

@@ -2,19 +2,33 @@ name: Build & Test Terminal.Gui with .NET Core
 
 on:
   push:
-    branches: [ main, develop, v2_develop ]
+    branches: [ v2_release, v2_develop ]
+    paths-ignore:
+      - '**.md'
   pull_request:
-    branches: [ main, develop, v2_develop ]
-
+    branches: [ v2_release, v2_develop ]
+    paths-ignore:
+      - '**.md'
+      
 jobs:
   build_and_test:
 
-    runs-on: windows-latest
+    runs-on: ${{ matrix.os }}
+    strategy:
+      # Turn off fail-fast to let all runners run even if there are errors
+      fail-fast: true
+      matrix:
+        os: [ ubuntu-latest, windows-latest, macos-latest ]
 
+    timeout-minutes: 10
     steps:
-    - uses: actions/checkout@v4
-    
-    - name: Setup dotnet
+
+# Build
+
+    - name: Checkout code
+      uses: actions/checkout@v4
+
+    - name: Setup .NET Core
       uses: actions/setup-dotnet@v4
       with:
         dotnet-version: 8.x
@@ -27,26 +41,55 @@ jobs:
     - name: Build Debug
       run: dotnet build --configuration Debug --no-restore
 
+# Test
+    # Note: The --blame and VSTEST_DUMP_PATH stuff is needed to diagnose the test runner crashing on ubuntu/mac
+    # See https://github.com/microsoft/vstest/issues/2952 for why the --blame stuff below is needed.
+    # Without it, the test runner crashes on ubuntu (but not Windows or mac)
+
+    - name: MacOS - Patch test runner settings to stop on fail
+      if: runner.os == 'macOS'
+      run: |
+        brew install gnu-sed
+        gsed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
+
+    - name: Windows/Linux - Patch test runner settings to stop on fail
+      if: runner.os != 'macOS'
+      run: |
+          sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
+
+    - name: Set VSTEST_DUMP_PATH
+      shell: bash
+      run: echo "{VSTEST_DUMP_PATH}={logs/${{ runner.os }}/}" >> $GITHUB_ENV
+
     - name: Test
       run: |
-        sed -i 's/"stopOnFail": false/"stopOnFail": true/g' UnitTests/xunit.runner.json
-        dotnet test --no-restore --verbosity normal --collect:"XPlat Code Coverage"  --settings UnitTests/coverlet.runsettings --blame
-        mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
+       dotnet test --verbosity normal --collect:"XPlat Code Coverage" --settings UnitTests/coverlet.runsettings --diag:logs/${{ runner.os }}/logs.txt --blame --blame-crash --blame-hang --blame-hang-timeout 60s --blame-crash-collect-always 
+     
+       # mv -v UnitTests/TestResults/*/*.* UnitTests/TestResults/
 
-    # Note: this step is currently not writing to the gist for some reason
-    - name: Create Test Coverage Badge
-      uses: simon-k/[email protected]
-      id: create_coverage_badge
+    - name: Upload Test Logs
+      if: always()
+      uses: actions/upload-artifact@v4
       with:
-        label: Unit Test Coverage
-        color: brightgreen
-        path: UnitTests/TestResults/coverage.opencover.xml
-        gist-filename: code-coverage.json
-        # https://gist.github.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27
-        gist-id: 90ef67a684cb71db1817921a970f8d27
-        gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}   
-
-    - name: Print Code Coverage
-      run: |
-        echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%"
-        echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"
+        name: test-logs-${{ runner.os }}
+        path: |
+          logs/    
+          UnitTests/TestResults/
+  
+    # Note: this step is currently not writing to the gist for some reason
+    # - name: Create Test Coverage Badge
+    #   uses: simon-k/[email protected]
+    #   id: create_coverage_badge
+    #   with:
+    #     label: Unit Test Coverage
+    #     color: brightgreen
+    #     path: UnitTests/TestResults/coverage.opencover.xml
+    #     gist-filename: code-coverage.json
+    #     # https://gist.github.com/migueldeicaza/90ef67a684cb71db1817921a970f8d27
+    #     gist-id: 90ef67a684cb71db1817921a970f8d27
+    #     gist-auth-token: ${{ secrets.GIST_AUTH_TOKEN }}   
+
+    # - name: Print Code Coverage
+    #   run: |
+    #     echo "Code coverage percentage: ${{steps.create_coverage_badge.outputs.percentage}}%"
+    #     echo "Badge data: ${{steps.create_coverage_badge.outputs.badge}}"

+ 1 - 2
.github/workflows/publish.yml

@@ -25,7 +25,7 @@ jobs:
           includePrerelease: true
 
     - name: Determine Version
-      uses: gittools/actions/gitversion/execute@v0
+      uses: gittools/actions/gitversion/execute@v1
       with:
         useConfigFile: true
         #additionalArguments: /b develop
@@ -43,7 +43,6 @@ jobs:
     - name: Build Release
       run: |
         dotnet-gitversion /updateprojectfiles
-        dotnet build ./Analyzers/Terminal.Gui.Analyzers.Internal --no-incremental --nologo --force --configuration Release
         dotnet build --no-incremental --nologo --force --configuration Release
 
     - name: Pack

+ 46 - 12
.gitignore

@@ -1,29 +1,63 @@
-bin
-obj
-~$*
+# Build artifacts
+[Bb]in/
+[Oo]bj/
+[Rr]elease/
+[Dd]ebug/
+[Xx]64/
+[Aa][Rr][Mm]/
+[Aa][Rr][Mm]64/
+
+# User-local settings and caches
+*.rsuser
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
 *.userprefs
+_ReSharper.**
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+.devcontainer/
+.vscode/
+.vs/
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!?*.[Cc]ache/
+
+# Roslyn generated cs files
+**.g.cs
+
+# Common temporary files
+~$*
 *~
-packages
-.vs
 
-# User-specific files
-*.user
+# NuGet Stuff
+*.nupkg
+*.snupkg
+# Exclude everything in packages directory except the packages/build directory
+**/[Pp]ackages/*
+!**/[Pp]ackages/build/
 
 # API Docs
 docfx/api
 docfx/_site
 
-# Unit Tests
+# Test Results
 UnitTests/TestResults
 TestResults
 
-#git merge files
+# git merge files
 *.orig
-
-.vscode/
+*.theirs
+*.ours
 
 demo.*
 
 *.deb
 
-*.tui/
+*.tui/
+
+*.dotCover

+ 33 - 0
.vsconfig

@@ -0,0 +1,33 @@
+{
+  "version": "1.0",
+  "components": [
+    "Microsoft.VisualStudio.Component.DependencyValidation.Community",
+    "Microsoft.VisualStudio.Component.CoreEditor",
+    "Microsoft.VisualStudio.Workload.CoreEditor",
+    "Microsoft.Net.Component.4.8.SDK",
+    "Microsoft.Net.Component.4.7.2.TargetingPack",
+    "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
+    "Microsoft.VisualStudio.Component.Roslyn.Compiler",
+    "Microsoft.Component.MSBuild",
+    "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
+    "Microsoft.VisualStudio.Component.TextTemplating",
+    "Microsoft.VisualStudio.Component.NuGet",
+    "Microsoft.VisualStudio.Component.ManagedDesktop.Core",
+    "Microsoft.NetCore.Component.Runtime.8.0",
+    "Microsoft.NetCore.Component.SDK",
+    "Microsoft.VisualStudio.Component.FSharp",
+    "Microsoft.NetCore.Component.DevelopmentTools",
+    "Microsoft.VisualStudio.Component.AppInsights.Tools",
+    "Microsoft.VisualStudio.Component.Debugger.JustInTime",
+    "Microsoft.Net.Component.4.6.2.TargetingPack",
+    "Microsoft.Net.Component.4.8.1.TargetingPack",
+    "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites",
+    "Microsoft.VisualStudio.Component.NuGet.BuildTools",
+    "Microsoft.Net.Component.4.6.TargetingPack",
+    "Microsoft.VisualStudio.Component.VSSDK",
+    "Microsoft.VisualStudio.ComponentGroup.VisualStudioExtension.Prerequisites",
+    "Microsoft.Component.CodeAnalysis.SDK",
+    "Microsoft.VisualStudio.Workload.VisualStudioExtension"
+  ],
+  "extensions": []
+}

+ 0 - 23
Analyzers/Directory.Build.props

@@ -1,23 +0,0 @@
-<Project>
-  <PropertyGroup>
-    <Nullable>enable</Nullable>
-    <AnalysisLevel>latest-recommended</AnalysisLevel>
-    <WarningLevel>7</WarningLevel>
-    <CharacterSet>UTF-8</CharacterSet>
-    <Deterministic>true</Deterministic>
-    <UTF8OutPut>true</UTF8OutPut>
-    <DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
-    <NoLogo>True</NoLogo>
-    <DefineTrace>True</DefineTrace>
-  </PropertyGroup>
-  <ItemGroup>
-    <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
-    <PackageReference Include="JetBrains.ExternalAnnotations" Version="10.2.147" />
-  </ItemGroup>
-  <ItemGroup>
-      <Using Include="System.Buffers" />
-      <Using Include="System.Collections.Specialized" />
-      <Using Include="System.Numerics" />
-      <Using Include="System.Runtime.CompilerServices" />
-  </ItemGroup>
-</Project>

+ 0 - 21
Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Program.cs

@@ -1,21 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Debugging;
-
-class Program
-{
-    static void Main (string [] args)
-    {
-        
-    }
-}
-
-[GenerateEnumExtensionMethods]
-public enum TestEnum
-{
-    Zero = 0,
-    One,
-    Two = 2,
-    Three,
-    Six = 6
-}

+ 0 - 25
Analyzers/Terminal.Gui.Analyzers.Internal.Debugging/Terminal.Gui.Analyzers.Internal.Debugging.csproj

@@ -1,25 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-  </PropertyGroup>
-  <ItemGroup>
-    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.9.2" PrivateAssets="all" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj">
-      <PrivateAssets>all</PrivateAssets>
-      <OutputItemType>Analyzer</OutputItemType>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-
-</Project>

+ 0 - 48
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/EnumMemberValues.cs

@@ -1,48 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-internal class SignedEnumMemberValues
-{
-    internal const int Bit31 = ~0b_01111111_11111111_11111111_11111111;
-    internal const int Bit30 =  0b_01000000_00000000_00000000_00000000;
-    internal const int Bit29 =  0b_00100000_00000000_00000000_00000000;
-    internal const int Bit28 =  0b_00010000_00000000_00000000_00000000;
-    internal const int Bit27 =  0b_00001000_00000000_00000000_00000000;
-    internal const int Bit26 =  0b_00000100_00000000_00000000_00000000;
-    internal const int Bit25 =  0b_00000010_00000000_00000000_00000000;
-    internal const int Bit24 =  0b_00000001_00000000_00000000_00000000;
-    internal const int Bit23 =  0b_00000000_10000000_00000000_00000000;
-    internal const int Bit22 =  0b_00000000_01000000_00000000_00000000;
-    internal const int Bit21 =  0b_00000000_00100000_00000000_00000000;
-    internal const int Bit20 =  0b_00000000_00010000_00000000_00000000;
-    internal const int Bit19 =  0b_00000000_00001000_00000000_00000000;
-    internal const int Bit18 =  0b_00000000_00000100_00000000_00000000;
-    internal const int Bit17 =  0b_00000000_00000010_00000000_00000000;
-    internal const int Bit16 =  0b_00000000_00000001_00000000_00000000;
-    internal const int Bit15 =  0b_00000000_00000000_10000000_00000000;
-    internal const int Bit14 =  0b_00000000_00000000_01000000_00000000;
-    internal const int Bit13 =  0b_00000000_00000000_00100000_00000000;
-    internal const int Bit12 =  0b_00000000_00000000_00010000_00000000;
-    internal const int Bit11 =  0b_00000000_00000000_00001000_00000000;
-    internal const int Bit10 =  0b_00000000_00000000_00000100_00000000;
-    internal const int Bit09 =  0b_00000000_00000000_00000010_00000000;
-    internal const int Bit08 =  0b_00000000_00000000_00000001_00000000;
-    internal const int Bit07 =  0b_00000000_00000000_00000000_10000000;
-    internal const int Bit06 =  0b_00000000_00000000_00000000_01000000;
-    internal const int Bit05 =  0b_00000000_00000000_00000000_00100000;
-    internal const int Bit04 =  0b_00000000_00000000_00000000_00010000;
-    internal const int Bit03 =  0b_00000000_00000000_00000000_00001000;
-    internal const int Bit02 =  0b_00000000_00000000_00000000_00000100;
-    internal const int Bit01 =  0b_00000000_00000000_00000000_00000010;
-    internal const int Bit00 =  0b_00000000_00000000_00000000_00000001;
-    internal const int All_0 =  0;
-    internal const int All_1 =  ~All_0;
-    internal const int Alternating_01 = 0b_01010101_01010101_01010101_01010101;
-    internal const int Alternating_10 = ~Alternating_01;
-    internal const int EvenBytesHigh = 0b_00000000_11111111_00000000_11111111;
-    internal const int OddBytesHigh = ~EvenBytesHigh;
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BasicEnum"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[GenerateEnumExtensionMethods]
-public enum BetterEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BasicEnum_ExplicitInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[GenerateEnumExtensionMethods]
-public enum BetterEnum_ExplicitInt
-{
-    Bit31 = BasicEnum_ExplicitInt.Bit31,
-    Bit30 = BasicEnum_ExplicitInt.Bit30,
-    Bit29 = BasicEnum_ExplicitInt.Bit29,
-    Bit28 = BasicEnum_ExplicitInt.Bit28,
-    Bit27 = BasicEnum_ExplicitInt.Bit27,
-    Bit26 = BasicEnum_ExplicitInt.Bit26,
-    Bit25 = BasicEnum_ExplicitInt.Bit25,
-    Bit24 = BasicEnum_ExplicitInt.Bit24,
-    Bit23 = BasicEnum_ExplicitInt.Bit23,
-    Bit22 = BasicEnum_ExplicitInt.Bit22,
-    Bit21 = BasicEnum_ExplicitInt.Bit21,
-    Bit20 = BasicEnum_ExplicitInt.Bit20,
-    Bit19 = BasicEnum_ExplicitInt.Bit19,
-    Bit18 = BasicEnum_ExplicitInt.Bit18,
-    Bit17 = BasicEnum_ExplicitInt.Bit17,
-    Bit16 = BasicEnum_ExplicitInt.Bit16,
-    Bit15 = BasicEnum_ExplicitInt.Bit15,
-    Bit14 = BasicEnum_ExplicitInt.Bit14,
-    Bit13 = BasicEnum_ExplicitInt.Bit13,
-    Bit12 = BasicEnum_ExplicitInt.Bit12,
-    Bit11 = BasicEnum_ExplicitInt.Bit11,
-    Bit10 = BasicEnum_ExplicitInt.Bit10,
-    Bit09 = BasicEnum_ExplicitInt.Bit09,
-    Bit08 = BasicEnum_ExplicitInt.Bit08,
-    Bit07 = BasicEnum_ExplicitInt.Bit07,
-    Bit06 = BasicEnum_ExplicitInt.Bit06,
-    Bit05 = BasicEnum_ExplicitInt.Bit05,
-    Bit04 = BasicEnum_ExplicitInt.Bit04,
-    Bit03 = BasicEnum_ExplicitInt.Bit03,
-    Bit02 = BasicEnum_ExplicitInt.Bit02,
-    Bit01 = BasicEnum_ExplicitInt.Bit01,
-    Bit00 = BasicEnum_ExplicitInt.Bit00,
-    All_0 = BasicEnum_ExplicitInt.All_0,
-    All_1 = BasicEnum_ExplicitInt.All_1,
-    Alternating_01 = BasicEnum_ExplicitInt.Alternating_01,
-    Alternating_10 = BasicEnum_ExplicitInt.Alternating_10,
-    EvenBytesHigh = BasicEnum_ExplicitInt.EvenBytesHigh,
-    OddBytesHigh = BasicEnum_ExplicitInt.OddBytesHigh
-}

+ 0 - 50
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitInt_NoFastIsDefined.cs

@@ -1,50 +0,0 @@
-// ReSharper disable EnumUnderlyingTypeIsInt
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BetterEnum_ExplicitInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute.FastIsDefined"/> = <see langword="false" />.
-/// </summary>
-[GenerateEnumExtensionMethods (FastIsDefined = false)]
-public enum BetterEnum_ExplicitInt_NoFastIsDefined : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 = 0b_01000000_00000000_00000000_00000000,
-    Bit29 = 0b_00100000_00000000_00000000_00000000,
-    Bit28 = 0b_00010000_00000000_00000000_00000000,
-    Bit27 = 0b_00001000_00000000_00000000_00000000,
-    Bit26 = 0b_00000100_00000000_00000000_00000000,
-    Bit25 = 0b_00000010_00000000_00000000_00000000,
-    Bit24 = 0b_00000001_00000000_00000000_00000000,
-    Bit23 = 0b_00000000_10000000_00000000_00000000,
-    Bit22 = 0b_00000000_01000000_00000000_00000000,
-    Bit21 = 0b_00000000_00100000_00000000_00000000,
-    Bit20 = 0b_00000000_00010000_00000000_00000000,
-    Bit19 = 0b_00000000_00001000_00000000_00000000,
-    Bit18 = 0b_00000000_00000100_00000000_00000000,
-    Bit17 = 0b_00000000_00000010_00000000_00000000,
-    Bit16 = 0b_00000000_00000001_00000000_00000000,
-    Bit15 = 0b_00000000_00000000_10000000_00000000,
-    Bit14 = 0b_00000000_00000000_01000000_00000000,
-    Bit13 = 0b_00000000_00000000_00100000_00000000,
-    Bit12 = 0b_00000000_00000000_00010000_00000000,
-    Bit11 = 0b_00000000_00000000_00001000_00000000,
-    Bit10 = 0b_00000000_00000000_00000100_00000000,
-    Bit09 = 0b_00000000_00000000_00000010_00000000,
-    Bit08 = 0b_00000000_00000000_00000001_00000000,
-    Bit07 = 0b_00000000_00000000_00000000_10000000,
-    Bit06 = 0b_00000000_00000000_00000000_01000000,
-    Bit05 = 0b_00000000_00000000_00000000_00100000,
-    Bit04 = 0b_00000000_00000000_00000000_00010000,
-    Bit03 = 0b_00000000_00000000_00000000_00001000,
-    Bit02 = 0b_00000000_00000000_00000000_00000100,
-    Bit01 = 0b_00000000_00000000_00000000_00000010,
-    Bit00 = 0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BasicEnum_ExplicitUInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[GenerateEnumExtensionMethods]
-public enum BetterEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_ExplicitUInt_NoFastIsDefined.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BetterEnum_ExplicitUInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute.FastIsDefined"/> = <see langword="false" />.
-/// </summary>
-[GenerateEnumExtensionMethods (FastIsDefined = false)]
-public enum BetterEnum_ExplicitUInt_NoFastIsDefined : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 49
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterEnum_NoFastIsDefined.cs

@@ -1,49 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="BetterEnum"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute.FastIsDefined"/> = <see langword="false" />.
-/// </summary>
-[GenerateEnumExtensionMethods (FastIsDefined = false)]
-public enum BetterEnum_NoFastIsDefined
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 50
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum.cs

@@ -1,50 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="FlagsEnum"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[Flags]
-[GenerateEnumExtensionMethods]
-public enum BetterFlagsEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 51
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitInt.cs

@@ -1,51 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-/// <summary>
-///     Same as <see cref="FlagsEnum_ExplicitInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[Flags]
-[GenerateEnumExtensionMethods]
-public enum BetterFlagsEnum_ExplicitInt : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 50
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithGenerator/BetterFlagsEnum_ExplicitUInt.cs

@@ -1,50 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Same as <see cref="FlagsEnum_ExplicitUInt"/>, but with <see cref="GenerateEnumExtensionMethodsAttribute"/> applied.
-/// </summary>
-[Flags]
-[GenerateEnumExtensionMethods]
-public enum BetterFlagsEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0  =  0,
-    All_1  = ~All_0,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = ~Alternating_01,
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-    OddBytesHigh = ~EvenBytesHigh,
-}

+ 0 - 46
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum.cs

@@ -1,46 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Basic enum without explicitly-defined backing type and no attributes on the enum or any of its members.
-/// </summary>
-public enum BasicEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = unchecked((int)0b_10101010_10101010_10101010_10101010),
-    OddBytesHigh = unchecked((int)0b_11111111_00000000_11111111_00000000),
-    EvenBytesHigh = 0b_00000000_11111111_00000000_11111111,
-}

+ 0 - 48
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitInt.cs

@@ -1,48 +0,0 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Basic enum with explicitly-defined backing type of int and no attributes on the enum or any of its members.
-/// </summary>
-public enum BasicEnum_ExplicitInt : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 =  0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 =  0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 =  0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101,
-    Alternating_10 = unchecked((int)0b_10101010_10101010_10101010_10101010),
-    OddBytesHigh = unchecked((int)0b_11111111_00000000_11111111_00000000),
-    EvenBytesHigh = unchecked((int)0b_00000000_11111111_00000000_11111111),
-}

+ 0 - 46
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/BasicEnum_ExplicitUint.cs

@@ -1,46 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Basic enum with explicitly-defined backing type of uint and no attributes on the enum or any of its members.
-/// </summary>
-public enum BasicEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0 = 0b_00000000_00000000_00000000_00000000u,
-    All_1 = 0b_11111111_11111111_11111111_11111111u,
-    Alternating_01 = 0b_01010101_01010101_01010101_01010101u,
-    Alternating_10 = 0b_10101010_10101010_10101010_10101010u,
-    OddBytesHigh   = 0b_11111111_00000000_11111111_00000000u,
-    EvenBytesHigh  = 0b_00000000_11111111_00000000_11111111u,
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum.cs

@@ -1,43 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Flags enum without explicitly-defined backing type and only a <see cref="FlagsAttribute"/> on the enum declaration No other attributes on the enum or its members..
-/// </summary>
-[Flags]
-public enum FlagsEnum
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitInt.cs

@@ -1,43 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Flags enum with explicitly-defined backing type of int and only a <see cref="FlagsAttribute"/> on the enum declaration No other attributes on the enum or its members..
-/// </summary>
-[Flags]
-public enum FlagsEnum_ExplicitInt : int
-{
-    Bit31 = -0b_10000000_00000000_00000000_00000000,
-    Bit30 =  0b_01000000_00000000_00000000_00000000,
-    Bit29 =  0b_00100000_00000000_00000000_00000000,
-    Bit28 =  0b_00010000_00000000_00000000_00000000,
-    Bit27 =  0b_00001000_00000000_00000000_00000000,
-    Bit26 =  0b_00000100_00000000_00000000_00000000,
-    Bit25 =  0b_00000010_00000000_00000000_00000000,
-    Bit24 =  0b_00000001_00000000_00000000_00000000,
-    Bit23 = -0b_00000000_10000000_00000000_00000000,
-    Bit22 =  0b_00000000_01000000_00000000_00000000,
-    Bit21 =  0b_00000000_00100000_00000000_00000000,
-    Bit20 =  0b_00000000_00010000_00000000_00000000,
-    Bit19 =  0b_00000000_00001000_00000000_00000000,
-    Bit18 =  0b_00000000_00000100_00000000_00000000,
-    Bit17 =  0b_00000000_00000010_00000000_00000000,
-    Bit16 =  0b_00000000_00000001_00000000_00000000,
-    Bit15 = -0b_00000000_00000000_10000000_00000000,
-    Bit14 =  0b_00000000_00000000_01000000_00000000,
-    Bit13 =  0b_00000000_00000000_00100000_00000000,
-    Bit12 =  0b_00000000_00000000_00010000_00000000,
-    Bit11 =  0b_00000000_00000000_00001000_00000000,
-    Bit10 =  0b_00000000_00000000_00000100_00000000,
-    Bit09 =  0b_00000000_00000000_00000010_00000000,
-    Bit08 =  0b_00000000_00000000_00000001_00000000,
-    Bit07 = -0b_00000000_00000000_00000000_10000000,
-    Bit06 =  0b_00000000_00000000_00000000_01000000,
-    Bit05 =  0b_00000000_00000000_00000000_00100000,
-    Bit04 =  0b_00000000_00000000_00000000_00010000,
-    Bit03 =  0b_00000000_00000000_00000000_00001000,
-    Bit02 =  0b_00000000_00000000_00000000_00000100,
-    Bit01 =  0b_00000000_00000000_00000000_00000010,
-    Bit00 =  0b_00000000_00000000_00000000_00000001,
-    All_0  =  0,
-    All_1  = -1
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumDefinitions/WithoutGenerator/FlagsEnum_ExplicitUInt.cs

@@ -1,43 +0,0 @@
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions.EnumDefinitions;
-
-/// <summary>
-///     Flags enum with explicitly-defined backing type of uint and only a <see cref="FlagsAttribute"/> on the enum declaration No other attributes on the enum or its members..
-/// </summary>
-[Flags]
-public enum FlagsEnum_ExplicitUInt : uint
-{
-    Bit31 = 0b_10000000_00000000_00000000_00000000u,
-    Bit30 = 0b_01000000_00000000_00000000_00000000u,
-    Bit29 = 0b_00100000_00000000_00000000_00000000u,
-    Bit28 = 0b_00010000_00000000_00000000_00000000u,
-    Bit27 = 0b_00001000_00000000_00000000_00000000u,
-    Bit26 = 0b_00000100_00000000_00000000_00000000u,
-    Bit25 = 0b_00000010_00000000_00000000_00000000u,
-    Bit24 = 0b_00000001_00000000_00000000_00000000u,
-    Bit23 = 0b_00000000_10000000_00000000_00000000u,
-    Bit22 = 0b_00000000_01000000_00000000_00000000u,
-    Bit21 = 0b_00000000_00100000_00000000_00000000u,
-    Bit20 = 0b_00000000_00010000_00000000_00000000u,
-    Bit19 = 0b_00000000_00001000_00000000_00000000u,
-    Bit18 = 0b_00000000_00000100_00000000_00000000u,
-    Bit17 = 0b_00000000_00000010_00000000_00000000u,
-    Bit16 = 0b_00000000_00000001_00000000_00000000u,
-    Bit15 = 0b_00000000_00000000_10000000_00000000u,
-    Bit14 = 0b_00000000_00000000_01000000_00000000u,
-    Bit13 = 0b_00000000_00000000_00100000_00000000u,
-    Bit12 = 0b_00000000_00000000_00010000_00000000u,
-    Bit11 = 0b_00000000_00000000_00001000_00000000u,
-    Bit10 = 0b_00000000_00000000_00000100_00000000u,
-    Bit09 = 0b_00000000_00000000_00000010_00000000u,
-    Bit08 = 0b_00000000_00000000_00000001_00000000u,
-    Bit07 = 0b_00000000_00000000_00000000_10000000u,
-    Bit06 = 0b_00000000_00000000_00000000_01000000u,
-    Bit05 = 0b_00000000_00000000_00000000_00100000u,
-    Bit04 = 0b_00000000_00000000_00000000_00010000u,
-    Bit03 = 0b_00000000_00000000_00000000_00001000u,
-    Bit02 = 0b_00000000_00000000_00000000_00000100u,
-    Bit01 = 0b_00000000_00000000_00000000_00000010u,
-    Bit00 = 0b_00000000_00000000_00000000_00000001u,
-    All_0 = 0b_00000000_00000000_00000000_00000000u,
-    All_1 = 0b_11111111_11111111_11111111_11111111u
-}

+ 0 - 329
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGeneratorTests.cs

@@ -1,329 +0,0 @@
-using System.Collections.Concurrent;
-using System.Collections.ObjectModel;
-using System.Collections.Specialized;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using NUnit.Framework.Interfaces;
-using NUnit.Framework.Internal;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests.Generators.EnumExtensions;
-
-[TestFixture]
-[Category ("Source Generators")]
-[TestOf (typeof (EnumExtensionMethodsIncrementalGenerator))]
-[Parallelizable (ParallelScope.Children)]
-public class EnumExtensionMethodsIncrementalGeneratorTests
-{
-    private static bool _isInitialized;
-
-    /// <summary>All enum types declared in the test assembly.</summary>
-    private static readonly ObservableCollection<Type> AllEnumTypes = [];
-
-    /// <summary>
-    ///     All enum types without a <see cref="GenerateEnumExtensionMethodsAttribute"/>, <see cref="AllEnumTypes"/>
-    /// </summary>
-    private static readonly HashSet<Type> BoringEnumTypes = [];
-
-    /// <summary>All extension classes generated for enums with our attribute.</summary>
-    private static readonly ObservableCollection<Type> EnumExtensionClasses = [];
-
-    private static readonly ConcurrentDictionary<Type, EnumData> ExtendedEnumTypeMappings = [];
-    private static IEnumerable<Type> ExtendedEnumTypes => ExtendedEnumTypeMappings.Keys;
-
-    private static readonly ReaderWriterLockSlim InitializationLock = new ();
-
-    private static IEnumerable<AssemblyExtendedEnumTypeAttribute> GetAssemblyExtendedEnumTypeAttributes () =>
-        Assembly.GetExecutingAssembly ()
-                .GetCustomAttributes<AssemblyExtendedEnumTypeAttribute> ();
-
-    private static IEnumerable<TestCaseData> Get_AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute_Cases ()
-    {
-        return GetAssemblyExtendedEnumTypeAttributes ()
-            .Select (
-                     static attr => new TestCaseData (attr)
-                     {
-                         TestName = $"{nameof (AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute)}({attr.EnumType.Name},{attr.ExtensionClass.Name})",
-                         HasExpectedResult = true,
-                         ExpectedResult = true
-                     });
-    }
-
-    [Test]
-    [Category ("Attributes")]
-    [TestCaseSource (nameof (Get_AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute_Cases))]
-    public bool AssemblyExtendedEnumTypeAttribute_EnumHasGeneratorAttribute (AssemblyExtendedEnumTypeAttribute attr)
-    {
-        Assume.That (attr, Is.Not.Null);
-        Assume.That (attr.EnumType, Is.Not.Null);
-        Assume.That (attr.EnumType!.IsEnum);
-
-        return attr.EnumType.IsDefined (typeof (GenerateEnumExtensionMethodsAttribute));
-    }
-
-    private const string AssemblyExtendedEnumTypeAttributeEnumPropertyName =
-        $"{nameof (AssemblyExtendedEnumTypeAttribute)}.{nameof (AssemblyExtendedEnumTypeAttribute.EnumType)}";
-
-    [Test]
-    [Category("Attributes")]
-    public void AssemblyExtendedEnumTypeAttribute_ExtensionClassHasExpectedReverseMappingAttribute ([ValueSource(nameof(GetAssemblyExtendedEnumTypeAttributes))]AssemblyExtendedEnumTypeAttribute attr)
-    {
-        Assume.That (attr, Is.Not.Null);
-        Assume.That (attr.ExtensionClass, Is.Not.Null);
-        Assume.That (attr.ExtensionClass!.IsClass);
-        Assume.That (attr.ExtensionClass!.IsSealed);
-
-        Assert.That (attr.ExtensionClass.IsDefined (typeof (ExtensionsForEnumTypeAttribute<>)));
-    }
-
-    [Test]
-    [Category("Attributes")]
-    public void ExtendedEnum_AssemblyHasMatchingAttribute ([ValueSource(nameof(GetExtendedEnum_EnumData))]EnumData enumData)
-    {
-        Assume.That (enumData, Is.Not.Null);
-        Assume.That (enumData.EnumType, Is.Not.Null);
-        Assume.That (enumData.EnumType!.IsEnum);
-
-        Assert.That (enumData.EnumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-    }
-
-    [Test]
-    public void BoringEnum_DoesNotHaveExtensions ([ValueSource (nameof (BoringEnumTypes))] Type enumType)
-    {
-        Assume.That (enumType.IsEnum);
-
-        Assert.That (enumType, Has.No.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-    }
-
-    [Test]
-    public void ExtendedEnum_FastIsDefinedFalse_DoesNotHaveFastIsDefined ([ValueSource (nameof (GetExtendedEnumTypes_FastIsDefinedFalse))] EnumData enumData)
-    {
-        Assume.That (enumData.EnumType.IsEnum);
-        Assume.That (enumData.EnumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-        Assume.That (enumData.GeneratorAttribute, Is.Not.Null);
-        Assume.That (enumData.GeneratorAttribute, Is.EqualTo (enumData.EnumType.GetCustomAttribute<GenerateEnumExtensionMethodsAttribute> ()));
-        Assume.That (enumData.GeneratorAttribute, Has.Property ("FastIsDefined").False);
-        Assume.That (enumData.ExtensionClass, Is.Not.Null);
-
-        Assert.That (enumData.ExtensionClass!.GetMethod ("FastIsDefined"), Is.Null);
-    }
-
-    [Test]
-    public void ExtendedEnum_StaticExtensionClassExists ([ValueSource (nameof (ExtendedEnumTypes))] Type enumType)
-    {
-        Assume.That (enumType.IsEnum);
-        Assume.That (enumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-        ITypeInfo enumTypeInfo = new TypeWrapper (enumType);
-        Assume.That (enumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-    }
-
-    [Test]
-    public void ExtendedEnum_FastIsDefinedTrue_HasFastIsDefined ([ValueSource (nameof (GetExtendedEnumTypes_FastIsDefinedTrue))] EnumData enumData)
-    {
-        Assume.That (enumData.EnumType, Is.Not.Null);
-        Assume.That (enumData.EnumType.IsEnum);
-        Assume.That (enumData.EnumType, Has.Attribute<GenerateEnumExtensionMethodsAttribute> ());
-        Assume.That (enumData.ExtensionClass, Is.Not.Null);
-        ITypeInfo extensionClassTypeInfo = new TypeWrapper (enumData.ExtensionClass!);
-        Assume.That (extensionClassTypeInfo.IsStaticClass);
-        Assume.That (enumData.GeneratorAttribute, Is.Not.Null);
-        Assume.That (enumData.GeneratorAttribute, Is.EqualTo (enumData.EnumType.GetCustomAttribute<GenerateEnumExtensionMethodsAttribute> ()));
-        Assume.That (enumData.GeneratorAttribute, Has.Property ("FastIsDefined").True);
-
-        MethodInfo? fastIsDefinedMethod = enumData.ExtensionClass!.GetMethod ("FastIsDefined");
-
-        Assert.That (fastIsDefinedMethod, Is.Not.Null);
-        Assert.That (fastIsDefinedMethod, Has.Attribute<ExtensionAttribute> ());
-        IMethodInfo[] extensionMethods = extensionClassTypeInfo.GetMethodsWithAttribute<ExtensionAttribute> (false);
-
-
-    }
-
-    private static IEnumerable<EnumData> GetExtendedEnum_EnumData ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return ExtendedEnumTypeMappings.Values;
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static IEnumerable<Type> GetBoringEnumTypes ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return BoringEnumTypes;
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static IEnumerable<EnumData> GetExtendedEnumTypes_FastIsDefinedFalse ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return ExtendedEnumTypeMappings.Values.Where (static t => t.GeneratorAttribute?.FastIsDefined is false);
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static IEnumerable<EnumData> GetExtendedEnumTypes_FastIsDefinedTrue ()
-    {
-        InitializationLock.EnterUpgradeableReadLock ();
-
-        try
-        {
-            if (!_isInitialized)
-            {
-                Initialize ();
-            }
-
-            return ExtendedEnumTypeMappings.Values.Where (static t => t.GeneratorAttribute?.FastIsDefined is true);
-        }
-        finally
-        {
-            InitializationLock.ExitUpgradeableReadLock ();
-        }
-    }
-
-    private static void Initialize ()
-    {
-        if (!InitializationLock.IsUpgradeableReadLockHeld || !InitializationLock.TryEnterWriteLock (5000))
-        {
-            return;
-        }
-
-        try
-        {
-            if (_isInitialized)
-            {
-                return;
-            }
-
-            AllEnumTypes.CollectionChanged += AllEnumTypes_CollectionChanged;
-            EnumExtensionClasses.CollectionChanged += EnumExtensionClasses_OnCollectionChanged;
-
-            Type [] allAssemblyTypes = Assembly
-                                       .GetExecutingAssembly ()
-                                       .GetTypes ();
-
-            IEnumerable<Type> allEnumTypes = allAssemblyTypes.Where (IsDefinedEnum);
-
-            foreach (Type type in allEnumTypes)
-            {
-                AllEnumTypes.Add (type);
-            }
-
-            foreach (Type type in allAssemblyTypes.Where (static t => t.IsClass && t.IsDefined (typeof (ExtensionsForEnumTypeAttribute<>))))
-            {
-                EnumExtensionClasses.Add (type);
-            }
-
-            _isInitialized = true;
-        }
-        finally
-        {
-            InitializationLock.ExitWriteLock ();
-        }
-
-        return;
-
-        static bool IsDefinedEnum (Type t) { return t is { IsEnum: true, IsGenericType: false, IsConstructedGenericType: false, IsTypeDefinition: true }; }
-
-        static void AllEnumTypes_CollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
-        {
-            if (e.Action is not NotifyCollectionChangedAction.Add and not NotifyCollectionChangedAction.Replace || e.NewItems is null)
-            {
-                return;
-            }
-
-            foreach (Type enumType in e.NewItems.OfType<Type> ())
-            {
-                if (enumType.GetCustomAttribute<GenerateEnumExtensionMethodsAttribute> () is not { } generatorAttribute)
-                {
-                    BoringEnumTypes.Add (enumType);
-
-                    continue;
-                }
-
-                ExtendedEnumTypeMappings.AddOrUpdate (
-                                               enumType,
-                                               CreateNewEnumData,
-                                               UpdateGeneratorAttributeProperty,
-                                               generatorAttribute);
-            }
-        }
-
-        static EnumData CreateNewEnumData (Type tEnum, GenerateEnumExtensionMethodsAttribute attr) { return new (tEnum, attr); }
-
-        static EnumData UpdateGeneratorAttributeProperty (Type tEnum, EnumData data, GenerateEnumExtensionMethodsAttribute attr)
-        {
-            data.GeneratorAttribute ??= attr;
-
-            return data;
-        }
-
-        static void EnumExtensionClasses_OnCollectionChanged (object? sender, NotifyCollectionChangedEventArgs e)
-        {
-            if (e.Action != NotifyCollectionChangedAction.Add)
-            {
-                return;
-            }
-
-            foreach (Type extensionClassType in e.NewItems!.OfType<Type> ())
-            {
-                if (extensionClassType.GetCustomAttribute (typeof (ExtensionsForEnumTypeAttribute<>), false) is not IExtensionsForEnumTypeAttributes
-                        {
-                            EnumType.IsEnum: true
-                        } extensionForAttribute)
-                {
-                    continue;
-                }
-
-                ExtendedEnumTypeMappings [extensionForAttribute.EnumType].ExtensionClass ??= extensionClassType;
-            }
-        }
-    }
-
-    public sealed record EnumData (
-        Type EnumType,
-        GenerateEnumExtensionMethodsAttribute? GeneratorAttribute = null,
-        Type? ExtensionClass = null,
-        IExtensionsForEnumTypeAttributes? ExtensionForEnumTypeAttribute = null)
-    {
-        public Type? ExtensionClass { get; set; } = ExtensionClass;
-
-        public IExtensionsForEnumTypeAttributes? ExtensionForEnumTypeAttribute { get; set; } = ExtensionForEnumTypeAttribute;
-        public GenerateEnumExtensionMethodsAttribute? GeneratorAttribute { get; set; } = GeneratorAttribute;
-    }
-}

+ 0 - 111
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/IndentedTextWriterExtensionsTests.cs

@@ -1,111 +0,0 @@
-using System.CodeDom.Compiler;
-using System.Text;
-
-namespace Terminal.Gui.Analyzers.Internal.Tests;
-
-[TestFixture]
-[Category ("Extension Methods")]
-[TestOf (typeof (IndentedTextWriterExtensions))]
-[Parallelizable (ParallelScope.Children)]
-public class IndentedTextWriterExtensionsTests
-{
-    [Test]
-    public void Pop_Decrements ()
-    {
-        StringBuilder sb = new (0);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw);
-        writer.Indent = 5;
-
-        Assume.That (writer.Indent, Is.EqualTo (5));
-
-        writer.Pop ();
-        Assert.That (writer.Indent, Is.EqualTo (4));
-    }
-
-    [Test]
-    public void Pop_WithClosing_WritesAndPops ([Values ("}", ")", "]")] string scopeClosing)
-    {
-        StringBuilder sb = new (256);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw, "  ");
-        writer.Indent = 5;
-        writer.Flush ();
-        Assume.That (writer.Indent, Is.EqualTo (5));
-        Assume.That (sb.Length, Is.Zero);
-
-        // Need to write something first, or IndentedTextWriter won't emit the indentation for the first call.
-        // So we'll write an empty line.
-        writer.WriteLine ();
-
-        for (ushort indentCount = 5; indentCount > 0;)
-        {
-            writer.Pop (scopeClosing);
-            Assert.That (writer.Indent, Is.EqualTo (--indentCount));
-        }
-
-        writer.Flush ();
-        var result = sb.ToString ();
-
-        Assert.That (
-                     result,
-                     Is.EqualTo (
-                                 $"""
-                                  
-                                          {scopeClosing}
-                                        {scopeClosing}
-                                      {scopeClosing}
-                                    {scopeClosing}
-                                  {scopeClosing}
-
-                                  """));
-    }
-
-    [Test]
-    public void Push_Increments ()
-    {
-        StringBuilder sb = new (32);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw, "  ");
-
-        for (int indentCount = 0; indentCount < 5; indentCount++)
-        {
-            writer.Push ();
-            Assert.That (writer.Indent, Is.EqualTo (indentCount + 1));
-        }
-    }
-
-    [Test]
-    public void Push_WithOpening_WritesAndPushes ([Values ('{', '(', '[')] char scopeOpening)
-    {
-        StringBuilder sb = new (256);
-        using var sw = new StringWriter (sb);
-        using var writer = new IndentedTextWriter (sw, "  ");
-
-        for (ushort indentCount = 0; indentCount < 5;)
-        {
-            writer.Push ("Opening UninterestingEnum", scopeOpening);
-            Assert.That (writer.Indent, Is.EqualTo (++indentCount));
-        }
-
-        writer.Flush ();
-        var result = sb.ToString ();
-
-        Assert.That (
-                     result,
-                     Is.EqualTo (
-                                 $"""
-                                  Opening UninterestingEnum
-                                  {scopeOpening}
-                                    Opening UninterestingEnum
-                                    {scopeOpening}
-                                      Opening UninterestingEnum
-                                      {scopeOpening}
-                                        Opening UninterestingEnum
-                                        {scopeOpening}
-                                          Opening UninterestingEnum
-                                          {scopeOpening}
-
-                                  """));
-    }
-}

+ 0 - 47
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj

@@ -1,47 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <TargetFramework>net8.0</TargetFramework>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <LangVersion>12</LangVersion>
-    <IsPackable>false</IsPackable>
-    <IsTestProject>true</IsTestProject>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <DebugType>portable</DebugType>
-    <DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
-    <ImplicitUsings>enable</ImplicitUsings>
-    <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
-    <PackageReference Include="NUnit" Version="4.1.0" />
-    <PackageReference Include="NUnit.Analyzers" Version="4.2.0">
-      <PrivateAssets>all</PrivateAssets>
-      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
-    </PackageReference>
-    <PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <ProjectReference Include="..\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj">
-      <PrivateAssets>all</PrivateAssets>
-      <OutputItemType>Analyzer</OutputItemType>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-
-  <ItemGroup>
-    <Using Include="NUnit.Framework" />
-    <Using Include="Terminal.Gui" />
-    <Using Include="Terminal.Gui.Analyzers" />
-    <Using Include="Terminal.Gui.Analyzers.Internal" />
-  </ItemGroup>
-
-</Project>

+ 0 - 3
Analyzers/Terminal.Gui.Analyzers.Internal.Tests/Terminal.Gui.Analyzers.Internal.Tests.csproj.DotSettings

@@ -1,3 +0,0 @@
-<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
-	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=generators_005Cenumextensions_005Cenumdefinitions_005Cwithgenerator/@EntryIndexedValue">True</s:Boolean>
-	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=generators_005Cenumextensions_005Cenumdefinitions_005Cwithoutgenerator/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

+ 0 - 20
Analyzers/Terminal.Gui.Analyzers.Internal/AccessibilityExtensions.cs

@@ -1,20 +0,0 @@
-using Microsoft.CodeAnalysis;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-internal static class AccessibilityExtensions
-{
-    internal static string ToCSharpString (this Accessibility value)
-    {
-        return value switch
-        {
-            Accessibility.Public => "public",
-            Accessibility.Internal => "internal",
-            Accessibility.Private => "private",
-            Accessibility.Protected => "protected",
-            Accessibility.ProtectedAndInternal => "private protected",
-            Accessibility.ProtectedOrInternal => "protected internal",
-            _ => string.Empty
-        };
-    }
-}

+ 0 - 8
Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Shipped.md

@@ -1,8 +0,0 @@
-## Release 1.0
-
-### New Rules
-
-Rule ID | Category | Severity | Notes
---------|----------|----------|--------------------
-TG0001  |   Usage  |  Error   | TG0001_GlobalNamespaceNotSupported
-TG0002  |   Usage  |  Error   | TG0002_UnderlyingTypeNotSupported

+ 0 - 4
Analyzers/Terminal.Gui.Analyzers.Internal/AnalyzerReleases.Unshipped.md

@@ -1,4 +0,0 @@
-### New Rules
-
-Rule ID | Category | Severity | Notes
---------|----------|----------|--------------------

+ 0 - 117
Analyzers/Terminal.Gui.Analyzers.Internal/Analyzers/GenerateEnumExtensionMethodsAttributeAnalyzer.cs

@@ -1,117 +0,0 @@
-#define JETBRAINS_ANNOTATIONS
-using System.Collections.Immutable;
-using System.Linq;
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.Diagnostics;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-namespace Terminal.Gui.Analyzers.Internal.Analyzers;
-
-/// <summary>
-///     Design-time analyzer that checks for proper use of <see cref="GenerateEnumExtensionMethodsAttribute"/>.
-/// </summary>
-[DiagnosticAnalyzer (LanguageNames.CSharp)]
-[UsedImplicitly]
-internal sealed class GenerateEnumExtensionMethodsAttributeAnalyzer : DiagnosticAnalyzer
-{
-    // ReSharper disable once InconsistentNaming
-    private static readonly DiagnosticDescriptor TG0001_GlobalNamespaceNotSupported = new (
-                                                                                           // ReSharper restore InconsistentNaming
-                                                                                           "TG0001",
-                                                                                           $"{nameof (GenerateEnumExtensionMethodsAttribute)} not supported on global enums",
-                                                                                           "{0} is in the global namespace, which is not supported by the source generator ({1}) used by {2}. Move the enum to a namespace or remove the attribute.",
-                                                                                           "Usage",
-                                                                                           DiagnosticSeverity.Error,
-                                                                                           true,
-                                                                                           null,
-                                                                                           null,
-                                                                                           WellKnownDiagnosticTags.NotConfigurable,
-                                                                                           WellKnownDiagnosticTags.Compiler);
-
-    // ReSharper disable once InconsistentNaming
-    private static readonly DiagnosticDescriptor TG0002_UnderlyingTypeNotSupported = new (
-                                                                                          "TG0002",
-                                                                                          $"{nameof (GenerateEnumExtensionMethodsAttribute)} not supported for this enum type",
-                                                                                          "{0} has an underlying type of {1}, which is not supported by the source generator ({2}) used by {3}. Only enums backed by int or uint are supported.",
-                                                                                          "Usage",
-                                                                                          DiagnosticSeverity.Error,
-                                                                                          true,
-                                                                                          null,
-                                                                                          null,
-                                                                                          WellKnownDiagnosticTags.NotConfigurable,
-                                                                                          WellKnownDiagnosticTags.Compiler);
-
-    /// <inheritdoc/>
-    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } =
-        [
-            TG0001_GlobalNamespaceNotSupported,
-            TG0002_UnderlyingTypeNotSupported
-        ];
-
-    /// <inheritdoc/>
-    public override void Initialize (AnalysisContext context)
-    {
-        context.ConfigureGeneratedCodeAnalysis (GeneratedCodeAnalysisFlags.None);
-        context.EnableConcurrentExecution ();
-
-        context.RegisterSyntaxNodeAction (CheckAttributeLocations, SyntaxKind.EnumDeclaration);
-
-        return;
-
-        static void CheckAttributeLocations (SyntaxNodeAnalysisContext analysisContext)
-        {
-            ISymbol? symbol = analysisContext.SemanticModel.GetDeclaredSymbol (analysisContext.Node) as INamedTypeSymbol;
-
-            if (symbol is not INamedTypeSymbol { EnumUnderlyingType: { } } enumSymbol)
-            {
-                // Somehow not even an enum declaration.
-                // Skip it.
-                return;
-            }
-
-            // Check attributes for those we care about and react accordingly.
-            foreach (AttributeData attributeData in enumSymbol.GetAttributes ())
-            {
-                if (attributeData.AttributeClass?.Name != nameof (GenerateEnumExtensionMethodsAttribute))
-                {
-                    // Just skip - not an interesting attribute.
-                    continue;
-                }
-
-                // Check enum underlying type for supported types (int and uint, currently)
-                // Report TG0002 if unsupported underlying type.
-                if (enumSymbol.EnumUnderlyingType is not { SpecialType: SpecialType.System_Int32 or SpecialType.System_UInt32 })
-                {
-                    analysisContext.ReportDiagnostic (
-                                                      Diagnostic.Create (
-                                                                         TG0002_UnderlyingTypeNotSupported,
-                                                                         enumSymbol.Locations.FirstOrDefault (),
-                                                                         enumSymbol.Name,
-                                                                         enumSymbol.EnumUnderlyingType.Name,
-                                                                         nameof (EnumExtensionMethodsIncrementalGenerator),
-                                                                         nameof (GenerateEnumExtensionMethodsAttribute)
-                                                                        )
-                                                     );
-                }
-
-                // Check enum namespace (only non-global supported, currently)
-                // Report TG0001 if in the global namespace.
-                if (enumSymbol.ContainingSymbol is not INamespaceSymbol { IsGlobalNamespace: false })
-                {
-                    analysisContext.ReportDiagnostic (
-                                                      Diagnostic.Create (
-                                                                         TG0001_GlobalNamespaceNotSupported,
-                                                                         enumSymbol.Locations.FirstOrDefault (),
-                                                                         enumSymbol.Name,
-                                                                         nameof (EnumExtensionMethodsIncrementalGenerator),
-                                                                         nameof (GenerateEnumExtensionMethodsAttribute)
-                                                                        )
-                                                     );
-                }
-            }
-        }
-    }
-}

+ 0 - 3
Analyzers/Terminal.Gui.Analyzers.Internal/ApiCompatExcludedAttributes.txt

@@ -1,3 +0,0 @@
-N:System.Runtime.CompilerServices
-N:System.Diagnostics.CodeAnalysis
-N:System.Numerics

+ 0 - 27
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/AssemblyExtendedEnumTypeAttribute.cs

@@ -1,27 +0,0 @@
-// ReSharper disable ClassNeverInstantiated.Global
-// ReSharper disable once RedundantNullableDirective
-#nullable enable
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>Assembly attribute declaring a known pairing of an <see langword="enum" /> type to an extension class.</summary>
-/// <remarks>This attribute should only be written by internal source generators for Terminal.Gui. No other usage of any kind is supported.</remarks>
-[System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple = true)]
-internal sealed class AssemblyExtendedEnumTypeAttribute : System.Attribute
-{
-    /// <summary>Creates a new instance of <see cref="AssemblyExtendedEnumTypeAttribute" /> from the provided parameters.</summary>
-    /// <param name="enumType">The <see cref="System.Type" /> of an <see langword="enum" /> decorated with a <see cref="GenerateEnumExtensionMethodsAttribute" />.</param>
-    /// <param name="extensionClass">The <see cref="System.Type" /> of the <see langword="class" /> decorated with an <see cref="ExtensionsForEnumTypeAttribute{TEnum}" /> referring to the same type as <paramref name="enumType" />.</param>
-    public AssemblyExtendedEnumTypeAttribute (System.Type enumType, System.Type extensionClass)
-    {
-        EnumType = enumType;
-        ExtensionClass = extensionClass;
-    }
-    ///<summary>An <see langword="enum" /> type that has been extended by Terminal.Gui source generators.</summary>
-    public System.Type EnumType { get; init; }
-    ///<summary>A class containing extension methods for <see cref="EnumType"/>.</summary>
-    public System.Type ExtensionClass { get; init; }
-
-    /// <inheritdoc />
-    public override string ToString () => $"{EnumType.Name},{ExtensionClass.Name}";
-}

+ 0 - 37
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/ExtensionsForEnumTypeAttribute.cs

@@ -1,37 +0,0 @@
-// ReSharper disable RedundantNameQualifier
-// ReSharper disable RedundantNullableDirective
-// ReSharper disable UnusedType.Global
-#pragma warning disable IDE0001, IDE0240
-#nullable enable
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>
-///     Attribute written by the source generator for <see langword="enum" /> extension classes, for easier analysis and reflection.
-/// </summary>
-/// <remarks>
-///     Properties are just convenient shortcuts to properties of <typeparamref name="TEnum"/>.
-/// </remarks>
-[System.AttributeUsage (System.AttributeTargets.Class | System.AttributeTargets.Interface)]
-internal sealed class ExtensionsForEnumTypeAttribute<TEnum>: System.Attribute, IExtensionsForEnumTypeAttributes where TEnum : struct, System.Enum
-{
-    /// <summary>
-    ///     The namespace-qualified name of <typeparamref name="TEnum"/>.
-    /// </summary>
-    public string EnumFullName => EnumType.FullName!;
-
-    /// <summary>
-    ///     The unqualified name of <typeparamref name="TEnum"/>.
-    /// </summary>
-    public string EnumName => EnumType.Name;
-
-    /// <summary>
-    ///     The namespace containing <typeparamref name="TEnum"/>.
-    /// </summary>
-    public string EnumNamespace => EnumType.Namespace!;
-
-    /// <summary>
-    ///     The <see cref="System.Type"/> given by <see langword="typeof"/>(<typeparamref name="TEnum"/>).
-    /// </summary>
-    public System.Type EnumType => typeof (TEnum);
-}

+ 0 - 110
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/GenerateEnumExtensionMethodsAttribute.cs

@@ -1,110 +0,0 @@
-// ReSharper disable RedundantNullableDirective
-// ReSharper disable RedundantUsingDirective
-// ReSharper disable ClassNeverInstantiated.Global
-
-#nullable enable
-using System;
-using Attribute = System.Attribute;
-using AttributeUsageAttribute = System.AttributeUsageAttribute;
-using AttributeTargets = System.AttributeTargets;
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>
-///     Used to enable source generation of a common set of extension methods for enum types.
-/// </summary>
-[AttributeUsage (AttributeTargets.Enum)]
-internal sealed class GenerateEnumExtensionMethodsAttribute : Attribute
-{
-    /// <summary>
-    ///     The name of the generated static class.
-    /// </summary>
-    /// <remarks>
-    ///     If unspecified, null, empty, or only whitespace, defaults to the name of the enum plus "Extensions".<br/>
-    ///     No other validation is performed, so illegal values will simply result in compiler errors.
-    ///     <para>
-    ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-    ///     </para>
-    /// </remarks>
-    public string? ClassName { get; set; }
-
-    /// <summary>
-    ///     The namespace in which to place the generated static class containing the extension methods.
-    /// </summary>
-    /// <remarks>
-    ///     If unspecified, null, empty, or only whitespace, defaults to the namespace of the enum.<br/>
-    ///     No other validation is performed, so illegal values will simply result in compiler errors.
-    ///     <para>
-    ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-    ///     </para>
-    /// </remarks>
-    public string? ClassNamespace { get; set; }
-
-    /// <summary>
-    ///     Whether to generate a fast, zero-allocation, non-boxing, and reflection-free alternative to the built-in
-    ///     <see cref="Enum.HasFlag"/> method.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         Default: false
-    ///     </para>
-    ///     <para>
-    ///         If the enum is not decorated with <see cref="FlagsAttribute"/>, this option has no effect.
-    ///     </para>
-    ///     <para>
-    ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-    ///         with the same value will be skipped.
-    ///     </para>
-    ///     <para>
-    ///         Overloads taking the enum type itself as well as the underlying type of the enum will be generated, enabling
-    ///         avoidance of implicit or explicit cast overhead.
-    ///     </para>
-    ///     <para>
-    ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-    ///     </para>
-    /// </remarks>
-    public bool FastHasFlags { get; set; }
-
-    /// <summary>
-    ///     Whether to generate a fast, zero-allocation, and reflection-free alternative to the built-in
-    ///     <see cref="Enum.IsDefined"/> method,
-    ///     using a switch expression as a hard-coded reverse mapping of numeric values to explicitly-named members.
-    /// </summary>
-    /// <remarks>
-    ///     <para>
-    ///         Default: true
-    ///     </para>
-    ///     <para>
-    ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-    ///         with the same value will be skipped.
-    ///     </para>
-    ///     <para>
-    ///         As with <see cref="Enum.IsDefined"/> the source generator only considers explicitly-named members.<br/>
-    ///         Generation of values which represent valid bitwise combinations of members of enums decorated with
-    ///         <see cref="FlagsAttribute"/> is not affected by this property.
-    ///     </para>
-    /// </remarks>
-    public bool FastIsDefined { get; init; } = true;
-
-    /// <summary>
-    ///     Gets a <see langword="bool"/> value indicating if this <see cref="GenerateEnumExtensionMethodsAttribute"/> instance
-    ///     contains default values only. See <see href="#remarks">remarks</see> of this method or documentation on properties of this type for details.
-    /// </summary>
-    /// <returns>
-    ///     A <see langword="bool"/> value indicating if all property values are default for this
-    ///     <see cref="GenerateEnumExtensionMethodsAttribute"/> instance.
-    /// </returns>
-    /// <remarks>
-    ///     Default values that will result in a <see langword="true"/> return value are:<br/>
-    ///     <see cref="FastIsDefined"/> &amp;&amp; !<see cref="FastHasFlags"/> &amp;&amp; <see cref="ClassName"/>
-    ///     <see langword="is"/> <see langword="null"/> &amp;&amp; <see cref="ClassNamespace"/> <see langword="is"/>
-    ///     <see langword="null"/>
-    /// </remarks>
-    public override bool IsDefaultAttribute ()
-    {
-        return FastIsDefined
-               && !FastHasFlags
-               && ClassName is null
-               && ClassNamespace is null;
-    }
-}

+ 0 - 14
Analyzers/Terminal.Gui.Analyzers.Internal/Attributes/IExtensionsForEnumTypeAttribute.cs

@@ -1,14 +0,0 @@
-// ReSharper disable All
-
-using System;
-
-namespace Terminal.Gui.Analyzers.Internal.Attributes;
-
-/// <summary>
-///     Interface to simplify general enumeration of constructed generic types for
-///     <see cref="ExtensionsForEnumTypeAttribute{TEnum}"/>
-/// </summary>
-internal interface IExtensionsForEnumTypeAttributes
-{
-    Type EnumType { get; }
-}

+ 0 - 11
Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IEqualityOperators.cs

@@ -1,11 +0,0 @@
-// ReSharper disable once CheckNamespace
-namespace System.Numerics;
-/// <summary>
-/// Included for compatibility with .net7+, but has no members.
-/// Thus it cannot be explicitly used in generator code.
-/// Use it for static analysis only.
-/// </summary>
-/// <typeparam name="T">The left operand type.</typeparam>
-/// <typeparam name="T1">The right operand type.</typeparam>
-/// <typeparam name="T2">The return type.</typeparam>
-internal interface IEqualityOperators<T, T1, T2>;

+ 0 - 6
Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/IntrinsicAttribute.cs

@@ -1,6 +0,0 @@
-namespace System.Runtime.CompilerServices;
-
-[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Field, Inherited = false)]
-public sealed class IntrinsicAttribute : Attribute
-{
-}

+ 0 - 43
Analyzers/Terminal.Gui.Analyzers.Internal/Compatibility/NumericExtensions.cs

@@ -1,43 +0,0 @@
-// ReSharper disable once CheckNamespace
-namespace Terminal.Gui.Analyzers.Internal.Compatibility;
-
-/// <summary>
-///     Extension methods for <see langword="int"/> and <see langword="uint"/> types.
-/// </summary>
-/// <remarks>
-///     This is mostly just for backward compatibility with netstandard2.0.
-/// </remarks>
-public static class NumericExtensions
-{
-    /// <summary>
-    ///     Gets the population count (number of bits set to 1) of this 32-bit value.
-    /// </summary>
-    /// <param name="value">The value to get the population count of.</param>
-    /// <remarks>
-    ///     The algorithm is the well-known SWAR (SIMD Within A Register) method for population count.<br/>
-    ///     Included for hardware- and runtime- agnostic support for the equivalent of the x86 popcnt instruction, since
-    ///     System.Numerics.Intrinsics isn't available in netstandard2.0.<br/>
-    ///     It performs the operation simultaneously on 4 bytes at a time, rather than the naive method of testing all 32 bits
-    ///     individually.<br/>
-    ///     Most compilers can recognize this and turn it into a single platform-specific instruction, when available.
-    /// </remarks>
-    /// <returns>
-    ///     An unsigned 32-bit integer value containing the population count of <paramref name="value"/>.
-    /// </returns>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static uint GetPopCount (this uint value)
-    {
-        unchecked
-        {
-            value -= (value >> 1) & 0x55555555;
-            value = (value & 0x33333333) + ((value >> 2) & 0x33333333);
-            value = (value + (value >> 4)) & 0x0F0F0F0F;
-
-            return (value * 0x01010101) >> 24;
-        }
-    }
-
-    /// <inheritdoc cref="GetPopCount(uint)"/>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static uint GetPopCount (this int value) { return GetPopCount (Unsafe.As<int, uint> (ref value)); }
-}

+ 0 - 204
Analyzers/Terminal.Gui.Analyzers.Internal/Constants/Strings.cs

@@ -1,204 +0,0 @@
-// ReSharper disable MemberCanBePrivate.Global
-
-using System;
-using System.CodeDom.Compiler;
-using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-
-namespace Terminal.Gui.Analyzers.Internal.Constants;
-
-/// <summary>String constants for frequently-used boilerplate.</summary>
-/// <remarks>These are for performance, instead of using Roslyn to build it all during execution of analyzers.</remarks>
-internal static class Strings
-{
-    internal const string AnalyzersAttributesNamespace = $"{InternalAnalyzersNamespace}.Attributes";
-
-    internal const string AssemblyExtendedEnumTypeAttributeFullName = $"{AnalyzersAttributesNamespace}.{nameof (AssemblyExtendedEnumTypeAttribute)}";
-
-    internal const string DefaultTypeNameSuffix = "Extensions";
-
-    internal const string FallbackClassNamespace = $"{TerminalGuiRootNamespace}";
-
-    internal const string InternalAnalyzersNamespace = $"{AnalyzersRootNamespace}.Internal";
-
-    internal const string TerminalGuiRootNamespace = "Terminal.Gui";
-
-    private const string AnalyzersRootNamespace = $"{TerminalGuiRootNamespace}.Analyzers";
-    private const string NetStandard20CompatibilityNamespace = $"{InternalAnalyzersNamespace}.Compatibility";
-
-    /// <summary>
-    ///     Names of dotnet namespaces and types. Included as compile-time constants to avoid unnecessary work for the Roslyn
-    ///     source generators.
-    /// </summary>
-    /// <remarks>Implemented as nested static types because XmlDoc doesn't work on namespaces.</remarks>
-    internal static class DotnetNames
-    {
-        /// <summary>Fully-qualified attribute type names. Specific applications (uses) are in <see cref="Applications"/>.</summary>
-        internal static class Attributes
-        {
-            /// <inheritdoc cref="CompilerGeneratedAttribute"/>
-            internal const string CompilerGenerated = $"{Namespaces.System_Runtime_CompilerServices}.{nameof (CompilerGeneratedAttribute)}";
-
-            /// <inheritdoc cref="DebuggerNonUserCodeAttribute"/>
-            internal const string DebuggerNonUserCode = $"{Namespaces.System_Diagnostics}.{nameof (DebuggerNonUserCodeAttribute)}";
-
-            /// <inheritdoc cref="ExcludeFromCodeCoverageAttribute"/>
-            internal const string ExcludeFromCodeCoverage = $"{Namespaces.System_Diagnostics_CodeAnalysis}.{nameof (ExcludeFromCodeCoverageAttribute)}";
-
-            internal const string Flags = $"{Namespaces.SystemNs}.{nameof (FlagsAttribute)}";
-
-            internal const string GeneratedCode = $"{Namespaces.System_CodeDom_Compiler}.{nameof (GeneratedCodeAttribute)}";
-
-            /// <inheritdoc cref="MethodImplOptions.AggressiveInlining"/>
-            /// <remarks>Use of this attribute should be carefully evaluated.</remarks>
-            internal const string MethodImpl = $"{Namespaces.System_Runtime_CompilerServices}.{nameof (MethodImplAttribute)}";
-
-            /// <summary>Attributes formatted for use in code, including square brackets.</summary>
-            internal static class Applications
-            {
-                // ReSharper disable MemberHidesStaticFromOuterClass
-                internal const string Flags = $"[{Attributes.Flags}]";
-
-                /// <inheritdoc cref="System.CodeDom.Compiler.GeneratedCodeAttribute"/>
-                internal const string GeneratedCode = $"""[{Attributes.GeneratedCode}("{InternalAnalyzersNamespace}","1.0")]""";
-
-                /// <inheritdoc cref="MethodImplOptions.AggressiveInlining"/>
-                /// <remarks>Use of this attribute should be carefully evaluated.</remarks>
-                internal const string AggressiveInlining = $"[{MethodImpl}({Types.MethodImplOptions}.{nameof (MethodImplOptions.AggressiveInlining)})]";
-
-                /// <inheritdoc cref="DebuggerNonUserCodeAttribute"/>
-                internal const string DebuggerNonUserCode = $"[{Attributes.DebuggerNonUserCode}]";
-
-                /// <inheritdoc cref="CompilerGeneratedAttribute"/>
-                internal const string CompilerGenerated = $"[{Attributes.CompilerGenerated}]";
-
-                /// <inheritdoc cref="ExcludeFromCodeCoverageAttribute"/>
-                internal const string ExcludeFromCodeCoverage = $"[{Attributes.ExcludeFromCodeCoverage}]";
-
-                // ReSharper restore MemberHidesStaticFromOuterClass
-            }
-        }
-
-        /// <summary>Names of dotnet namespaces.</summary>
-        internal static class Namespaces
-        {
-            internal const string SystemNs = nameof (System);
-            // ReSharper disable InconsistentNaming
-            internal const string System_CodeDom = $"{SystemNs}.{nameof (System.CodeDom)}";
-            internal const string System_CodeDom_Compiler = $"{System_CodeDom}.{nameof (System.CodeDom.Compiler)}";
-            internal const string System_ComponentModel = $"{SystemNs}.{nameof (System.ComponentModel)}";
-            internal const string System_Diagnostics = $"{SystemNs}.{nameof (System.Diagnostics)}";
-            internal const string System_Diagnostics_CodeAnalysis = $"{System_Diagnostics}.{nameof (System.Diagnostics.CodeAnalysis)}";
-            internal const string System_Numerics = $"{SystemNs}.{nameof (System.Numerics)}";
-            internal const string System_Runtime = $"{SystemNs}.{nameof (System.Runtime)}";
-            internal const string System_Runtime_CompilerServices = $"{System_Runtime}.{nameof (System.Runtime.CompilerServices)}";
-            // ReSharper restore InconsistentNaming
-        }
-
-        internal static class Types
-        {
-            internal const string Attribute = $"{Namespaces.SystemNs}.{nameof (System.Attribute)}";
-            internal const string AttributeTargets = $"{Namespaces.SystemNs}.{nameof (System.AttributeTargets)}";
-            internal const string AttributeUsageAttribute = $"{Namespaces.SystemNs}.{nameof (System.AttributeUsageAttribute)}";
-
-            internal const string MethodImplOptions =
-                $"{Namespaces.System_Runtime_CompilerServices}.{nameof (System.Runtime.CompilerServices.MethodImplOptions)}";
-        }
-    }
-
-    internal static class Templates
-    {
-        internal const string AutoGeneratedCommentBlock = $"""
-                                                           //------------------------------------------------------------------------------
-                                                           // <auto-generated>
-                                                           //   This file and the code it contains was generated by a source generator in
-                                                           //   the {InternalAnalyzersNamespace} library.
-                                                           //
-                                                           //   Modifications to this file are not supported and will be lost when
-                                                           //   source generation is triggered, either implicitly or explicitly.
-                                                           // </auto-generated>
-                                                           //------------------------------------------------------------------------------
-                                                           """;
-
-        /// <summary>
-        ///     A set of explicit type aliases to work around Terminal.Gui having name collisions with types like
-        ///     <see cref="System.Attribute"/>.
-        /// </summary>
-        internal const string DotnetExplicitTypeAliasUsingDirectives = $"""
-                                                                        using Attribute = {DotnetNames.Types.Attribute};
-                                                                        using AttributeUsageAttribute = {DotnetNames.Types.AttributeUsageAttribute};
-                                                                        using GeneratedCode = {DotnetNames.Attributes.GeneratedCode};
-                                                                        """;
-
-        /// <summary>Using directives for common namespaces in generated code.</summary>
-        internal const string DotnetNamespaceUsingDirectives = $"""
-                                                                using {DotnetNames.Namespaces.SystemNs};
-                                                                using {DotnetNames.Namespaces.System_CodeDom};
-                                                                using {DotnetNames.Namespaces.System_CodeDom_Compiler};
-                                                                using {DotnetNames.Namespaces.System_ComponentModel};
-                                                                using {DotnetNames.Namespaces.System_Numerics};
-                                                                using {DotnetNames.Namespaces.System_Runtime};
-                                                                using {DotnetNames.Namespaces.System_Runtime_CompilerServices};
-                                                                """;
-
-        /// <summary>
-        ///     A set of empty namespaces that MAY be referenced in generated code, especially in using statements,
-        ///     which are always included to avoid additional complexity due to conditional compilation.
-        /// </summary>
-        internal const string DummyNamespaceDeclarations = $$"""
-                                                             // These are dummy declarations to avoid complexity with conditional compilation.
-                                                             #pragma warning disable IDE0079 // Remove unnecessary suppression
-                                                             #pragma warning disable RCS1259 // Remove empty syntax
-                                                             namespace {{TerminalGuiRootNamespace}} { }
-                                                             namespace {{AnalyzersRootNamespace}} { }
-                                                             namespace {{InternalAnalyzersNamespace}} { }
-                                                             namespace {{NetStandard20CompatibilityNamespace}} { }
-                                                             namespace {{AnalyzersAttributesNamespace}} { }
-                                                             #pragma warning restore RCS1259 // Remove empty syntax
-                                                             #pragma warning restore IDE0079 // Remove unnecessary suppression
-                                                             """;
-
-        internal const string StandardHeader = $"""
-                                                {AutoGeneratedCommentBlock}
-                                                // ReSharper disable RedundantUsingDirective
-                                                // ReSharper disable once RedundantNullableDirective
-                                                {NullableContextDirective}
-
-                                                {StandardUsingDirectivesText}
-                                                """;
-
-        /// <summary>
-        ///     Standard set of using directives for generated extension method class files.
-        ///     Not all are always needed, but all are included so we don't have to worry about it.
-        /// </summary>
-        internal const string StandardUsingDirectivesText = $"""
-                                                             {DotnetNamespaceUsingDirectives}
-                                                             {DotnetExplicitTypeAliasUsingDirectives}
-                                                             using {TerminalGuiRootNamespace};
-                                                             using {AnalyzersRootNamespace};
-                                                             using {InternalAnalyzersNamespace};
-                                                             using {AnalyzersAttributesNamespace};
-                                                             using {NetStandard20CompatibilityNamespace};
-                                                             """;
-
-        internal const string AttributesForGeneratedInterfaces = $"""
-                                                                  {DotnetNames.Attributes.Applications.GeneratedCode}
-                                                                  {DotnetNames.Attributes.Applications.CompilerGenerated}
-                                                                  """;
-
-        internal const string AttributesForGeneratedTypes = $"""
-                                                             {DotnetNames.Attributes.Applications.GeneratedCode}
-                                                             {DotnetNames.Attributes.Applications.CompilerGenerated}
-                                                             {DotnetNames.Attributes.Applications.DebuggerNonUserCode}
-                                                             {DotnetNames.Attributes.Applications.ExcludeFromCodeCoverage}
-                                                             """;
-
-        /// <summary>
-        ///     Preprocessor directive to enable nullability context for generated code.<br/>
-        ///     This should always be emitted, as it applies only to generated code.<br/>
-        ///     As such, generated code MUST be properly annotated.
-        /// </summary>
-        internal const string NullableContextDirective = "#nullable enable";
-    }
-}

+ 0 - 235
Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/CodeWriter.cs

@@ -1,235 +0,0 @@
-using System;
-using System.CodeDom.Compiler;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Text;
-using Microsoft.CodeAnalysis.Text;
-using Terminal.Gui.Analyzers.Internal.Constants;
-
-namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-/// <summary>
-///     The class responsible for turning an <see cref="EnumExtensionMethodsGenerationInfo"/>
-///     into actual C# code.
-/// </summary>
-/// <remarks>Try to use this type as infrequently as possible.</remarks>
-/// <param name="metadata">
-///     A reference to an <see cref="IGeneratedTypeMetadata{TSelf}"/> which will be used
-///     to generate the extension class code. The object will not be validated,
-///     so it is critical that it be correct and remain unchanged while in use
-///     by an instance of this class. Behavior if those rules are not followed
-///     is undefined.
-/// </param>
-[SuppressMessage ("CodeQuality", "IDE0079", Justification = "Suppressions here are intentional and the warnings they disable are just noise.")]
-internal sealed class CodeWriter (in EnumExtensionMethodsGenerationInfo metadata) : IStandardCSharpCodeGenerator<EnumExtensionMethodsGenerationInfo>
-{
-    // Using the null suppression operator here because this will always be
-    // initialized to non-null before a reference to it is returned.
-    private SourceText _sourceText = null!;
-
-    /// <inheritdoc/>
-    public EnumExtensionMethodsGenerationInfo Metadata
-    {
-        [MethodImpl (MethodImplOptions.AggressiveInlining)]
-        [return: NotNull]
-        get;
-        [param: DisallowNull]
-        set;
-    } = metadata;
-
-    /// <inheritdoc/>
-    public ref readonly SourceText GenerateSourceText (Encoding? encoding = null)
-    {
-        encoding ??= Encoding.UTF8;
-        _sourceText = SourceText.From (GetFullSourceText (), encoding);
-
-        return ref _sourceText;
-    }
-
-    /// <summary>
-    ///     Gets the using directive for the namespace containing the enum,
-    ///     if different from the extension class namespace, or an empty string, if they are the same.
-    /// </summary>
-    private string EnumNamespaceUsingDirective => Metadata.TargetTypeNamespace != Metadata.GeneratedTypeNamespace
-
-                                                      // ReSharper disable once HeapView.ObjectAllocation
-                                                      ? $"using {Metadata.TargetTypeNamespace};"
-                                                      : string.Empty;
-
-    private string EnumTypeKeyword => Metadata.EnumBackingTypeCode switch
-                                      {
-                                          TypeCode.Int32 => "int",
-                                          TypeCode.UInt32 => "uint",
-                                          _ => string.Empty
-                                      };
-
-    /// <summary>Gets the class declaration line.</summary>
-    private string ExtensionClassDeclarationLine => $"public static partial class {Metadata.GeneratedTypeName}";
-
-    // ReSharper disable once HeapView.ObjectAllocation
-    /// <summary>Gets the XmlDoc for the extension class declaration.</summary>
-    private string ExtensionClassDeclarationXmlDoc =>
-        $"/// <summary>Extension methods for the <see cref=\"{Metadata.TargetTypeFullName}\"/> <see langword=\"enum\" /> type.</summary>";
-
-    // ReSharper disable once HeapView.ObjectAllocation
-    /// <summary>Gets the extension class file-scoped namespace directive.</summary>
-    private string ExtensionClassNamespaceDirective => $"namespace {Metadata.GeneratedTypeNamespace};";
-
-    /// <summary>
-    ///     An attribute to decorate the extension class with for easy mapping back to the target enum type, for reflection and
-    ///     analysis.
-    /// </summary>
-    private string ExtensionsForTypeAttributeLine => $"[ExtensionsForEnumType<{Metadata.TargetTypeFullName}>]";
-
-    /// <summary>
-    ///     Creates the code for the FastHasFlags method.
-    /// </summary>
-    /// <remarks>
-    ///     Since the generator already only writes code for enums backed by <see langword="int"/> and <see langword="uint"/>,
-    ///     this method is safe, as we'll always be using a DWORD.
-    /// </remarks>
-    /// <param name="w">An instance of an <see cref="IndentedTextWriter"/> to write to.</param>
-    private void GetFastHasFlagsMethods (IndentedTextWriter w)
-    {
-        // The version taking the same enum type as the check value.
-        w.WriteLine (
-                     $"/// <summary>Determines if the specified flags are set in the current value of this <see cref=\"{Metadata.TargetTypeFullName}\" />.</summary>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-
-        w.WriteLine (
-                     $"/// <returns>True, if all flags present in <paramref name=\"checkFlags\" /> are also present in the current value of the <see cref=\"{Metadata.TargetTypeFullName}\" />.<br />Otherwise false.</returns>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-
-        w.Push (
-                $"{Metadata.Accessibility.ToCSharpString ()} static bool FastHasFlags (this {Metadata.TargetTypeFullName} e, {Metadata.TargetTypeFullName} checkFlags)");
-        w.WriteLine ($"ref uint enumCurrentValueRef = ref Unsafe.As<{Metadata.TargetTypeFullName},uint> (ref e);");
-        w.WriteLine ($"ref uint checkFlagsValueRef = ref Unsafe.As<{Metadata.TargetTypeFullName},uint> (ref checkFlags);");
-        w.WriteLine ("return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;");
-        w.Pop ();
-
-        // The version taking the underlying type of the enum as the check value.
-        w.WriteLine (
-                     $"/// <summary>Determines if the specified mask bits are set in the current value of this <see cref=\"{Metadata.TargetTypeFullName}\" />.</summary>");
-
-        w.WriteLine (
-                     $"/// <param name=\"e\">The <see cref=\"{Metadata.TargetTypeFullName}\" /> value to check against the <paramref name=\"mask\" /> value.</param>");
-        w.WriteLine ("/// <param name=\"mask\">A mask to apply to the current value.</param>");
-
-        w.WriteLine (
-                     $"/// <returns>True, if all bits set to 1 in the mask are also set to 1 in the current value of the <see cref=\"{Metadata.TargetTypeFullName}\" />.<br />Otherwise false.</returns>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-
-        w.Push (
-                $"{Metadata.Accessibility.ToCSharpString ()} static bool FastHasFlags (this {Metadata.TargetTypeFullName} e, {EnumTypeKeyword} mask)");
-        w.WriteLine ($"ref {EnumTypeKeyword} enumCurrentValueRef = ref Unsafe.As<{Metadata.TargetTypeFullName},{EnumTypeKeyword}> (ref e);");
-        w.WriteLine ("return (enumCurrentValueRef & mask) == mask;");
-        w.Pop ();
-    }
-
-    /// <summary>
-    ///     Creates the code for the FastIsDefined method.
-    /// </summary>
-    [SuppressMessage ("ReSharper", "SwitchStatementHandlesSomeKnownEnumValuesWithDefault", Justification = "Only need to handle int and uint.")]
-    [SuppressMessage ("ReSharper", "SwitchStatementMissingSomeEnumCasesNoDefault", Justification = "Only need to handle int and uint.")]
-    private void GetFastIsDefinedMethod (IndentedTextWriter w)
-    {
-        w.WriteLine (
-                     $"/// <summary>Determines if the specified <see langword=\"{EnumTypeKeyword}\" /> value is explicitly defined as a named value of the <see cref=\"{Metadata.TargetTypeFullName}\" /> <see langword=\"enum\" /> type.</summary>");
-
-        w.WriteLine (
-                     "/// <remarks>Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are not explicitly named will return false.</remarks>");
-
-        w.Push (
-                $"{Metadata.Accessibility.ToCSharpString ()} static bool FastIsDefined (this {Metadata.TargetTypeFullName} e, {EnumTypeKeyword} value)");
-        w.Push ("return value switch");
-
-        switch (Metadata.EnumBackingTypeCode)
-        {
-            case TypeCode.Int32:
-                foreach (int definedValue in Metadata._intMembers)
-                {
-                    w.WriteLine ($"{definedValue:D} => true,");
-                }
-
-                break;
-            case TypeCode.UInt32:
-                foreach (uint definedValue in Metadata._uIntMembers)
-                {
-                    w.WriteLine ($"{definedValue:D} => true,");
-                }
-
-                break;
-        }
-
-        w.WriteLine ("_ => false");
-
-        w.Pop ("};");
-        w.Pop ();
-    }
-
-    private string GetFullSourceText ()
-    {
-        StringBuilder sb = new (
-                                $"""
-                                 {Strings.Templates.StandardHeader}
-
-                                 [assembly: {Strings.AssemblyExtendedEnumTypeAttributeFullName} (typeof({Metadata.TargetTypeFullName}), typeof({Metadata.GeneratedTypeFullName}))]
-
-                                 {EnumNamespaceUsingDirective}
-                                 {ExtensionClassNamespaceDirective}
-                                 {ExtensionClassDeclarationXmlDoc}
-                                 {Strings.Templates.AttributesForGeneratedTypes}
-                                 {ExtensionsForTypeAttributeLine}
-                                 {ExtensionClassDeclarationLine}
-                                 
-                                 """,
-                                4096);
-
-        using IndentedTextWriter w = new (new StringWriter (sb));
-        w.Push ();
-
-        GetNamedValuesToInt32Method (w);
-        GetNamedValuesToUInt32Method (w);
-
-        if (Metadata.GenerateFastIsDefined)
-        {
-            GetFastIsDefinedMethod (w);
-        }
-
-        if (Metadata.GenerateFastHasFlags)
-        {
-            GetFastHasFlagsMethods (w);
-        }
-
-        w.Pop ();
-
-        w.Flush ();
-
-        return sb.ToString ();
-    }
-
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    private void GetNamedValuesToInt32Method (IndentedTextWriter w)
-    {
-        w.WriteLine (
-                     $"/// <summary>Directly converts this <see cref=\"{Metadata.TargetTypeFullName}\" /> value to an <see langword=\"int\" /> value with the same binary representation.</summary>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-        w.Push ($"{Metadata.Accessibility.ToCSharpString ()} static int AsInt32 (this {Metadata.TargetTypeFullName} e)");
-        w.WriteLine ($"return Unsafe.As<{Metadata.TargetTypeFullName},int> (ref e);");
-        w.Pop ();
-    }
-
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    private void GetNamedValuesToUInt32Method (IndentedTextWriter w)
-    {
-        w.WriteLine (
-                     $"/// <summary>Directly converts this <see cref=\"{Metadata.TargetTypeFullName}\" /> value to a <see langword=\"uint\" /> value with the same binary representation.</summary>");
-        w.WriteLine ("/// <remarks>NO VALIDATION IS PERFORMED!</remarks>");
-        w.WriteLine (Strings.DotnetNames.Attributes.Applications.AggressiveInlining);
-        w.Push ($"{Metadata.Accessibility.ToCSharpString ()} static uint AsUInt32 (this {Metadata.TargetTypeFullName} e)");
-        w.WriteLine ($"return Unsafe.As<{Metadata.TargetTypeFullName},uint> (ref e);");
-        w.Pop ();
-    }
-}

+ 0 - 443
Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsGenerationInfo.cs

@@ -1,443 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using System.Threading;
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Constants;
-
-namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-/// <summary>
-///     Type containing the information necessary to generate code according to the declared attribute values,
-///     as well as the actual code to create the corresponding source code text, to be used in the
-///     source generator pipeline.
-/// </summary>
-/// <remarks>
-///     Minimal validation is performed by this type.<br/>
-///     Errors in analyzed source code will result in generation failure or broken output.<br/>
-///     This type is not intended for use outside of Terminal.Gui library development.
-/// </remarks>
-internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetadata<EnumExtensionMethodsGenerationInfo>,
-                                                            IEqualityOperators<EnumExtensionMethodsGenerationInfo, EnumExtensionMethodsGenerationInfo, bool>
-{
-    private const int ExplicitFastHasFlagsMask  = 0b_0100;
-    private const int ExplicitFastIsDefinedMask = 0b_1000;
-    private const int ExplicitNameMask          = 0b_0010;
-    private const int ExplicitNamespaceMask     = 0b_0001;
-    private const string GeneratorAttributeFullyQualifiedName = $"{GeneratorAttributeNamespace}.{GeneratorAttributeName}";
-    private const string GeneratorAttributeName = nameof (GenerateEnumExtensionMethodsAttribute);
-    private const string GeneratorAttributeNamespace = Strings.AnalyzersAttributesNamespace;
-
-    /// <summary>
-    ///     Type containing the information necessary to generate code according to the declared attribute values,
-    ///     as well as the actual code to create the corresponding source code text, to be used in the
-    ///     source generator pipeline.
-    /// </summary>
-    /// <param name="enumNamespace">The fully-qualified namespace of the enum type, without assembly name.</param>
-    /// <param name="enumTypeName">
-    ///     The name of the enum type, as would be given by <see langword="nameof"/> on the enum's type
-    ///     declaration.
-    /// </param>
-    /// <param name="typeNamespace">
-    ///     The fully-qualified namespace in which to place the generated code, without assembly name. If omitted or explicitly
-    ///     null, uses the value provided in <paramref name="enumNamespace"/>.
-    /// </param>
-    /// <param name="typeName">
-    ///     The name of the generated class. If omitted or explicitly null, appends "Extensions" to the value of
-    ///     <paramref name="enumTypeName"/>.
-    /// </param>
-    /// <param name="enumBackingTypeCode">The backing type of the enum. Defaults to <see cref="int"/>.</param>
-    /// <param name="generateFastHasFlags">
-    ///     Whether to generate a fast HasFlag alternative. (Default: true) Ignored if the enum does not also have
-    ///     <see cref="FlagsAttribute"/>.
-    /// </param>
-    /// <param name="generateFastIsDefined">Whether to generate a fast IsDefined alternative. (Default: true)</param>
-    /// <remarks>
-    ///     Minimal validation is performed by this type.<br/>
-    ///     Errors in analyzed source code will result in generation failure or broken output.<br/>
-    ///     This type is not intended for use outside of Terminal.Gui library development.
-    /// </remarks>
-    public EnumExtensionMethodsGenerationInfo (
-        string enumNamespace,
-        string enumTypeName,
-        string? typeNamespace = null,
-        string? typeName = null,
-        TypeCode enumBackingTypeCode = TypeCode.Int32,
-        bool generateFastHasFlags = true,
-        bool generateFastIsDefined = true
-    ) : this (enumNamespace, enumTypeName, enumBackingTypeCode)
-    {
-        GeneratedTypeNamespace = typeNamespace ?? enumNamespace;
-        GeneratedTypeName = typeName ?? string.Concat (enumTypeName, Strings.DefaultTypeNameSuffix);
-        GenerateFastHasFlags = generateFastHasFlags;
-        GenerateFastIsDefined = generateFastIsDefined;
-    }
-
-    public EnumExtensionMethodsGenerationInfo (string enumNamespace, string enumTypeName, TypeCode enumBackingType)
-    {
-        // Interning these since they're rather unlikely to change.
-        string enumInternedNamespace = string.Intern (enumNamespace);
-        string enumInternedName = string.Intern (enumTypeName);
-        TargetTypeNamespace = enumInternedNamespace;
-        TargetTypeName = enumInternedName;
-        EnumBackingTypeCode = enumBackingType;
-    }
-
-    [AccessedThroughProperty (nameof (EnumBackingTypeCode))]
-    private readonly TypeCode _enumBackingTypeCode;
-
-    [AccessedThroughProperty (nameof (GeneratedTypeName))]
-    private string? _generatedTypeName;
-
-    [AccessedThroughProperty (nameof (GeneratedTypeNamespace))]
-    private string? _generatedTypeNamespace;
-
-    private BitVector32 _discoveredProperties = new (0);
-
-    /// <summary>The name of the extension class.</summary>
-    public string? GeneratedTypeName
-    {
-        get => _generatedTypeName ?? string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-        set => _generatedTypeName = value ?? string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-    }
-
-    /// <summary>The namespace for the extension class.</summary>
-    /// <remarks>
-    ///     Value is not validated by the set accessor.<br/>
-    ///     Get accessor will never return null and is thus marked [NotNull] for static analysis, even though the property is
-    ///     declared as a nullable <see langword="string?"/>.<br/>If the backing field for this property is null, the get
-    ///     accessor will return <see cref="TargetTypeNamespace"/> instead.
-    /// </remarks>
-    public string? GeneratedTypeNamespace
-    {
-        get => _generatedTypeNamespace ?? TargetTypeNamespace;
-        set => _generatedTypeNamespace = value ?? TargetTypeNamespace;
-    }
-
-    /// <inheritdoc/>
-    public string TargetTypeFullName => string.Concat (TargetTypeNamespace, ".", TargetTypeName);
-
-    /// <inheritdoc/>
-    public Accessibility Accessibility
-    {
-        get;
-        [UsedImplicitly]
-        internal set;
-    } = Accessibility.Public;
-
-    /// <inheritdoc/>
-    public TypeKind TypeKind => TypeKind.Class;
-
-    /// <inheritdoc/>
-    public bool IsRecord => false;
-
-    /// <inheritdoc/>
-    public bool IsClass => true;
-
-    /// <inheritdoc/>
-    public bool IsStruct => false;
-
-    /// <inheritdoc/>
-    public bool IsByRefLike => false;
-
-    /// <inheritdoc/>
-    public bool IsSealed => false;
-
-    /// <inheritdoc/>
-    public bool IsAbstract => false;
-
-    /// <inheritdoc/>
-    public bool IsEnum => false;
-
-    /// <inheritdoc/>
-    public bool IsStatic => true;
-
-    /// <inheritdoc/>
-    public bool IncludeInterface => false;
-
-    public string GeneratedTypeFullName => $"{GeneratedTypeNamespace}.{GeneratedTypeName}";
-
-    /// <summary>Whether to generate the extension class as partial (Default: true)</summary>
-    public bool IsPartial => true;
-
-    /// <summary>The fully-qualified namespace of the source enum type.</summary>
-    public string TargetTypeNamespace
-    {
-        get;
-        [UsedImplicitly]
-        set;
-    }
-
-    /// <summary>The UNQUALIFIED name of the source enum type.</summary>
-    public string TargetTypeName
-    {
-        get;
-        [UsedImplicitly]
-        set;
-    }
-
-    /// <summary>
-    ///     The backing type for the enum.
-    /// </summary>
-    /// <remarks>For simplicity and formality, only System.Int32 and System.UInt32 are supported at this time.</remarks>
-    public TypeCode EnumBackingTypeCode
-    {
-        get => _enumBackingTypeCode;
-        init
-        {
-            if (value is not TypeCode.Int32 and not TypeCode.UInt32)
-            {
-                throw new NotSupportedException ("Only System.Int32 and System.UInt32 are supported at this time.");
-            }
-
-            _enumBackingTypeCode = value;
-        }
-    }
-
-    /// <summary>
-    ///     Whether a fast alternative to the built-in Enum.HasFlag method will be generated (Default: false)
-    /// </summary>
-    public bool GenerateFastHasFlags { [UsedImplicitly] get; set; }
-
-    /// <summary>Whether a switch-based IsDefined replacement will be generated (Default: true)</summary>
-    public bool GenerateFastIsDefined { [UsedImplicitly]get; set; } = true;
-
-    internal ImmutableHashSet<int>? _intMembers;
-    internal ImmutableHashSet<uint>? _uIntMembers;
-
-    /// <summary>
-    ///     Fully-qualified name of the extension class
-    /// </summary>
-    internal string FullyQualifiedClassName => $"{GeneratedTypeNamespace}.{GeneratedTypeName}";
-
-    /// <summary>
-    ///     Whether a Flags was found on the enum type.
-    /// </summary>
-    internal bool HasFlagsAttribute {[UsedImplicitly] get; set; }
-
-    private static readonly SymbolDisplayFormat FullyQualifiedSymbolDisplayFormatWithoutGlobal =
-        SymbolDisplayFormat.FullyQualifiedFormat
-                           .WithGlobalNamespaceStyle (
-                                                      SymbolDisplayGlobalNamespaceStyle.Omitted);
-
-
-    internal bool TryConfigure (INamedTypeSymbol enumSymbol, CancellationToken cancellationToken)
-    {
-        using var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken);
-        cts.Token.ThrowIfCancellationRequested ();
-
-        ImmutableArray<AttributeData> attributes = enumSymbol.GetAttributes ();
-
-        // This is theoretically impossible, but guarding just in case and canceling if it does happen.
-        if (attributes.Length == 0)
-        {
-            cts.Cancel (true);
-
-            return false;
-        }
-
-        // Check all attributes provided for anything interesting.
-        // Attributes can be in any order, so just check them all and adjust at the end if necessary.
-        // Note that we do not perform as strict validation on actual usage of the attribute, at this stage,
-        // because the analyzer should have already thrown errors for invalid uses like global namespace
-        // or unsupported enum underlying types.
-        foreach (AttributeData attr in attributes)
-        {
-            cts.Token.ThrowIfCancellationRequested ();
-            string? attributeFullyQualifiedName = attr.AttributeClass?.ToDisplayString (FullyQualifiedSymbolDisplayFormatWithoutGlobal);
-
-            // Skip if null or not possibly an attribute we care about
-            if (attributeFullyQualifiedName is null or not { Length: >= 5 })
-            {
-                continue;
-            }
-
-            switch (attributeFullyQualifiedName)
-            {
-                // For Flags enums
-                case Strings.DotnetNames.Attributes.Flags:
-                {
-                    HasFlagsAttribute = true;
-                }
-
-                    continue;
-
-                // For the attribute that started this whole thing
-                case GeneratorAttributeFullyQualifiedName:
-
-                {
-                    // If we can't successfully complete this method,
-                    // something is wrong enough that we may as well just stop now.
-                    if (!TryConfigure (attr, cts.Token))
-                    {
-                        if (cts.Token.CanBeCanceled)
-                        {
-                            cts.Cancel ();
-                        }
-
-                        return false;
-                    }
-                }
-
-                    continue;
-            }
-        }
-
-        // Now get the members, if we know we'll need them.
-        if (GenerateFastIsDefined || GenerateFastHasFlags)
-        {
-            if (EnumBackingTypeCode == TypeCode.Int32)
-            {
-                PopulateIntMembersHashSet (enumSymbol);
-            }
-            else if (EnumBackingTypeCode == TypeCode.UInt32)
-            {
-                PopulateUIntMembersHashSet (enumSymbol);
-            }
-        }
-
-        return true;
-    }
-
-    private void PopulateIntMembersHashSet (INamedTypeSymbol enumSymbol)
-    {
-        ImmutableArray<ISymbol> enumMembers = enumSymbol.GetMembers ();
-        IEnumerable<IFieldSymbol> fieldSymbols = enumMembers.OfType<IFieldSymbol> ();
-        _intMembers = fieldSymbols.Select (static m => m.HasConstantValue ? (int)m.ConstantValue : 0).ToImmutableHashSet ();
-    }
-    private void PopulateUIntMembersHashSet (INamedTypeSymbol enumSymbol)
-    {
-        _uIntMembers = enumSymbol.GetMembers ().OfType<IFieldSymbol> ().Select (static m => (uint)m.ConstantValue).ToImmutableHashSet ();
-    }
-
-    private bool HasExplicitFastHasFlags
-    {
-        [UsedImplicitly]get => _discoveredProperties [ExplicitFastHasFlagsMask];
-        set => _discoveredProperties [ExplicitFastHasFlagsMask] = value;
-    }
-
-    private bool HasExplicitFastIsDefined
-    {
-        [UsedImplicitly]get => _discoveredProperties [ExplicitFastIsDefinedMask];
-        set => _discoveredProperties [ExplicitFastIsDefinedMask] = value;
-    }
-
-    private bool HasExplicitTypeName
-    {
-        get => _discoveredProperties [ExplicitNameMask];
-        set => _discoveredProperties [ExplicitNameMask] = value;
-    }
-
-    private bool HasExplicitTypeNamespace
-    {
-        get => _discoveredProperties [ExplicitNamespaceMask];
-        set => _discoveredProperties [ExplicitNamespaceMask] = value;
-    }
-
-    [MemberNotNullWhen (true, nameof (_generatedTypeName), nameof (_generatedTypeNamespace))]
-    private bool TryConfigure (AttributeData attr, CancellationToken cancellationToken)
-    {
-        using var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken);
-        cts.Token.ThrowIfCancellationRequested ();
-
-        if (attr is not { NamedArguments.Length: > 0 })
-        {
-            // Just a naked attribute, so configure with appropriate defaults.
-            GeneratedTypeNamespace = TargetTypeNamespace;
-            GeneratedTypeName = string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-
-            return true;
-        }
-
-        cts.Token.ThrowIfCancellationRequested ();
-
-        foreach (KeyValuePair<string, TypedConstant> kvp in attr.NamedArguments)
-        {
-            string? propName = kvp.Key;
-            TypedConstant propValue = kvp.Value;
-
-            cts.Token.ThrowIfCancellationRequested ();
-
-            // For every property name and value pair, set associated metadata
-            // property, if understood.
-            switch (propName, propValue)
-            {
-                // Null or empty string doesn't make sense, so skip if it happens.
-                case (null, _):
-                case ("", _):
-                    continue;
-
-                // ClassName is specified, not explicitly null, and at least 1 character long.
-                case (AttributeProperties.TypeNamePropertyName, { IsNull: false, Value: string { Length: > 1 } classNameProvidedValue }):
-                    if (string.IsNullOrWhiteSpace (classNameProvidedValue))
-                    {
-                        return false;
-                    }
-
-                    GeneratedTypeName = classNameProvidedValue;
-                    HasExplicitTypeName = true;
-
-                    continue;
-
-                // Class namespace is specified, not explicitly null, and at least 1 character long.
-                case (AttributeProperties.TypeNamespacePropertyName, { IsNull: false, Value: string { Length: > 1 } classNamespaceProvidedValue }):
-
-                    if (string.IsNullOrWhiteSpace (classNamespaceProvidedValue))
-                    {
-                        return false;
-                    }
-
-                    GeneratedTypeNamespace = classNamespaceProvidedValue;
-                    HasExplicitTypeNamespace = true;
-
-                    continue;
-
-                // FastHasFlags is specified
-                case (AttributeProperties.FastHasFlagsPropertyName, { IsNull: false } fastHasFlagsConstant):
-                    GenerateFastHasFlags = fastHasFlagsConstant.Value is true;
-                    HasExplicitFastHasFlags = true;
-
-                    continue;
-
-                // FastIsDefined is specified
-                case (AttributeProperties.FastIsDefinedPropertyName, { IsNull: false } fastIsDefinedConstant):
-                    GenerateFastIsDefined = fastIsDefinedConstant.Value is true;
-                    HasExplicitFastIsDefined = true;
-
-                    continue;
-            }
-        }
-
-        // The rest is simple enough it's not really worth worrying about cancellation, so don't bother from here on...
-
-        // Configure anything that wasn't specified that doesn't have an implicitly safe default
-        if (!HasExplicitTypeName || _generatedTypeName is null)
-        {
-            _generatedTypeName = string.Concat (TargetTypeName, Strings.DefaultTypeNameSuffix);
-        }
-
-        if (!HasExplicitTypeNamespace || _generatedTypeNamespace is null)
-        {
-            _generatedTypeNamespace = TargetTypeNamespace;
-        }
-
-        if (!HasFlagsAttribute)
-        {
-            GenerateFastHasFlags = false;
-        }
-
-        return true;
-    }
-
-    private static class AttributeProperties
-    {
-        internal const string FastHasFlagsPropertyName = nameof (GenerateEnumExtensionMethodsAttribute.FastHasFlags);
-        internal const string FastIsDefinedPropertyName = nameof (GenerateEnumExtensionMethodsAttribute.FastIsDefined);
-        internal const string TypeNamePropertyName = nameof (GenerateEnumExtensionMethodsAttribute.ClassName);
-        internal const string TypeNamespacePropertyName = nameof (GenerateEnumExtensionMethodsAttribute.ClassNamespace);
-    }
-}

+ 0 - 452
Analyzers/Terminal.Gui.Analyzers.Internal/Generators/EnumExtensions/EnumExtensionMethodsIncrementalGenerator.cs

@@ -1,452 +0,0 @@
-using System;
-using System.Diagnostics.CodeAnalysis;
-using System.Text;
-using System.Threading;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-using Terminal.Gui.Analyzers.Internal.Attributes;
-using Terminal.Gui.Analyzers.Internal.Constants;
-
-namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
-
-/// <summary>
-///     Incremental code generator for enums decorated with <see cref="GenerateEnumExtensionMethodsAttribute"/>.
-/// </summary>
-[SuppressMessage ("CodeQuality", "IDE0079", Justification = "Suppressions here are intentional and the warnings they disable are just noise.")]
-[Generator (LanguageNames.CSharp)]
-public sealed class EnumExtensionMethodsIncrementalGenerator : IIncrementalGenerator
-{
-    private const string ExtensionsForEnumTypeAttributeFullyQualifiedName = $"{Strings.AnalyzersAttributesNamespace}.{ExtensionsForEnumTypeAttributeName}";
-    private const string ExtensionsForEnumTypeAttributeName = "ExtensionsForEnumTypeAttribute";
-    private const string GeneratorAttributeFullyQualifiedName = $"{Strings.AnalyzersAttributesNamespace}.{GeneratorAttributeName}";
-    private const string GeneratorAttributeName = nameof (GenerateEnumExtensionMethodsAttribute);
-
-    /// <summary>Fully-qualified symbol name format without the "global::" prefix.</summary>
-    private static readonly SymbolDisplayFormat _fullyQualifiedSymbolDisplayFormatWithoutGlobal =
-        SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle (SymbolDisplayGlobalNamespaceStyle.Omitted);
-
-    /// <inheritdoc/>
-    /// <remarks>
-    ///     <para>
-    ///         Basically, this method is called once by the compiler, and is responsible for wiring up
-    ///         everything important about how source generation works.
-    ///     </para>
-    ///     <para>
-    ///         See in-line comments for specifics of what's going on.
-    ///     </para>
-    ///     <para>
-    ///         Note that <paramref name="context"/> is everything in the compilation,
-    ///         except for code generated by this generator or generators which have not yet executed.<br/>
-    ///         The methods registered to perform generation get called on-demand by the host (the IDE,
-    ///         compiler, etc), sometimes as often as every single keystroke.
-    ///     </para>
-    /// </remarks>
-    public void Initialize (IncrementalGeneratorInitializationContext context)
-    {
-        // Write out namespaces that may be used later. Harmless to declare them now and will avoid
-        // additional processing and potential omissions later on.
-        context.RegisterPostInitializationOutput (GenerateDummyNamespaces);
-
-        // This executes the delegate given to it immediately after Roslyn gets all set up.
-        // 
-        // As written, this will result in the GenerateEnumExtensionMethodsAttribute code
-        // being added to the environment, so that it can be used without having to actually
-        // be declared explicitly in the target project.
-        // This is important, as it guarantees the type will exist and also guarantees it is
-        // defined exactly as the generator expects it to be defined.
-        context.RegisterPostInitializationOutput (GenerateAttributeSources);
-
-        // Next up, we define our pipeline.
-        // To do so, we create one or more IncrementalValuesProvider<T> objects, each of which
-        // defines on stage of analysis or generation as needed.
-        //
-        // Critically, these must be as fast and efficient as reasonably possible because,
-        // once the pipeline is registered, this stuff can get called A LOT.
-        //
-        // Note that declaring these doesn't really do much of anything unless they are given to the
-        // RegisterSourceOutput method at the end of this method.
-        //
-        // The delegates are not actually evaluated right here. That is triggered by changes being
-        // made to the source code.
-
-        // This provider grabs attributes that pass our filter and then creates lightweight
-        // metadata objects to be used in the final code generation step.
-        // It also preemptively removes any nulls from the collection before handing things off
-        // to the code generation logic.
-        IncrementalValuesProvider<EnumExtensionMethodsGenerationInfo?> enumGenerationInfos =
-            context
-                .SyntaxProvider
-
-                // This method is a highly-optimized (and highly-recommended) filter on the incoming
-                // code elements that only bothers to present code that is annotated with the specified
-                // attribute, by its fully-qualified name, as a string, which is the first parameter.
-                //
-                // Two delegates are passed to it, in the second and third parameters.
-                //
-                // The second parameter is a filter predicate taking each SyntaxNode that passes the
-                // name filter above, and then refines that result.
-                //
-                // It is critical that the filter predicate be as simple and fast as possible, as it
-                // will be called a ton, triggered by keystrokes or anything else that modifies code
-                // in or even related to (in either direction) the pre-filtered code.
-                // It should collect metadata only and not actually generate any code.
-                // It must return a boolean indicating whether the supplied SyntaxNode should be
-                // given to the transform delegate at all.
-                // 
-                // The third parameter is the "transform" delegate.
-                // That one only runs when code is changed that passed both the attribute name filter
-                // and the filter predicate in the second parameter.
-                // It will be called for everything that passes both of those, so it can still happen
-                // a lot, but should at least be pretty close.
-                // In our case, it should be 100% accurate, since we're using OUR attribute, which can
-                // only be applied to enum types in the first place.
-                //
-                // That delegate is responsible for creating some sort of lightweight data structure
-                // which can later be used to generate the actual source code for output.
-                //
-                // THIS DELEGATE DOES NOT GENERATE CODE!
-                // However, it does need to return instances of the metadata class in use that are either
-                // null or complete enough to generate meaningful code from, later on.
-                //
-                // We then filter out any that were null with the .Where call at the end, so that we don't
-                // know or care about them when it's time to generate code.
-                //
-                // While the syntax of that .Where call is the same as LINQ, that is actually a
-                // highly-optimized implementation specifically for this use.
-                .ForAttributeWithMetadataName (
-                                               GeneratorAttributeFullyQualifiedName,
-                                               IsPotentiallyInterestingDeclaration,
-                                               GatherMetadataForCodeGeneration
-                                              )
-                .WithTrackingName ("CollectEnumMetadata")
-                .Where (static eInfo => eInfo is { });
-
-        // Finally, we wire up any IncrementalValuesProvider<T> instances above to the appropriate
-        // delegate that takes the SourceProductionContext that is current at run-time and an instance of
-        // our metadata type and takes appropriate action.
-        // Typically that means generating code from that metadata and adding it to the compilation via
-        // the received context object.
-        //
-        // As with everything else , the delegate will be invoked once for each item that passed
-        // all of the filters above, so we get to write that method from the perspective of a single
-        // enum type declaration.
-
-        context.RegisterSourceOutput (enumGenerationInfos, GenerateSourceFromGenerationInfo);
-    }
-
-    private static EnumExtensionMethodsGenerationInfo? GatherMetadataForCodeGeneration (
-        GeneratorAttributeSyntaxContext context,
-        CancellationToken cancellationToken
-    )
-    {
-        var cts = CancellationTokenSource.CreateLinkedTokenSource (cancellationToken);
-        cancellationToken.ThrowIfCancellationRequested ();
-
-        // If it's not an enum symbol, we don't care.
-        // EnumUnderlyingType is null for non-enums, so this validates it's an enum declaration.
-        if (context.TargetSymbol is not INamedTypeSymbol { EnumUnderlyingType: { } } namedSymbol)
-        {
-            return null;
-        }
-
-        INamespaceSymbol? enumNamespaceSymbol = namedSymbol.ContainingNamespace;
-
-        if (enumNamespaceSymbol is null or { IsGlobalNamespace: true })
-        {
-            // Explicitly choosing not to support enums in the global namespace.
-            // The corresponding analyzer will report this.
-            return null;
-        }
-
-        string enumName = namedSymbol.Name;
-
-        string enumNamespace = enumNamespaceSymbol.ToDisplayString (_fullyQualifiedSymbolDisplayFormatWithoutGlobal);
-
-        TypeCode enumTypeCode = namedSymbol.EnumUnderlyingType.Name switch
-                                {
-                                    "UInt32" => TypeCode.UInt32,
-                                    "Int32" => TypeCode.Int32,
-                                    _ => TypeCode.Empty
-                                };
-
-        EnumExtensionMethodsGenerationInfo info = new (
-                                                       enumNamespace,
-                                                       enumName,
-                                                       enumTypeCode
-                                                      );
-
-        if (!info.TryConfigure (namedSymbol, cts.Token))
-        {
-            cts.Cancel ();
-            cts.Token.ThrowIfCancellationRequested ();
-        }
-
-        return info;
-    }
-
-
-    private static void GenerateAttributeSources (IncrementalGeneratorPostInitializationContext postInitializationContext)
-    {
-        postInitializationContext
-            .AddSource (
-                        $"{nameof (IExtensionsForEnumTypeAttributes)}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           // ReSharper disable All
-                                           {{Strings.Templates.AutoGeneratedCommentBlock}}
-                                           using System;
-
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>
-                                           ///     Interface to simplify general enumeration of constructed generic types for
-                                           ///     <see cref="ExtensionsForEnumTypeAttribute{TEnum}"/>
-                                           /// </summary>
-                                           {{Strings.Templates.AttributesForGeneratedInterfaces}}
-                                           public interface IExtensionsForEnumTypeAttributes
-                                           {
-                                               System.Type EnumType { get; }
-                                           }
-
-                                           """,
-                                         Encoding.UTF8));
-
-        postInitializationContext
-            .AddSource (
-                        $"{nameof (AssemblyExtendedEnumTypeAttribute)}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           // ReSharper disable All
-                                           #nullable enable
-                                           {{Strings.Templates.AutoGeneratedCommentBlock}}
-
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>Assembly attribute declaring a known pairing of an <see langword="enum" /> type to an extension class.</summary>
-                                           /// <remarks>This attribute should only be written by internal source generators for Terminal.Gui. No other usage of any kind is supported.</remarks>
-                                           {{Strings.Templates.AttributesForGeneratedTypes}}
-                                           [System.AttributeUsageAttribute(System.AttributeTargets.Assembly, AllowMultiple = true)]
-                                           public sealed class {{nameof(AssemblyExtendedEnumTypeAttribute)}} : System.Attribute
-                                           {
-                                               /// <summary>Creates a new instance of <see cref="AssemblyExtendedEnumTypeAttribute" /> from the provided parameters.</summary>
-                                               /// <param name="enumType">The <see cref="System.Type" /> of an <see langword="enum" /> decorated with a <see cref="GenerateEnumExtensionMethodsAttribute" />.</param>
-                                               /// <param name="extensionClass">The <see cref="System.Type" /> of the <see langword="class" /> decorated with an <see cref="ExtensionsForEnumTypeAttribute{TEnum}" /> referring to the same type as <paramref name="enumType" />.</param>
-                                               public AssemblyExtendedEnumTypeAttribute (System.Type enumType, System.Type extensionClass)
-                                               {
-                                                   EnumType = enumType;
-                                                   ExtensionClass = extensionClass;
-                                               }
-                                               /// <summary>An <see langword="enum" /> type that has been extended by Terminal.Gui source generators.</summary>
-                                               public System.Type EnumType { get; init; }
-                                               /// <summary>A class containing extension methods for <see cref="EnumType"/>.</summary>
-                                               public System.Type ExtensionClass { get; init; }
-                                               /// <inheritdoc />
-                                               public override string ToString () => $"{EnumType.Name},{ExtensionClass.Name}";
-                                           }
-
-                                           """,
-                                         Encoding.UTF8));
-
-        postInitializationContext
-            .AddSource (
-                        $"{GeneratorAttributeFullyQualifiedName}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           {{Strings.Templates.StandardHeader}}
-                                           
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>
-                                           ///     Used to enable source generation of a common set of extension methods for enum types.
-                                           /// </summary>
-                                           {{Strings.Templates.AttributesForGeneratedTypes}}
-                                           [{{Strings.DotnetNames.Types.AttributeUsageAttribute}} ({{Strings.DotnetNames.Types.AttributeTargets}}.Enum)]
-                                           public sealed class {{GeneratorAttributeName}} : {{Strings.DotnetNames.Types.Attribute}}
-                                           {
-                                               /// <summary>
-                                               ///     The name of the generated static class.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     If unspecified, null, empty, or only whitespace, defaults to the name of the enum plus "Extensions".<br/>
-                                               ///     No other validation is performed, so illegal values will simply result in compiler errors.
-                                               ///     <para>
-                                               ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public string? ClassName { get; set; }
-                                           
-                                               /// <summary>
-                                               ///     The namespace in which to place the generated static class containing the extension methods.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     If unspecified, null, empty, or only whitespace, defaults to the namespace of the enum.<br/>
-                                               ///     No other validation is performed, so illegal values will simply result in compiler errors.
-                                               ///     <para>
-                                               ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public string? ClassNamespace { get; set; }
-                                           
-                                               /// <summary>
-                                               ///     Whether to generate a fast, zero-allocation, non-boxing, and reflection-free alternative to the built-in
-                                               ///     <see cref="Enum.HasFlag"/> method.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     <para>
-                                               ///         Default: false
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         If the enum is not decorated with <see cref="Flags"/>, this option has no effect.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-                                               ///         with the same value will be skipped.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         Overloads taking the enum type itself as well as the underlying type of the enum will be generated, enabling
-                                               ///         avoidance of implicit or explicit cast overhead.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         Explicitly specifying a default value is unnecessary and will result in unnecessary processing.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public bool FastHasFlags { get; set; }
-                                           
-                                               /// <summary>
-                                               ///     Whether to generate a fast, zero-allocation, and reflection-free alternative to the built-in
-                                               ///     <see cref="Enum.IsDefined"/> method,
-                                               ///     using a switch expression as a hard-coded reverse mapping of numeric values to explicitly-named members.
-                                               /// </summary>
-                                               /// <remarks>
-                                               ///     <para>
-                                               ///         Default: true
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         If multiple members have the same value, the first member with that value will be used and subsequent members
-                                               ///         with the same value will be skipped.
-                                               ///     </para>
-                                               ///     <para>
-                                               ///         As with <see cref="Enum.IsDefined"/> the source generator only considers explicitly-named members.<br/>
-                                               ///         Generation of values which represent valid bitwise combinations of members of enums decorated with
-                                               ///         <see cref="Flags"/> is not affected by this property.
-                                               ///     </para>
-                                               /// </remarks>
-                                               public bool FastIsDefined { get; init; } = true;
-                                           
-                                               /// <summary>
-                                               ///     Gets a <see langword="bool"/> value indicating if this <see cref="GenerateEnumExtensionMethodsAttribute"/> instance
-                                               ///     contains default values only. See <see href="#remarks">remarks</see> of this method or documentation on properties of this type for details.
-                                               /// </summary>
-                                               /// <returns>
-                                               ///     A <see langword="bool"/> value indicating if all property values are default for this
-                                               ///     <see cref="GenerateEnumExtensionMethodsAttribute"/> instance.
-                                               /// </returns>
-                                               /// <remarks>
-                                               ///     Default values that will result in a <see langword="true"/> return value are:<br/>
-                                               ///     <see cref="FastIsDefined"/> &amp;&amp; !<see cref="FastHasFlags"/> &amp;&amp; <see cref="ClassName"/>
-                                               ///     <see langword="is"/> <see langword="null"/> &amp;&amp; <see cref="ClassNamespace"/> <see langword="is"/>
-                                               ///     <see langword="null"/>
-                                               /// </remarks>
-                                               public override bool IsDefaultAttribute ()
-                                               {
-                                                   return FastIsDefined
-                                                          && !FastHasFlags
-                                                          && ClassName is null
-                                                          && ClassNamespace is null;
-                                               }
-                                           }
-                                           
-                                           """,
-                                         Encoding.UTF8));
-
-        postInitializationContext
-            .AddSource (
-                        $"{ExtensionsForEnumTypeAttributeFullyQualifiedName}.g.cs",
-                        SourceText.From (
-                                         $$"""
-                                           // ReSharper disable RedundantNameQualifier
-                                           // ReSharper disable RedundantNullableDirective
-                                           // ReSharper disable UnusedType.Global
-                                           {{Strings.Templates.AutoGeneratedCommentBlock}}
-                                           #nullable enable
-
-                                           namespace {{Strings.AnalyzersAttributesNamespace}};
-
-                                           /// <summary>
-                                           ///     Attribute written by the source generator for enum extension classes, for easier analysis and reflection.
-                                           /// </summary>
-                                           /// <remarks>
-                                           ///     Properties are just convenient shortcuts to properties of <typeparamref name="TEnum"/>.
-                                           /// </remarks>
-                                           {{Strings.Templates.AttributesForGeneratedTypes}}
-                                           [System.AttributeUsageAttribute (System.AttributeTargets.Class | System.AttributeTargets.Interface)]
-                                           public sealed class {{ExtensionsForEnumTypeAttributeName}}<TEnum>: System.Attribute, IExtensionsForEnumTypeAttributes where TEnum : struct, Enum
-                                           {
-                                               /// <summary>
-                                               ///     The namespace-qualified name of <typeparamref name="TEnum"/>.
-                                               /// </summary>
-                                               public string EnumFullName => EnumType.FullName!;
-                                           
-                                               /// <summary>
-                                               ///     The unqualified name of <typeparamref name="TEnum"/>.
-                                               /// </summary>
-                                               public string EnumName => EnumType.Name;
-                                           
-                                               /// <summary>
-                                               ///     The namespace containing <typeparamref name="TEnum"/>.
-                                               /// </summary>
-                                               public string EnumNamespace => EnumType.Namespace!;
-                                           
-                                               /// <summary>
-                                               ///     The <see cref="Type"/> given by <see langword="typeof"/>(<typeparamref name="TEnum"/>).
-                                               /// </summary>
-                                               public Type EnumType => typeof (TEnum);
-                                           }
-                                           
-                                           """,
-                                         Encoding.UTF8));
-    }
-
-    [SuppressMessage ("Roslynator", "RCS1267", Justification = "Intentionally used so that Spans are used.")]
-    private static void GenerateDummyNamespaces (IncrementalGeneratorPostInitializationContext postInitializeContext)
-    {
-        postInitializeContext.AddSource (
-                                         string.Concat (Strings.InternalAnalyzersNamespace, "Namespaces.g.cs"),
-                                         SourceText.From (Strings.Templates.DummyNamespaceDeclarations, Encoding.UTF8));
-    }
-
-    private static void GenerateSourceFromGenerationInfo (SourceProductionContext context, EnumExtensionMethodsGenerationInfo? enumInfo)
-    {
-        // Just in case we still made it this far with a null...
-        if (enumInfo is not { })
-        {
-            return;
-        }
-
-        CodeWriter writer = new (enumInfo);
-
-        context.AddSource ($"{enumInfo.FullyQualifiedClassName}.g.cs", writer.GenerateSourceText ());
-    }
-
-    /// <summary>
-    ///     Returns true if <paramref name="syntaxNode"/> is an EnumDeclarationSyntax
-    ///     whose parent is a NamespaceDeclarationSyntax, FileScopedNamespaceDeclarationSyntax, or a
-    ///     (Class|Struct)DeclarationSyntax.<br/>
-    ///     Additional filtering is performed in later stages.
-    /// </summary>
-    private static bool IsPotentiallyInterestingDeclaration (SyntaxNode syntaxNode, CancellationToken cancellationToken)
-    {
-        cancellationToken.ThrowIfCancellationRequested ();
-
-        return syntaxNode is
-               {
-                   RawKind: 8858, //(int)SyntaxKind.EnumDeclaration,
-                   Parent.RawKind: 8845 //(int)SyntaxKind.FileScopedNamespaceDeclaration
-                                   or 8842 //(int)SyntaxKind.NamespaceDeclaration
-                                   or 8855 //(int)SyntaxKind.ClassDeclaration
-                                   or 8856 //(int)SyntaxKind.StructDeclaration
-                                   or 9068 //(int)SyntaxKind.RecordStructDeclaration
-                                   or 9063 //(int)SyntaxKind.RecordDeclaration
-               };
-    }
-}

+ 0 - 38
Analyzers/Terminal.Gui.Analyzers.Internal/IGeneratedTypeMetadata.cs

@@ -1,38 +0,0 @@
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-/// <summary>
-/// Interface for all generators to use for their metadata classes.
-/// </summary>
-/// <typeparam name="TSelf">The type implementing this interface.</typeparam>
-internal interface IGeneratedTypeMetadata<out TSelf> where TSelf : IGeneratedTypeMetadata<TSelf>
-{
-    [UsedImplicitly]
-    string GeneratedTypeNamespace { get; }
-    [UsedImplicitly]
-    string? GeneratedTypeName { get; }
-    [UsedImplicitly]
-    string GeneratedTypeFullName { get; }
-    [UsedImplicitly]
-    string TargetTypeNamespace { get; }
-    [UsedImplicitly]
-    string TargetTypeName { get; }
-    string TargetTypeFullName { get; }
-    [UsedImplicitly]
-    Accessibility Accessibility { get; }
-    TypeKind TypeKind { get; }
-    bool IsRecord { get; }
-    bool IsClass { get; }
-    bool IsStruct { get; }
-    [UsedImplicitly]
-    bool IsPartial { get; }
-    bool IsByRefLike { get; }
-    bool IsSealed { get; }
-    bool IsAbstract { get; }
-    bool IsEnum { get; }
-    bool IsStatic { get; }
-    [UsedImplicitly]
-    bool IncludeInterface { get; }
-}

+ 0 - 28
Analyzers/Terminal.Gui.Analyzers.Internal/IStandardCSharpCodeGenerator.cs

@@ -1,28 +0,0 @@
-using System.Text;
-using JetBrains.Annotations;
-using Microsoft.CodeAnalysis.Text;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-internal interface IStandardCSharpCodeGenerator<T> where T : IGeneratedTypeMetadata<T>
-{
-    /// <summary>
-    ///     Generates and returns the full source text corresponding to <see cref="Metadata"/>,
-    ///     in the requested <paramref name="encoding"/> or <see cref="Encoding.UTF8"/> if not provided.
-    /// </summary>
-    /// <param name="encoding">
-    ///     The <see cref="Encoding"/> of the generated source text or <see cref="Encoding.UTF8"/> if not
-    ///     provided.
-    /// </param>
-    /// <returns></returns>
-    [UsedImplicitly]
-    [SkipLocalsInit]
-    ref readonly SourceText GenerateSourceText (Encoding? encoding = null);
-
-    /// <summary>
-    ///     A type implementing <see cref="IGeneratedTypeMetadata{T}"/> which
-    ///     will be used for source generation.
-    /// </summary>
-    [UsedImplicitly]
-    T Metadata { get; set; }
-}

+ 0 - 71
Analyzers/Terminal.Gui.Analyzers.Internal/IndentedTextWriterExtensions.cs

@@ -1,71 +0,0 @@
-using System.CodeDom.Compiler;
-
-namespace Terminal.Gui.Analyzers.Internal;
-
-/// <summary>
-///     Just a simple set of extension methods to increment and decrement the indentation
-///     level of an <see cref="IndentedTextWriter"/> via push and pop terms, and to avoid having
-///     explicit values all over the place.
-/// </summary>
-public static class IndentedTextWriterExtensions
-{
-    /// <summary>
-    ///     Decrements <see cref="IndentedTextWriter.Indent"/> by 1, but only if it is greater than 0.
-    /// </summary>
-    /// <returns>
-    ///     The resulting indentation level of the <see cref="IndentedTextWriter"/>.
-    /// </returns>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static int Pop (this IndentedTextWriter w, string endScopeDelimiter = "}")
-    {
-        if (w.Indent > 0)
-        {
-            w.Indent--;
-            w.WriteLine (endScopeDelimiter);
-        }
-        return w.Indent;
-    }
-
-    /// <summary>
-    ///     Decrements <see cref="IndentedTextWriter.Indent"/> by 1 and then writes a closing curly brace.
-    /// </summary>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static void PopCurly (this IndentedTextWriter w, bool withSemicolon = false)
-    {
-        w.Indent--;
-
-        if (withSemicolon)
-        {
-            w.WriteLine ("};");
-        }
-        else
-        {
-            w.WriteLine ('}');
-        }
-    }
-
-    /// <summary>
-    ///     Increments <see cref="IndentedTextWriter.Indent"/> by 1, with optional parameters to customize the scope push.
-    /// </summary>
-    /// <param name="w">An instance of an <see cref="IndentedTextWriter"/>.</param>
-    /// <param name="declaration">
-    ///     The first line to be written before indenting and before the optional <paramref name="scopeDelimiter"/> line or
-    ///     null if not needed.
-    /// </param>
-    /// <param name="scopeDelimiter">
-    ///     An opening delimiter to write. Written before the indentation and after <paramref name="declaration"/> (if provided). Default is an opening curly brace.
-    /// </param>
-    /// <remarks>Calling with no parameters will write an opening curly brace and a line break at the current indentation and then increment.</remarks>
-    [MethodImpl (MethodImplOptions.AggressiveInlining)]
-    public static void Push (this IndentedTextWriter w, string? declaration = null, char scopeDelimiter = '{')
-    {
-        if (declaration is { Length: > 0 })
-        {
-            w.WriteLine (declaration);
-        }
-
-        w.WriteLine (scopeDelimiter);
-
-        w.Indent++;
-    }
-}

+ 0 - 8
Analyzers/Terminal.Gui.Analyzers.Internal/Properties/launchSettings.json

@@ -1,8 +0,0 @@
-{
-  "profiles": {
-    "InternalAnalyzers Debug": {
-      "commandName": "DebugRoslynComponent",
-      "targetProject": "..\\Terminal.Gui.Analyzers.Internal.Debugging\\Terminal.Gui.Analyzers.Internal.Debugging.csproj"
-    }
-  }
-}

+ 0 - 63
Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj

@@ -1,63 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk">
-    <PropertyGroup>
-        <!-- 
-        Do not remove netstandard2.0 from the TargetFramework.
-        Visual Studio requires that Analyzers/Generators target netstandard2.0 to work properly.
-        Also do not change this to TargetFrameworks without fully understanding the behavior change that implies.
-        -->
-        <TargetFramework>netstandard2.0</TargetFramework>
-    </PropertyGroup>
-
-    <PropertyGroup>
-        <OutputType>Library</OutputType>
-        <LangVersion>12</LangVersion>
-        <RootNamespace>Terminal.Gui.Analyzers.Internal</RootNamespace>
-        <ImplicitUsings>disable</ImplicitUsings>
-        <InvariantGlobalization>true</InvariantGlobalization>
-        <EnableNETAnalyzers>true</EnableNETAnalyzers>
-        <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
-        <CodeAnalysisIgnoreGeneratedCode>true</CodeAnalysisIgnoreGeneratedCode>
-        <ProduceReferenceAssembly>true</ProduceReferenceAssembly>
-        <EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
-        <GenerateDocumentationFile>True</GenerateDocumentationFile>
-        <IsRoslynComponent>true</IsRoslynComponent>
-        <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
-    </PropertyGroup>
-
-    <ItemGroup>
-      <ApiCompatExcludeAttributesFile Include="ApiCompatExcludedAttributes.txt" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <Compile Remove="Compatibility/*.cs" />
-    </ItemGroup>
-
-    <PropertyGroup>
-        <!-- Disabling some useless warnings caused by the netstandard2.0 target -->
-        <NoWarn>$(NoWarn);nullable;CA1067</NoWarn>
-    </PropertyGroup>
-    <ItemGroup>                           
-        <Compile Include="Compatibility/IEqualityOperators.cs" />             
-        <Compile Include="Compatibility/NumericExtensions.cs" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
-        <AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
-    </ItemGroup>
-
-    <ItemGroup>
-        <PackageReference Include="Meziantou.Polyfill" Version="1.0.38" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0" PrivateAssets="all" />
-        <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.0" PrivateAssets="all" />
-        <PackageReference Include="Roslynator.Analyzers" Version="4.12.2" PrivateAssets="all" />
-        <PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.2" PrivateAssets="all" />
-        <PackageReference Include="Roslynator.CSharp" Version="4.12.2" PrivateAssets="all" />
-        <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" PrivateAssets="all" />
-        <PackageReference Include="System.Runtime.Extensions" Version="4.3.1" PrivateAssets="all" />
-        <PackageReference Include="System.Runtime.Numerics" Version="4.3.0" PrivateAssets="all" />
-    </ItemGroup>
-</Project>

+ 0 - 4
Analyzers/Terminal.Gui.Analyzers.Internal/Terminal.Gui.Analyzers.Internal.csproj.DotSettings

@@ -1,4 +0,0 @@
-<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
-	<s:String x:Key="/Default/CodeInspection/CSharpLanguageProject/LanguageLevel/@EntryValue">CSharp120</s:String>
-	<s:String x:Key="/Default/CodeInspection/Highlighting/UsageCheckingInspectionLevel/@EntryValue">InternalsOnly</s:String>
-	<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=compatibility/@EntryIndexedValue">False</s:Boolean></wpf:ResourceDictionary>

+ 4 - 0
CommunityToolkitExample/CommunityToolkitExample.csproj

@@ -16,4 +16,8 @@
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
   </ItemGroup>
 
+  <ItemGroup>
+    <PackageReference Update="JetBrains.Annotations" Version="2024.2.0" />
+  </ItemGroup>
+
 </Project>

+ 1 - 1
Directory.Build.props

@@ -1,6 +1,6 @@
 <Project>
   <ItemGroup>
     <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="all" />
-    <PackageReference Include="JetBrains.ExternalAnnotations" Version="10.2.147" PrivateAssets="all" />
+    <PackageReference Include="JetBrains.ExternalAnnotations" Version="10.2.149" PrivateAssets="all" />
   </ItemGroup>
 </Project>

+ 3 - 0
Example/Example.csproj

@@ -13,4 +13,7 @@
   <ItemGroup>
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
   </ItemGroup>
+  <ItemGroup>
+    <PackageReference Update="JetBrains.Annotations" Version="2024.2.0" />
+  </ItemGroup>
 </Project>

+ 25 - 17
GitVersion.yml

@@ -1,10 +1,10 @@
 mode: ContinuousDeployment
 tag-prefix: '[vV]'
-continuous-delivery-fallback-tag: pre
+continuous-delivery-fallback-tag: dev
 branches:
   develop:
     mode: ContinuousDeployment
-    tag: pre
+    tag: dev
     regex: develop
     source-branches:
     - main
@@ -12,28 +12,36 @@ branches:
 
   v2_develop:
     mode: ContinuousDeployment
-    tag: pre
+    tag: dev
     regex: ^v2_develop?[/-]
-    is-release-branch: true
     tracks-release-branches: true
-    #is-source-branch-for: ['v2']
+    is-source-branch-for: ['v2_release']
     source-branches: []
 
-  main:
-    tag: rc
-    increment: Patch
-    source-branches:
-    - develop
-    - main
-  feature:
-    tag: useBranchName
-    regex: ^features?[/-]
-    source-branches:
-    - develop
-    - main
+  v2_release:
+    mode: ContinuousDeployment
+    tag: prealpha
+    regex: v2_release
+    is-release-branch: true
+    source-branches: ['v2_develop']
+
   pull-request:
+    mode: ContinuousDeployment
     tag: PullRequest.{BranchName}
     increment: Inherit
+    tag-number-pattern: '[/-](?<number>\d+)'
+    regex: ^(pull|pull\-requests|pr)[/-]
+    source-branches:
+    - develop
+    - main
+    - release
+    - v2_develop
+    - v2_release
+    - feature
+    - support
+    - hotfix
+    pre-release-weight: 30000
+
 ignore:
   sha: []
 

+ 10 - 0
NoSamples.slnf

@@ -0,0 +1,10 @@
+{
+  "solution": {
+    "path": "Terminal.sln",
+    "projects": [
+      "Terminal.Gui\\Terminal.Gui.csproj",
+      "UICatalog\\UICatalog.csproj",
+      "UnitTests\\UnitTests.csproj"
+    ]
+  }
+}

+ 4 - 1
ReactiveExample/ReactiveExample.csproj

@@ -12,10 +12,13 @@
   </PropertyGroup>
   <ItemGroup>
     <PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
-    <PackageReference Include="ReactiveUI" Version="20.0.1" />
+    <PackageReference Include="ReactiveUI" Version="20.1.1" />
     <PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
   </ItemGroup>
+  <ItemGroup>
+    <PackageReference Update="JetBrains.Annotations" Version="2024.2.0" />
+  </ItemGroup>
 </Project>

+ 10 - 0
Release.slnf

@@ -0,0 +1,10 @@
+{
+  "solution": {
+    "path": "Terminal.sln",
+    "projects": [
+      "Terminal.Gui\\Terminal.Gui.csproj",
+      "UICatalog\\UICatalog.csproj",
+      "UnitTests\\UnitTests.csproj"
+    ]
+  }
+}

+ 0 - 117
Scripts/Terminal.Gui.PowerShell.Analyzers.psd1

@@ -1,117 +0,0 @@
-#
-# Module manifest for module 'Terminal.Gui.Powershell.Analyzers'
-#
-# Generated by: Brandon Thetford (GitHub @dodexahedron)
-#
-# Generated on: 4/24/2024
-#
-
-@{
-
-# Script module or binary module file associated with this manifest.
-RootModule = ''
-
-# Version number of this module.
-ModuleVersion = '1.0.0'
-
-# Supported PSEditions
-CompatiblePSEditions = @('Core')
-
-# ID used to uniquely identify this module
-GUID = '3e85001d-6539-4cf1-b71c-ec9e983f7fc8'
-
-# Author of this module
-Author = 'Brandon Thetford (GitHub @dodexahedron)'
-
-# Company or vendor of this module
-CompanyName = 'The Terminal.Gui Project'
-
-# Copyright statement for this module
-Copyright = '(c) Brandon Thetford (GitHub @dodexahedron). Provided to the Terminal.Gui project and you under the terms of the MIT License.'
-
-# Description of the functionality provided by this module
-Description = 'Operations involving Terminal.Gui analyzer projects, fur use during development of Terminal.Gui'
-
-# Minimum version of the PowerShell engine required by this module
-PowerShellVersion = '7.4.0'
-
-# Name of the PowerShell host required by this module
-PowerShellHostName = 'ConsoleHost'
-
-# Minimum version of the PowerShell host required by this module
-# PowerShellHostVersion = ''
-
-# Processor architecture (None, X86, Amd64) required by this module
-ProcessorArchitecture = ''
-
-# Modules that must be imported into the global environment prior to importing this module
-RequiredModules = @('Microsoft.PowerShell.Management','Microsoft.PowerShell.Utility','./Terminal.Gui.PowerShell.Core.psd1')
-
-# Assemblies that must be loaded prior to importing this module
-# RequiredAssemblies = @()
-
-# Script files (.ps1) that are run in the caller's environment prior to importing this module.
-# ScriptsToProcess = @()
-
-# Type files (.ps1xml) to be loaded when importing this module
-# TypesToProcess = @()
-
-# Format files (.ps1xml) to be loaded when importing this module
-# FormatsToProcess = @()
-
-# Modules to import as nested modules.
-NestedModules = @('./Terminal.Gui.PowerShell.Analyzers.psm1')
-
-# Functions to export from this module.
-FunctionsToExport = @('Build-Analyzers')
-
-# Cmdlets to export from this module.
-CmdletsToExport = @()
-
-# Variables to export from this module
-VariablesToExport = @()
-
-# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
-AliasesToExport = @()
-
-# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
-PrivateData = @{
-
-    PSData = @{
-
-        # Tags applied to this module. These help with module discovery in online galleries.
-        # Tags = @()
-
-        # A URL to the license for this module.
-        LicenseUri = 'https://github.com/gui-cs/Terminal.Gui/Scripts/COPYRIGHT'
-
-        # A URL to the main website for this project.
-        ProjectUri = 'https://github.com/gui-cs/Terminal.Gui'
-
-        # A URL to an icon representing this module.
-        # IconUri = ''
-
-        # ReleaseNotes of this module
-        # ReleaseNotes = ''
-
-        # Prerelease string of this module
-        # Prerelease = ''
-
-        # Flag to indicate whether the module requires explicit user acceptance for install/update/save
-        # RequireLicenseAcceptance = $false
-
-        # External dependent modules of this module
-        # ExternalModuleDependencies = @()
-
-    } # End of PSData hashtable
-
-} # End of PrivateData hashtable
-
-# HelpInfo URI of this module
-# HelpInfoURI = ''
-
-# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
-# DefaultCommandPrefix = ''
-
-}
-

+ 0 - 96
Scripts/Terminal.Gui.PowerShell.Analyzers.psm1

@@ -1,96 +0,0 @@
-<#
-  .SYNOPSIS
-  Builds all analyzer projects in Debug and Release configurations.
-  .DESCRIPTION
-  Uses dotnet build to build all analyzer projects, with optional behavior changes via switch parameters.
-  .PARAMETER AutoClose
-  Automatically close running Visual Studio processes which have the Terminal.sln solution loaded, before taking any other actions.
-  .PARAMETER AutoLaunch
-  Automatically start a new Visual Studio process and load the solution after completion.
-  .PARAMETER Force
-  Carry out operations unconditionally and do not prompt for confirmation.
-  .PARAMETER NoClean
-  Do not delete the bin and obj folders before building the analyzers. Usually best not to use this, but can speed up the builds slightly.
-  .PARAMETER Quiet
-  Write less text output to the terminal.
-  .INPUTS
-  None
-  .OUTPUTS
-  None
-#>
-Function Build-Analyzers {
-  [CmdletBinding()]
-  param(
-    [Parameter(Mandatory=$false, HelpMessage="Automatically close running Visual Studio processes which have the Terminal.sln solution loaded, before taking any other actions.")]
-    [switch]$AutoClose,
-    [Parameter(Mandatory=$false, HelpMessage="Automatically start a new Visual Studio process and load the solution after completion.")]
-    [switch]$AutoLaunch,
-    [Parameter(Mandatory=$false, HelpMessage="Carry out operations unconditionally and do not prompt for confirmation.")]
-    [switch]$Force,
-    [Parameter(Mandatory=$false, HelpMessage="Do not delete the bin and obj folders before building the analyzers.")]
-    [switch]$NoClean,
-    [Parameter(Mandatory=$false, HelpMessage="Write less text output to the terminal.")]
-    [switch]$Quiet
-  )
-  
-  if($AutoClose) {
-    if(!$Quiet) {
-      Write-Host Closing Visual Studio processes
-    }
-    Close-Solution
-  }
-
-  if($Force){
-    $response = 'Y'
-  }
-  elseif(!$Force && $NoClean){
-    $response = ($r = Read-Host "Pre-build Terminal.Gui.InternalAnalyzers without removing old build artifacts? [Y/n]") ? $r : 'Y'
-  }
-  else{
-    $response = ($r = Read-Host "Delete bin and obj folders for Terminal.Gui and Terminal.Gui.InternalAnalyzers and pre-build Terminal.Gui.InternalAnalyzers? [Y/n]") ? $r : 'Y'
-  }
-
-  if (($response -ne 'Y')) {
-    Write-Host Took no action
-    return
-  }
-  
-  Push-Location $InternalAnalyzersProjectDirectory
-  
-  if(!$NoClean) {
-    if(!$Quiet) {
-      Write-Host Deleting bin and obj folders for Terminal.Gui
-    }
-    Remove-Item -Recurse -Force $TerminalGuiProjectDirectory/bin -ErrorAction SilentlyContinue
-    Remove-Item -Recurse -Force $TerminalGuiProjectDirectory/obj -ErrorAction SilentlyContinue
-
-    if(!$Quiet) {
-      Write-Host Deleting bin and obj folders for Terminal.Gui.InternalAnalyzers
-    }
-    Remove-Item -Recurse -Force $InternalAnalyzersProjectDirectory/bin -ErrorAction SilentlyContinue
-    Remove-Item -Recurse -Force $InternalAnalyzersProjectDirectory/obj -ErrorAction SilentlyContinue
-  }
-  
-  if(!$Quiet) {
-    Write-Host Building analyzers in Debug configuration
-  }
-  dotnet build $InternalAnalyzersProjectFilePath --no-incremental --nologo --force --configuration Debug
-
-  if(!$Quiet) {
-    Write-Host Building analyzers in Release configuration
-  }
-  dotnet build $InternalAnalyzersProjectFilePath --no-incremental --nologo --force --configuration Release
-
-  Pop-Location
-  
-  if(!$AutoLaunch) {
-    Write-Host -ForegroundColor Green Finished. Restart Visual Studio for changes to take effect.
-  } else {
-    if(!$Quiet) {
-      Write-Host -ForegroundColor Green Finished. Re-loading Terminal.sln.
-    }
-    Open-Solution
-  }
-
-  return
-}

+ 0 - 6
Scripts/Terminal.Gui.PowerShell.Core.psm1

@@ -69,9 +69,6 @@ Function Set-PowerShellEnvironment {
   New-Variable -Name SolutionFilePath -Value (Join-Path -Resolve $RepositoryRootDirectory "Terminal.sln") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name TerminalGuiProjectDirectory -Value (Join-Path -Resolve $RepositoryRootDirectory "Terminal.Gui") -Option ReadOnly -Scope Global -Visibility Public
   New-Variable -Name TerminalGuiProjectFilePath -Value (Join-Path -Resolve $TerminalGuiProjectDirectory "Terminal.Gui.csproj") -Option ReadOnly -Scope Global -Visibility Public
-  New-Variable -Name AnalyzersDirectory -Value (Join-Path -Resolve $RepositoryRootDirectory "Analyzers") -Option ReadOnly -Scope Global -Visibility Public
-  New-Variable -Name InternalAnalyzersProjectDirectory -Value (Join-Path -Resolve $AnalyzersDirectory "Terminal.Gui.Analyzers.Internal") -Option ReadOnly -Scope Global -Visibility Public
-  New-Variable -Name InternalAnalyzersProjectFilePath -Value (Join-Path -Resolve $InternalAnalyzersProjectDirectory "Terminal.Gui.Analyzers.Internal.csproj") -Option ReadOnly -Scope Global -Visibility Public
 
   # Save existing PSModulePath for optional reset later.
   # If it is already saved, do not overwrite, but continue anyway.
@@ -137,9 +134,6 @@ Function Reset-PowerShellEnvironment {
   Remove-Variable -Name TerminalGuiProjectDirectory -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name TerminalGuiProjectFilePath -Scope Global -Force -ErrorAction SilentlyContinue
   Remove-Variable -Name ScriptsDirectory -Scope Global -Force -ErrorAction SilentlyContinue
-  Remove-Variable -Name AnalyzersDirectory -Scope Global -Force -ErrorAction SilentlyContinue
-  Remove-Variable -Name InternalAnalyzersProjectDirectory -Scope Global -Force -ErrorAction SilentlyContinue
-  Remove-Variable -Name InternalAnalyzersProjectFilePath -Scope Global -Force -ErrorAction SilentlyContinue
 }
 
 # This ensures the environment is reset when unloading the module.

+ 1 - 1
Scripts/Terminal.Gui.PowerShell.psd1

@@ -81,7 +81,7 @@ RequiredModules = @(
 
 # Modules to import as nested modules of this module.
 # This module is just a shortcut that loads all of our modules.
-NestedModules = @('./Terminal.Gui.PowerShell.Core.psd1', './Terminal.Gui.PowerShell.Analyzers.psd1', './Terminal.Gui.PowerShell.Git.psd1', './Terminal.Gui.PowerShell.Build.psd1')
+NestedModules = @('./Terminal.Gui.PowerShell.Core.psd1', './Terminal.Gui.PowerShell.Git.psd1', './Terminal.Gui.PowerShell.Build.psd1')
 
 # Functions to export from this module.
 # Not filtered, so exports all functions exported by all nested modules.

+ 65 - 4
Terminal.Gui/Application/Application.cs

@@ -308,7 +308,7 @@ public static partial class Application
         SupportedCultures = GetSupportedCultures ();
         _mainThreadId = Thread.CurrentThread.ManagedThreadId;
         _initialized = true;
-        InitializedChanged?.Invoke (null, new (false, _initialized));
+        InitializedChanged?.Invoke (null, new (in _initialized));
     }
 
     private static void Driver_SizeChanged (object sender, SizeChangedEventArgs e) { OnSizeChanging (e); }
@@ -349,16 +349,18 @@ public static partial class Application
         // TODO: Throw an exception if Init hasn't been called.
         ResetState ();
         PrintJsonErrors ();
-        InitializedChanged?.Invoke (null, new (true, _initialized));
+        InitializedChanged?.Invoke (null, new (in _initialized));
     }
 
+#nullable enable
     /// <summary>
-    ///     This event is fired after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
+    ///     This event is raised after the <see cref="Init"/> and <see cref="Shutdown"/> methods have been called.
     /// </summary>
     /// <remarks>
     ///     Intended to support unit tests that need to know when the application has been initialized.
     /// </remarks>
-    public static event EventHandler<StateEventArgs<bool>> InitializedChanged;
+    public static event EventHandler<EventArgs<bool>>? InitializedChanged;
+#nullable restore
 
     #endregion Initialization (Init/Shutdown)
 
@@ -973,6 +975,7 @@ public static partial class Application
 
         if (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded || OverlappedChildNeedsDisplay ())
         {
+            state.Toplevel.SetNeedsDisplay ();
             state.Toplevel.Draw ();
             Driver.UpdateScreen ();
 
@@ -1436,4 +1439,62 @@ public static partial class Application
     }
 
     #endregion Toplevel handling
+
+    /// <summary>
+    ///     Gets a string representation of the Application as rendered by <see cref="Driver"/>.
+    /// </summary>
+    /// <returns>A string representation of the Application </returns>
+    public new static string ToString ()
+    {
+        ConsoleDriver driver = Driver;
+
+        if (driver is null)
+        {
+            return string.Empty;
+        }
+
+        return ToString (driver);
+    }
+
+    /// <summary>
+    ///     Gets a string representation of the Application rendered by the provided <see cref="ConsoleDriver"/>.
+    /// </summary>
+    /// <param name="driver">The driver to use to render the contents.</param>
+    /// <returns>A string representation of the Application </returns>
+    public static string ToString (ConsoleDriver driver)
+    {
+        var sb = new StringBuilder ();
+
+        Cell [,] contents = driver.Contents;
+
+        for (var r = 0; r < driver.Rows; r++)
+        {
+            for (var c = 0; c < driver.Cols; c++)
+            {
+                Rune rune = contents [r, c].Rune;
+
+                if (rune.DecodeSurrogatePair (out char [] sp))
+                {
+                    sb.Append (sp);
+                }
+                else
+                {
+                    sb.Append ((char)rune.Value);
+                }
+
+                if (rune.GetColumns () > 1)
+                {
+                    c++;
+                }
+
+                // See Issue #2616
+                //foreach (var combMark in contents [r, c].CombiningMarks) {
+                //	sb.Append ((char)combMark.Value);
+                //}
+            }
+
+            sb.AppendLine ();
+        }
+        return sb.ToString ();
+    }
 }

+ 2 - 0
Terminal.Gui/Configuration/ConfigurationManager.cs

@@ -4,6 +4,7 @@ using System.Collections;
 using System.Diagnostics;
 using System.Diagnostics.CodeAnalysis;
 using System.Reflection;
+using System.Runtime.Versioning;
 using System.Text.Encodings.Web;
 using System.Text.Json;
 using System.Text.Json.Serialization;
@@ -49,6 +50,7 @@ namespace Terminal.Gui;
 ///         Lowest Precedence.
 ///     </para>
 /// </summary>
+[ComponentGuarantees (ComponentGuaranteesOptions.None)]
 public static class ConfigurationManager
 {
     /// <summary>

+ 3 - 0
Terminal.Gui/Configuration/SettingsScope.cs

@@ -118,6 +118,9 @@ public class SettingsScope : Scope<SettingsScope>
             return this;
         }
 
+        // BUG: Not trim-compatible
+        // Not a bug, per se, but it's easily fixable by just loading the file.
+        // Defaults can just be field initializers for involved types.
         using Stream? stream = assembly.GetManifestResourceStream (resourceName)!;
 
         if (stream is null)

+ 1 - 3
Terminal.Gui/Drawing/Alignment.cs

@@ -1,12 +1,10 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
+
 
 namespace Terminal.Gui;
 
 /// <summary>
 ///     Determines the position of items when arranged in a container.
 /// </summary>
-[GenerateEnumExtensionMethods (FastHasFlags = true)]
-
 public enum Alignment
 {
     /// <summary>

+ 1 - 2
Terminal.Gui/Drawing/AlignmentModes.cs

@@ -1,4 +1,4 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
+
 
 namespace Terminal.Gui;
 
@@ -6,7 +6,6 @@ namespace Terminal.Gui;
 ///     Determines alignment modes for <see cref="Alignment"/>.
 /// </summary>
 [Flags]
-[GenerateEnumExtensionMethods (FastHasFlags = true)]
 public enum AlignmentModes
 {
     /// <summary>

+ 5 - 4
Terminal.Gui/Drawing/Cell.cs

@@ -4,18 +4,19 @@
 ///     Represents a single row/column in a Terminal.Gui rendering surface (e.g. <see cref="LineCanvas"/> and
 ///     <see cref="ConsoleDriver"/>).
 /// </summary>
-public class Cell
+public record struct Cell ()
 {
-    private Rune _rune;
 
     /// <summary>The attributes to use when drawing the Glyph.</summary>
-    public Attribute? Attribute { get; set; }
+    public Attribute? Attribute { get; set; } = null;
 
     /// <summary>
     ///     Gets or sets a value indicating whether this <see cref="T:Terminal.Gui.Cell"/> has been modified since the
     ///     last time it was drawn.
     /// </summary>
-    public bool IsDirty { get; set; }
+    public bool IsDirty { get; set; } = false;
+
+    private Rune _rune = default;
 
     /// <summary>The character to display. If <see cref="Rune"/> is <see langword="null"/>, then <see cref="Rune"/> is ignored.</summary>
     public Rune Rune

+ 21 - 0
Terminal.Gui/Drawing/Color.cs

@@ -259,6 +259,27 @@ public readonly partial record struct Color : ISpanParsable<Color>, IUtf8SpanPar
 
     }
 
+    /// <summary>
+    /// Gets a color that is the same hue as the current color, but with a different lightness.
+    /// </summary>
+    /// <returns></returns>
+    public Color GetDarkerColor ()
+    {
+        // TODO: This is a temporary implementation; just enough to show how it could work. 
+        var hsl = ColorHelper.ColorConverter.RgbToHsl (new RGB (R, G, B));
+
+        var amount = .3;
+        if (hsl.L <= 5)
+        {
+            return DarkGray;
+        }
+        hsl.L = (byte)(hsl.L * amount);
+
+        var rgb = ColorHelper.ColorConverter.HslToRgb (hsl);
+        return new (rgb.R, rgb.G, rgb.B);
+
+    }
+
     #region Legacy Color Names
 
     /// <summary>The black color.</summary>

+ 41 - 0
Terminal.Gui/Drawing/FillPair.cs

@@ -0,0 +1,41 @@
+namespace Terminal.Gui;
+
+/// <summary>
+///     Describes a pair of <see cref="IFill"/> which cooperate in creating
+///     <see cref="Attribute"/>. One gives foreground color while other gives background.
+/// </summary>
+public class FillPair
+{
+    /// <summary>
+    ///     Creates a new instance using the provided fills for foreground and background
+    ///     color when assembling <see cref="Attribute"/>.
+    /// </summary>
+    /// <param name="fore"></param>
+    /// <param name="back"></param>
+    public FillPair (IFill fore, IFill back)
+    {
+        Foreground = fore;
+        Background = back;
+    }
+
+    /// <summary>
+    ///     The fill which provides point based foreground color.
+    /// </summary>
+    public IFill Foreground { get; init; }
+
+    /// <summary>
+    ///     The fill which provides point based background color.
+    /// </summary>
+    public IFill Background { get; init; }
+
+    /// <summary>
+    ///     Returns the color pair (foreground+background) to use when rendering
+    ///     a rune at the given <paramref name="point"/>.
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
+    public Attribute GetAttribute (Point point)
+    {
+        return new (Foreground.GetColor (point), Background.GetColor (point));
+    }
+}

+ 23 - 3
Terminal.Gui/Drawing/Glyphs.cs

@@ -32,13 +32,13 @@ public class GlyphDefinitions
     #region ----------------- Single Glyphs -----------------
 
     /// <summary>Checked indicator (e.g. for <see cref="ListView"/> and <see cref="CheckBox"/>).</summary>
-    public Rune Checked { get; set; } = (Rune)'☑';
+    public Rune CheckStateChecked { get; set; } = (Rune)'☑';
 
     /// <summary>Not Checked indicator (e.g. for <see cref="ListView"/> and <see cref="CheckBox"/>).</summary>
-    public Rune UnChecked { get; set; } = (Rune)'☐';
+    public Rune CheckStateUnChecked { get; set; } = (Rune)'☐';
 
     /// <summary>Null Checked indicator (e.g. for <see cref="ListView"/> and <see cref="CheckBox"/>).</summary>
-    public Rune NullChecked { get; set; } = (Rune)'☒';
+    public Rune CheckStateNone { get; set; } = (Rune)'☒';
 
     /// <summary>Selected indicator  (e.g. for <see cref="ListView"/> and <see cref="RadioGroup"/>).</summary>
     public Rune Selected { get; set; } = (Rune)'◉';
@@ -437,4 +437,24 @@ public class GlyphDefinitions
     public Rune CrossHv { get; set; } = (Rune)'╋';
 
     #endregion
+
+    #region ----------------- ShadowStyle -----------------
+
+
+    /// <summary>Shadow - Vertical Start - Left Half Block - ▌ U+0258c</summary>
+    public Rune ShadowVerticalStart { get; set; } =  (Rune)'▌'; // Half: '\u2596'  ▖;
+
+    /// <summary>Shadow - Vertical - Left Half Block - ▌ U+0258c</summary>
+    public Rune ShadowVertical { get; set; } = (Rune)'▌';
+
+    /// <summary>Shadow - Horizontal Start - Upper Half Block - ▀ U+02580</summary>
+    public Rune ShadowHorizontalStart { get; set; } = (Rune)'▀'; // Half: ▝ U+0259d;
+
+    /// <summary>Shadow - Horizontal - Upper Half Block - ▀ U+02580</summary>
+    public Rune ShadowHorizontal { get; set; } = (Rune)'▀';
+
+    /// <summary>Shadow - Horizontal End - Quadrant Upper Left - ▘ U+02598</summary>
+    public Rune ShadowHorizontalEnd { get; set; } = (Rune)'▘';
+
+    #endregion
 }

+ 255 - 0
Terminal.Gui/Drawing/Gradient.cs

@@ -0,0 +1,255 @@
+// This code is a C# port from python library Terminal Text Effects  https://github.com/ChrisBuilds/terminaltexteffects/
+
+namespace Terminal.Gui;
+
+/// <summary>
+///     Describes the pattern that a <see cref="Gradient"/> results in e.g. <see cref="Vertical"/>,
+///     <see cref="Horizontal"/> etc
+/// </summary>
+public enum GradientDirection
+{
+    /// <summary>
+    ///     Color varies along Y axis but is constant on X axis.
+    /// </summary>
+    Vertical,
+
+    /// <summary>
+    ///     Color varies along X axis but is constant on Y axis.
+    /// </summary>
+    Horizontal,
+
+    /// <summary>
+    ///     Color varies by distance from center (i.e. in circular ripples)
+    /// </summary>
+    Radial,
+
+    /// <summary>
+    ///     Color varies by X and Y axis (i.e. a slanted gradient)
+    /// </summary>
+    Diagonal
+}
+
+/// <summary>
+/// Describes a <see cref="Spectrum"/> of colors that can be combined
+/// to make a color gradient.  Use <see cref="BuildCoordinateColorMapping"/>
+/// to create into gradient fill area maps.
+/// </summary>
+public class Gradient
+{
+    /// <summary>
+    ///     The discrete colors that will make up the <see cref="Gradient"/>.
+    /// </summary>
+    public List<Color> Spectrum { get; }
+
+    private readonly bool _loop;
+    private readonly List<Color> _stops;
+    private readonly List<int> _steps;
+
+    /// <summary>
+    ///     Creates a new instance of the <see cref="Gradient"/> class which hosts a <see cref="Spectrum"/>
+    ///     of colors including all <paramref name="stops"/> and <paramref name="steps"/> interpolated colors
+    ///     between each corresponding pair.
+    /// </summary>
+    /// <param name="stops">The colors to use in the spectrum (N)</param>
+    /// <param name="steps">
+    ///     The number of colors to generate between each pair (must be N-1 numbers).
+    ///     If only one step is passed then it is assumed to be the same distance for all pairs.
+    /// </param>
+    /// <param name="loop">True to duplicate the first stop and step so that the gradient repeats itself</param>
+    /// <exception cref="ArgumentException"></exception>
+    public Gradient (IEnumerable<Color> stops, IEnumerable<int> steps, bool loop = false)
+    {
+        _stops = stops.ToList ();
+
+        if (_stops.Count < 1)
+        {
+            throw new ArgumentException ("At least one color stop must be provided.");
+        }
+
+        _steps = steps.ToList ();
+
+        // If multiple colors and only 1 step assume same distance applies to all steps
+        if (_stops.Count > 2 && _steps.Count == 1)
+        {
+            _steps = Enumerable.Repeat (_steps.Single (), _stops.Count () - 1).ToList ();
+        }
+
+        if (_steps.Any (step => step < 1))
+        {
+            throw new ArgumentException ("Steps must be greater than 0.");
+        }
+
+        if (_steps.Count != _stops.Count - 1)
+        {
+            throw new ArgumentException ("Number of steps must be N-1");
+        }
+
+        _loop = loop;
+        Spectrum = GenerateGradient (_steps);
+    }
+
+    /// <summary>
+    ///     Returns the color to use at the given part of the spectrum
+    /// </summary>
+    /// <param name="fraction">
+    ///     Proportion of the way through the spectrum, must be between
+    ///     0 and 1 (inclusive).  Returns the last color if <paramref name="fraction"/> is
+    ///     <see cref="double.NaN"/>.
+    /// </param>
+    /// <returns></returns>
+    /// <exception cref="ArgumentOutOfRangeException"></exception>
+    public Color GetColorAtFraction (double fraction)
+    {
+        if (double.IsNaN (fraction))
+        {
+            return Spectrum.Last ();
+        }
+
+        if (fraction is < 0 or > 1)
+        {
+            throw new ArgumentOutOfRangeException (nameof (fraction), @"Fraction must be between 0 and 1.");
+        }
+
+        var index = (int)(fraction * (Spectrum.Count - 1));
+
+        return Spectrum [index];
+    }
+
+    private List<Color> GenerateGradient (IEnumerable<int> steps)
+    {
+        List<Color> gradient = new ();
+
+        if (_stops.Count == 1)
+        {
+            for (var i = 0; i < steps.Sum (); i++)
+            {
+                gradient.Add (_stops [0]);
+            }
+
+            return gradient;
+        }
+
+        List<Color> stopsToUse = _stops.ToList ();
+        List<int> stepsToUse = _steps.ToList ();
+
+        if (_loop)
+        {
+            stopsToUse.Add (_stops [0]);
+            stepsToUse.Add (_steps.First ());
+        }
+
+        var colorPairs = stopsToUse.Zip (stopsToUse.Skip (1), (start, end) => new { start, end });
+        List<int> stepsList = stepsToUse;
+
+        foreach ((var colorPair, int thesteps) in colorPairs.Zip (stepsList, (pair, step) => (pair, step)))
+        {
+            gradient.AddRange (InterpolateColors (colorPair.start, colorPair.end, thesteps));
+        }
+
+        return gradient;
+    }
+
+    private static IEnumerable<Color> InterpolateColors (Color start, Color end, int steps)
+    {
+        for (var step = 0; step < steps; step++)
+        {
+            double fraction = (double)step / steps;
+            var r = (int)(start.R + fraction * (end.R - start.R));
+            var g = (int)(start.G + fraction * (end.G - start.G));
+            var b = (int)(start.B + fraction * (end.B - start.B));
+
+            yield return new (r, g, b);
+        }
+
+        yield return end; // Ensure the last color is included
+    }
+
+    /// <summary>
+    ///     <para>
+    ///         Creates a mapping starting at 0,0 and going to <paramref name="maxRow"/> and <paramref name="maxColumn"/>
+    ///         (inclusively) using the supplied <paramref name="direction"/>.
+    ///     </para>
+    ///     <para>
+    ///         Note that this method is inclusive i.e. passing 1/1 results in 4 mapped coordinates.
+    ///     </para>
+    /// </summary>
+    /// <param name="maxRow"></param>
+    /// <param name="maxColumn"></param>
+    /// <param name="direction"></param>
+    /// <returns></returns>
+    public Dictionary<Point, Color> BuildCoordinateColorMapping (int maxRow, int maxColumn, GradientDirection direction)
+    {
+        Dictionary<Point, Color> gradientMapping = new ();
+
+        switch (direction)
+        {
+            case GradientDirection.Vertical:
+                for (var row = 0; row <= maxRow; row++)
+                {
+                    double fraction = maxRow == 0 ? 1.0 : (double)row / maxRow;
+                    Color color = GetColorAtFraction (fraction);
+
+                    for (var col = 0; col <= maxColumn; col++)
+                    {
+                        gradientMapping [new (col, row)] = color;
+                    }
+                }
+
+                break;
+
+            case GradientDirection.Horizontal:
+                for (var col = 0; col <= maxColumn; col++)
+                {
+                    double fraction = maxColumn == 0 ? 1.0 : (double)col / maxColumn;
+                    Color color = GetColorAtFraction (fraction);
+
+                    for (var row = 0; row <= maxRow; row++)
+                    {
+                        gradientMapping [new (col, row)] = color;
+                    }
+                }
+
+                break;
+
+            case GradientDirection.Radial:
+                for (var row = 0; row <= maxRow; row++)
+                {
+                    for (var col = 0; col <= maxColumn; col++)
+                    {
+                        double distanceFromCenter = FindNormalizedDistanceFromCenter (maxRow, maxColumn, new (col, row));
+                        Color color = GetColorAtFraction (distanceFromCenter);
+                        gradientMapping [new (col, row)] = color;
+                    }
+                }
+
+                break;
+
+            case GradientDirection.Diagonal:
+                for (var row = 0; row <= maxRow; row++)
+                {
+                    for (var col = 0; col <= maxColumn; col++)
+                    {
+                        double fraction = ((double)row * 2 + col) / (maxRow * 2 + maxColumn);
+                        Color color = GetColorAtFraction (fraction);
+                        gradientMapping [new (col, row)] = color;
+                    }
+                }
+
+                break;
+        }
+
+        return gradientMapping;
+    }
+
+    private static double FindNormalizedDistanceFromCenter (int maxRow, int maxColumn, Point coord)
+    {
+        double centerX = maxColumn / 2.0;
+        double centerY = maxRow / 2.0;
+        double dx = coord.X - centerX;
+        double dy = coord.Y - centerY;
+        double distance = Math.Sqrt (dx * dx + dy * dy);
+        double maxDistance = Math.Sqrt (centerX * centerX + centerY * centerY);
+
+        return distance / maxDistance;
+    }
+}

+ 42 - 0
Terminal.Gui/Drawing/GradientFill.cs

@@ -0,0 +1,42 @@
+namespace Terminal.Gui;
+
+/// <summary>
+///     Implementation of <see cref="IFill"/> that uses a color gradient (including
+///     radial, diagonal etc.).
+/// </summary>
+public class GradientFill : IFill
+{
+    private readonly Dictionary<Point, Color> _map;
+
+    /// <summary>
+    ///     Creates a new instance of the <see cref="GradientFill"/> class that can return
+    ///     color for any point in the given <paramref name="area"/> using the provided
+    ///     <paramref name="gradient"/> and <paramref name="direction"/>.
+    /// </summary>
+    /// <param name="area"></param>
+    /// <param name="gradient"></param>
+    /// <param name="direction"></param>
+    public GradientFill (Rectangle area, Gradient gradient, GradientDirection direction)
+    {
+        _map = gradient.BuildCoordinateColorMapping (area.Height - 1, area.Width - 1, direction)
+                       .ToDictionary (
+                                      kvp => new Point (kvp.Key.X + area.X, kvp.Key.Y + area.Y),
+                                      kvp => kvp.Value);
+    }
+
+    /// <summary>
+    ///     Returns the color to use for the given <paramref name="point"/> or Black if it
+    ///     lies outside the prepared gradient area (see constructor).
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
+    public Color GetColor (Point point)
+    {
+        if (_map.TryGetValue (point, out Color color))
+        {
+            return color;
+        }
+
+        return new (0, 0); // Default to black if point not found
+    }
+}

+ 14 - 0
Terminal.Gui/Drawing/IFill.cs

@@ -0,0 +1,14 @@
+namespace Terminal.Gui;
+
+/// <summary>
+///     Describes an area fill (e.g. solid color or gradient).
+/// </summary>
+public interface IFill
+{
+    /// <summary>
+    ///     Returns the color that should be used at the given point
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
+    Color GetColor (Point point);
+}

+ 24 - 14
Terminal.Gui/Drawing/LineCanvas.cs

@@ -4,6 +4,13 @@ namespace Terminal.Gui;
 /// <summary>Facilitates box drawing and line intersection detection and rendering.  Does not support diagonal lines.</summary>
 public class LineCanvas : IDisposable
 {
+    /// <summary>
+    ///     Optional <see cref="FillPair"/> which when present overrides the <see cref="StraightLine.Attribute"/>
+    ///     (colors) of lines in the canvas. This can be used e.g. to apply a global <see cref="GradientFill"/>
+    ///     across all lines.
+    /// </summary>
+    public FillPair? Fill { get; set; }
+
     private readonly List<StraightLine> _lines = [];
 
     private readonly Dictionary<IntersectionRuneType, IntersectionRuneResolver> _runeResolvers = new ()
@@ -85,7 +92,7 @@ public class LineCanvas : IDisposable
                     viewport = Rectangle.Union (viewport, _lines [i].Viewport);
                 }
 
-                if (viewport is {Width: 0} or {Height: 0})
+                if (viewport is { Width: 0 } or { Height: 0 })
                 {
                     viewport = viewport with
                     {
@@ -135,7 +142,7 @@ public class LineCanvas : IDisposable
     )
     {
         _cachedViewport = Rectangle.Empty;
-        _lines.Add (new StraightLine (start, length, orientation, style, attribute));
+        _lines.Add (new (start, length, orientation, style, attribute));
     }
 
     /// <summary>Adds a new line to the canvas</summary>
@@ -165,9 +172,9 @@ public class LineCanvas : IDisposable
     ///     intersection symbols.
     /// </summary>
     /// <returns>A map of all the points within the canvas.</returns>
-    public Dictionary<Point, Cell> GetCellMap ()
+    public Dictionary<Point, Cell?> GetCellMap ()
     {
-        Dictionary<Point, Cell> map = new ();
+        Dictionary<Point, Cell?> map = new ();
 
         // walk through each pixel of the bitmap
         for (int y = Viewport.Y; y < Viewport.Y + Viewport.Height; y++)
@@ -183,7 +190,7 @@ public class LineCanvas : IDisposable
 
                 if (cell is { })
                 {
-                    map.Add (new Point (x, y), cell);
+                    map.Add (new (x, y), cell);
                 }
             }
         }
@@ -218,7 +225,7 @@ public class LineCanvas : IDisposable
 
                 if (rune is { })
                 {
-                    map.Add (new Point (x, y), rune.Value);
+                    map.Add (new (x, y), rune.Value);
                 }
             }
         }
@@ -324,7 +331,10 @@ public class LineCanvas : IDisposable
     /// <returns></returns>
     private bool Exactly (HashSet<IntersectionType> intersects, params IntersectionType [] types) { return intersects.SetEquals (types); }
 
-    private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects) { return intersects [0]!.Line.Attribute; }
+    private Attribute? GetAttributeForIntersects (IntersectionDefinition? [] intersects)
+    {
+        return Fill != null ? Fill.GetAttribute (intersects [0]!.Point) : intersects [0]!.Line.Attribute;
+    }
 
     private Cell? GetCellForIntersects (ConsoleDriver driver, IntersectionDefinition? [] intersects)
     {
@@ -428,12 +438,12 @@ public class LineCanvas : IDisposable
                        useThickDotted ? Glyphs.VLineHvDa4 : Glyphs.VLine;
 
             default:
-                throw new Exception (
-                                     "Could not find resolver or switch case for "
-                                     + nameof (runeType)
-                                     + ":"
-                                     + runeType
-                                    );
+                throw new (
+                           "Could not find resolver or switch case for "
+                           + nameof (runeType)
+                           + ":"
+                           + runeType
+                          );
         }
     }
 
@@ -843,4 +853,4 @@ public class LineCanvas : IDisposable
             _normal = Glyphs.URCorner;
         }
     }
-}
+}

+ 24 - 0
Terminal.Gui/Drawing/SolidFill.cs

@@ -0,0 +1,24 @@
+namespace Terminal.Gui;
+
+/// <summary>
+///     <see cref="IFill"/> implementation that uses a solid color for all points
+/// </summary>
+public class SolidFill : IFill
+{
+    private readonly Color _color;
+
+    /// <summary>
+    ///     Creates a new instance of the <see cref="SolidFill"/> class which will return
+    ///     the provided <paramref name="color"/> regardless of which point is requested.
+    /// </summary>
+    /// <param name="color"></param>
+    public SolidFill (Color color) { _color = color; }
+
+    /// <summary>
+    ///     Returns the color this instance was constructed with regardless of
+    ///     which <paramref name="point"/> is being colored.
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
+    public Color GetColor (Point point) { return _color; }
+}

+ 43 - 38
Terminal.Gui/Drawing/StraightLine.cs

@@ -45,6 +45,7 @@ public class StraightLine
     ///     Gets the rectangle that describes the bounds of the canvas. Location is the coordinates of the line that is
     ///     furthest left/top and Size is defined by the line that extends the furthest right/bottom.
     /// </summary>
+
     // PERF: Probably better to store the rectangle rather than make a new one on every single access to Viewport.
     internal Rectangle Viewport
     {
@@ -111,26 +112,28 @@ public class StraightLine
             return null;
         }
 
+        var p = new Point (x, y);
+
         if (StartsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               Start,
-                                               GetTypeByLength (
-                                                                IntersectionType.StartLeft,
-                                                                IntersectionType.PassOverHorizontal,
-                                                                IntersectionType.StartRight
-                                                               ),
-                                               this
-                                              );
+            return new (
+                        p,
+                        GetTypeByLength (
+                                         IntersectionType.StartLeft,
+                                         IntersectionType.PassOverHorizontal,
+                                         IntersectionType.StartRight
+                                        ),
+                        this
+                       );
         }
 
         if (EndsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               Start,
-                                               Length < 0 ? IntersectionType.StartRight : IntersectionType.StartLeft,
-                                               this
-                                              );
+            return new (
+                        p,
+                        Length < 0 ? IntersectionType.StartRight : IntersectionType.StartLeft,
+                        this
+                       );
         }
 
         int xmin = Math.Min (Start.X, Start.X + Length);
@@ -138,11 +141,11 @@ public class StraightLine
 
         if (xmin < x && xmax > x)
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
-                                               IntersectionType.PassOverHorizontal,
-                                               this
-                                              );
+            return new (
+                        p,
+                        IntersectionType.PassOverHorizontal,
+                        this
+                       );
         }
 
         return null;
@@ -155,26 +158,28 @@ public class StraightLine
             return null;
         }
 
+        var p = new Point (x, y);
+
         if (StartsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               Start,
-                                               GetTypeByLength (
-                                                                IntersectionType.StartUp,
-                                                                IntersectionType.PassOverVertical,
-                                                                IntersectionType.StartDown
-                                                               ),
-                                               this
-                                              );
+            return new (
+                        p,
+                        GetTypeByLength (
+                                         IntersectionType.StartUp,
+                                         IntersectionType.PassOverVertical,
+                                         IntersectionType.StartDown
+                                        ),
+                        this
+                       );
         }
 
         if (EndsAt (x, y))
         {
-            return new IntersectionDefinition (
-                                               Start,
-                                               Length < 0 ? IntersectionType.StartDown : IntersectionType.StartUp,
-                                               this
-                                              );
+            return new (
+                        p,
+                        Length < 0 ? IntersectionType.StartDown : IntersectionType.StartUp,
+                        this
+                       );
         }
 
         int ymin = Math.Min (Start.Y, Start.Y + Length);
@@ -182,11 +187,11 @@ public class StraightLine
 
         if (ymin < y && ymax > y)
         {
-            return new IntersectionDefinition (
-                                               new Point (x, y),
-                                               IntersectionType.PassOverVertical,
-                                               this
-                                              );
+            return new (
+                        p,
+                        IntersectionType.PassOverVertical,
+                        this
+                       );
         }
 
         return null;

+ 71 - 95
Terminal.Gui/Drawing/Thickness.cs

@@ -1,4 +1,5 @@
-using System.Text.Json.Serialization;
+using System.Numerics;
+using System.Text.Json.Serialization;
 
 namespace Terminal.Gui;
 
@@ -13,28 +14,18 @@ namespace Terminal.Gui;
 ///         frame,
 ///         with the thickness widths subtracted.
 ///     </para>
-///     <para>Use the helper API (<see cref="Draw(Rectangle, string)"/> to draw the frame with the specified thickness.</para>
+///     <para>
+///         Use the helper API (<see cref="Draw(Rectangle, string)"/> to draw the frame with the specified thickness.
+///     </para>
+///     <para>
+///         Thickness uses <see langword="float"/> intenrally. As a result, there is a potential precision loss for very
+///         large numbers. This is typically not an issue for UI dimensions but could be relevant in other contexts.
+///     </para>
 /// </remarks>
-public class Thickness : IEquatable<Thickness>
+public record struct Thickness
 {
-    /// <summary>Gets or sets the width of the lower side of the rectangle.</summary>
-    [JsonInclude]
-    public int Bottom;
-
-    /// <summary>Gets or sets the width of the left side of the rectangle.</summary>
-    [JsonInclude]
-    public int Left;
-
-    /// <summary>Gets or sets the width of the right side of the rectangle.</summary>
-    [JsonInclude]
-    public int Right;
-
-    /// <summary>Gets or sets the width of the upper side of the rectangle.</summary>
-    [JsonInclude]
-    public int Top;
-
     /// <summary>Initializes a new instance of the <see cref="Thickness"/> class with all widths set to 0.</summary>
-    public Thickness () { }
+    public Thickness () { _sides = Vector4.Zero; }
 
     /// <summary>Initializes a new instance of the <see cref="Thickness"/> class with a uniform width to each side.</summary>
     /// <param name="width"></param>
@@ -56,36 +47,24 @@ public class Thickness : IEquatable<Thickness>
         Bottom = bottom;
     }
 
-    // TODO: add operator overloads
-    /// <summary>Gets an empty thickness.</summary>
-    public static Thickness Empty => new (0);
+    private Vector4 _sides;
 
     /// <summary>
-    ///     Gets the total width of the left and right sides of the rectangle. Sets the width of the left and rigth sides
-    ///     of the rectangle to half the specified value.
+    ///     Adds the thickness widths of another <see cref="Thickness"/> to the current <see cref="Thickness"/>, returning a
+    ///     new <see cref="Thickness"/>.
     /// </summary>
-    public int Horizontal
-    {
-        get => Left + Right;
-        set => Left = Right = value / 2;
-    }
+    /// <param name="other"></param>
+    /// <returns></returns>
+    public readonly Thickness Add (Thickness other) { return new (Left + other.Left, Top + other.Top, Right + other.Right, Bottom + other.Bottom); }
 
-    /// <summary>
-    ///     Gets the total height of the top and bottom sides of the rectangle. Sets the height of the top and bottom
-    ///     sides of the rectangle to half the specified value.
-    /// </summary>
-    public int Vertical
+    /// <summary>Gets or sets the width of the lower side of the rectangle.</summary>
+    [JsonInclude]
+    public int Bottom
     {
-        get => Top + Bottom;
-        set => Top = Bottom = value / 2;
+        get => (int)_sides.W;
+        set => _sides.W = value;
     }
 
-    // IEquitable
-    /// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
-    /// <param name="other"></param>
-    /// <returns>true if the current object is equal to the other parameter; otherwise, false.</returns>
-    public bool Equals (Thickness other) { return other is { } && Left == other.Left && Right == other.Right && Top == other.Top && Bottom == other.Bottom; }
-
     /// <summary>
     ///     Gets whether the specified coordinates lie within the thickness (inside the bounding rectangle but outside
     ///     the rectangle described by <see cref="GetInside(Rectangle)"/>.
@@ -100,22 +79,6 @@ public class Thickness : IEquatable<Thickness>
         return outside.Contains (location) && !inside.Contains (location);
     }
 
-    /// <summary>
-    ///     Adds the thickness widths of another <see cref="Thickness"/> to the current <see cref="Thickness"/>, returning a
-    ///     new <see cref="Thickness"/>.
-    /// </summary>
-    /// <param name="other"></param>
-    /// <returns></returns>
-    public Thickness Add (Thickness other) { return new (Left + other.Left, Top + other.Top, Right + other.Right, Bottom + other.Bottom); }
-
-    /// <summary>
-    ///     Adds the thickness widths of another <see cref="Thickness"/> to another <see cref="Thickness"/>.
-    /// </summary>
-    /// <param name="a"></param>
-    /// <param name="b"></param>
-    /// <returns></returns>
-    public static Thickness operator + (Thickness a, Thickness b) { return a.Add (b); }
-
     /// <summary>Draws the <see cref="Thickness"/> rectangle with an optional diagnostics label.</summary>
     /// <remarks>
     ///     If <see cref="ViewDiagnosticFlags"/> is set to
@@ -240,31 +203,8 @@ public class Thickness : IEquatable<Thickness>
         return GetInside (rect);
     }
 
-    /// <summary>Determines whether the specified object is equal to the current object.</summary>
-    /// <param name="obj">The object to compare with the current object.</param>
-    /// <returns><c>true</c> if the specified object is equal to the current object; otherwise, <c>false</c>.</returns>
-    public override bool Equals (object obj)
-    {
-        //Check for null and compare run-time types.
-        if (obj is null || !GetType ().Equals (obj.GetType ()))
-        {
-            return false;
-        }
-
-        return Equals ((Thickness)obj);
-    }
-
-    /// <inheritdoc/>
-    public override int GetHashCode ()
-    {
-        var hashCode = 1380952125;
-        hashCode = hashCode * -1521134295 + Left.GetHashCode ();
-        hashCode = hashCode * -1521134295 + Right.GetHashCode ();
-        hashCode = hashCode * -1521134295 + Top.GetHashCode ();
-        hashCode = hashCode * -1521134295 + Bottom.GetHashCode ();
-
-        return hashCode;
-    }
+    /// <summary>Gets an empty thickness.</summary>
+    public static Thickness Empty => new (0);
 
     /// <summary>
     ///     Returns a rectangle describing the location and size of the inside area of <paramref name="rect"/> with the
@@ -289,23 +229,59 @@ public class Thickness : IEquatable<Thickness>
         return new (x, y, width, height);
     }
 
-    /// <inheritdoc/>
-    public static bool operator == (Thickness left, Thickness right) { return EqualityComparer<Thickness>.Default.Equals (left, right); }
+    /// <summary>
+    ///     Gets the total width of the left and right sides of the rectangle. Sets the width of the left and rigth sides
+    ///     of the rectangle to half the specified value.
+    /// </summary>
+    public int Horizontal
+    {
+        get => Left + Right;
+        set => Left = Right = value / 2;
+    }
 
-    /// <inheritdoc/>
-    public static bool operator != (Thickness left, Thickness right) { return !(left == right); }
+    /// <summary>Gets or sets the width of the left side of the rectangle.</summary>
+    [JsonInclude]
+    public int Left
+    {
+        get => (int)_sides.X;
+        set => _sides.X = value;
+    }
+
+    /// <summary>
+    ///     Adds the thickness widths of another <see cref="Thickness"/> to another <see cref="Thickness"/>.
+    /// </summary>
+    /// <param name="a"></param>
+    /// <param name="b"></param>
+    /// <returns></returns>
+    public static Thickness operator + (Thickness a, Thickness b) { return a.Add (b); }
+
+    /// <summary>Gets or sets the width of the right side of the rectangle.</summary>
+    [JsonInclude]
+    public int Right
+    {
+        get => (int)_sides.Z;
+        set => _sides.Z = value;
+    }
+
+    /// <summary>Gets or sets the width of the upper side of the rectangle.</summary>
+    [JsonInclude]
+    public int Top
+    {
+        get => (int)_sides.Y;
+        set => _sides.Y = value;
+    }
 
     /// <summary>Returns the thickness widths of the Thickness formatted as a string.</summary>
     /// <returns>The thickness widths as a string.</returns>
     public override string ToString () { return $"(Left={Left},Top={Top},Right={Right},Bottom={Bottom})"; }
 
-    private int validate (int width)
+    /// <summary>
+    ///     Gets the total height of the top and bottom sides of the rectangle. Sets the height of the top and bottom
+    ///     sides of the rectangle to half the specified value.
+    /// </summary>
+    public int Vertical
     {
-        if (width < 0)
-        {
-            throw new ArgumentException ("Thickness widths cannot be negative.");
-        }
-
-        return width;
+        get => Top + Bottom;
+        set => Top = Bottom = value / 2;
     }
 }

+ 0 - 16
Terminal.Gui/Drawing/ThicknessEventArgs.cs

@@ -1,16 +0,0 @@
-#nullable enable
-
-namespace Terminal.Gui;
-
-/// <summary>Event arguments for the <see cref="Thickness"/> events.</summary>
-public class ThicknessEventArgs : EventArgs
-{
-    /// <summary>Initializes a new instance of <see cref="ThicknessEventArgs"/></summary>
-    public ThicknessEventArgs () { }
-
-    /// <summary>The previous Thickness.</summary>
-    public Thickness PreviousThickness { get; set; } = Thickness.Empty;
-
-    /// <summary>The new Thickness.</summary>
-    public Thickness Thickness { get; set; } = Thickness.Empty;
-}

+ 51 - 0
Terminal.Gui/EnumExtensions/AddOrSubtractExtensions.cs

@@ -0,0 +1,51 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.AddOrSubtract"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class AddOrSubtractExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.AddOrSubtract"/> value to an <see langword="int"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this AddOrSubtract e) => Unsafe.As<AddOrSubtract, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.AddOrSubtract"/> value to a <see langword="uint"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this AddOrSubtract e) => Unsafe.As<AddOrSubtract, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.AddOrSubtract"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this AddOrSubtract _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   _ => false
+               };
+    }
+}

+ 53 - 0
Terminal.Gui/EnumExtensions/AlignmentExtensions.cs

@@ -0,0 +1,53 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.Alignment"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class AlignmentExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.Alignment"/> value to an <see langword="int"/> value with the same
+    ///     binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this Alignment e) => Unsafe.As<Alignment, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.Alignment"/> value to a <see langword="uint"/> value with the same
+    ///     binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this Alignment e) => Unsafe.As<Alignment, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.Alignment"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this Alignment _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   3 => true,
+                   _ => false
+               };
+    }
+}

+ 90 - 0
Terminal.Gui/EnumExtensions/AlignmentModesExtensions.cs

@@ -0,0 +1,90 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.AlignmentModes"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class AlignmentModesExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.AlignmentModes"/> value to an <see langword="int"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this AlignmentModes e) => Unsafe.As<AlignmentModes, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.AlignmentModes"/> value to a <see langword="uint"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this AlignmentModes e) => Unsafe.As<AlignmentModes, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified flags are set in the current value of this
+    ///     <see cref="Terminal.Gui.AlignmentModes"/>.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    /// <returns>
+    ///     True, if all flags present in <paramref name="checkFlags"/> are also present in the current value of the
+    ///     <see cref="Terminal.Gui.AlignmentModes"/>.<br/>Otherwise false.
+    /// </returns>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this AlignmentModes e, AlignmentModes checkFlags)
+    {
+        ref uint enumCurrentValueRef = ref Unsafe.As<AlignmentModes, uint> (ref e);
+        ref uint checkFlagsValueRef = ref Unsafe.As<AlignmentModes, uint> (ref checkFlags);
+
+        return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;
+    }
+
+    /// <summary>
+    ///     Determines if the specified mask bits are set in the current value of this
+    ///     <see cref="Terminal.Gui.AlignmentModes"/>.
+    /// </summary>
+    /// <param name="e">The <see cref="Terminal.Gui.AlignmentModes"/> value to check against the <paramref name="mask"/> value.</param>
+    /// <param name="mask">A mask to apply to the current value.</param>
+    /// <returns>
+    ///     True, if all bits set to 1 in the mask are also set to 1 in the current value of the
+    ///     <see cref="Terminal.Gui.AlignmentModes"/>.<br/>Otherwise false.
+    /// </returns>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this AlignmentModes e, int mask)
+    {
+        ref int enumCurrentValueRef = ref Unsafe.As<AlignmentModes, int> (ref e);
+
+        return (enumCurrentValueRef & mask) == mask;
+    }
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.AlignmentModes"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this AlignmentModes _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   4 => true,
+                   _ => false
+               };
+    }
+}

+ 89 - 0
Terminal.Gui/EnumExtensions/BorderSettingsExtensions.cs

@@ -0,0 +1,89 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.BorderSettings"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class BorderSettingsExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.BorderSettings"/> value to an <see langword="int"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this BorderSettings e) => Unsafe.As<BorderSettings, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.BorderSettings"/> value to a <see langword="uint"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this BorderSettings e) => Unsafe.As<BorderSettings, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified flags are set in the current value of this
+    ///     <see cref="Terminal.Gui.BorderSettings"/>.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    /// <returns>
+    ///     True, if all flags present in <paramref name="checkFlags"/> are also present in the current value of the
+    ///     <see cref="Terminal.Gui.BorderSettings"/>.<br/>Otherwise false.
+    /// </returns>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this BorderSettings e, BorderSettings checkFlags)
+    {
+        ref uint enumCurrentValueRef = ref Unsafe.As<BorderSettings, uint> (ref e);
+        ref uint checkFlagsValueRef = ref Unsafe.As<BorderSettings, uint> (ref checkFlags);
+
+        return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;
+    }
+
+    /// <summary>
+    ///     Determines if the specified mask bits are set in the current value of this
+    ///     <see cref="Terminal.Gui.BorderSettings"/>.
+    /// </summary>
+    /// <param name="e">The <see cref="Terminal.Gui.BorderSettings"/> value to check against the <paramref name="mask"/> value.</param>
+    /// <param name="mask">A mask to apply to the current value.</param>
+    /// <returns>
+    ///     True, if all bits set to 1 in the mask are also set to 1 in the current value of the
+    ///     <see cref="Terminal.Gui.BorderSettings"/>.<br/>Otherwise false.
+    /// </returns>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this BorderSettings e, int mask)
+    {
+        ref int enumCurrentValueRef = ref Unsafe.As<BorderSettings, int> (ref e);
+
+        return (enumCurrentValueRef & mask) == mask;
+    }
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.BorderSettings"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this BorderSettings _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   _ => false
+               };
+    }
+}

+ 89 - 0
Terminal.Gui/EnumExtensions/DimAutoStyleExtensions.cs

@@ -0,0 +1,89 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.DimAutoStyle"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class DimAutoStyleExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.DimAutoStyle"/> value to an <see langword="int"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this DimAutoStyle e) => Unsafe.As<DimAutoStyle, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.DimAutoStyle"/> value to a <see langword="uint"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this DimAutoStyle e) => Unsafe.As<DimAutoStyle, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified flags are set in the current value of this <see cref="Terminal.Gui.DimAutoStyle"/>
+    ///     .
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    /// <returns>
+    ///     True, if all flags present in <paramref name="checkFlags"/> are also present in the current value of the
+    ///     <see cref="Terminal.Gui.DimAutoStyle"/>.<br/>Otherwise false.
+    /// </returns>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this DimAutoStyle e, DimAutoStyle checkFlags)
+    {
+        ref uint enumCurrentValueRef = ref Unsafe.As<DimAutoStyle, uint> (ref e);
+        ref uint checkFlagsValueRef = ref Unsafe.As<DimAutoStyle, uint> (ref checkFlags);
+
+        return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;
+    }
+
+    /// <summary>
+    ///     Determines if the specified mask bits are set in the current value of this
+    ///     <see cref="Terminal.Gui.DimAutoStyle"/>.
+    /// </summary>
+    /// <param name="e">The <see cref="Terminal.Gui.DimAutoStyle"/> value to check against the <paramref name="mask"/> value.</param>
+    /// <param name="mask">A mask to apply to the current value.</param>
+    /// <returns>
+    ///     True, if all bits set to 1 in the mask are also set to 1 in the current value of the
+    ///     <see cref="Terminal.Gui.DimAutoStyle"/>.<br/>Otherwise false.
+    /// </returns>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this DimAutoStyle e, int mask)
+    {
+        ref int enumCurrentValueRef = ref Unsafe.As<DimAutoStyle, int> (ref e);
+
+        return (enumCurrentValueRef & mask) == mask;
+    }
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.DimAutoStyle"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this DimAutoStyle _, int value)
+    {
+        return value switch
+               {
+                   1 => true,
+                   2 => true,
+                   3 => true,
+                   _ => false
+               };
+    }
+}

+ 51 - 0
Terminal.Gui/EnumExtensions/DimPercentModeExtensions.cs

@@ -0,0 +1,51 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.DimPercentMode"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class DimPercentModeExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.DimPercentMode"/> value to an <see langword="int"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this DimPercentMode e) => Unsafe.As<DimPercentMode, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.DimPercentMode"/> value to a <see langword="uint"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this DimPercentMode e) => Unsafe.As<DimPercentMode, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.DimPercentMode"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this DimPercentMode _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   _ => false
+               };
+    }
+}

+ 51 - 0
Terminal.Gui/EnumExtensions/DimensionExtensions.cs

@@ -0,0 +1,51 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.Dimension"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+public static class DimensionExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.Dimension"/> value to an <see langword="int"/> value with the same
+    ///     binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this Dimension e) => Unsafe.As<Dimension, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.Dimension"/> value to a <see langword="uint"/> value with the same
+    ///     binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this Dimension e) => Unsafe.As<Dimension, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.Dimension"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this Dimension _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   _ => false
+               };
+    }
+}

+ 93 - 0
Terminal.Gui/EnumExtensions/KeyBindingScopeExtensions.cs

@@ -0,0 +1,93 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.KeyBindingScope"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class KeyBindingScopeExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.KeyBindingScope"/> value to an <see langword="int"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this KeyBindingScope e) => Unsafe.As<KeyBindingScope, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.KeyBindingScope"/> value to a <see langword="uint"/> value with the
+    ///     same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this KeyBindingScope e) => Unsafe.As<KeyBindingScope, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified flags are set in the current value of this
+    ///     <see cref="Terminal.Gui.KeyBindingScope"/>.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    /// <returns>
+    ///     True, if all flags present in <paramref name="checkFlags"/> are also present in the current value of the
+    ///     <see cref="Terminal.Gui.KeyBindingScope"/>.<br/>Otherwise false.
+    /// </returns>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this KeyBindingScope e, KeyBindingScope checkFlags)
+    {
+        ref uint enumCurrentValueRef = ref Unsafe.As<KeyBindingScope, uint> (ref e);
+        ref uint checkFlagsValueRef = ref Unsafe.As<KeyBindingScope, uint> (ref checkFlags);
+
+        return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;
+    }
+
+    /// <summary>
+    ///     Determines if the specified mask bits are set in the current value of this
+    ///     <see cref="Terminal.Gui.KeyBindingScope"/>.
+    /// </summary>
+    /// <param name="e">
+    ///     The <see cref="Terminal.Gui.KeyBindingScope"/> value to check against the <paramref name="mask"/>
+    ///     value.
+    /// </param>
+    /// <param name="mask">A mask to apply to the current value.</param>
+    /// <returns>
+    ///     True, if all bits set to 1 in the mask are also set to 1 in the current value of the
+    ///     <see cref="Terminal.Gui.KeyBindingScope"/>.<br/>Otherwise false.
+    /// </returns>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this KeyBindingScope e, int mask)
+    {
+        ref int enumCurrentValueRef = ref Unsafe.As<KeyBindingScope, int> (ref e);
+
+        return (enumCurrentValueRef & mask) == mask;
+    }
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.KeyBindingScope"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this KeyBindingScope _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   4 => true,
+                   _ => false
+               };
+    }
+}

+ 53 - 0
Terminal.Gui/EnumExtensions/SideExtensions.cs

@@ -0,0 +1,53 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.Side"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class SideExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.Side"/> value to an <see langword="int"/> value with the same binary
+    ///     representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this Side e) => Unsafe.As<Side, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.Side"/> value to a <see langword="uint"/> value with the same binary
+    ///     representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this Side e) => Unsafe.As<Side, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified <see langword="int"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.Side"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this Side _, int value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   3 => true,
+                   _ => false
+               };
+    }
+}

+ 93 - 0
Terminal.Gui/EnumExtensions/ViewDiagnosticFlagsExtensions.cs

@@ -0,0 +1,93 @@
+#nullable enable
+
+using System.CodeDom.Compiler;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.CompilerServices;
+
+namespace Terminal.Gui.EnumExtensions;
+
+/// <summary>Extension methods for the <see cref="Terminal.Gui.ViewDiagnosticFlags"/> <see langword="enum"/> type.</summary>
+[GeneratedCode ("Terminal.Gui.Analyzers.Internal", "1.0")]
+[CompilerGenerated]
+[DebuggerNonUserCode]
+[ExcludeFromCodeCoverage (Justification = "Generated code is already tested.")]
+[PublicAPI]
+public static class ViewDiagnosticFlagsExtensions
+{
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.ViewDiagnosticFlags"/> value to an <see langword="int"/> value with
+    ///     the same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static int AsInt32 (this ViewDiagnosticFlags e) => Unsafe.As<ViewDiagnosticFlags, int> (ref e);
+
+    /// <summary>
+    ///     Directly converts this <see cref="Terminal.Gui.ViewDiagnosticFlags"/> value to a <see langword="uint"/> value with
+    ///     the same binary representation.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static uint AsUInt32 (this ViewDiagnosticFlags e) => Unsafe.As<ViewDiagnosticFlags, uint> (ref e);
+
+    /// <summary>
+    ///     Determines if the specified flags are set in the current value of this
+    ///     <see cref="Terminal.Gui.ViewDiagnosticFlags"/>.
+    /// </summary>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    /// <returns>
+    ///     True, if all flags present in <paramref name="checkFlags"/> are also present in the current value of the
+    ///     <see cref="Terminal.Gui.ViewDiagnosticFlags"/>.<br/>Otherwise false.
+    /// </returns>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this ViewDiagnosticFlags e, ViewDiagnosticFlags checkFlags)
+    {
+        ref uint enumCurrentValueRef = ref Unsafe.As<ViewDiagnosticFlags, uint> (ref e);
+        ref uint checkFlagsValueRef = ref Unsafe.As<ViewDiagnosticFlags, uint> (ref checkFlags);
+
+        return (enumCurrentValueRef & checkFlagsValueRef) == checkFlagsValueRef;
+    }
+
+    /// <summary>
+    ///     Determines if the specified mask bits are set in the current value of this
+    ///     <see cref="Terminal.Gui.ViewDiagnosticFlags"/>.
+    /// </summary>
+    /// <param name="e">
+    ///     The <see cref="Terminal.Gui.ViewDiagnosticFlags"/> value to check against the <paramref name="mask"/>
+    ///     value.
+    /// </param>
+    /// <param name="mask">A mask to apply to the current value.</param>
+    /// <returns>
+    ///     True, if all bits set to 1 in the mask are also set to 1 in the current value of the
+    ///     <see cref="Terminal.Gui.ViewDiagnosticFlags"/>.<br/>Otherwise false.
+    /// </returns>
+    /// <remarks>NO VALIDATION IS PERFORMED!</remarks>
+    [MethodImpl (MethodImplOptions.AggressiveInlining)]
+    public static bool FastHasFlags (this ViewDiagnosticFlags e, uint mask)
+    {
+        ref uint enumCurrentValueRef = ref Unsafe.As<ViewDiagnosticFlags, uint> (ref e);
+
+        return (enumCurrentValueRef & mask) == mask;
+    }
+
+    /// <summary>
+    ///     Determines if the specified <see langword="uint"/> value is explicitly defined as a named value of the
+    ///     <see cref="Terminal.Gui.ViewDiagnosticFlags"/> <see langword="enum"/> type.
+    /// </summary>
+    /// <remarks>
+    ///     Only explicitly named values return true, as with IsDefined. Combined valid flag values of flags enums which are
+    ///     not explicitly named will return false.
+    /// </remarks>
+    public static bool FastIsDefined (this ViewDiagnosticFlags _, uint value)
+    {
+        return value switch
+               {
+                   0 => true,
+                   1 => true,
+                   2 => true,
+                   4 => true,
+                   _ => false
+               };
+    }
+}

+ 2 - 2
Terminal.Gui/Input/KeyBindingScope.cs

@@ -1,4 +1,4 @@
-using Terminal.Gui.Analyzers.Internal.Attributes;
+
 
 namespace Terminal.Gui;
 
@@ -10,7 +10,7 @@ namespace Terminal.Gui;
 ///     <para>Key bindings are scoped to the most-focused view (<see cref="Focused"/>) by default.</para>
 /// </remarks>
 [Flags]
-[GenerateEnumExtensionMethods (FastHasFlags = true)]
+
 public enum KeyBindingScope
 {
     /// <summary>The key binding is disabled.</summary>

+ 1 - 2
Terminal.Gui/Input/ShortcutHelper.cs

@@ -2,6 +2,7 @@
 
 namespace Terminal.Gui;
 
+// TODO: Nuke when #2975 is completed
 /// <summary>Represents a helper to manipulate shortcut keys used on views.</summary>
 public class ShortcutHelper
 {
@@ -115,8 +116,6 @@ public class ShortcutHelper
             return true;
         }
 
-        Debug.WriteLine ($"WARNING: {Key.ToString (key)} is not a valid shortcut key.");
-
         return false;
     }
 

+ 1 - 1
Terminal.Gui/Resources/Strings.pt-PT.resx

@@ -166,7 +166,7 @@
     <value>Acabam_ento</value>
   </data>
   <data name="wzNext" xml:space="preserve">
-    <value>S_eguir</value>
+    <value>S_eguir...</value>
   </data>
   <data name="btnSaveAs" xml:space="preserve">
     <value>Guardar como</value>

+ 7 - 3
Terminal.Gui/Resources/config.json

@@ -10,7 +10,8 @@
   // note that not all values here will be recreated (e.g. the Light and Dark themes and any property initialized
   // null).
   //
-  "$schema": "https://gui-cs.github.io/Terminal.Gui/schemas/tui-config-schema.json",
+  // TODO: V2 - Reference via http
+  "$schema": "../../docfx/schemas/tui-config-schema.json",
 
   // Set this to true in a .config file to be loaded to cause JSON parsing errors
   // to throw exceptions. 
@@ -18,8 +19,8 @@
 
   "Application.AlternateBackwardKey": "Ctrl+PageUp",
   "Application.AlternateForwardKey": "Ctrl+PageDown",
-  "Application.QuitKey": "Ctrl+Q",
-  "Application.IsMouseDisabled": false,
+  "Application.QuitKey": "Esc",
+
   "Theme": "Default",
   "Themes": [
     {
@@ -28,6 +29,9 @@
         "Dialog.DefaultButtonAlignmentModes": "AddSpaceBetweenItems",
         "FrameView.DefaultBorderStyle": "Single",
         "Window.DefaultBorderStyle": "Single",
+        "Dialog.DefaultBorderStyle": "Single",
+        "MessageBox.DefaultBorderStyle": "Double",
+        "Button.DefaultShadow": "None",
         "ColorSchemes": [
           {
             "TopLevel": {

+ 37 - 37
Terminal.Gui/Terminal.Gui.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <!-- =================================================================== -->
   <!-- Version numbers -->
   <!-- Automatically updated by gitversion (run `dotnet-gitversion /updateprojectfiles`)  -->
@@ -7,28 +7,35 @@
   <PropertyGroup>
     <Version>2.0.0</Version>
   </PropertyGroup>
+  <!-- =================================================================== -->
+  <!-- Assembly name. -->
+  <!-- Referenced throughout this file for consistency. -->
+  <!-- =================================================================== -->
+<PropertyGroup>
+  <AssemblyName>Terminal.Gui</AssemblyName>
+</PropertyGroup>
+
   <!-- =================================================================== -->
   <!-- .NET Build Settings -->
   <!-- =================================================================== -->
   <PropertyGroup>
-    <TargetFrameworks>net8.0</TargetFrameworks>
+    <TargetFramework>net8.0</TargetFramework>
     <LangVersion>12</LangVersion>
-    <RootNamespace>Terminal.Gui</RootNamespace>
-    <AssemblyName>Terminal.Gui</AssemblyName>
+    <RootNamespace>$(AssemblyName)</RootNamespace>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-    <DefineTrace>True</DefineTrace>
+    <DefineTrace>true</DefineTrace>
     <DebugType>portable</DebugType>
     <DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
     <ImplicitUsings>enable</ImplicitUsings>
-    <NoLogo>True</NoLogo>
+    <NoLogo>true</NoLogo>
     <SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DefineDebug>True</DefineDebug>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <DefineDebug>true</DefineDebug>
     <DefineConstants>$(DefineConstants);DEBUG_IDISPOSABLE</DefineConstants>
   </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <Optimize>True</Optimize>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <Optimize>true</Optimize>
     <VersionSuffix></VersionSuffix>
   </PropertyGroup>
   <!-- =================================================================== -->
@@ -36,8 +43,6 @@
   <!-- =================================================================== -->
   <ItemGroup>
     <None Remove="Resources\config.json" />
-  </ItemGroup>
-  <ItemGroup>
     <EmbeddedResource Include="Resources\config.json" />
   </ItemGroup>
   <!-- =================================================================== -->
@@ -45,20 +50,15 @@
   <!-- =================================================================== -->
   <ItemGroup>
     <PackageReference Include="ColorHelper" Version="1.8.1" />
-    <PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="All" />
-    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.9.2" PrivateAssets="all" />
-    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.9.2" PrivateAssets="all" />
+    <PackageReference Include="JetBrains.Annotations" Version="2024.2.0" PrivateAssets="all" />
+    <PackageReference Include="Microsoft.CodeAnalysis" Version="4.10.0" PrivateAssets="all" />
+    <PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.10.0" PrivateAssets="all" />
+    <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" PrivateAssets="all" />
     <!-- Enable Nuget Source Link for github -->
-    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
-    <PackageReference Include="System.IO.Abstractions" Version="21.0.2" />
-    <PackageReference Include="System.Text.Json" Version="8.0.3" />
+    <PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
+    <PackageReference Include="System.IO.Abstractions" Version="21.0.22" />
+    <PackageReference Include="System.Text.Json" Version="8.0.4" />
     <PackageReference Include="Wcwidth" Version="2.0.0" />
-    <ProjectReference Include="..\Analyzers\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj">
-      <PrivateAssets>all</PrivateAssets>
-      <OutputItemType>Analyzer</OutputItemType>
-      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
-    </ProjectReference>
   </ItemGroup>
   <!-- =================================================================== -->
   <!-- Global Usings and Type Aliases -->
@@ -68,9 +68,10 @@
     <Using Include="JetBrains.Annotations.PureAttribute" Alias="PureAttribute" />
     <Using Include="System.Drawing" />
     <Using Include="System.Text" />
+    <Using Include="Terminal.Gui.EnumExtensions" />
   </ItemGroup>
   <!-- =================================================================== -->
-  <!-- Namespaces for which internal items are visible -->
+  <!-- Assembliy names for which internal items are visible -->
   <!-- =================================================================== -->
   <ItemGroup>
     <InternalsVisibleTo Include="UnitTests" />
@@ -81,11 +82,11 @@
   <!-- =================================================================== -->
   <ItemGroup>
     <None Include="..\docfx\images\logo.png">
-      <Pack>True</Pack>
+      <Pack>true</Pack>
       <PackagePath>\</PackagePath>
     </None>
     <None Include="..\README.md">
-      <Pack>True</Pack>
+      <Pack>true</Pack>
       <PackagePath>\</PackagePath>
     </None>
   </ItemGroup>
@@ -94,8 +95,8 @@
   <!-- =================================================================== -->
   <ItemGroup>
     <Compile Update="Resources\Strings.Designer.cs">
-      <DesignTime>True</DesignTime>
-      <AutoGen>True</AutoGen>
+      <DesignTime>true</DesignTime>
+      <AutoGen>true</AutoGen>
       <DependentUpon>Strings.resx</DependentUpon>
     </Compile>
   </ItemGroup>
@@ -109,33 +110,32 @@
   <!-- Nuget  -->
   <!-- =================================================================== -->
   <PropertyGroup>
-    <PackageId>Terminal.Gui</PackageId>
+    <PackageId>$(AssemblyName)</PackageId>
     <PackageLicenseExpression>MIT</PackageLicenseExpression>
-    <PackageProjectUrl>https://github.com/gui-cs/Terminal.Gui/</PackageProjectUrl>
+    <PackageProjectUrl>https://github.com/gui-cs/$(AssemblyName)</PackageProjectUrl>
     <PackageIcon>logo.png</PackageIcon>
     <PackageReadmeFile>README.md</PackageReadmeFile>
     <PackageTags>csharp, terminal, c#, f#, gui, toolkit, console, tui</PackageTags>
     <Description>Cross platform Terminal UI toolkit for .NET</Description>
     <Owners>Miguel de Icaza, Tig Kindel</Owners>
     <Summary>A toolkit for building rich console apps for .NET that works on Windows, Mac, and Linux/Unix.</Summary>
-    <Title>Terminal.Gui - Cross platform Terminal User Interface (TUI) toolkit for .NET</Title>
+    <Title>$(AssemblyName) - Cross-platform Terminal User Interface (TUI) toolkit for .NET</Title>
     <PackageReleaseNotes>
-      See: https://github.com/gui-cs/Terminal.Gui/releases
+      See: $(PackageProjectUrl)/releases
     </PackageReleaseNotes>
-    <DocumentationFile>bin\$(Configuration)\Terminal.Gui.xml</DocumentationFile>
+    <DocumentationFile>bin\$(Configuration)\$(AssemblyName).xml</DocumentationFile>
     <GeneratePackageOnBuild Condition=" '$(Configuration)' == 'Debug' ">true</GeneratePackageOnBuild>
     <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
-    <RepositoryUrl>https://github.com/gui-cs/Terminal.Gui.git</RepositoryUrl>
+    <RepositoryUrl>https://github.com/gui-cs/$(AssemblyName).git</RepositoryUrl>
     <RepositoryType>git</RepositoryType>
     <IncludeSymbols>true</IncludeSymbols>
     <SymbolPackageFormat>snupkg</SymbolPackageFormat>
     <!-- Publish the repository URL in the built .nupkg (in the NuSpec <Repository> element) -->
     <PublishRepositoryUrl>true</PublishRepositoryUrl>
-    <!-- Embed source files that are not tracked by the source control manager in the PDB -->
     <GitRepositoryRemoteName>upstream</GitRepositoryRemoteName>
+    <!-- Embed source files that are not tracked by the source control manager in the PDB -->
     <EmbedUntrackedSources>true</EmbedUntrackedSources>
     <EnableSourceLink>true</EnableSourceLink>
     <Authors>Miguel de Icaza, Tig Kindel (@tig), @BDisp</Authors>
-    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
   </PropertyGroup>
 </Project>

+ 0 - 26
Terminal.Gui/Text/StringEventArgs.cs

@@ -1,26 +0,0 @@
-using System.ComponentModel;
-
-namespace Terminal.Gui;
-
-/// <summary>Cancellable event args for string-based property change events.</summary>
-public class StringEventArgs : CancelEventArgs
-{
-    /// <summary>
-    /// Initializes a new instance of <see cref="StringEventArgs"/>
-    /// </summary>
-    public StringEventArgs () {}
-
-    /// <summary>Initializes a new instance of <see cref="StringEventArgs"/></summary>
-    /// <param name="oldString">The old string.</param>
-    /// <param name="newString">The new string.</param>
-    public StringEventArgs (string oldString, string newString)
-    {
-        OldValue = oldString;
-        NewValue = newString;
-    }
-    /// <summary>The new string.</summary>
-    public string NewValue { get; set; }
-
-    /// <summary>The old string.</summary>
-    public string OldValue { get; set; }
-}

+ 13 - 13
Terminal.Gui/View/Adornment/Adornment.cs

@@ -1,4 +1,6 @@
-namespace Terminal.Gui;
+#nullable enable
+using Terminal.Gui;
+using Attribute = Terminal.Gui.Attribute;
 
 /// <summary>
 ///     Adornments are a special form of <see cref="View"/> that appear outside the <see cref="View.Viewport"/>:
@@ -33,7 +35,7 @@ public class Adornment : View
     ///     Adornments are distinguished from typical View classes in that they are not sub-views, but have a parent/child
     ///     relationship with their containing View.
     /// </remarks>
-    public View Parent { get; set; }
+    public View? Parent { get; set; }
 
     #region Thickness
 
@@ -45,10 +47,10 @@ public class Adornment : View
         get => _thickness;
         set
         {
-            Thickness prev = _thickness;
+            Thickness current = _thickness;
             _thickness = value;
 
-            if (prev != _thickness)
+            if (current != _thickness)
             {
                 if (Parent?.IsInitialized == false)
                 {
@@ -61,21 +63,19 @@ public class Adornment : View
                     Parent?.LayoutSubviews ();
                 }
 
-                OnThicknessChanged (prev);
+                OnThicknessChanged ();
             }
         }
     }
 
     /// <summary>Fired whenever the <see cref="Thickness"/> property changes.</summary>
-    public event EventHandler<ThicknessEventArgs> ThicknessChanged;
+    [CanBeNull]
+    public event EventHandler? ThicknessChanged;
 
     /// <summary>Called whenever the <see cref="Thickness"/> property changes.</summary>
-    public void OnThicknessChanged (Thickness previousThickness)
+    public void OnThicknessChanged ()
     {
-        ThicknessChanged?.Invoke (
-                                  this,
-                                  new () { Thickness = Thickness, PreviousThickness = previousThickness }
-                                 );
+        ThicknessChanged?.Invoke (this, EventArgs.Empty);
     }
 
     #endregion Thickness
@@ -88,7 +88,7 @@ public class Adornment : View
     /// </summary>
     public override View SuperView
     {
-        get => null;
+        get => null!;
         set => throw new InvalidOperationException (@"Adornments can not be Subviews or have SuperViews. Use Parent instead.");
     }
 
@@ -137,7 +137,7 @@ public class Adornment : View
     /// <inheritdoc/>
     public override Point ScreenToFrame (in Point location)
     {
-        return Parent.ScreenToFrame (new (location.X - Frame.X, location.Y - Frame.Y));
+        return Parent!.ScreenToFrame (new (location.X - Frame.X, location.Y - Frame.Y));
     }
 
     /// <summary>Does nothing for Adornment</summary>

+ 98 - 53
Terminal.Gui/View/Adornment/Border.cs

@@ -78,7 +78,7 @@ public class Border : Adornment
         if ((Parent?.Arrangement & ViewArrangement.Movable) != 0)
         {
             HighlightStyle |= HighlightStyle.Hover;
-        }   
+        }
 #endif
 
         base.BeginInit ();
@@ -149,31 +149,32 @@ public class Border : Adornment
         }
     }
 
-    Rectangle GetBorderRectangle (Rectangle screenRect)
+    private Rectangle GetBorderRectangle (Rectangle screenRect)
     {
         return new (
-                                      screenRect.X + Math.Max (0, Thickness.Left - 1),
-                                      screenRect.Y + Math.Max (0, Thickness.Top - 1),
-                                      Math.Max (
-                                                0,
-                                                screenRect.Width
-                                                - Math.Max (
-                                                            0,
-                                                            Math.Max (0, Thickness.Left - 1)
-                                                            + Math.Max (0, Thickness.Right - 1)
-                                                           )
-                                               ),
-                                      Math.Max (
-                                                0,
-                                                screenRect.Height
-                                                - Math.Max (
-                                                            0,
-                                                            Math.Max (0, Thickness.Top - 1)
-                                                            + Math.Max (0, Thickness.Bottom - 1)
-                                                           )
-                                               )
-                                     );
+                    screenRect.X + Math.Max (0, Thickness.Left - 1),
+                    screenRect.Y + Math.Max (0, Thickness.Top - 1),
+                    Math.Max (
+                              0,
+                              screenRect.Width
+                              - Math.Max (
+                                          0,
+                                          Math.Max (0, Thickness.Left - 1)
+                                          + Math.Max (0, Thickness.Right - 1)
+                                         )
+                             ),
+                    Math.Max (
+                              0,
+                              screenRect.Height
+                              - Math.Max (
+                                          0,
+                                          Math.Max (0, Thickness.Top - 1)
+                                          + Math.Max (0, Thickness.Bottom - 1)
+                                         )
+                             )
+                   );
     }
+
     /// <summary>
     ///     Sets the style of the border by changing the <see cref="Thickness"/>. This is a helper API for setting the
     ///     <see cref="Thickness"/> to <c>(1,1,1,1)</c> and setting the line style of the views that comprise the border. If
@@ -196,21 +197,22 @@ public class Border : Adornment
         set => _lineStyle = value;
     }
 
-    private bool _showTitle = true;
+    private BorderSettings _settings = BorderSettings.Title;
 
     /// <summary>
-    ///     Gets or sets whether the title should be shown. The default is <see langword="true"/>.
+    ///     Gets or sets the settings for the border.
     /// </summary>
-    public bool ShowTitle
+    public BorderSettings Settings
     {
-        get => _showTitle;
+        get => _settings;
         set
         {
-            if (value == _showTitle)
+            if (value == _settings)
             {
                 return;
             }
-            _showTitle = value;
+
+            _settings = value;
 
             Parent?.SetNeedsDisplay ();
         }
@@ -220,24 +222,25 @@ public class Border : Adornment
 
     private Color? _savedForeColor;
 
-    private void Border_Highlight (object sender, HighlightEventArgs e)
+    private void Border_Highlight (object sender, CancelEventArgs<HighlightStyle> e)
     {
         if (!Parent.Arrangement.HasFlag (ViewArrangement.Movable))
         {
             e.Cancel = true;
+
             return;
         }
 
-        if (e.HighlightStyle.HasFlag (HighlightStyle.Pressed))
+        if (e.NewValue.HasFlag (HighlightStyle.Pressed))
         {
             if (!_savedForeColor.HasValue)
             {
                 _savedForeColor = ColorScheme.Normal.Foreground;
             }
 
-            ColorScheme cs = new ColorScheme (ColorScheme)
+            var cs = new ColorScheme (ColorScheme)
             {
-                Normal = new Attribute (ColorScheme.Normal.Foreground.GetHighlightColor (), ColorScheme.Normal.Background)
+                Normal = new (ColorScheme.Normal.Foreground.GetHighlightColor (), ColorScheme.Normal.Background)
             };
             ColorScheme = cs;
         }
@@ -252,14 +255,15 @@ public class Border : Adornment
         }
 #endif
 
-        if (e.HighlightStyle == HighlightStyle.None && _savedForeColor.HasValue)
+        if (e.NewValue == HighlightStyle.None && _savedForeColor.HasValue)
         {
-            ColorScheme cs = new ColorScheme (ColorScheme)
+            var cs = new ColorScheme (ColorScheme)
             {
-                Normal = new Attribute (_savedForeColor.Value, ColorScheme.Normal.Background)
+                Normal = new (_savedForeColor.Value, ColorScheme.Normal.Background)
             };
             ColorScheme = cs;
         }
+
         Parent?.SetNeedsDisplay ();
         e.Cancel = true;
     }
@@ -267,7 +271,7 @@ public class Border : Adornment
     private Point? _dragPosition;
     private Point _startGrabPoint;
 
-    /// <inheritdoc />
+    /// <inheritdoc/>
     protected internal override bool OnMouseEvent (MouseEvent mouseEvent)
     {
         if (base.OnMouseEvent (mouseEvent))
@@ -299,6 +303,7 @@ public class Border : Adornment
                 _startGrabPoint = new (mouseEvent.Position.X + Frame.X, mouseEvent.Position.Y + Frame.Y);
                 _dragPosition = mouseEvent.Position;
                 Application.GrabMouse (this);
+
                 SetHighlight (HighlightStyle);
             }
 
@@ -321,16 +326,17 @@ public class Border : Adornment
 
                 _dragPosition = mouseEvent.Position;
 
-                Point parentLoc = Parent.SuperView?.ScreenToViewport (new (mouseEvent.ScreenPosition.X, mouseEvent.ScreenPosition.Y)) ?? mouseEvent.ScreenPosition;
+                Point parentLoc = Parent.SuperView?.ScreenToViewport (new (mouseEvent.ScreenPosition.X, mouseEvent.ScreenPosition.Y))
+                                  ?? mouseEvent.ScreenPosition;
 
                 GetLocationEnsuringFullVisibility (
-                                     Parent,
-                                     parentLoc.X - _startGrabPoint.X,
-                                     parentLoc.Y - _startGrabPoint.Y,
-                                     out int nx,
-                                     out int ny,
-                                     out _
-                                    );
+                                                   Parent,
+                                                   parentLoc.X - _startGrabPoint.X,
+                                                   parentLoc.Y - _startGrabPoint.Y,
+                                                   out int nx,
+                                                   out int ny,
+                                                   out _
+                                                  );
 
                 Parent.X = nx;
                 Parent.Y = ny;
@@ -351,7 +357,6 @@ public class Border : Adornment
         return false;
     }
 
-
     /// <inheritdoc/>
     protected override void Dispose (bool disposing)
     {
@@ -402,7 +407,7 @@ public class Border : Adornment
         // ...thickness extends outward (border/title is always as far in as possible)
         // PERF: How about a call to Rectangle.Offset?
 
-        var borderBounds = GetBorderRectangle (screenBounds);
+        Rectangle borderBounds = GetBorderRectangle (screenBounds);
         int topTitleLineY = borderBounds.Y;
         int titleY = borderBounds.Y;
         var titleBarsLength = 0; // the little vertical thingies
@@ -420,7 +425,7 @@ public class Border : Adornment
         int sideLineLength = borderBounds.Height;
         bool canDrawBorder = borderBounds is { Width: > 0, Height: > 0 };
 
-        if (ShowTitle)
+        if (Settings.FastHasFlags (BorderSettings.Title))
         {
             if (Thickness.Top == 2)
             {
@@ -452,9 +457,10 @@ public class Border : Adornment
             }
         }
 
-        if (canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && ShowTitle && !string.IsNullOrEmpty (Parent?.Title))
+        if (canDrawBorder && Thickness.Top > 0 && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title) && !string.IsNullOrEmpty (Parent?.Title))
         {
-            var focus = Parent.GetNormalColor ();
+            Attribute focus = Parent.GetNormalColor ();
+
             if (Parent.SuperView is { } && Parent.SuperView?.Subviews!.Count (s => s.CanFocus) > 1)
             {
                 // Only use focus color if there are multiple focusable views
@@ -491,7 +497,7 @@ public class Border : Adornment
             {
                 // ╔╡Title╞═════╗
                 // ╔╡╞═════╗
-                if (borderBounds.Width < 4 || !ShowTitle || string.IsNullOrEmpty (Parent?.Title))
+                if (borderBounds.Width < 4 || !Settings.FastHasFlags (BorderSettings.Title) || string.IsNullOrEmpty (Parent?.Title))
                 {
                     // ╔╡╞╗ should be ╔══╗
                     lc.AddLine (
@@ -630,7 +636,7 @@ public class Border : Adornment
             Driver.SetAttribute (prevAttr);
 
             // TODO: This should be moved to LineCanvas as a new BorderStyle.Ruler
-            if (View.Diagnostics.HasFlag (ViewDiagnosticFlags.Ruler))
+            if (Diagnostics.HasFlag (ViewDiagnosticFlags.Ruler))
             {
                 // Top
                 var hruler = new Ruler { Length = screenBounds.Width, Orientation = Orientation.Horizontal };
@@ -641,7 +647,7 @@ public class Border : Adornment
                 }
 
                 // Redraw title 
-                if (drawTop && maxTitleWidth > 0 && ShowTitle)
+                if (drawTop && maxTitleWidth > 0 && Settings.FastHasFlags (BorderSettings.Title))
                 {
                     Parent.TitleTextFormatter.Draw (
                                                     new (borderBounds.X + 2, titleY, maxTitleWidth, 1),
@@ -669,6 +675,45 @@ public class Border : Adornment
                     vruler.Draw (new (screenBounds.X + screenBounds.Width - 1, screenBounds.Y + 1), 1);
                 }
             }
+
+            // TODO: This should not be done on each draw?
+            if (Settings.FastHasFlags (BorderSettings.Gradient))
+            {
+                SetupGradientLineCanvas (lc, screenBounds);
+            }
+            else
+            {
+                lc.Fill = null;
+            }
         }
     }
+
+    private void SetupGradientLineCanvas (LineCanvas lc, Rectangle rect)
+    {
+        GetAppealingGradientColors (out List<Color> stops, out List<int> steps);
+
+        var g = new Gradient (stops, steps);
+
+        var fore = new GradientFill (rect, g, GradientDirection.Diagonal);
+        var back = new SolidFill (GetNormalColor ().Background);
+
+        lc.Fill = new (fore, back);
+    }
+
+    private static void GetAppealingGradientColors (out List<Color> stops, out List<int> steps)
+    {
+        // Define the colors of the gradient stops with more appealing colors
+        stops = new()
+        {
+            new (0, 128, 255), // Bright Blue
+            new (0, 255, 128), // Bright Green
+            new (255, 255), // Bright Yellow
+            new (255, 128), // Bright Orange
+            new (255, 0, 128) // Bright Pink
+        };
+
+        // Define the number of steps between each color for smoother transitions
+        // If we pass only a single value then it will assume equal steps between all pairs
+        steps = new() { 15 };
+    }
 }

+ 26 - 0
Terminal.Gui/View/Adornment/BorderSettings.cs

@@ -0,0 +1,26 @@
+
+
+namespace Terminal.Gui;
+
+/// <summary>
+/// Determines the settings for <see cref="Border"/>.
+/// </summary>
+[Flags]
+
+public enum BorderSettings
+{
+    /// <summary>
+    /// No settings.
+    /// </summary>
+    None = 0,
+
+    /// <summary>
+    /// Show the title.
+    /// </summary>
+    Title = 1,
+
+    /// <summary>
+    /// Use <see cref="GradientFill"/> to draw the border.
+    /// </summary>
+    Gradient = 2,
+}

+ 192 - 2
Terminal.Gui/View/Adornment/Margin.cs

@@ -1,4 +1,6 @@
-namespace Terminal.Gui;
+#nullable enable
+
+namespace Terminal.Gui;
 
 /// <summary>The Margin for a <see cref="View"/>.</summary>
 /// <remarks>
@@ -15,6 +17,52 @@ public class Margin : Adornment
     public Margin (View parent) : base (parent)
     {
         /* Do nothing; View.CreateAdornment requires a constructor that takes a parent */
+
+        HighlightStyle |= HighlightStyle.Pressed;
+        Highlight += Margin_Highlight;
+        LayoutStarted += Margin_LayoutStarted;
+
+        // Margin should not be focusable
+        CanFocus = false;
+    }
+
+    private bool _pressed;
+
+    private ShadowView? _bottomShadow;
+    private ShadowView? _rightShadow;
+
+    /// <inheritdoc/>
+    public override void BeginInit ()
+    {
+        base.BeginInit ();
+
+        if (Parent is null)
+        {
+            return;
+        }
+
+        ShadowStyle = base.ShadowStyle;
+
+        Add (
+             _rightShadow = new()
+             {
+                 X = Pos.AnchorEnd (1),
+                 Y = 0,
+                 Width = 1,
+                 Height = Dim.Fill (),
+                 ShadowStyle = ShadowStyle,
+                 Orientation = Orientation.Vertical
+             },
+             _bottomShadow = new()
+             {
+                 X = 0,
+                 Y = Pos.AnchorEnd (1),
+                 Width = Dim.Fill (),
+                 Height = 1,
+                 ShadowStyle = ShadowStyle,
+                 Orientation = Orientation.Horizontal
+             }
+            );
     }
 
     /// <summary>
@@ -30,7 +78,7 @@ public class Margin : Adornment
                 return base.ColorScheme;
             }
 
-            return Parent?.SuperView?.ColorScheme ?? Colors.ColorSchemes ["TopLevel"];
+            return (Parent?.SuperView?.ColorScheme ?? Colors.ColorSchemes ["TopLevel"])!;
         }
         set
         {
@@ -38,4 +86,146 @@ public class Margin : Adornment
             Parent?.SetNeedsDisplay ();
         }
     }
+
+    /// <inheritdoc/>
+    public override void OnDrawContent (Rectangle viewport)
+    {
+        Rectangle screen = ViewportToScreen (viewport);
+        Attribute normalAttr = GetNormalColor ();
+
+        Driver?.SetAttribute (normalAttr);
+
+        // This just draws/clears the thickness, not the insides.
+        if (ShadowStyle != ShadowStyle.None)
+        {
+            screen = Rectangle.Inflate (screen, -1, -1);
+        }
+
+        Thickness.Draw (screen, ToString ());
+
+        if (Subviews.Count > 0)
+        {
+            // Draw subviews
+            // TODO: Implement OnDrawSubviews (cancelable);
+            if (Subviews is { } && SubViewNeedsDisplay)
+            {
+                IEnumerable<View> subviewsNeedingDraw = Subviews.Where (
+                                                                        view => view.Visible
+                                                                                && (view.NeedsDisplay || view.SubViewNeedsDisplay || view.LayoutNeeded)
+                                                                       );
+
+                foreach (View view in subviewsNeedingDraw)
+                {
+                    if (view.LayoutNeeded)
+                    {
+                        view.LayoutSubviews ();
+                    }
+
+                    view.Draw ();
+                }
+            }
+        }
+    }
+
+    /// <summary>
+    ///     Sets whether the Margin includes a shadow effect. The shadow is drawn on the right and bottom sides of the
+    ///     Margin.
+    /// </summary>
+    public ShadowStyle SetShadow (ShadowStyle style)
+    {
+        if (ShadowStyle == style)
+        {
+            // return style;
+        }
+
+        if (ShadowStyle != ShadowStyle.None)
+        {
+            // Turn off shadow
+            Thickness = new (Thickness.Left, Thickness.Top, Thickness.Right - 1, Thickness.Bottom - 1);
+        }
+
+        if (style != ShadowStyle.None)
+        {
+            // Turn on shadow
+            Thickness = new (Thickness.Left, Thickness.Top, Thickness.Right + 1, Thickness.Bottom + 1);
+        }
+
+        if (_rightShadow is { })
+        {
+            _rightShadow.ShadowStyle = style;
+        }
+
+        if (_bottomShadow is { })
+        {
+            _bottomShadow.ShadowStyle = style;
+        }
+
+        return style;
+    }
+
+    /// <inheritdoc/>
+    public override ShadowStyle ShadowStyle
+    {
+        get => base.ShadowStyle;
+        set => base.ShadowStyle = SetShadow (value);
+    }
+
+    private void Margin_Highlight (object? sender, CancelEventArgs<HighlightStyle> e)
+    {
+        if (ShadowStyle != ShadowStyle.None)
+        {
+            if (_pressed && e.NewValue == HighlightStyle.None)
+            {
+                // If the view is pressed and the highlight is being removed, move the shadow back.
+                // Note, for visual effects reasons, we only move horizontally.
+                // TODO: Add a setting or flag that lets the view move vertically as well.
+                Thickness = new (Thickness.Left - 1, Thickness.Top, Thickness.Right + 1, Thickness.Bottom);
+
+                if (_rightShadow is { })
+                {
+                    _rightShadow.Visible = true;
+                }
+
+                if (_bottomShadow is { })
+                {
+                    _bottomShadow.Visible = true;
+                }
+
+                _pressed = false;
+
+                return;
+            }
+
+            if (!_pressed && e.NewValue.HasFlag (HighlightStyle.Pressed))
+            {
+                // If the view is not pressed and we want highlight move the shadow
+                // Note, for visual effects reasons, we only move horizontally.
+                // TODO: Add a setting or flag that lets the view move vertically as well.
+                Thickness = new (Thickness.Left + 1, Thickness.Top, Thickness.Right - 1, Thickness.Bottom);
+                _pressed = true;
+
+                if (_rightShadow is { })
+                {
+                    _rightShadow.Visible = false;
+                }
+
+                if (_bottomShadow is { })
+                {
+                    _bottomShadow.Visible = false;
+                }
+            }
+        }
+    }
+
+    private void Margin_LayoutStarted (object? sender, LayoutEventArgs e)
+    {
+        // Adjust the shadow such that it is drawn aligned with the Border
+        if (ShadowStyle != ShadowStyle.None && _rightShadow is { } && _bottomShadow is { })
+        {
+            _rightShadow.Y = Parent.Border.Thickness.Top > 0
+                                 ? Parent.Border.Thickness.Top - (Parent.Border.Thickness.Top > 2 && Parent.Border.Settings.FastHasFlags (BorderSettings.Title) ? 1 : 0)
+                                 : 1;
+            _bottomShadow.X = Parent.Border.Thickness.Left > 0 ? Parent.Border.Thickness.Left : 1;
+        }
+    }
 }

Some files were not shown because too many files changed in this diff