mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-13 06:04:30 +08:00
feat(enum): 添加枚举扩展方法生成器功能
- 实现 EnumExtensionsGenerator 自动生成枚举扩展方法 - 支持 GenerateIsMethods 和 GenerateIsInMethod 两种生成开关 - 添加完整的单元测试和快照验证机制 - 实现 IsIn 扩展方法支持多值匹配功能 - 支持带显式位标志值的枚举生成扩展方法 - 提供灵活的属性参数配置选项
This commit is contained in:
parent
08b12ae852
commit
30e3ca05fd
@ -1,4 +1,5 @@
|
|||||||
using GFramework.SourceGenerators.Common.Constants;
|
using GFramework.Core.SourceGenerators.Abstractions.Enums;
|
||||||
|
using GFramework.SourceGenerators.Common.Constants;
|
||||||
using GFramework.SourceGenerators.Common.Diagnostics;
|
using GFramework.SourceGenerators.Common.Diagnostics;
|
||||||
using GFramework.SourceGenerators.Common.Generator;
|
using GFramework.SourceGenerators.Common.Generator;
|
||||||
|
|
||||||
@ -18,6 +19,12 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected override string AttributeShortNameWithoutSuffix => "GenerateEnumExtensions";
|
protected override string AttributeShortNameWithoutSuffix => "GenerateEnumExtensions";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按元数据名称解析枚举上的 <c>GenerateEnumExtensionsAttribute</c>。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="compilation">当前编译上下文。</param>
|
||||||
|
/// <param name="symbol">待检查的枚举符号。</param>
|
||||||
|
/// <returns>匹配到的属性数据;若未标注目标属性则返回 <see langword="null" />。</returns>
|
||||||
protected override AttributeData? ResolveAttribute(Compilation compilation, INamedTypeSymbol symbol)
|
protected override AttributeData? ResolveAttribute(Compilation compilation, INamedTypeSymbol symbol)
|
||||||
{
|
{
|
||||||
var attrSymbol = compilation.GetTypeByMetadataName(AttributeMetadataName);
|
var attrSymbol = compilation.GetTypeByMetadataName(AttributeMetadataName);
|
||||||
@ -30,6 +37,15 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase
|
|||||||
SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol));
|
SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证候选符号仍然是可生成扩展方法的枚举类型。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context">源生成诊断上下文。</param>
|
||||||
|
/// <param name="compilation">当前编译上下文。</param>
|
||||||
|
/// <param name="syntax">候选枚举声明语法。</param>
|
||||||
|
/// <param name="symbol">候选命名类型符号。</param>
|
||||||
|
/// <param name="attr">已解析出的生成器属性。</param>
|
||||||
|
/// <returns>当符号满足生成前置条件时返回 <see langword="true" />。</returns>
|
||||||
protected override bool ValidateSymbol(SourceProductionContext context, Compilation compilation,
|
protected override bool ValidateSymbol(SourceProductionContext context, Compilation compilation,
|
||||||
EnumDeclarationSyntax syntax,
|
EnumDeclarationSyntax syntax,
|
||||||
INamedTypeSymbol symbol, AttributeData attr)
|
INamedTypeSymbol symbol, AttributeData attr)
|
||||||
@ -56,6 +72,14 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase
|
|||||||
? null
|
? null
|
||||||
: symbol.ContainingNamespace.ToDisplayString();
|
: symbol.ContainingNamespace.ToDisplayString();
|
||||||
|
|
||||||
|
var generateIsMethods = GetNamedBooleanArgument(
|
||||||
|
attr,
|
||||||
|
nameof(GenerateEnumExtensionsAttribute.GenerateIsMethods),
|
||||||
|
true);
|
||||||
|
var generateIsInMethod = GetNamedBooleanArgument(
|
||||||
|
attr,
|
||||||
|
nameof(GenerateEnumExtensionsAttribute.GenerateIsInMethod),
|
||||||
|
true);
|
||||||
var enumName = symbol.Name;
|
var enumName = symbol.Name;
|
||||||
var fullEnumName = symbol.ToDisplayString();
|
var fullEnumName = symbol.ToDisplayString();
|
||||||
var members = symbol.GetMembers()
|
var members = symbol.GetMembers()
|
||||||
@ -74,23 +98,28 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase
|
|||||||
sb.AppendLine($" public static partial class {enumName}Extensions");
|
sb.AppendLine($" public static partial class {enumName}Extensions");
|
||||||
sb.AppendLine(" {");
|
sb.AppendLine(" {");
|
||||||
|
|
||||||
// 生成 IsX 方法
|
// 两个生成开关是彼此独立的契约,需要分别控制输出,并保持空行布局稳定,便于快照精确回归。
|
||||||
foreach (var memberName in members.Select(m => m.Name))
|
var hasGeneratedMembers = false;
|
||||||
|
|
||||||
|
if (generateIsMethods)
|
||||||
|
{
|
||||||
|
hasGeneratedMembers = AppendIsMethods(
|
||||||
|
sb,
|
||||||
|
members,
|
||||||
|
fullEnumName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (generateIsInMethod)
|
||||||
|
{
|
||||||
|
if (hasGeneratedMembers)
|
||||||
{
|
{
|
||||||
sb.AppendLine($" /// <summary>是否为 {memberName}</summary>");
|
|
||||||
sb.AppendLine(
|
|
||||||
$" public static bool Is{memberName}(this {fullEnumName} value) => value == {fullEnumName}.{memberName};");
|
|
||||||
sb.AppendLine();
|
sb.AppendLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成 IsIn 方法
|
AppendIsInMethod(
|
||||||
sb.AppendLine(" /// <summary>判断是否属于指定集合</summary>");
|
sb,
|
||||||
sb.AppendLine($" public static bool IsIn(this {fullEnumName} value, params {fullEnumName}[] values)");
|
fullEnumName);
|
||||||
sb.AppendLine(" {");
|
}
|
||||||
sb.AppendLine(" if (values == null) return false;");
|
|
||||||
sb.AppendLine(" foreach (var v in values) if (value == v) return true;");
|
|
||||||
sb.AppendLine(" return false;");
|
|
||||||
sb.AppendLine(" }");
|
|
||||||
|
|
||||||
sb.AppendLine(" }");
|
sb.AppendLine(" }");
|
||||||
sb.AppendLine("}"); // namespace
|
sb.AppendLine("}"); // namespace
|
||||||
@ -107,4 +136,69 @@ public sealed class EnumExtensionsGenerator : AttributeEnumGeneratorBase
|
|||||||
{
|
{
|
||||||
return $"{symbol.Name}.EnumExtensions.g.cs";
|
return $"{symbol.Name}.EnumExtensions.g.cs";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 读取属性上的命名布尔参数,并在参数未显式提供时回退到属性契约默认值。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="attribute">待读取的属性数据。</param>
|
||||||
|
/// <param name="argumentName">命名参数名称。</param>
|
||||||
|
/// <param name="defaultValue">属性未提供该参数时使用的默认值。</param>
|
||||||
|
/// <returns>解析得到的布尔值;若参数缺失或类型不匹配则返回 <paramref name="defaultValue" />。</returns>
|
||||||
|
private static bool GetNamedBooleanArgument(AttributeData attribute, string argumentName, bool defaultValue)
|
||||||
|
{
|
||||||
|
foreach (var namedArgument in attribute.NamedArguments)
|
||||||
|
{
|
||||||
|
if (namedArgument.Key == argumentName &&
|
||||||
|
namedArgument.Value.Value is bool value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 为每个枚举成员追加单值判断扩展方法。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">目标源码构建器。</param>
|
||||||
|
/// <param name="members">需要生成扩展方法的枚举成员。</param>
|
||||||
|
/// <param name="fullEnumName">枚举的完整类型名。</param>
|
||||||
|
/// <returns>当至少生成了一个方法时返回 <see langword="true" />。</returns>
|
||||||
|
private static bool AppendIsMethods(StringBuilder builder, IEnumerable<IFieldSymbol> members, string fullEnumName)
|
||||||
|
{
|
||||||
|
var hasGeneratedMembers = false;
|
||||||
|
|
||||||
|
foreach (var memberName in members.Select(m => m.Name))
|
||||||
|
{
|
||||||
|
if (hasGeneratedMembers)
|
||||||
|
{
|
||||||
|
builder.AppendLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.AppendLine($" /// <summary>是否为 {memberName}</summary>");
|
||||||
|
builder.AppendLine(
|
||||||
|
$" public static bool Is{memberName}(this {fullEnumName} value) => value == {fullEnumName}.{memberName};");
|
||||||
|
hasGeneratedMembers = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return hasGeneratedMembers;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 追加用于多值匹配的 <c>IsIn</c> 扩展方法。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="builder">目标源码构建器。</param>
|
||||||
|
/// <param name="fullEnumName">枚举的完整类型名。</param>
|
||||||
|
private static void AppendIsInMethod(StringBuilder builder, string fullEnumName)
|
||||||
|
{
|
||||||
|
builder.AppendLine(" /// <summary>判断是否属于指定集合</summary>");
|
||||||
|
builder.AppendLine(
|
||||||
|
$" public static bool IsIn(this {fullEnumName} value, params {fullEnumName}[] values)");
|
||||||
|
builder.AppendLine(" {");
|
||||||
|
builder.AppendLine(" if (values == null) return false;");
|
||||||
|
builder.AppendLine(" foreach (var v in values) if (value == v) return true;");
|
||||||
|
builder.AppendLine(" return false;");
|
||||||
|
builder.AppendLine(" }");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,17 @@ using GFramework.SourceGenerators.Tests.Core;
|
|||||||
|
|
||||||
namespace GFramework.SourceGenerators.Tests.Enums;
|
namespace GFramework.SourceGenerators.Tests.Enums;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证枚举扩展生成器在不同属性开关组合下的快照输出。
|
||||||
|
/// </summary>
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class EnumExtensionsGeneratorSnapshotTests
|
public class EnumExtensionsGeneratorSnapshotTests
|
||||||
{
|
{
|
||||||
private const string EnumAttributeNamespace = "GFramework.Core.SourceGenerators.Abstractions.Enums";
|
private const string EnumAttributeNamespace = "GFramework.Core.SourceGenerators.Abstractions.Enums";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证默认配置会为普通枚举生成逐项判断方法与集合判断方法。
|
||||||
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Snapshot_BasicEnum_IsMethods()
|
public async Task Snapshot_BasicEnum_IsMethods()
|
||||||
{
|
{
|
||||||
@ -24,14 +30,12 @@ public class EnumExtensionsGeneratorSnapshotTests
|
|||||||
|
|
||||||
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
||||||
source,
|
source,
|
||||||
Path.Combine(
|
GetSnapshotFolder("BasicEnum_IsMethods"));
|
||||||
TestContext.CurrentContext.TestDirectory,
|
|
||||||
"enums",
|
|
||||||
"snapshots",
|
|
||||||
"EnumExtensionsGenerator",
|
|
||||||
"BasicEnum_IsMethods"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证默认配置在较小枚举上仍会生成集合判断方法。
|
||||||
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Snapshot_BasicEnum_IsInMethod()
|
public async Task Snapshot_BasicEnum_IsInMethod()
|
||||||
{
|
{
|
||||||
@ -46,14 +50,12 @@ public class EnumExtensionsGeneratorSnapshotTests
|
|||||||
|
|
||||||
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
||||||
source,
|
source,
|
||||||
Path.Combine(
|
GetSnapshotFolder("BasicEnum_IsInMethod"));
|
||||||
TestContext.CurrentContext.TestDirectory,
|
|
||||||
"enums",
|
|
||||||
"snapshots",
|
|
||||||
"EnumExtensionsGenerator",
|
|
||||||
"BasicEnum_IsInMethod"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证带显式位标志值的枚举也会生成对应扩展方法。
|
||||||
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Snapshot_EnumWithFlagValues()
|
public async Task Snapshot_EnumWithFlagValues()
|
||||||
{
|
{
|
||||||
@ -71,14 +73,12 @@ public class EnumExtensionsGeneratorSnapshotTests
|
|||||||
|
|
||||||
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
||||||
source,
|
source,
|
||||||
Path.Combine(
|
GetSnapshotFolder("EnumWithFlagValues"));
|
||||||
TestContext.CurrentContext.TestDirectory,
|
|
||||||
"enums",
|
|
||||||
"snapshots",
|
|
||||||
"EnumExtensionsGenerator",
|
|
||||||
"EnumWithFlagValues"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证关闭逐项判断开关后仅保留集合判断方法。
|
||||||
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Snapshot_DisableIsMethods()
|
public async Task Snapshot_DisableIsMethods()
|
||||||
{
|
{
|
||||||
@ -94,14 +94,12 @@ public class EnumExtensionsGeneratorSnapshotTests
|
|||||||
|
|
||||||
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
||||||
source,
|
source,
|
||||||
Path.Combine(
|
GetSnapshotFolder("DisableIsMethods"));
|
||||||
TestContext.CurrentContext.TestDirectory,
|
|
||||||
"enums",
|
|
||||||
"snapshots",
|
|
||||||
"EnumExtensionsGenerator",
|
|
||||||
"DisableIsMethods"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证关闭集合判断开关后仅保留逐项判断方法。
|
||||||
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Snapshot_DisableIsInMethod()
|
public async Task Snapshot_DisableIsInMethod()
|
||||||
{
|
{
|
||||||
@ -117,16 +115,63 @@ public class EnumExtensionsGeneratorSnapshotTests
|
|||||||
|
|
||||||
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
||||||
source,
|
source,
|
||||||
Path.Combine(
|
GetSnapshotFolder("DisableIsInMethod"));
|
||||||
TestContext.CurrentContext.TestDirectory,
|
|
||||||
"enums",
|
|
||||||
"snapshots",
|
|
||||||
"EnumExtensionsGenerator",
|
|
||||||
"DisableIsInMethod"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 验证同时关闭两个生成开关时不会输出任何扩展方法。
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public async Task Snapshot_DisableAllGeneratedMethods()
|
||||||
|
{
|
||||||
|
var source = BuildSource(
|
||||||
|
"""
|
||||||
|
public enum Status
|
||||||
|
{
|
||||||
|
Active,
|
||||||
|
Inactive
|
||||||
|
}
|
||||||
|
""",
|
||||||
|
"[GenerateEnumExtensions(GenerateIsMethods = false, GenerateIsInMethod = false)]");
|
||||||
|
|
||||||
|
await GeneratorSnapshotTest<EnumExtensionsGenerator>.RunAsync(
|
||||||
|
source,
|
||||||
|
GetSnapshotFolder("DisableAllGeneratedMethods"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将运行时测试目录映射回仓库内已提交的枚举快照目录。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="scenarioName">快照场景名称。</param>
|
||||||
|
/// <returns>场景对应的绝对快照目录。</returns>
|
||||||
|
private static string GetSnapshotFolder(string scenarioName)
|
||||||
|
{
|
||||||
|
return Path.GetFullPath(
|
||||||
|
Path.Combine(
|
||||||
|
TestContext.CurrentContext.TestDirectory,
|
||||||
|
"..",
|
||||||
|
"..",
|
||||||
|
"..",
|
||||||
|
"Enums",
|
||||||
|
"snapshots",
|
||||||
|
"EnumExtensionsGenerator",
|
||||||
|
scenarioName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造最小自洽的测试输入源码,以稳定驱动枚举扩展生成器的快照测试。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="enumBody">要注入到测试命名空间中的枚举声明文本。</param>
|
||||||
|
/// <param name="attributeUsage">枚举上的属性使用方式,默认启用所有生成选项。</param>
|
||||||
|
/// <returns>包含内联测试属性与目标枚举声明的完整源码。</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// 这里内联声明 <c>GenerateEnumExtensionsAttribute</c>,以便每个快照输入保持最小自洽。
|
||||||
|
/// 属性命名空间必须与生成器按 metadata name 查找的契约保持一致;如果命名空间、属性名或参数发生变更,
|
||||||
|
/// 需要同步更新该模板与相关快照,否则测试可能出现静默漂移。
|
||||||
|
/// </remarks>
|
||||||
private static string BuildSource(string enumBody, string attributeUsage = "[GenerateEnumExtensions]")
|
private static string BuildSource(string enumBody, string attributeUsage = "[GenerateEnumExtensions]")
|
||||||
{
|
{
|
||||||
|
// 保持属性声明与测试输入同处一个模板中,能够明确锁定生成器对元数据名称和可选参数的语义假设。
|
||||||
return $$"""
|
return $$"""
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public static partial class StatusExtensions
|
||||||
|
{
|
||||||
|
/// <summary>是否为 Active</summary>
|
||||||
|
public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active;
|
||||||
|
|
||||||
|
/// <summary>是否为 Inactive</summary>
|
||||||
|
public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive;
|
||||||
|
|
||||||
|
/// <summary>判断是否属于指定集合</summary>
|
||||||
|
public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values)
|
||||||
|
{
|
||||||
|
if (values == null) return false;
|
||||||
|
foreach (var v in values) if (value == v) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public static partial class StatusExtensions
|
||||||
|
{
|
||||||
|
/// <summary>是否为 Active</summary>
|
||||||
|
public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active;
|
||||||
|
|
||||||
|
/// <summary>是否为 Inactive</summary>
|
||||||
|
public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive;
|
||||||
|
|
||||||
|
/// <summary>是否为 Pending</summary>
|
||||||
|
public static bool IsPending(this TestApp.Status value) => value == TestApp.Status.Pending;
|
||||||
|
|
||||||
|
/// <summary>判断是否属于指定集合</summary>
|
||||||
|
public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values)
|
||||||
|
{
|
||||||
|
if (values == null) return false;
|
||||||
|
foreach (var v in values) if (value == v) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public static partial class StatusExtensions
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public static partial class StatusExtensions
|
||||||
|
{
|
||||||
|
/// <summary>是否为 Active</summary>
|
||||||
|
public static bool IsActive(this TestApp.Status value) => value == TestApp.Status.Active;
|
||||||
|
|
||||||
|
/// <summary>是否为 Inactive</summary>
|
||||||
|
public static bool IsInactive(this TestApp.Status value) => value == TestApp.Status.Inactive;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public static partial class StatusExtensions
|
||||||
|
{
|
||||||
|
/// <summary>判断是否属于指定集合</summary>
|
||||||
|
public static bool IsIn(this TestApp.Status value, params TestApp.Status[] values)
|
||||||
|
{
|
||||||
|
if (values == null) return false;
|
||||||
|
foreach (var v in values) if (value == v) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
namespace TestApp
|
||||||
|
{
|
||||||
|
public static partial class PermissionsExtensions
|
||||||
|
{
|
||||||
|
/// <summary>是否为 None</summary>
|
||||||
|
public static bool IsNone(this TestApp.Permissions value) => value == TestApp.Permissions.None;
|
||||||
|
|
||||||
|
/// <summary>是否为 Read</summary>
|
||||||
|
public static bool IsRead(this TestApp.Permissions value) => value == TestApp.Permissions.Read;
|
||||||
|
|
||||||
|
/// <summary>是否为 Write</summary>
|
||||||
|
public static bool IsWrite(this TestApp.Permissions value) => value == TestApp.Permissions.Write;
|
||||||
|
|
||||||
|
/// <summary>是否为 Execute</summary>
|
||||||
|
public static bool IsExecute(this TestApp.Permissions value) => value == TestApp.Permissions.Execute;
|
||||||
|
|
||||||
|
/// <summary>判断是否属于指定集合</summary>
|
||||||
|
public static bool IsIn(this TestApp.Permissions value, params TestApp.Permissions[] values)
|
||||||
|
{
|
||||||
|
if (values == null) return false;
|
||||||
|
foreach (var v in values) if (value == v) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,6 +29,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Remove="**\snapshots\**\*.cs"/>
|
||||||
|
<None Include="**\snapshots\**\*.cs"/>
|
||||||
<Folder Include="rule\snapshots\ContextAwareGenerator\"/>
|
<Folder Include="rule\snapshots\ContextAwareGenerator\"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user