Merge pull request #3448 from dodexahedron/41-clean-up-unusedunimplemented-code-from-existing-analyzer-project

Fixes #3443 - clean up unused/unimplemented code from existing analyzer project
This commit is contained in:
Tig
2024-05-03 11:33:03 -06:00
committed by GitHub
24 changed files with 143 additions and 735 deletions

View File

@@ -0,0 +1,23 @@
<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>

View File

@@ -4,7 +4,6 @@
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis" Version="4.9.2" PrivateAssets="all" />

View File

@@ -4,15 +4,12 @@
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineTrace>True</DefineTrace>
<DebugType>portable</DebugType>
<DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
<ImplicitUsings>enable</ImplicitUsings>
<NoLogo>True</NoLogo>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
</PropertyGroup>

View File

@@ -1,4 +1,5 @@
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable once RedundantNullableDirective
#nullable enable
namespace Terminal.Gui.Analyzers.Internal.Attributes;

View File

@@ -1,22 +0,0 @@
using System;
using JetBrains.Annotations;
namespace Terminal.Gui.Analyzers.Internal.Attributes;
/// <summary>
/// Designates an enum member for inclusion in generation of bitwise combinations with other members decorated with
/// this attribute which have the same <see cref="GroupTag"/> value.<br/>
/// </summary>
/// <remarks>
/// This attribute is only considered for members of enum types which have the
/// <see cref="GenerateEnumExtensionMethodsAttribute"/>.
/// </remarks>
[AttributeUsage (AttributeTargets.Field)]
[UsedImplicitly]
internal sealed class CombinationGroupingAttribute : Attribute
{
/// <summary>
/// Name of a group this member participates in, for FastHasFlags.
/// </summary>
public string GroupTag { get; set; }
}

View File

@@ -1,110 +0,0 @@
// ReSharper disable RedundantUsingDirective
using System;
using JetBrains.Annotations;
using Terminal.Gui.Analyzers.Internal.Compatibility;
namespace Terminal.Gui.Analyzers.Internal.Attributes;
/// <summary>
/// Designates an enum member for inclusion in generation of bitwise combinations with other members decorated with
/// this attribute which have the same <see cref="GroupTag"/> value.<br/>
/// </summary>
/// <remarks>
/// <para>
/// This attribute is only considered for enum types with the <see cref="GenerateEnumExtensionMethodsAttribute"/>.
/// </para>
/// </remarks>
[AttributeUsage (AttributeTargets.Enum)]
[UsedImplicitly]
public sealed class GenerateEnumMemberCombinationsAttribute : System.Attribute
{
private const byte MaximumPopCountLimit = 14;
private uint _mask;
private uint _maskPopCount;
private byte _popCountLimit = 8;
/// <inheritdoc cref="CombinationGroupingAttribute.GroupTag" />
public string GroupTag { get; set; }
/// <summary>
/// The mask for the group defined in <see cref="GroupTag"/>
/// </summary>
public uint Mask
{
get => _mask;
set
{
#if NET8_0_OR_GREATER
_maskPopCount = uint.PopCount (value);
#else
_maskPopCount = value.GetPopCount ();
#endif
PopCountLimitExceeded = _maskPopCount > PopCountLimit;
MaximumPopCountLimitExceeded = _maskPopCount > MaximumPopCountLimit;
if (PopCountLimitExceeded || MaximumPopCountLimitExceeded)
{
return;
}
_mask = value;
}
}
/// <summary>
/// The maximum number of bits allowed to be set to 1 in <see cref="Mask"/>.
/// </summary>
/// <remarks>
/// <para>
/// Default: 8 (256 possible combinations)
/// </para>
/// <para>
/// Increasing this value is not recommended!<br/>
/// Decreasing this value is pointless unless you want to limit maximum possible generated combinations even
/// further.
/// </para>
/// <para>
/// If the result of <see cref="NumericExtensions.GetPopCount(uint)"/>(<see cref="Mask"/>) exceeds 2 ^
/// <see cref="PopCountLimit"/>, no
/// combinations will be generated for the members which otherwise would have been included by <see cref="Mask"/>.
/// Values exceeding the actual population count of <see cref="Mask"/> have no effect.
/// </para>
/// <para>
/// This option is set to a sane default of 8, but also has a hard-coded limit of 14 (16384 combinations), as a
/// protection against generation of extremely large files.
/// </para>
/// <para>
/// CAUTION: The maximum number of possible combinations possible is equal to 1 &lt;&lt;
/// <see cref="NumericExtensions.GetPopCount(uint)"/>(<see cref="Mask"/>).
/// See <see cref="MaximumPopCountLimit"/> for hard-coded limit,
/// </para>
/// </remarks>
public byte PopCountLimit
{
get => _popCountLimit;
set
{
#if NET8_0_OR_GREATER
_maskPopCount = uint.PopCount (_mask);
#else
_maskPopCount = _mask.GetPopCount ();
#endif
PopCountLimitExceeded = _maskPopCount > value;
MaximumPopCountLimitExceeded = _maskPopCount > MaximumPopCountLimit;
if (PopCountLimitExceeded || MaximumPopCountLimitExceeded)
{
return;
}
_mask = value;
_popCountLimit = value;
}
}
[UsedImplicitly]
internal bool MaximumPopCountLimitExceeded { get; private set; }
[UsedImplicitly]
internal bool PopCountLimitExceeded { get; private set; }
}

View File

@@ -1,33 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ReSharper disable once CheckNamespace
namespace System.Runtime.CompilerServices;
/// <summary>
/// Indicates that compiler support for a particular feature is required for the location where this attribute is
/// applied.
/// </summary>
[AttributeUsage (AttributeTargets.All, AllowMultiple = true, Inherited = false)]
internal sealed class CompilerFeatureRequiredAttribute(string featureName) : Attribute
{
/// <summary>
/// The <see cref="FeatureName"/> used for the ref structs C# feature.
/// </summary>
public const string RefStructs = nameof (RefStructs);
/// <summary>
/// The <see cref="FeatureName"/> used for the required members C# feature.
/// </summary>
public const string RequiredMembers = nameof (RequiredMembers);
/// <summary>
/// The name of the compiler feature.
/// </summary>
public string FeatureName { get; } = featureName;
/// <summary>
/// If true, the compiler can choose to allow access to the location where this attribute is applied if it does not
/// understand <see cref="FeatureName"/>.
/// </summary>
public bool IsOptional { get; init; }
}

View File

@@ -1,18 +0,0 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
// ReSharper disable CheckNamespace
namespace System.Runtime.CompilerServices;
/// <summary>
/// Reserved to be used by the compiler for tracking metadata.
/// This class should not be used by developers in source code.
/// </summary>
/// <remarks>
/// Copied from .net source code, for support of init property accessors in netstandard2.0.
/// </remarks>
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
[EditorBrowsable (EditorBrowsableState.Never)]
public static class IsExternalInit;

View File

@@ -1,208 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
// This file is further modified from the original, for this project,
// to comply with project style.
// No changes are made which affect compatibility with the same types from
// APIs later than netstandard2.0, nor will this file be included in compilations
// targeted at later APIs.
//
// Originally rom https://github.com/dotnet/runtime/blob/ef72b95937703e485fdbbb75f3251fedfd1a0ef9/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
// ReSharper disable CheckNamespace
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable UnusedType.Global
namespace System.Diagnostics.CodeAnalysis;
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class AllowNullAttribute : Attribute;
/// <summary>Specifies that null is disallowed as an input even if the corresponding type allows it.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class DisallowNullAttribute : Attribute;
/// <summary>Specifies that an output may be null even if the corresponding type disallows it.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class MaybeNullAttribute : Attribute;
/// <summary>
/// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input
/// argument was not null when the call returns.
/// </summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class NotNullAttribute : Attribute;
/// <summary>
/// Specifies that when a method returns <see cref="ReturnValue"/>, the parameter may be null even if the corresponding
/// type disallows it.
/// </summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Parameter)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class MaybeNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter may be null.
/// </param>
#pragma warning disable IDE0290 // Use primary constructor
public MaybeNullWhenAttribute (bool returnValue) { ReturnValue = returnValue; }
#pragma warning restore IDE0290 // Use primary constructor
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
}
/// <summary>
/// Specifies that when a method returns <see cref="ReturnValue"/>, the parameter will not be null even if the
/// corresponding type allows it.
/// </summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Parameter)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class NotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
#pragma warning disable IDE0290 // Use primary constructor
public NotNullWhenAttribute (bool returnValue) { ReturnValue = returnValue; }
#pragma warning restore IDE0290 // Use primary constructor
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
}
/// <summary>Specifies that the output will be non-null if the named parameter is non-null.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class NotNullIfNotNullAttribute : Attribute
{
/// <summary>Initializes the attribute with the associated parameter name.</summary>
/// <param name="parameterName">
/// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null.
/// </param>
#pragma warning disable IDE0290 // Use primary constructor
public NotNullIfNotNullAttribute (string parameterName) { ParameterName = parameterName; }
#pragma warning restore IDE0290 // Use primary constructor
/// <summary>Gets the associated parameter name.</summary>
public string ParameterName { get; }
}
/// <summary>Applied to a method that will never return under any circumstance.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class DoesNotReturnAttribute : Attribute;
/// <summary>Specifies that the method will not return if the associated Boolean parameter is passed the specified value.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Parameter)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class DoesNotReturnIfAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified parameter value.</summary>
/// <param name="parameterValue">
/// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument
/// to
/// the associated parameter matches this value.
/// </param>
#pragma warning disable IDE0290 // Use primary constructor
public DoesNotReturnIfAttribute (bool parameterValue) { ParameterValue = parameterValue; }
#pragma warning restore IDE0290 // Use primary constructor
/// <summary>Gets the condition parameter value.</summary>
public bool ParameterValue { get; }
}
/// <summary>
/// Specifies that the method or property will ensure that the listed field and property members have not-null
/// values.
/// </summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class MemberNotNullAttribute : Attribute
{
/// <summary>Initializes the attribute with a field or property member.</summary>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullAttribute (string member) { Members = [member]; }
/// <summary>Initializes the attribute with the list of field and property members.</summary>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullAttribute (params string [] members) { Members = members; }
/// <summary>Gets field or property member names.</summary>
public string [] Members { get; }
}
/// <summary>
/// Specifies that the method or property will ensure that the listed field and property members have not-null values
/// when returning with the specified return value condition.
/// </summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
[DebuggerNonUserCode]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute (bool returnValue, string member)
{
ReturnValue = returnValue;
Members = [member];
}
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute (bool returnValue, params string [] members)
{
ReturnValue = returnValue;
Members = members;
}
/// <summary>Gets field or property member names.</summary>
public string [] Members { get; }
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
}

View File

@@ -1,12 +0,0 @@
// ReSharper disable CheckNamespace
// ReSharper disable ConditionalAnnotation
using JetBrains.Annotations;
namespace System.Runtime.CompilerServices;
/// <summary>Polyfill to enable netstandard2.0 assembly to use the required keyword.</summary>
/// <remarks>Excluded from output assembly via file specified in ApiCompatExcludeAttributesFile element in the project file.</remarks>
[AttributeUsage (AttributeTargets.Property)]
[UsedImplicitly]
public sealed class RequiredMemberAttribute : Attribute;

View File

@@ -1,12 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ReSharper disable once CheckNamespace
namespace System.Diagnostics.CodeAnalysis;
/// <summary>
/// Specifies that this constructor sets all required members for the current type, and callers
/// do not need to set any required members themselves.
/// </summary>
[AttributeUsage (AttributeTargets.Constructor)]
public sealed class SetsRequiredMembersAttribute : Attribute;

View File

@@ -1,14 +0,0 @@
namespace System.Runtime.CompilerServices;
[AttributeUsage (
AttributeTargets.Class
| AttributeTargets.Constructor
| AttributeTargets.Event
| AttributeTargets.Interface
| AttributeTargets.Method
| AttributeTargets.Module
| AttributeTargets.Property
| AttributeTargets.Struct,
Inherited = false)]
internal sealed class SkipLocalsInitAttribute : Attribute;

View File

@@ -46,7 +46,7 @@ internal static class Strings
/// <inheritdoc cref="ExcludeFromCodeCoverageAttribute"/>
internal const string ExcludeFromCodeCoverage = $"{Namespaces.System_Diagnostics_CodeAnalysis}.{nameof (ExcludeFromCodeCoverageAttribute)}";
internal const string Flags = $"{Namespaces.SystemNS}.{nameof (FlagsAttribute)}";
internal const string Flags = $"{Namespaces.SystemNs}.{nameof (FlagsAttribute)}";
internal const string GeneratedCode = $"{Namespaces.System_CodeDom_Compiler}.{nameof (GeneratedCodeAttribute)}";
@@ -83,22 +83,24 @@ internal static class Strings
/// <summary>Names of dotnet namespaces.</summary>
internal static class Namespaces
{
internal const string SystemNS = nameof (System);
internal const string System_CodeDom = $"{SystemNS}.{nameof (System.CodeDom)}";
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_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_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 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)}";
@@ -131,7 +133,7 @@ internal static class Strings
/// <summary>Using directives for common namespaces in generated code.</summary>
internal const string DotnetNamespaceUsingDirectives = $"""
using {DotnetNames.Namespaces.SystemNS};
using {DotnetNames.Namespaces.SystemNs};
using {DotnetNames.Namespaces.System_CodeDom};
using {DotnetNames.Namespaces.System_CodeDom_Compiler};
using {DotnetNames.Namespaces.System_ComponentModel};

View File

@@ -147,14 +147,14 @@ internal sealed class CodeWriter (in EnumExtensionMethodsGenerationInfo metadata
switch (Metadata.EnumBackingTypeCode)
{
case TypeCode.Int32:
foreach (int definedValue in Metadata.IntMembers)
foreach (int definedValue in Metadata._intMembers)
{
w.WriteLine ($"{definedValue:D} => true,");
}
break;
case TypeCode.UInt32:
foreach (uint definedValue in Metadata.UIntMembers)
foreach (uint definedValue in Metadata._uIntMembers)
{
w.WriteLine ($"{definedValue:D} => true,");
}

View File

@@ -24,15 +24,13 @@ namespace Terminal.Gui.Analyzers.Internal.Generators.EnumExtensions;
internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetadata<EnumExtensionMethodsGenerationInfo>,
IEqualityOperators<EnumExtensionMethodsGenerationInfo, EnumExtensionMethodsGenerationInfo, bool>
{
private const int ExplicitFastHasFlagsMask = 0b1000;
private const int ExplicitFastIsDefinedMask = 0b1_0000;
private const int ExplicitIncludeInterfaceMask = 0b10_0000;
private const int ExplicitNameMask = 0b10;
private const int ExplicitNamespaceMask = 0b1;
private const int ExplicitPartialMask = 0b100;
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 = Constants.Strings.AnalyzersAttributesNamespace;
private const string GeneratorAttributeNamespace = Strings.AnalyzersAttributesNamespace;
/// <summary>
/// Type containing the information necessary to generate code according to the declared attribute values,
@@ -90,7 +88,7 @@ internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetada
}
[AccessedThroughProperty (nameof (EnumBackingTypeCode))]
private TypeCode _enumBackingTypeCode;
private readonly TypeCode _enumBackingTypeCode;
[AccessedThroughProperty (nameof (GeneratedTypeName))]
private string? _generatedTypeName;
@@ -159,7 +157,7 @@ internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetada
public bool IsStatic => true;
/// <inheritdoc/>
public bool IncludeInterface { get; private set; }
public bool IncludeInterface => false;
public string GeneratedTypeFullName => $"{GeneratedTypeNamespace}.{GeneratedTypeName}";
@@ -189,7 +187,7 @@ internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetada
public TypeCode EnumBackingTypeCode
{
get => _enumBackingTypeCode;
set
init
{
if (value is not TypeCode.Int32 and not TypeCode.UInt32)
{
@@ -208,8 +206,8 @@ internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetada
/// <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;
internal ImmutableHashSet<int>? _intMembers;
internal ImmutableHashSet<uint>? _uIntMembers;
/// <summary>
/// Fully-qualified name of the extension class
@@ -309,11 +307,11 @@ internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetada
{
ImmutableArray<ISymbol> enumMembers = enumSymbol.GetMembers ();
IEnumerable<IFieldSymbol> fieldSymbols = enumMembers.OfType<IFieldSymbol> ();
IntMembers = fieldSymbols.Select (static m => m.HasConstantValue ? (int)m.ConstantValue : 0).ToImmutableHashSet ();
_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 ();
_uIntMembers = enumSymbol.GetMembers ().OfType<IFieldSymbol> ().Select (static m => (uint)m.ConstantValue).ToImmutableHashSet ();
}
private bool HasExplicitFastHasFlags
@@ -328,18 +326,6 @@ internal sealed record EnumExtensionMethodsGenerationInfo : IGeneratedTypeMetada
set => _discoveredProperties [ExplicitFastIsDefinedMask] = value;
}
private bool HasExplicitIncludeInterface
{
[UsedImplicitly]get => _discoveredProperties [ExplicitIncludeInterfaceMask];
set => _discoveredProperties [ExplicitIncludeInterfaceMask] = value;
}
private bool HasExplicitPartial
{
[UsedImplicitly]get => _discoveredProperties [ExplicitPartialMask];
set => _discoveredProperties [ExplicitPartialMask] = value;
}
private bool HasExplicitTypeName
{
get => _discoveredProperties [ExplicitNameMask];

View File

@@ -22,7 +22,7 @@ public sealed class EnumExtensionMethodsIncrementalGenerator : IIncrementalGener
private const string GeneratorAttributeName = nameof (GenerateEnumExtensionMethodsAttribute);
/// <summary>Fully-qualified symbol name format without the "global::" prefix.</summary>
private static readonly SymbolDisplayFormat FullyQualifiedSymbolDisplayFormatWithoutGlobal =
private static readonly SymbolDisplayFormat _fullyQualifiedSymbolDisplayFormatWithoutGlobal =
SymbolDisplayFormat.FullyQualifiedFormat.WithGlobalNamespaceStyle (SymbolDisplayGlobalNamespaceStyle.Omitted);
/// <inheritdoc/>
@@ -160,7 +160,7 @@ public sealed class EnumExtensionMethodsIncrementalGenerator : IIncrementalGener
string enumName = namedSymbol.Name;
string enumNamespace = enumNamespaceSymbol.ToDisplayString (FullyQualifiedSymbolDisplayFormatWithoutGlobal);
string enumNamespace = enumNamespaceSymbol.ToDisplayString (_fullyQualifiedSymbolDisplayFormatWithoutGlobal);
TypeCode enumTypeCode = namedSymbol.EnumUnderlyingType.Name switch
{
@@ -260,8 +260,8 @@ public sealed class EnumExtensionMethodsIncrementalGenerator : IIncrementalGener
/// Used to enable source generation of a common set of extension methods for enum types.
/// </summary>
{{Strings.Templates.AttributesForGeneratedTypes}}
[System.AttributeUsageAttribute (System.AttributeTargets.Enum)]
public sealed class {{GeneratorAttributeName}} : Attribute
[{{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.

View File

@@ -1,130 +0,0 @@
using System.Text;
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>
/// Implementation of <see cref="IIncrementalGenerator"/> for types decorated with <see cref="GenerateEnumMemberCombinationsAttribute"/>.
/// </summary>
[Generator]
internal sealed class EnumMemberCombinationsGenerator : IIncrementalGenerator
{
private const string AttributeCodeText = $$"""
{{Strings.Templates.StandardHeader}}
namespace {{Strings.AnalyzersAttributesNamespace}};
/// <summary>
/// Designates an enum member for inclusion in generation of bitwise combinations with other members decorated with
/// this attribute which have the same <see cref="{{nameof (GenerateEnumMemberCombinationsAttribute.GroupTag)}}"/> value.<br/>
/// </summary>
/// <remarks>
/// <para>
/// This attribute is only considered for enum types with the <see cref="{{nameof (GenerateEnumMemberCombinationsAttribute)}}"/>.
/// </para>
/// <para>
/// Masks with more than 8 bits set will
/// </para>
/// </remarks>
[AttributeUsageAttribute(AttributeTargets.Enum)]
internal sealed class {{nameof (GenerateEnumMemberCombinationsAttribute)}} : System.Attribute
{
public const byte MaximumPopCountLimit = 14;
private uint _mask;
private uint _maskPopCount;
private byte _popCountLimit = 8;
public required string GroupTag { get; set; }
public required uint Mask
{
get => _mask;
set
{
_maskPopCount = uint.PopCount(value);
PopCountLimitExceeded = _maskPopCount > PopCountLimit;
MaximumPopCountLimitExceeded = _maskPopCount > MaximumPopCountLimit;
if (PopCountLimitExceeded || MaximumPopCountLimitExceeded)
{
return;
}
_mask = value;
}
}
/// <summary>
/// The maximum number of bits allowed to be set to 1 in <see cref="{{nameof (GenerateEnumMemberCombinationsAttribute.Mask)}}"/>.
/// </summary>
/// <remarks>
/// <para>
/// Default: 8 (256 possible combinations)
/// </para>
/// <para>
/// Increasing this value is not recommended!<br/>
/// Decreasing this value is pointless unless you want to limit maximum possible generated combinations even
/// further.
/// </para>
/// <para>
/// If the result of <see cref="uint.PopCount"/>(<see cref="{{nameof (GenerateEnumMemberCombinationsAttribute.Mask)}}"/>) exceeds 2 ^ <see cref="PopCountLimit"/>, no
/// combinations will be generated for the members which otherwise would have been included by <see cref="{{nameof (GenerateEnumMemberCombinationsAttribute.Mask)}}"/>.
/// Values exceeding the actual population count of <see cref="{{nameof (GenerateEnumMemberCombinationsAttribute.Mask)}}"/> have no effect.
/// </para>
/// <para>
/// This option is set to a sane default of 8, but also has a hard-coded limit of 14 (16384 combinations), as a
/// protection against generation of extremely large files.
/// </para>
/// <para>
/// CAUTION: The maximum number of possible combinations possible is equal to 1 &lt;&lt;
/// <see cref="uint.PopCount"/>(<see cref="{{nameof (GenerateEnumMemberCombinationsAttribute.Mask)}}"/>).
/// See <see cref="MaximumPopCountLimit"/> for hard-coded limit,
/// </para>
/// </remarks>
public byte PopCountLimit
{
get => _popCountLimit;
set
{
_maskPopCount = uint.PopCount(_mask);
PopCountLimitExceeded = _maskPopCount > value;
MaximumPopCountLimitExceeded = _maskPopCount > MaximumPopCountLimit;
if (PopCountLimitExceeded || MaximumPopCountLimitExceeded)
{
return;
}
_mask = value;
_popCountLimit = value;
}
}
internal bool MaximumPopCountLimitExceeded { get; private set; }
internal bool PopCountLimitExceeded { get; private set; }
}
""";
private const string AttributeFullyQualifiedName = $"{Strings.AnalyzersAttributesNamespace}.{AttributeName}";
private const string AttributeName = "GenerateEnumMemberCombinationsAttribute";
/// <inheritdoc/>
public void Initialize (IncrementalGeneratorInitializationContext context)
{
context.RegisterPostInitializationOutput (GenerateAttributeCode);
return;
static void GenerateAttributeCode (IncrementalGeneratorPostInitializationContext initContext)
{
#pragma warning disable IDE0061 // Use expression body for local function
initContext.AddSource ($"{AttributeFullyQualifiedName}.g.cs", SourceText.From (AttributeCodeText, Encoding.UTF8));
#pragma warning restore IDE0061 // Use expression body for local function
}
}
}

View File

@@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!--
Do not remove netstandard2.0 from the TargetFrameworks.
Do not remove netstandard2.0 from the TargetFramework.
Visual Studio requires that Analyzers/Generators target netstandard2.0 to work properly.
Additional TFMs are for support of additional APIs and language features.
Also do not change this to TargetFrameworks without fully understanding the behavior change that implies.
-->
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
@@ -11,21 +11,14 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<LangVersion>12</LangVersion>
<Nullable>enable</Nullable>
<RootNamespace>Terminal.Gui.Analyzers.Internal</RootNamespace>
<ImplicitUsings>disable</ImplicitUsings>
<InvariantGlobalization>true</InvariantGlobalization>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<WarningLevel>7</WarningLevel>
<CharacterSet>UTF-8</CharacterSet>
<CodeAnalysisIgnoreGeneratedCode>true</CodeAnalysisIgnoreGeneratedCode>
<Deterministic>true</Deterministic>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<UTF8OutPut>true</UTF8OutPut>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<IsRoslynComponent>true</IsRoslynComponent>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
@@ -39,33 +32,13 @@
<Compile Remove="Compatibility/*.cs" />
</ItemGroup>
<Choose>
<When Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PropertyGroup>
<!-- Disabling some useless warnings caused by the netstandard2.0 target -->
<NoWarn>$(NoWarn);nullable;CA1067</NoWarn>
</PropertyGroup>
<ItemGroup>
<Compile Include="Compatibility/CompilerFeatureRequiredAttribute.cs" />
<Compile Include="Compatibility/IsExternalInit.cs" />
<Compile Include="Compatibility/IEqualityOperators.cs" />
<Compile Include="Compatibility/NullableAttributes.cs" />
<Compile Include="Compatibility/RequiredMemberAttribute.cs" />
<Compile Include="Compatibility/SetsRequiredMembersAttribute.cs" />
</ItemGroup>
<ItemGroup>
<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>
</When>
<When Condition="'$(TargetFramework)' == 'net8.0'">
</When>
</Choose>
<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" />
<Compile Include="Compatibility/SkipLocalsInitAttribute.cs" />
</ItemGroup>
<ItemGroup>
@@ -74,25 +47,17 @@
</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.1" PrivateAssets="all">
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
</PackageReference>
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.1" PrivateAssets="all">
<!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.12.1" PrivateAssets="all" />
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" Version="4.12.1" PrivateAssets="all" />
<PackageReference Include="Roslynator.CSharp" Version="4.12.1" 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>
<ItemGroup>
<Using Include="System.Buffers" />
<Using Include="System.Collections.Specialized" />
<Using Include="System.Numerics" />
<Using Include="System.Runtime.CompilerServices" />
</ItemGroup>
</Project>

View File

@@ -55,43 +55,34 @@ Function Build-Analyzers {
return
}
New-Variable -Name solutionRoot -Visibility Public -Value (Resolve-Path ..)
Push-Location $solutionRoot
New-Variable -Name solutionFile -Visibility Public -Value (Resolve-Path ./Terminal.sln)
$mainProjectRoot = Resolve-Path ./Terminal.Gui
$mainProjectFile = Join-Path $mainProjectRoot Terminal.Gui.csproj
$analyzersRoot = Resolve-Path ./Analyzers
$internalAnalyzersProjectRoot = Join-Path $analyzersRoot Terminal.Gui.Analyzers.Internal
$internalAnalyzersProjectFile = Join-Path $internalAnalyzersProjectRoot Terminal.Gui.Analyzers.Internal.csproj
Push-Location $InternalAnalyzersProjectDirectory
if(!$NoClean) {
if(!$Quiet) {
Write-Host Deleting bin and obj folders for Terminal.Gui
}
if(Test-Path $mainProjectRoot/bin) {
Remove-Item -Recurse -Force $mainProjectRoot/bin
Remove-Item -Recurse -Force $mainProjectRoot/obj
}
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
}
if(Test-Path $internalAnalyzersProjectRoot/bin) {
Remove-Item -Recurse -Force $internalAnalyzersProjectRoot/bin
Remove-Item -Recurse -Force $internalAnalyzersProjectRoot/obj
}
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 $internalAnalyzersProjectFile --no-incremental --nologo --force --configuration Debug
dotnet build $InternalAnalyzersProjectFilePath --no-incremental --nologo --force --configuration Debug
if(!$Quiet) {
Write-Host Building analyzers in Release configuration
}
dotnet build $internalAnalyzersProjectFile --no-incremental --nologo --force --configuration Release
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 {
@@ -102,4 +93,4 @@ Function Build-Analyzers {
}
return
}
}

View File

@@ -14,17 +14,18 @@ Function Open-Solution {
[CmdletBinding()]
param(
[Parameter(Mandatory=$false, HelpMessage="The path to the solution file to open.")]
[Uri]$SolutionFilePath = (Resolve-Path "../Terminal.sln")
[ValidatePattern(".*Terminal\.sln" )]
[string]$Path = $SolutionFilePath
)
if(!$IsWindows) {
[string]$warningMessage = "The Open-Solution cmdlet is only supported on Windows.`n`
Attempt to open file $SolutionFilePath with the system default handler?"
Attempt to open file $Path with the system default handler?"
Write-Warning $warningMessage -WarningAction Inquire
}
Invoke-Item $SolutionFilePath
Invoke-Item $Path
return
}
@@ -62,6 +63,16 @@ Function Set-PowerShellEnvironment {
[CmdletBinding()]
param()
# Set up some common globals
New-Variable -Name ScriptsDirectory -Value $PSScriptRoot -Option ReadOnly -Scope Global -Visibility Public
New-Variable -Name RepositoryRootDirectory -Value (Join-Path -Resolve $ScriptsDirectory "..") -Option ReadOnly -Scope Global -Visibility Public
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
# Set a custom prompt to indicate we're in our modified environment.
# Save the normal one first, though.
# And save it as ReadOnly and without the -Force parameter, so this will be skipped if run more than once in the same session without a reset.
@@ -132,6 +143,14 @@ Function Reset-PowerShellEnvironment {
}
Remove-Variable -Name PathVarSeparator -Scope Global -Force -ErrorAction SilentlyContinue
Remove-Variable -Name RepositoryRootDirectory -Scope Global -Force -ErrorAction SilentlyContinue
Remove-Variable -Name SolutionFilePath -Scope Global -Force -ErrorAction SilentlyContinue
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.
@@ -140,4 +159,4 @@ $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
Reset-PowerShellEnvironment
}
Set-PowerShellEnvironment
Set-PowerShellEnvironment

View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<!-- =================================================================== -->
<!-- Version numbers -->
<!-- Automatically updated by gitversion (run `dotnet-gitversion /updateprojectfiles`) -->
@@ -18,7 +18,7 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DefineTrace>True</DefineTrace>
<DebugType>portable</DebugType>
<DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL</DefineConstants>
<DefineConstants>$(DefineConstants);JETBRAINS_ANNOTATIONS;CONTRACTS_FULL;CODE_ANALYSIS</DefineConstants>
<ImplicitUsings>enable</ImplicitUsings>
<NoLogo>True</NoLogo>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
@@ -45,19 +45,27 @@
<!-- =================================================================== -->
<ItemGroup>
<PackageReference Include="ColorHelper" Version="1.8.1" />
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
<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" />
<!-- 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="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 -->
<!-- =================================================================== -->
<ItemGroup>
<Using Include="JetBrains.Annotations" />
<Using Include="System.Diagnostics.Contracts.PureAttribute" Alias="PureAttribute" />
<Using Include="JetBrains.Annotations.PureAttribute" Alias="PureAttribute" />
<Using Include="System.Drawing" />
<Using Include="System.Text" />
</ItemGroup>

View File

@@ -244,7 +244,7 @@ public class Adornment : View
protected internal override bool OnMouseLeave (MouseEvent mouseEvent)
{
// Invert Normal
if (Diagnostics.HasFlag (ViewDiagnosticFlags.MouseEnter) && ColorScheme != null)
if (Diagnostics.FastHasFlags (ViewDiagnosticFlags.MouseEnter) && ColorScheme != null)
{
var cs = new ColorScheme (ColorScheme)
{

View File

@@ -1,8 +1,11 @@

using Terminal.Gui.Analyzers.Internal.Attributes;
namespace Terminal.Gui;
/// <summary>Enables diagnostic functions for <see cref="View"/>.</summary>
[Flags]
[GenerateEnumExtensionMethods(FastHasFlags = true)]
public enum ViewDiagnosticFlags : uint
{
/// <summary>All diagnostics off</summary>

View File

@@ -30,54 +30,57 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
testenvironments.json = testenvironments.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analyzers", "Analyzers", "{CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui.Analyzers.Internal", "Analyzers\Terminal.Gui.Analyzers.Internal\Terminal.Gui.Analyzers.Internal.csproj", "{5DE91722-8765-4E2B-97E4-2A18010B5CED}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui.Analyzers.Internal.Tests", "Analyzers\Terminal.Gui.Analyzers.Internal.Tests\Terminal.Gui.Analyzers.Internal.Tests.csproj", "{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui.Analyzers.Internal.Debugging", "Analyzers\Terminal.Gui.Analyzers.Internal.Debugging\Terminal.Gui.Analyzers.Internal.Debugging.csproj", "{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}"
EndProject
Global
GlobalSection(NestedProjects) = preSolution
{5DE91722-8765-4E2B-97E4-2A18010B5CED} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|x86.ActiveCfg = Debug|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|x86.Build.0 = Debug|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|Any CPU.Build.0 = Release|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|x86.ActiveCfg = Release|Any CPU
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|x86.Build.0 = Release|Any CPU
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Release|Any CPU.Build.0 = Release|Any CPU
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Release|Any CPU.Build.0 = Release|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Debug|x86.ActiveCfg = Debug|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Debug|x86.Build.0 = Debug|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|Any CPU.Build.0 = Release|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|x86.ActiveCfg = Release|Any CPU
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|x86.Build.0 = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|x86.ActiveCfg = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Debug|x86.Build.0 = Debug|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|Any CPU.Build.0 = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|x86.ActiveCfg = Release|Any CPU
{8B901EDE-8974-4820-B100-5226917E2990}.Release|x86.Build.0 = Release|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Debug|x86.ActiveCfg = Debug|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Debug|x86.Build.0 = Debug|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Release|Any CPU.Build.0 = Release|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Release|x86.ActiveCfg = Release|Any CPU
{44E15B48-0DB2-4560-82BD-D3B7989811C3}.Release|x86.Build.0 = Release|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Debug|x86.ActiveCfg = Debug|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Debug|x86.Build.0 = Debug|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Release|Any CPU.Build.0 = Release|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Release|x86.ActiveCfg = Release|Any CPU
{B0A602CD-E176-449D-8663-64238D54F857}.Release|x86.Build.0 = Release|Any CPU
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -85,34 +88,4 @@ Global
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9F8F8A4D-7B8D-4C2A-AC5E-CD7117F74C03}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.TextStylePolicy = $1
$1.FileWidth = 80
$1.scope = text/x-csharp
$1.TabWidth = 8
$1.IndentWidth = 8
$0.CSharpFormattingPolicy = $2
$2.scope = text/x-csharp
$2.IndentSwitchSection = False
$2.NewLinesForBracesInTypes = False
$2.NewLinesForBracesInProperties = False
$2.NewLinesForBracesInAccessors = False
$2.NewLinesForBracesInAnonymousMethods = False
$2.NewLinesForBracesInControlBlocks = False
$2.NewLinesForBracesInAnonymousTypes = False
$2.NewLinesForBracesInObjectCollectionArrayInitializers = False
$2.NewLinesForBracesInLambdaExpressionBody = False
$2.NewLineForElse = False
$2.NewLineForCatch = False
$2.NewLineForFinally = False
$2.NewLineForMembersInObjectInit = False
$2.NewLineForMembersInAnonymousTypes = False
$2.NewLineForClausesInQuery = False
$2.SpacingAfterMethodDeclarationName = True
$2.SpaceAfterMethodCallName = True
$2.SpaceBeforeOpenSquareBracket = True
$0.DotNetNamingPolicy = $3
$0.StandardHeader = $4
EndGlobalSection
EndGlobal