diff --git a/.editorconfig b/.editorconfig index c22fdd7..78b36ca 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,99 +1 @@ root = true - -[*.cs] -# Treat ALL diagnostics as errors — compiler, analyzers, IDE, style -dotnet_analyzer_diagnostic.severity = error - -# ────────────────────────────────────────────────────────────────────────────── -# Naming rules (dotnet/runtime style) -# -# Mirrors ANcpLua.NET.Sdk's NamingConvention.editorconfig. This repo doesn't -# consume the SDK, so the rules are inlined here under [*.cs] (no is_global — -# IDE picks them up via filesystem walk, no MSBuild registration needed). -# Source of truth: ANcpLua.NET.Sdk/src/Config/NamingConvention.editorconfig. -# ────────────────────────────────────────────────────────────────────────────── - -dotnet_naming_style.non_private_static_field_style.capitalization = pascal_case - -# constant fields using PascalCase -dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields -dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_fields.applicable_kinds = field -dotnet_naming_symbols.constant_fields.required_modifiers = const -dotnet_naming_style.pascal_case_style.capitalization = pascal_case - -# private/internal static fields (incl. readonly) use s_ prefix. -# Matches dotnet/runtime: private/internal static readonly is NOT PascalCase — -# the const rule above keeps const fields PascalCase; the fallback rule at the -# bottom keeps public/protected static (readonly) fields PascalCase. -dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion -dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields -dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style -dotnet_naming_symbols.static_fields.applicable_kinds = field -dotnet_naming_symbols.static_fields.required_modifiers = static -dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected -dotnet_naming_style.static_prefix_style.required_prefix = s_ -dotnet_naming_style.static_prefix_style.capitalization = camel_case - -# private/internal instance fields use _camelCase. -# The static rule above is more specific (kinds + modifier + accessibility) -# and wins for static fields. -dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion -dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields -dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style -dotnet_naming_symbols.private_internal_fields.applicable_kinds = field -dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal -dotnet_naming_style.camel_case_underscore_style.required_prefix = _ -dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case - -# name all constant variables using PascalCase -dotnet_naming_rule.constant_variables_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.constant_variables_should_be_pascal_case.symbols = constant_variables -dotnet_naming_rule.constant_variables_should_be_pascal_case.style = pascal_case_style -dotnet_naming_symbols.constant_variables.applicable_kinds = local -dotnet_naming_symbols.constant_variables.required_modifiers = const - -# Locals and parameters are camelCase -dotnet_naming_rule.locals_should_be_camel_case.severity = suggestion -dotnet_naming_rule.locals_should_be_camel_case.symbols = locals_and_parameters -dotnet_naming_rule.locals_should_be_camel_case.style = camel_case_style - -dotnet_naming_symbols.locals_and_parameters.applicable_kinds = parameter, local -dotnet_naming_style.camel_case_style.capitalization = camel_case - -# Local functions are PascalCase -dotnet_naming_rule.local_functions_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.local_functions_should_be_pascal_case.symbols = local_functions -dotnet_naming_rule.local_functions_should_be_pascal_case.style = non_private_static_field_style - -dotnet_naming_symbols.local_functions.applicable_kinds = local_function -dotnet_naming_style.local_function_style.capitalization = pascal_case - -# Type Parameters -dotnet_naming_style.type_parameter_style.capitalization = pascal_case -dotnet_naming_style.type_parameter_style.required_prefix = T - -dotnet_naming_rule.type_parameter_naming.symbols = type_parameter_symbol -dotnet_naming_rule.type_parameter_naming.style = type_parameter_style -dotnet_naming_rule.type_parameter_naming.severity = warning -dotnet_naming_symbols.type_parameter_symbol.applicable_kinds = type_parameter -dotnet_naming_symbols.type_parameter_symbol.applicable_accessibilities = * - -# Interface -dotnet_naming_style.interface_style.capitalization = pascal_case -dotnet_naming_style.interface_style.required_prefix = I - -dotnet_naming_rule.interface_should_be_begins_with_i.severity = warning -dotnet_naming_rule.interface_should_be_begins_with_i.style = interface_style -dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface_symbols - -dotnet_naming_symbols.interface_symbols.applicable_kinds = interface -dotnet_naming_symbols.interface_symbols.applicable_accessibilities = * - -# By default, name items with PascalCase -dotnet_naming_rule.members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.members_should_be_pascal_case.symbols = all_members -dotnet_naming_rule.members_should_be_pascal_case.style = non_private_static_field_style - -dotnet_naming_symbols.all_members.applicable_kinds = * diff --git a/Directory.Build.props b/Directory.Build.props index a961331..934f240 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,7 @@ + - + $(MSBuildThisFileDirectory)artifacts/ $(ArtifactsPath)bin/$(MSBuildProjectName)/ $(ArtifactsPath)obj/$(MSBuildProjectName)/ @@ -13,9 +14,16 @@ true + latest + enable + enable + true + latest-all + + true + true + true - - true $(NoWarn);NU1604 $(NoWarn);NU1701 @@ -26,6 +34,16 @@ $(RepositoryUrl) + + + true + + + + + + true diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/AI/BitNetCollection.cs b/src/ANcpLua.Roslyn.Utilities.Testing/AI/BitNetCollection.cs deleted file mode 100644 index f9ce064..0000000 --- a/src/ANcpLua.Roslyn.Utilities.Testing/AI/BitNetCollection.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Xunit; - -namespace ANcpLua.Roslyn.Utilities.Testing.AI; - -/// -/// xUnit v3 collection definition for tests requiring a live BitNet server. -/// Apply [Collection(BitNetTestGroup.Name)] to test classes that inject . -/// -[CollectionDefinition(Name)] -public sealed class BitNetTestGroup : ICollectionFixture -{ - /// - /// Collection name constant. Use in [Collection(BitNetTestGroup.Name)]. - /// - public const string Name = "BitNet"; -} - -/// -/// Marks a test class as requiring the BitNet LLM fixture. -/// -[AttributeUsage(AttributeTargets.Class)] -public sealed class BitNetAttribute : Attribute; diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/AI/BitNetFixture.cs b/src/ANcpLua.Roslyn.Utilities.Testing/AI/BitNetFixture.cs deleted file mode 100644 index 96ba047..0000000 --- a/src/ANcpLua.Roslyn.Utilities.Testing/AI/BitNetFixture.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.ClientModel; -using Microsoft.Extensions.AI; -using OpenAI; -using Xunit; - -namespace ANcpLua.Roslyn.Utilities.Testing.AI; - -/// -/// Shared xUnit v3 fixture that probes a BitNet (llama.cpp) server and exposes an . -/// Guard tests with Skip.IfNot(fixture.IsAvailable, "BitNet server not running"). -/// -/// -/// BITNET_URL overrides the default endpoint. BITNET_MODEL overrides the default model. -/// Health probe retries 3 times with 1-second backoff. -/// -public sealed class BitNetFixture : IAsyncLifetime -{ - private static readonly Uri s_defaultEndpoint = new("http://localhost:8080"); - private const string DefaultModel = "bitnet-b1.58-2B-4T"; - private const int MaxRetries = 3; - - private readonly HttpClient _http = new() { Timeout = TimeSpan.FromSeconds(5) }; - - /// Chat client wired to the BitNet server. Only valid when . - public IChatClient ChatClient { get; private set; } = null!; - - /// Whether the server responded during initialization. - public bool IsAvailable { get; private set; } - - /// Resolved endpoint URI. - public Uri Endpoint { get; private set; } = s_defaultEndpoint; - - /// Resolved model name. - public string Model { get; private set; } = DefaultModel; - - public async ValueTask InitializeAsync() - { - Endpoint = Environment.GetEnvironmentVariable("BITNET_URL") is { Length: > 0 } url - ? new Uri(url) - : s_defaultEndpoint; - - Model = Environment.GetEnvironmentVariable("BITNET_MODEL") is { Length: > 0 } model - ? model - : DefaultModel; - - IsAvailable = await ProbeWithRetryAsync().ConfigureAwait(false); - if (!IsAvailable) return; - - var client = new OpenAIClient( - new ApiKeyCredential("unused"), - new OpenAIClientOptions { Endpoint = Endpoint }); - - ChatClient = (IChatClient)client.GetChatClient(Model); - } - - public ValueTask DisposeAsync() - { - _http.Dispose(); - (ChatClient as IDisposable)?.Dispose(); - return ValueTask.CompletedTask; - } - - private async Task ProbeWithRetryAsync() - { - for (var attempt = 0; attempt < MaxRetries; attempt++) - { - try - { - using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3)); - using var response = await _http.GetAsync(new Uri(Endpoint, "/health"), cts.Token) - .ConfigureAwait(false); - if (response.IsSuccessStatusCode) return true; - } - catch - { - // Server not up yet - } - - if (attempt < MaxRetries - 1) - await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false); - } - - return false; - } -} diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/MSBuild/DotNetSdkHelpers.cs b/src/ANcpLua.Roslyn.Utilities.Testing/MSBuild/DotNetSdkHelpers.cs index 380b568..c41d77a 100644 --- a/src/ANcpLua.Roslyn.Utilities.Testing/MSBuild/DotNetSdkHelpers.cs +++ b/src/ANcpLua.Roslyn.Utilities.Testing/MSBuild/DotNetSdkHelpers.cs @@ -139,7 +139,7 @@ public static async Task Get(NetSdkVersion version) if (Path.GetExtension(file.Name) is ".zip") { using var ms = new MemoryStream(bytes); - var zip = new ZipArchive(ms); + using var zip = new ZipArchive(ms); await zip.ExtractToDirectoryAsync(tempFolder, true).ConfigureAwait(false); } else @@ -212,4 +212,4 @@ public static void ClearCache() { s_values.Clear(); } -} \ No newline at end of file +} diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/IntegrationTestBase.cs b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/IntegrationTestBase.cs index 873a279..ffd2afa 100644 --- a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/IntegrationTestBase.cs +++ b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/IntegrationTestBase.cs @@ -28,6 +28,10 @@ public abstract class IntegrationTestBase /// Creates the WebApplicationFactory once per test class. [OneTimeSetUp] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Reliability", + "CA2000:Dispose objects before losing scope", + Justification = "The factory lifetime is stored on the test fixture and disposed by OneTimeTearDownAsync.")] public virtual void OneTimeSetUp() { Factory = new WebApplicationFactory() diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/KestrelTestBase.cs b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/KestrelTestBase.cs index 5701625..28356b0 100644 --- a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/KestrelTestBase.cs +++ b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/NUnit/KestrelTestBase.cs @@ -32,6 +32,10 @@ public abstract class KestrelTestBase /// Creates a fresh Kestrel server per test. [SetUp] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Reliability", + "CA2000:Dispose objects before losing scope", + Justification = "The factory lifetime is stored in _factory and disposed by TearDownAsync.")] public virtual void SetUp() { _factory = new WebApplicationFactory() diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/IntegrationTestBase.cs b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/IntegrationTestBase.cs index 452b97d..d188d45 100644 --- a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/IntegrationTestBase.cs +++ b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/IntegrationTestBase.cs @@ -31,6 +31,10 @@ public abstract class IntegrationTestBase /// Creates the factory, HTTP client, and log collector per test. [Before(HookType.Test)] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Reliability", + "CA2000:Dispose objects before losing scope", + Justification = "The factory lifetime is stored in _factory and disposed by TearDown.")] public virtual Task SetUp() { _factory = new WebApplicationFactory() diff --git a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/KestrelTestBase.cs b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/KestrelTestBase.cs index 1208343..a524a70 100644 --- a/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/KestrelTestBase.cs +++ b/src/ANcpLua.Roslyn.Utilities.Testing/WebTesting/TUnit/KestrelTestBase.cs @@ -32,6 +32,10 @@ public abstract class KestrelTestBase /// Starts a fresh Kestrel server per test. [Before(HookType.Test)] + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Reliability", + "CA2000:Dispose objects before losing scope", + Justification = "The factory lifetime is stored in _factory and disposed by TearDown.")] public virtual Task SetUp() { _factory = new WebApplicationFactory() diff --git a/src/ANcpLua.Roslyn.Utilities/Encoding/Base64Url.cs b/src/ANcpLua.Roslyn.Utilities/Encoding/Base64Url.cs index 4db94cf..cb6cce5 100644 --- a/src/ANcpLua.Roslyn.Utilities/Encoding/Base64Url.cs +++ b/src/ANcpLua.Roslyn.Utilities/Encoding/Base64Url.cs @@ -48,7 +48,9 @@ namespace ANcpLua.Roslyn.Utilities; #endif static class Base64Url { +#if NET5_0_OR_GREATER private const int StackallocByteThreshold = 192; +#endif /// /// Encodes raw bytes as URL-safe Base64 without = padding. diff --git a/src/ANcpLua.Roslyn.Utilities/Ids/ShortId.cs b/src/ANcpLua.Roslyn.Utilities/Ids/ShortId.cs index bca0c26..2fe9a9d 100644 --- a/src/ANcpLua.Roslyn.Utilities/Ids/ShortId.cs +++ b/src/ANcpLua.Roslyn.Utilities/Ids/ShortId.cs @@ -74,6 +74,10 @@ public static string NewHex(int hexChars) /// tail is cryptographically strong. Suitable for tokens that appear in URLs or tenant ids. /// /// + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Globalization", + "CA1308:Normalize strings to uppercase", + Justification = "This helper's public contract returns lowercase hexadecimal identifiers.")] public static string NewPrefixedSortable(string prefix, int randomHexChars = 24) { if (string.IsNullOrWhiteSpace(prefix)) diff --git a/src/ANcpLua.Roslyn.Utilities/OperationExtensions.cs b/src/ANcpLua.Roslyn.Utilities/OperationExtensions.cs index 41b2ead..4e39a50 100644 --- a/src/ANcpLua.Roslyn.Utilities/OperationExtensions.cs +++ b/src/ANcpLua.Roslyn.Utilities/OperationExtensions.cs @@ -176,14 +176,12 @@ public static bool IsInExpressionTree(this IOperation operation, INamedTypeSymbo // Each of the four shapes that carry a type contributes one switch arm. private static bool HasExpressionType(IOperation op, ISymbol expressionSymbol) { - var type = op switch + return op switch { - IArgumentOperation { Parameter.Type: { } pt } => pt, - IConversionOperation { Type: { } ct } => ct, - _ => null + IArgumentOperation { Parameter.Type: { } pt } => IsConstructedFromExpressionType(pt, expressionSymbol), + IConversionOperation { Type: { } ct } => IsConstructedFromExpressionType(ct, expressionSymbol), + _ => false }; - - return type is not null && IsConstructedFromExpressionType(type, expressionSymbol); } /// diff --git a/src/ANcpLua.Roslyn.Utilities/ReflectionExtensions.cs b/src/ANcpLua.Roslyn.Utilities/ReflectionExtensions.cs index f9c069c..6ce36b9 100644 --- a/src/ANcpLua.Roslyn.Utilities/ReflectionExtensions.cs +++ b/src/ANcpLua.Roslyn.Utilities/ReflectionExtensions.cs @@ -117,13 +117,13 @@ public static MethodInfo GetMethodFromGenericDefinition(this Type specializedTyp #if NET6_0_OR_GREATER return (MethodInfo)specializedType.GetMemberWithSameMetadataDefinitionAs(genericMethodDefinition); #else - const BindingFlags all = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | + const BindingFlags All = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance; - foreach (var m in specializedType.GetMethods(all)) + foreach (var m in specializedType.GetMethods(All)) if (m.MetadataToken == genericMethodDefinition.MetadataToken) return m; throw new MissingMethodException(specializedType.FullName, genericMethodDefinition.Name); #endif } -} \ No newline at end of file +} diff --git a/src/ANcpLua.Roslyn.Utilities/StringExtensions.Hashing.cs b/src/ANcpLua.Roslyn.Utilities/StringExtensions.Hashing.cs index 294eafb..530aacc 100644 --- a/src/ANcpLua.Roslyn.Utilities/StringExtensions.Hashing.cs +++ b/src/ANcpLua.Roslyn.Utilities/StringExtensions.Hashing.cs @@ -51,6 +51,10 @@ public static string ToShortHash(this string input) /// parallel branches. Cyclomatic complexity per overload stays at 1–2. /// /// + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Globalization", + "CA1308:Normalize strings to uppercase", + Justification = "The lowercase option intentionally formats hexadecimal output for callers that require it.")] public static string ToShortHash(this string input, int hexChars, bool lowercase = false) { if (hexChars is < 1 or > 64) diff --git a/src/ANcpLua.Roslyn.Utilities/StringExtensions.Identifiers.cs b/src/ANcpLua.Roslyn.Utilities/StringExtensions.Identifiers.cs index 0b09b65..5ddc545 100644 --- a/src/ANcpLua.Roslyn.Utilities/StringExtensions.Identifiers.cs +++ b/src/ANcpLua.Roslyn.Utilities/StringExtensions.Identifiers.cs @@ -81,6 +81,10 @@ public static string ToPropertyName(this string input) /// /// /// + [System.Diagnostics.CodeAnalysis.SuppressMessage( + "Globalization", + "CA1308:Normalize strings to uppercase", + Justification = "Parameter names and C# keyword escaping intentionally produce lowercase or camelCase names.")] public static string ToParameterName(this string input) { if (input is null) diff --git a/src/ANcpLua.Roslyn.Utilities/Web/QueryString.cs b/src/ANcpLua.Roslyn.Utilities/Web/QueryString.cs index 434d90f..5335206 100644 --- a/src/ANcpLua.Roslyn.Utilities/Web/QueryString.cs +++ b/src/ANcpLua.Roslyn.Utilities/Web/QueryString.cs @@ -31,7 +31,7 @@ public static string Build(params (string Key, string? Value)[] pairs) if (string.IsNullOrWhiteSpace(value)) continue; if (!first) sb.Append('&'); first = false; - sb.Append(key).Append('=').Append(Uri.EscapeDataString(value!)); + sb.Append(key).Append('=').Append(Uri.EscapeDataString(value)); } return sb.ToString(); } diff --git a/tests/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/DiscriminatedUnionGeneratorTests.cs b/tests/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/DiscriminatedUnionGeneratorTests.cs index d68de62..9b983f0 100644 --- a/tests/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/DiscriminatedUnionGeneratorTests.cs +++ b/tests/ANcpLua.Roslyn.Utilities.DiscriminatedUnion.Tests/DiscriminatedUnionGeneratorTests.cs @@ -11,20 +11,20 @@ public sealed class DiscriminatedUnionGeneratorTests [Fact] public void Emits_PrivateCtor_Sealed_Cases_And_Match_Switch() { - var source = """ - using ANcpLua.Analyzers.DiscriminatedUnion; - - namespace TestNs - { - [DiscriminatedUnion] - public partial record Msg - { - public partial record AddPoint(double X, double Y); - public partial record Undo; - public partial record Redo; - } - } - """; + const string source = """ + using ANcpLua.Analyzers.DiscriminatedUnion; + + namespace TestNs + { + [DiscriminatedUnion] + public partial record Msg + { + public partial record AddPoint(double X, double Y); + public partial record Undo; + public partial record Redo; + } + } + """; var result = GeneratorTestHelper.RunGenerator(source); @@ -55,7 +55,7 @@ public partial record Redo; [Fact] public void Output_Compilation_Has_No_Errors_And_Switch_Is_Exhaustive() { - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs @@ -94,7 +94,7 @@ public static string Describe(Result r) => r.Match( public void Closed_Hierarchy_Rejects_External_Inheritance() { // The private base ctor should make derivation outside the union root impossible. - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs @@ -122,7 +122,7 @@ public sealed record EvilMsg : Msg; // must fail to compile [Fact] public void Reports_AL0300_When_Root_Is_Not_Partial() { - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs @@ -143,7 +143,7 @@ public partial record A; [Fact] public void Reports_AL0301_When_Root_Has_No_Cases() { - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs @@ -163,7 +163,7 @@ public partial record Empty [Fact] public void Reports_AL0302_When_Case_Is_Not_Partial_Record() { - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs @@ -184,7 +184,7 @@ public class NotARecord { } [Fact] public void Reports_AL0303_When_Root_Has_PrimaryCtor_Parameters() { - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs @@ -205,7 +205,7 @@ public partial record A; [Fact] public void Generic_Union_Root_Flows_Type_Parameters_To_Cases() { - var source = """ + const string source = """ using ANcpLua.Analyzers.DiscriminatedUnion; namespace TestNs diff --git a/tests/ANcpLua.Roslyn.Utilities.ExtensibleEnumMirror.Tests/ExtensibleEnumMirrorGeneratorTests.cs b/tests/ANcpLua.Roslyn.Utilities.ExtensibleEnumMirror.Tests/ExtensibleEnumMirrorGeneratorTests.cs index 701a7b0..eaf13e1 100644 --- a/tests/ANcpLua.Roslyn.Utilities.ExtensibleEnumMirror.Tests/ExtensibleEnumMirrorGeneratorTests.cs +++ b/tests/ANcpLua.Roslyn.Utilities.ExtensibleEnumMirror.Tests/ExtensibleEnumMirrorGeneratorTests.cs @@ -121,7 +121,7 @@ public class ReasonMirror { } [Fact] public void Reports_AL0202_When_Target_Is_Not_Extensible_Enum_Struct() { - var source = """ + const string source = """ using ANcpLua.Analyzers.ExtensibleEnumMirror; namespace TestNs @@ -141,7 +141,7 @@ public partial class WrongMirror { } [Fact] public void Emits_Mirror_With_Only_Unknown_When_Target_Has_No_Known_Values() { - var source = """ + const string source = """ using ANcpLua.Analyzers.ExtensibleEnumMirror; namespace TestNs diff --git a/tests/ANcpLua.Roslyn.Utilities.Testing.Tests/MatchingDslTests.cs b/tests/ANcpLua.Roslyn.Utilities.Testing.Tests/MatchingDslTests.cs index 51e1003..1a7a7a4 100644 --- a/tests/ANcpLua.Roslyn.Utilities.Testing.Tests/MatchingDslTests.cs +++ b/tests/ANcpLua.Roslyn.Utilities.Testing.Tests/MatchingDslTests.cs @@ -20,7 +20,7 @@ public void TypeMatcher_InheritsFromName_MatchesSimpleAndQualifiedNames(string b var derived = compilation.GetTypeByMetadataName("Probe.Derived"); derived.Should().NotBeNull(); - Match.Type().InheritsFrom(baseTypeName).Matches(derived!).Should().BeTrue(); + Match.Type().InheritsFrom(baseTypeName).Matches(derived).Should().BeTrue(); } [Theory] @@ -33,7 +33,7 @@ public void TypeMatcher_Implements_MatchesSimpleAndQualifiedNames(string interfa var derived = compilation.GetTypeByMetadataName("Probe.Derived"); derived.Should().NotBeNull(); - Match.Type().Implements(interfaceName).Matches(derived!).Should().BeTrue(); + Match.Type().Implements(interfaceName).Matches(derived).Should().BeTrue(); } [Theory]