diff --git a/src/Application.Interfaces/Filtering.cs b/src/Application.Interfaces/Filtering.cs index 1da149ac..c2864206 100644 --- a/src/Application.Interfaces/Filtering.cs +++ b/src/Application.Interfaces/Filtering.cs @@ -1,3 +1,5 @@ +using Common.Extensions; + namespace Application.Interfaces; /// @@ -13,7 +15,7 @@ public Filtering() public Filtering(string field) { - ArgumentException.ThrowIfNullOrEmpty(field); + field.ThrowIfNotValuedParameter(nameof(field)); if (!_fields.Contains(field)) { _fields.Add(field); diff --git a/src/Application.Interfaces/Sorting.cs b/src/Application.Interfaces/Sorting.cs index 03e37c04..36a7bfb0 100644 --- a/src/Application.Interfaces/Sorting.cs +++ b/src/Application.Interfaces/Sorting.cs @@ -1,3 +1,5 @@ +using Common.Extensions; + namespace Application.Interfaces; /// @@ -7,7 +9,7 @@ public class Sorting { public Sorting(string by, SortDirection direction = SortDirection.Ascending) { - ArgumentException.ThrowIfNullOrEmpty(by); + by.ThrowIfNotValuedParameter(nameof(by)); By = by; Direction = direction; } diff --git a/src/Common/Error.cs b/src/Common/Error.cs index 8ec9a4dc..37341145 100644 --- a/src/Common/Error.cs +++ b/src/Common/Error.cs @@ -1,4 +1,6 @@ +#if !ANALYZERS_NONPLATFORM using Common.Extensions; +#endif namespace Common; @@ -25,6 +27,7 @@ internal Error(ErrorCode code, string? message = null) public ErrorCode Code { get; } +#if !ANALYZERS_NONPLATFORM /// /// Wraps the existing message within the specified message /// @@ -39,7 +42,8 @@ public Error Wrap(string message) ? $"{message}{Environment.NewLine}\t{Message}" : message); } - +#endif + /// /// Creates a error /// diff --git a/src/Common/Extensions/CollectionExtensions.cs b/src/Common/Extensions/CollectionExtensions.cs index dc545b03..9e5679e2 100644 --- a/src/Common/Extensions/CollectionExtensions.cs +++ b/src/Common/Extensions/CollectionExtensions.cs @@ -1,5 +1,8 @@ -#if COMMON_PROJECT +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM using System.Text; +#endif + +#if COMMON_PROJECT using JetBrains.Annotations; #endif @@ -11,7 +14,7 @@ namespace Common.Extensions; public static class CollectionExtensions { -#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the string exists in the /// @@ -34,7 +37,7 @@ public static TResult First(this IReadOnlyList list) return list[0]; } #endif -#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the collection contains any items /// @@ -44,7 +47,7 @@ public static bool HasAny(this IEnumerable? collection) { return false; } -#if COMMON_PROJECT +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM return !collection.HasNone(); #elif GENERATORS_WEB_API_PROJECT return !collection!.HasNone(); @@ -59,7 +62,7 @@ public static bool HasNone(this IEnumerable collection) return !collection.Any(); } #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Joins all values separated by the /// @@ -78,7 +81,8 @@ public static string Join(this IEnumerable values, string separator) return stringBuilder.ToString(); } - +#endif +#if COMMON_PROJECT /// /// Returns a string value for all the items in the list, separated by the specified /// @@ -94,7 +98,8 @@ public static TResult Last(this IReadOnlyList list) { return list[^1]; } - +#endif +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the string does not exist in the /// diff --git a/src/Common/Extensions/ObjectExtensions.cs b/src/Common/Extensions/ObjectExtensions.cs index e52ee6f8..3321208a 100644 --- a/src/Common/Extensions/ObjectExtensions.cs +++ b/src/Common/Extensions/ObjectExtensions.cs @@ -1,6 +1,8 @@ #if COMMON_PROJECT -using System.Diagnostics.CodeAnalysis; using AutoMapper; +#endif +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM || ANALYZERS_PLATFORM +using System.Diagnostics.CodeAnalysis; using JetBrains.Annotations; #endif @@ -20,7 +22,7 @@ public static TTarget Convert(this TSource source) return mapper.Map(source); } #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM || ANALYZERS_PLATFORM /// /// Whether the object does exist /// @@ -29,17 +31,8 @@ public static bool Exists([NotNullWhen(true)] this object? instance) { return instance is not null; } -#elif GENERATORS_WEB_API_PROJECT - /// - /// Whether the object does exist - /// - public static bool Exists(this object? instance) - { - return instance is not null; - } - #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the parameter from being invalid according to the , /// and if invalid, returns a error @@ -93,7 +86,7 @@ public static bool IsNotValuedParameter(this string? value, string parameterName return IsInvalidParameter(value.HasValue, parameterName, null, out error); } #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM || ANALYZERS_PLATFORM /// /// Whether the object does not exist /// @@ -102,14 +95,6 @@ public static bool NotExists([NotNullWhen(false)] this object? instance) { return instance is null; } -#elif GENERATORS_WEB_API_PROJECT - /// - /// Whether the object does not exist - /// - public static bool NotExists(this object? instance) - { - return instance is null; - } #endif #if COMMON_PROJECT /// @@ -145,7 +130,8 @@ public static void ThrowIfInvalidParameter(this TValue? value, Predicate throw new ArgumentOutOfRangeException(parameterName, errorMessage); } } - +#endif +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Throws an if the specified does not have a value /// @@ -172,5 +158,17 @@ private static bool IsInvalidParameter(Func predicate, string parameterNam error = Error.NoError; return false; } + + /// + /// Throws an if the specified is null + /// + public static void ThrowIfNullParameter(this TValue? value, string parameterName, + string? errorMessage = null) + { + if (value is null) + { + throw new ArgumentNullException(parameterName, errorMessage); + } + } #endif -} +} \ No newline at end of file diff --git a/src/Common/Extensions/StringExtensions.cs b/src/Common/Extensions/StringExtensions.cs index ba36d420..e8424d08 100644 --- a/src/Common/Extensions/StringExtensions.cs +++ b/src/Common/Extensions/StringExtensions.cs @@ -1,18 +1,23 @@ #if COMMON_PROJECT -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; +#endif +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || GENERATORS_COMMON_PROJECT || ANALYZERS_NONPLATFORM +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using JetBrains.Annotations; +#endif -#elif GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Text; -#elif GENERATORS_COMMON_PROJECT +#endif + +#if GENERATORS_COMMON_PROJECT using System.Globalization; using System.Text; #endif @@ -24,7 +29,7 @@ namespace Common.Extensions; #endif public static class StringExtensions { -#if COMMON_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM /// /// Defines the casing used in JSON serialization /// @@ -33,10 +38,11 @@ public enum JsonCasing Pascal, Camel } - +#endif +#if COMMON_PROJECT private static readonly TimeSpan DefaultRegexTimeout = TimeSpan.FromSeconds(10); #endif -#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the is the same as the value (case-insensitive) /// @@ -45,7 +51,7 @@ public static bool EqualsIgnoreCase(this string value, string other) return string.Equals(value, other, StringComparison.OrdinalIgnoreCase); } #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the is precisely the same as the value (case-sensitive) /// @@ -53,7 +59,8 @@ public static bool EqualsOrdinal(this string value, string other) { return string.Equals(value, other, StringComparison.Ordinal); } - +#endif +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Formats the with the /// @@ -78,7 +85,7 @@ public static string Format(this string value, params object[] arguments) PropertyNameCaseInsensitive = true }); } -#elif GENERATORS_WEB_API_PROJECT +#elif GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM public static TObject FromJson(this string json) where TObject : new() { @@ -87,11 +94,27 @@ public static TObject FromJson(this string json) return new TObject(); } - var serializer = new DataContractJsonSerializer(typeof(TObject), new DataContractJsonSerializerSettings()); + var deserialized = FromJson(json, typeof(TObject)); + if (deserialized is not null) + { + return (TObject)deserialized; + } + + return new TObject(); + } + + public static object? FromJson(this string json, Type type) + { + if (json.HasNoValue()) + { + return null; + } + + var serializer = new DataContractJsonSerializer(type, new DataContractJsonSerializerSettings()); using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(json))) { - return (TObject)serializer.ReadObject(ms); + return serializer.ReadObject(ms); } } #endif @@ -112,7 +135,7 @@ public static TObject FromJson(this string json) }); } #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || GENERATORS_WEB_API_PROJECT || GENERATORS_COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Whether the string value contains no value: it is either: null, empty or only whitespaces /// @@ -132,22 +155,6 @@ public static bool HasValue([NotNullWhen(true)] this string? value) { return !string.IsNullOrEmpty(value) && !string.IsNullOrWhiteSpace(value); } -#elif GENERATORS_WEB_API_PROJECT || GENERATORS_COMMON_PROJECT - /// - /// Whether the string value contains no value: it is either: null, empty or only whitespaces - /// - public static bool HasNoValue(this string? value) - { - return string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value); - } - - /// - /// Whether the string value contains any value except: null, empty or only whitespaces - /// - public static bool HasValue(this string? value) - { - return !string.IsNullOrEmpty(value) && !string.IsNullOrWhiteSpace(value); - } #endif #if COMMON_PROJECT /// @@ -261,7 +268,7 @@ public static string ToCamelCase(this string value) return char.ToLowerInvariant(titleCase[0]) + titleCase.Substring(1); } #endif -#if COMMON_PROJECT +#if COMMON_PROJECT || ANALYZERS_NONPLATFORM /// /// Converts the to a integer value /// @@ -321,8 +328,9 @@ public static int ToIntOrDefault(this string? value, int defaultValue) : JsonIgnoreCondition.WhenWritingNull }); } -#elif GENERATORS_WEB_API_PROJECT - public static string? ToJson(this TObject? value, bool? prettyPrint = false) +#elif GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM || ANALYZERS_NONPLATFORM + public static string? ToJson(this TObject? value, bool? prettyPrint = true, JsonCasing casing = + JsonCasing.Pascal) { if (value is null) { diff --git a/src/Common/Optional.cs b/src/Common/Optional.cs index c2ec687e..e83e6df6 100644 --- a/src/Common/Optional.cs +++ b/src/Common/Optional.cs @@ -65,7 +65,7 @@ public static Optional None() /// public static Optional Some(TValue value) { - ArgumentNullException.ThrowIfNull(value); + value.ThrowIfNullParameter(nameof(value)); if (value.TryGetContainedValue(out var contained)) { diff --git a/src/Infrastructure.Common/Infrastructure.Common.csproj b/src/Infrastructure.Common/Infrastructure.Common.csproj index d3795bf4..560ed14a 100644 --- a/src/Infrastructure.Common/Infrastructure.Common.csproj +++ b/src/Infrastructure.Common/Infrastructure.Common.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Infrastructure.Web.Api.Interfaces/AuthorizeAttribute.cs b/src/Infrastructure.Web.Api.Interfaces/AuthorizeAttribute.cs index 4e9213bf..1d77cda8 100644 --- a/src/Infrastructure.Web.Api.Interfaces/AuthorizeAttribute.cs +++ b/src/Infrastructure.Web.Api.Interfaces/AuthorizeAttribute.cs @@ -3,7 +3,7 @@ using Common.Extensions; using Domain.Interfaces.Authorization; using Infrastructure.Interfaces; -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM using System.Runtime.Serialization; #endif @@ -346,17 +346,17 @@ private static FeatureLevel[] ToTenant(Features features) /// /// Provides a serializable class for storing policy names /// -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM [DataContract] #endif public class PolicyName { -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM [DataMember(Order = 1, EmitDefaultValue = false)] #endif public PolicyNameStage? Features { get; set; } -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM [DataMember(Order = 2, EmitDefaultValue = false)] #endif public PolicyNameStage? Roles { get; set; } @@ -365,17 +365,17 @@ public class PolicyName /// /// Provides a serializable class for storing policy stages /// -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM [DataContract] #endif public class PolicyNameStage { -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM [DataMember(Order = 1, EmitDefaultValue = false)] #endif public List? Tenant { get; set; } -#if GENERATORS_WEB_API_PROJECT +#if GENERATORS_WEB_API_PROJECT || ANALYZERS_NONPLATFORM [DataMember(Order = 1, EmitDefaultValue = false)] #endif public List? Platform { get; set; } diff --git a/src/SaaStack.sln b/src/SaaStack.sln index a4848427..bf34687b 100644 --- a/src/SaaStack.sln +++ b/src/SaaStack.sln @@ -320,6 +320,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrganizationsInfrastructure EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OrganizationsInfrastructure.UnitTests", "OrganizationsInfrastructure.UnitTests\OrganizationsInfrastructure.UnitTests.csproj", "{B2ABB588-A7D4-44DB-8A2B-C1657D57D546}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTesting.CodeAnalysis.Common", "UnitTesting.CodeAnalysis.Common\UnitTesting.CodeAnalysis.Common.csproj", "{3A491D02-702A-4738-B3F5-26066E60F834}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1011,6 +1013,12 @@ Global {B2ABB588-A7D4-44DB-8A2B-C1657D57D546}.Release|Any CPU.Build.0 = Release|Any CPU {B2ABB588-A7D4-44DB-8A2B-C1657D57D546}.ReleaseForDeploy|Any CPU.ActiveCfg = ReleaseForDeploy|Any CPU {B2ABB588-A7D4-44DB-8A2B-C1657D57D546}.ReleaseForDeploy|Any CPU.Build.0 = ReleaseForDeploy|Any CPU + {3A491D02-702A-4738-B3F5-26066E60F834}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A491D02-702A-4738-B3F5-26066E60F834}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A491D02-702A-4738-B3F5-26066E60F834}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A491D02-702A-4738-B3F5-26066E60F834}.Release|Any CPU.Build.0 = Release|Any CPU + {3A491D02-702A-4738-B3F5-26066E60F834}.ReleaseForDeploy|Any CPU.ActiveCfg = ReleaseForDeploy|Any CPU + {3A491D02-702A-4738-B3F5-26066E60F834}.ReleaseForDeploy|Any CPU.Build.0 = ReleaseForDeploy|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {F5C77A86-38AF-40E4-82FC-617E624B2754} = {508E7DA4-4DF2-4201-955D-CCF70C41AD05} @@ -1165,5 +1173,6 @@ Global {4DBA0B71-413D-43A9-AF68-150135A74F5B} = {90ED1D1C-5960-4F56-94F1-8063490725C4} {B2ABB588-A7D4-44DB-8A2B-C1657D57D546} = {90ED1D1C-5960-4F56-94F1-8063490725C4} {EA58877D-3023-429C-A1A8-E8479441139E} = {D3B68FF7-293B-4458-B8D8-49D3DF59B495} + {3A491D02-702A-4738-B3F5-26066E60F834} = {5838EE94-374F-4A6F-A231-1BC1C87985F4} EndGlobalSection EndGlobal diff --git a/src/Tools.Analyzers.Common/Tools.Analyzers.Common.csproj b/src/Tools.Analyzers.Common/Tools.Analyzers.Common.csproj index 32f4cae6..f32aead7 100644 --- a/src/Tools.Analyzers.Common/Tools.Analyzers.Common.csproj +++ b/src/Tools.Analyzers.Common/Tools.Analyzers.Common.csproj @@ -1,7 +1,9 @@ - net8.0 + netstandard2.0 + latest + enable true true diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignAnalyzerSpec.cs b/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignAnalyzerSpec.cs index 4d72fbac..fa1f3e81 100644 --- a/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignAnalyzerSpec.cs +++ b/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignAnalyzerSpec.cs @@ -1,8 +1,8 @@ extern alias NonPlatformAnalyzers; -using JetBrains.Annotations; using Xunit; using NonPlatform_DomainDrivenDesignAnalyzer = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.DomainDrivenDesignAnalyzer; +using UsedImplicitly = NonPlatformAnalyzers::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Analyzers.NonPlatform.UnitTests; diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignCodeFixSpec.cs b/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignCodeFixSpec.cs index 572e49b7..1b32d8cd 100644 --- a/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignCodeFixSpec.cs +++ b/src/Tools.Analyzers.NonPlatform.UnitTests/DomainDrivenDesignCodeFixSpec.cs @@ -1,10 +1,10 @@ extern alias NonPlatformAnalyzers; -using JetBrains.Annotations; using Xunit; using NonPlatform_DomainDrivenDesignAnalyzer = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.DomainDrivenDesignAnalyzer; using NonPlatform_DomainDrivenDesignCodeFix = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.DomainDrivenDesignCodeFix; +using UsedImplicitly = NonPlatformAnalyzers::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Analyzers.NonPlatform.UnitTests; diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/Tools.Analyzers.NonPlatform.UnitTests.csproj b/src/Tools.Analyzers.NonPlatform.UnitTests/Tools.Analyzers.NonPlatform.UnitTests.csproj index 61c1f69e..18cbaf58 100644 --- a/src/Tools.Analyzers.NonPlatform.UnitTests/Tools.Analyzers.NonPlatform.UnitTests.csproj +++ b/src/Tools.Analyzers.NonPlatform.UnitTests/Tools.Analyzers.NonPlatform.UnitTests.csproj @@ -6,17 +6,12 @@ - - + - - - - diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/Verify.cs b/src/Tools.Analyzers.NonPlatform.UnitTests/Verify.cs index b0010131..916b2929 100644 --- a/src/Tools.Analyzers.NonPlatform.UnitTests/Verify.cs +++ b/src/Tools.Analyzers.NonPlatform.UnitTests/Verify.cs @@ -1,21 +1,16 @@ extern alias CommonAnalyzers; +extern alias NonPlatformAnalyzers; using System.Reflection; -using Common; -using Common.Extensions; -using Domain.Common; -using Domain.Interfaces; -using Infrastructure.Web.Api.Common; -using Infrastructure.Web.Api.Interfaces; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Testing; +using NonPlatformAnalyzers::QueryAny; using NuGet.Frameworks; -using QueryAny; using AnalyzerConstants = CommonAnalyzers::Tools.Analyzers.Common.AnalyzerConstants; using Task = System.Threading.Tasks.Task; - +using ObjectExtensions = NonPlatformAnalyzers::Common.Extensions.ObjectExtensions; namespace Tools.Analyzers.NonPlatform.UnitTests; public static class Verify @@ -27,12 +22,7 @@ public static class Verify { typeof(Verify).Assembly, typeof(AnalyzerConstants).Assembly, - typeof(Query).Assembly, - typeof(CommonMarker).Assembly, - typeof(DomainInterfacesMarker).Assembly, - typeof(DomainCommonMarker).Assembly, - typeof(InfrastructureWebApiInterfacesMarker).Assembly, - typeof(InfrastructureWebApiCommonMarker).Assembly + typeof(IQueryableEntity).Assembly, }; // HACK: we have to define the .NET 8.0 framework here, @@ -125,7 +115,7 @@ private static async Task DiagnosticExists(DiagnosticDescriptor descr (int locationX, int locationY, string argument) expected1, params object?[]? messageArgs) where TAnalyzer : DiagnosticAnalyzer, new() { - var arguments = messageArgs.Exists() && messageArgs.Any() + var arguments = ObjectExtensions.Exists(messageArgs) && messageArgs.Any() ? new object[] { expected1.argument }.Concat(messageArgs) : new object[] { expected1.argument }; diff --git a/src/Tools.Analyzers.NonPlatform.UnitTests/WebApiClassAnalyzerSpec.cs b/src/Tools.Analyzers.NonPlatform.UnitTests/WebApiClassAnalyzerSpec.cs index 7ea32a7e..7feb327b 100644 --- a/src/Tools.Analyzers.NonPlatform.UnitTests/WebApiClassAnalyzerSpec.cs +++ b/src/Tools.Analyzers.NonPlatform.UnitTests/WebApiClassAnalyzerSpec.cs @@ -1,10 +1,16 @@ extern alias NonPlatformAnalyzers; -using Application.Interfaces; -using Infrastructure.Web.Api.Interfaces; -using JetBrains.Annotations; using Xunit; using TypeExtensions = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.TypeExtensions; using WebApiClassAnalyzer = NonPlatformAnalyzers::Tools.Analyzers.NonPlatform.WebApiClassAnalyzer; +using ServiceOperation = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.ServiceOperation; +using IWebResponse = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebResponse; +using IWebSearchResponse = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebSearchResponse; +using Route = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.RouteAttribute; +using Authorize = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.AuthorizeAttribute; +using SearchResultMetadata = NonPlatformAnalyzers::Application.Interfaces.SearchResultMetadata; +using AccessType = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.AccessType; +using Roles = NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.Roles; +using UsedImplicitly = NonPlatformAnalyzers::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Analyzers.NonPlatform.UnitTests; @@ -1628,43 +1634,43 @@ public class TestSearchResponse : IWebSearchResponse } [UsedImplicitly] -public class TestNoRouteAttributeRequest : IWebRequest; +public class TestNoRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Search)] [UsedImplicitly] -public class TestSearchRouteAttributeRequest : IWebRequest; +public class TestSearchRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Post)] [UsedImplicitly] -public class TestPostRouteAttributeRequest : IWebRequest; +public class TestPostRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Get)] [UsedImplicitly] -public class TestGetRouteAttributeRequest : IWebRequest; +public class TestGetRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource/1", ServiceOperation.Get)] [UsedImplicitly] -public class TestGetRouteAttributeRequest1 : IWebRequest; +public class TestGetRouteAttributeRequest1 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource/2", ServiceOperation.Get)] [UsedImplicitly] -public class TestGetRouteAttributeRequest2 : IWebRequest; +public class TestGetRouteAttributeRequest2 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource/3", ServiceOperation.Get)] [UsedImplicitly] -public class TestGetRouteAttributeRequest3 : IWebRequest; +public class TestGetRouteAttributeRequest3 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/anotherresource/1", ServiceOperation.Get)] [UsedImplicitly] -public class TestGetRouteAttributeRequest4 : IWebRequest; +public class TestGetRouteAttributeRequest4 : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.PutPatch)] [UsedImplicitly] -public class TestPutPatchRouteAttributeRequest : IWebRequest; +public class TestPutPatchRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Delete)] [UsedImplicitly] -public class TestDeleteRouteAttributeRequest : IWebRequest; +public class TestDeleteRouteAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [AttributeUsage(AttributeTargets.Method)] [UsedImplicitly] @@ -1672,18 +1678,18 @@ public class TestAttribute : Attribute; [Route("/aresource", ServiceOperation.Post)] [UsedImplicitly] -public class TestAnonymousRouteNoAuthorizeAttributeRequest : IWebRequest; +public class TestAnonymousRouteNoAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Post)] [Authorize(Roles.Platform_Standard)] [UsedImplicitly] -public class TestAnonymousRouteAuthorizeAttributeRequest : IWebRequest; +public class TestAnonymousRouteAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Post, AccessType.Token)] [Authorize(Roles.Platform_Standard)] [UsedImplicitly] -public class TestSecureRouteAuthorizeAttributeRequest : IWebRequest; +public class TestSecureRouteAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; [Route("/aresource", ServiceOperation.Post, AccessType.Token)] [UsedImplicitly] -public class TestSecureRouteNoAuthorizeAttributeRequest : IWebRequest; \ No newline at end of file +public class TestSecureRouteNoAuthorizeAttributeRequest : NonPlatformAnalyzers::Infrastructure.Web.Api.Interfaces.IWebRequest; \ No newline at end of file diff --git a/src/Tools.Analyzers.NonPlatform/Extensions/DictionaryExtensions.cs b/src/Tools.Analyzers.NonPlatform/Extensions/DictionaryExtensions.cs new file mode 100644 index 00000000..43eeacee --- /dev/null +++ b/src/Tools.Analyzers.NonPlatform/Extensions/DictionaryExtensions.cs @@ -0,0 +1,21 @@ +// ReSharper disable once CheckNamespace + +namespace Common.Extensions; + +public static class DictionaryExtensions2 +{ + /// + /// Adds the item to the dictionary if the key does not exist + /// + public static bool TryAdd(this IDictionary values, TKey key, TValue value) + { + if (values.ContainsKey(key)) + { + return false; + } + + values.Add(key, value); + + return true; + } +} \ No newline at end of file diff --git a/src/Tools.Analyzers.NonPlatform/Extensions/StringBuilderExtensions.cs b/src/Tools.Analyzers.NonPlatform/Extensions/StringBuilderExtensions.cs new file mode 100644 index 00000000..e9b03836 --- /dev/null +++ b/src/Tools.Analyzers.NonPlatform/Extensions/StringBuilderExtensions.cs @@ -0,0 +1,11 @@ +using System.Text; + +namespace Tools.Analyzers.NonPlatform.Extensions; + +public static class StringBuilderExtensions +{ + public static void AppendJoin(this StringBuilder builder, string separator, IEnumerable values) + { + builder.Append(string.Join(separator, values)); + } +} \ No newline at end of file diff --git a/src/Tools.Analyzers.NonPlatform/Reference/QueryAny.cs b/src/Tools.Analyzers.NonPlatform/Reference/QueryAny.cs new file mode 100644 index 00000000..da9f33d8 --- /dev/null +++ b/src/Tools.Analyzers.NonPlatform/Reference/QueryAny.cs @@ -0,0 +1,18 @@ +using JetBrains.Annotations; + +// ReSharper disable once CheckNamespace +namespace QueryAny; + +/// +/// HACK: This is a workaround to include types from the QueryAny library, since it cannot be used in netstandard20 +/// +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +[UsedImplicitly] +public class EntityNameAttribute : Attribute +{ + public EntityNameAttribute(string name) + { + } +} + +public interface IQueryableEntity; \ No newline at end of file diff --git a/src/Tools.Analyzers.NonPlatform/Reference/System.Diagnostics.CodeAnalysis.cs b/src/Tools.Analyzers.NonPlatform/Reference/System.Diagnostics.CodeAnalysis.cs new file mode 100644 index 00000000..aeb26de7 --- /dev/null +++ b/src/Tools.Analyzers.NonPlatform/Reference/System.Diagnostics.CodeAnalysis.cs @@ -0,0 +1,30 @@ +#define INTERNAL_NULLABLE_ATTRIBUTES + +// ReSharper disable once CheckNamespace +namespace System.Diagnostics.CodeAnalysis; + +/// +/// HACK: This code is to enable the use of the '[NotNullWhen]' attribute that is not present in netstandard20 +/// Specifies that when a method returns , the parameter will not be null even if the +/// corresponding type allows it. +/// +[AttributeUsage(AttributeTargets.Parameter)] +#if INTERNAL_NULLABLE_ATTRIBUTES +internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) + { + ReturnValue = returnValue; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } +} \ No newline at end of file diff --git a/src/Tools.Analyzers.NonPlatform/Reference/System.Runtime.CompilerServices.cs b/src/Tools.Analyzers.NonPlatform/Reference/System.Runtime.CompilerServices.cs new file mode 100644 index 00000000..806512c9 --- /dev/null +++ b/src/Tools.Analyzers.NonPlatform/Reference/System.Runtime.CompilerServices.cs @@ -0,0 +1,48 @@ +using System.ComponentModel; + +// ReSharper disable once CheckNamespace +namespace System.Runtime.CompilerServices +{ +#if !NET5_0_OR_GREATER + + [EditorBrowsable(EditorBrowsableState.Never)] + internal static class IsExternalInit; + +#endif // !NET5_0_OR_GREATER + +#if !NET7_0_OR_GREATER + + /// + /// HACK: This code is to enable the use of the 'required' keyword that is not present in netstandard20 + /// + [AttributeUsage( + AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, + Inherited = false)] + internal sealed class RequiredMemberAttribute : Attribute; + + [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] + internal sealed class CompilerFeatureRequiredAttribute : Attribute + { + public CompilerFeatureRequiredAttribute(string featureName) + { + FeatureName = featureName; + } + + public string FeatureName { get; } + + public bool IsOptional { get; init; } + + public const string RefStructs = nameof(RefStructs); + public const string RequiredMembers = nameof(RequiredMembers); + } + +#endif // !NET7_0_OR_GREATER +} + +namespace System.Diagnostics.CodeAnalysis +{ +#if !NET7_0_OR_GREATER + [AttributeUsage(AttributeTargets.Constructor)] + internal sealed class SetsRequiredMembersAttribute : Attribute; +#endif +} \ No newline at end of file diff --git a/src/Tools.Analyzers.NonPlatform/Tools.Analyzers.NonPlatform.csproj b/src/Tools.Analyzers.NonPlatform/Tools.Analyzers.NonPlatform.csproj index 9b3d1f95..f1c97a31 100644 --- a/src/Tools.Analyzers.NonPlatform/Tools.Analyzers.NonPlatform.csproj +++ b/src/Tools.Analyzers.NonPlatform/Tools.Analyzers.NonPlatform.csproj @@ -1,33 +1,30 @@ - net8.0 + netstandard2.0 + $(DefineConstants);ANALYZERS_NONPLATFORM + latest + enable true true true - $(NoWarn),RS2007;NU5128 + $(NoWarn),RS2007,NU5128 - - - - - - all runtime; build; native; contentfiles; analyzers; buildtransitive - + @@ -37,6 +34,249 @@ + + + Reference\Common\Annotations.cs + + + Reference\Common\Extensions\StringExtensions.cs + + + Reference\Common\Extensions\CollectionExtensions.cs + + + Reference\Common\Extensions\DictionaryExtensions.cs + + + Reference\Common\Extensions\ObjectExtensions.cs + + + Reference\Common\Error.cs + + + Reference\Common\Result.cs + + + Reference\Common\Optional.cs + + + Reference\Common\IRecorder.cs + + + Reference\Common\Resources.Designer.cs + + + Reference\Common\ICallContext.cs + + + Reference\Common\Recording\CrashLevel.cs + + + Reference\Infrastructure.Web.Api.Interfaces\ApiResult.cs + + + Reference\Infrastructure.Web.Api.Interfaces\IWebApiService.cs + + + Reference\Infrastructure.Web.Api.Interfaces\IWebRequest.cs + + + Reference\Infrastructure.Web.Api.Interfaces\IWebResponse.cs + + + Reference\Infrastructure.Web.Api.Interfaces\IWebSearchResponse.cs + + + Reference\Infrastructure.Web.Api.Interfaces\EmptyResponse.cs + + + Reference\Infrastructure.Web.Api.Interfaces\ServiceOperation.cs + + + Reference\Infrastructure.Web.Api.Interfaces\AuthorizeAttribute.cs + + + Reference\Infrastructure.Web.Api.Interfaces\AuthorizeAttribute.g.cs + + + Reference\Infrastructure.Web.Api.Interfaces\RouteAttribute.cs + + + Reference\Infrastructure.Interfaces\AuthenticationConstants.cs + + + Reference\Application.Interfaces\SearchResultMetadata.cs + + + Reference\Application.Interfaces\Filtering.cs + + + Reference\Application.Interfaces\Sorting.cs + + + Reference\Application.Interfaces\ICallerContext.cs + + + Reference\Application.Interfaces\ICallerContext.RolesAndFeatures.cs + + + Reference\Domain.Interfaces\Authorization\IHierarchicalLevel.cs + + + Reference\Domain.Interfaces\Authorization\HierarchicalLevelBase.cs + + + Reference\Domain.Interfaces\Authorization\FeatureLevel.cs + + + Reference\Domain.Interfaces\Authorization\RoleLevel.cs + + + Reference\Domain.Interfaces\Authorization\PlatformRoles.cs + + + Reference\Domain.Interfaces\Authorization\TenantRoles.cs + + + Reference\Domain.Interfaces\Authorization\PlatformFeatures.cs + + + Reference\Domain.Interfaces\Authorization\TenantFeatures.cs + + + Reference\Domain.Interfaces\Entities\IDehydratableEntity.cs + + + Reference\Domain.Interfaces\Entities\IAggregateRoot.cs + + + Reference\Domain.Interfaces\Entities\IEntity.cs + + + Reference\Domain.Interfaces\Entities\IDomainEvent.cs + + + Reference\Domain.Interfaces\Entities\IDomainEventProducingEntity.cs + + + Reference\Domain.Interfaces\Entities\IEventingEntity.cs + + + Reference\Domain.Interfaces\Entities\IIdentifiableEntity.cs + + + Reference\Domain.Interfaces\Entities\IDomainEventConsumingEntity.cs + + + Reference\Domain.Interfaces\Entities\IDehydratableAggregateRoot.cs + + + Reference\Domain.Interfaces\Entities\ITombstoneEvent.cs + + + Reference\Domain.Interfaces\Entities\IEventingAggregateRoot.cs + + + Reference\Domain.Interfaces\Entities\EventSourcedChangeEvent.cs + + + Reference\Domain.Interfaces\Entities\IChangeEventConsumingAggregateRoot.cs + + + Reference\Domain.Interfaces\Entities\IEventSourcedChangeEventMigrator.cs + + + Reference\Domain.Interfaces\Entities\IChangeEventProducingAggregateRoot.cs + + + Reference\Domain.Interfaces\ValueObjects\IValueObject.cs + + + Reference\Domain.Interfaces\ValueObjects\ISingleValueObject.cs + + + Reference\Domain.Interfaces\ValueObjects\SkipImmutabilityCheckAttribute.cs + + + Reference\Domain.Interfaces\ValueObjects\IDehydratableValueObject.cs + + + Reference\Domain.Interfaces\Services\IDependencyContainer.cs + + + Reference\Domain.Interfaces\IRehydratableObject.cs + + + Reference\Domain.Interfaces\HydrationProperties.cs + + + Reference\Domain.Interfaces\DomainFactories.cs + + + Reference\Domain.Common\Resources.Designer.cs + + + Reference\Domain.Common\Events\Global.cs + + + Reference\Domain.Common\Identity\IIdentifierFactory.cs + + + Reference\Domain.Common\Identity\FixedIdentifierFactory.cs + + + Reference\Domain.Common\Entities\EntityBase.cs + + + Reference\Domain.Common\Entities\AggregateRootBase.cs + + + Reference\Domain.Common\Entities\EventSourcedChangeEventExtensions.cs + + + Reference\Domain.Common\Extensions\HydrationPropertiesExtensions.cs + + + Reference\Domain.Common\Extensions\DomainEventExtensions.cs + + + Reference\Domain.Common\ValueObjects\Identifier.cs + + + Reference\Domain.Common\ValueObjects\EventStream.cs + + + Reference\Domain.Common\ValueObjects\IdentifierExtensions.cs + + + Reference\Domain.Common\ValueObjects\ValueObjectBase.cs + + + Reference\Domain.Common\ValueObjects\ValueObjectBase.Comparable.cs + + + Reference\Domain.Common\ValueObjects\ValueObjectBase.Equality.cs + + + Reference\Domain.Common\ValueObjects\SingleValueObjectBase.cs + + + Reference\Domain.Common\ValueObjects\SingleValueObjectBase.Equality.cs + + + Reference\Domain.Common\ValueObjects\SingleValueObjectBase.Comparable.cs + + + Reference\Domain.Common\ValueObjects\ValueObjectExtensions.cs + + + Reference\Domain.Common\ValueObjects\EventMetadata.cs + + + Reference\Domain.Common\ValueObjects\EventMetadataExtensions.cs + + + ResXFileCodeGenerator @@ -52,26 +292,43 @@ - + $(GetTargetPathDependsOn);GetDependencyTargetPaths + <_TargetFramework>8.0.2 + <_AspNetFrameworkInstallFolder>C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\$(_TargetFramework) + <_FrameworkInstallFolder>C:\Program Files\dotnet\shared\Microsoft.NETCore.App\$(_TargetFramework) - + - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/src/Tools.Analyzers.NonPlatform/WebApiClassAnalyzer.cs b/src/Tools.Analyzers.NonPlatform/WebApiClassAnalyzer.cs index 25f2e9c9..44de51b7 100644 --- a/src/Tools.Analyzers.NonPlatform/WebApiClassAnalyzer.cs +++ b/src/Tools.Analyzers.NonPlatform/WebApiClassAnalyzer.cs @@ -428,7 +428,7 @@ public void SetRouteSegments(string? routePath) { if (routePath.HasValue()) { - RouteSegments = routePath.Split("/", StringSplitOptions.RemoveEmptyEntries); + RouteSegments = routePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); } } } diff --git a/src/Tools.Analyzers.Platform.UnitTests/MissingDocsAnalyzerSpec.cs b/src/Tools.Analyzers.Platform.UnitTests/MissingDocsAnalyzerSpec.cs index 07af2227..6647f82a 100644 --- a/src/Tools.Analyzers.Platform.UnitTests/MissingDocsAnalyzerSpec.cs +++ b/src/Tools.Analyzers.Platform.UnitTests/MissingDocsAnalyzerSpec.cs @@ -1,7 +1,7 @@ extern alias PlatformAnalyzers; -using JetBrains.Annotations; using Xunit; -using Platform_MissingDocsAnalyzer = PlatformAnalyzers::Tools.Analyzers.Platform.MissingDocsAnalyzer; +using MissingDocsAnalyzer = PlatformAnalyzers::Tools.Analyzers.Platform.MissingDocsAnalyzer; +using UsedImplicitly = PlatformAnalyzers::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Analyzers.Platform.UnitTests; @@ -20,7 +20,7 @@ public class AClass { }"; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -32,7 +32,7 @@ public class AClass { }"; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -40,7 +40,7 @@ public async Task WhenPublicDelegate_ThenAlerts() { const string input = @"public delegate void ADelegate();"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 1, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 1, 22, "ADelegate"); } @@ -49,7 +49,7 @@ public async Task WhenInternalDelegate_ThenAlerts() { const string input = @"internal delegate void ADelegate();"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 1, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 1, 24, "ADelegate"); } @@ -61,7 +61,7 @@ public interface AnInterface { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 18, "AnInterface"); } @@ -73,7 +73,7 @@ internal interface AnInterface { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 20, "AnInterface"); } @@ -85,7 +85,7 @@ public enum AnEnum { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 13, "AnEnum"); } @@ -97,7 +97,7 @@ internal enum AnEnum { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 15, "AnEnum"); } @@ -109,7 +109,7 @@ public struct AStruct { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 15, "AStruct"); } @@ -121,7 +121,7 @@ internal struct AStruct { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 17, "AStruct"); } @@ -133,7 +133,7 @@ public readonly struct AStruct { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 24, "AStruct"); } @@ -145,7 +145,7 @@ internal readonly struct AStruct { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 26, "AStruct"); } @@ -157,7 +157,7 @@ public record ARecord() { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 15, "ARecord"); } @@ -169,7 +169,7 @@ internal record ARecord { }"; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 17, "ARecord"); } @@ -182,7 +182,7 @@ public static class AClass } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -194,7 +194,7 @@ internal static class AClass } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -209,7 +209,7 @@ public static class AClass2 } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -227,7 +227,7 @@ private static class AClass2 } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -245,7 +245,7 @@ public class AClass2 } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 7, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 7, 18, "AClass2"); } @@ -264,7 +264,7 @@ private class AClass2 } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -276,7 +276,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 14, "AClass"); } @@ -289,7 +289,7 @@ public partial class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 22, "AClass"); } @@ -305,9 +305,9 @@ public partial class AClass } "; - await Verify.DiagnosticExists(input, - (Platform_MissingDocsAnalyzer.Sas001, 2, 22, "AClass"), - (Platform_MissingDocsAnalyzer.Sas001, 5, 22, "AClass")); + await Verify.DiagnosticExists(input, + (MissingDocsAnalyzer.Sas001, 2, 22, "AClass"), + (MissingDocsAnalyzer.Sas001, 5, 22, "AClass")); } [Fact] @@ -319,7 +319,7 @@ internal class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 16, "AClass"); } @@ -332,7 +332,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 2, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 2, 14, "AClass"); } @@ -346,7 +346,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 3, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 3, 14, "AClass"); } @@ -362,7 +362,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 5, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 5, 14, "AClass"); } @@ -378,7 +378,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 5, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 5, 14, "AClass"); } @@ -394,7 +394,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 5, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 5, 14, "AClass"); } @@ -410,7 +410,7 @@ public class AClass } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas001, input, 5, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas001, input, 5, 14, "AClass"); } @@ -424,7 +424,7 @@ public class AClass } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -439,7 +439,7 @@ public class AClass } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -454,7 +454,7 @@ public partial class AClass } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -472,7 +472,7 @@ public partial class AClass } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } } @@ -488,7 +488,7 @@ public static class AClass public static void AMethod(){} }"; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -500,7 +500,7 @@ public static class AClass public static void AMethod(){} }"; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -512,7 +512,7 @@ public static void AMethod1(){} public static void AMethod2(this string value){} }"; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -525,7 +525,7 @@ public static void AMethod(){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 4, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 4, 24, "AMethod"); } @@ -542,7 +542,7 @@ public static void AMethod(){} } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -555,7 +555,7 @@ internal static void AMethod(){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 4, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 4, 26, "AMethod"); } @@ -569,7 +569,7 @@ public static void AMethod(string value){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 4, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 4, 24, "AMethod"); } @@ -583,7 +583,7 @@ internal static void AMethod(string value){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 4, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 4, 26, "AMethod"); } @@ -597,7 +597,7 @@ internal static void AMethod(this string value){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 4, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 4, 26, "AMethod"); } @@ -611,7 +611,7 @@ private static void AMethod(this string value){} } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -624,7 +624,7 @@ public static void AMethod(this string value){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 4, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 4, 24, "AMethod"); } @@ -641,7 +641,7 @@ public static void AMethod(this string value){} } "; - await Verify.DiagnosticExists(Platform_MissingDocsAnalyzer.Sas002, input, 7, + await Verify.DiagnosticExists(MissingDocsAnalyzer.Sas002, input, 7, 24, "AMethod"); } @@ -658,7 +658,7 @@ public static void AMethod(this string value){} } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } [Fact] @@ -672,7 +672,7 @@ public static void AMethod(this string value){} } "; - await Verify.NoDiagnosticExists(input); + await Verify.NoDiagnosticExists(input); } } } \ No newline at end of file diff --git a/src/Tools.Analyzers.Platform.UnitTests/Tools.Analyzers.Platform.UnitTests.csproj b/src/Tools.Analyzers.Platform.UnitTests/Tools.Analyzers.Platform.UnitTests.csproj index 52f79ddc..8eb8a209 100644 --- a/src/Tools.Analyzers.Platform.UnitTests/Tools.Analyzers.Platform.UnitTests.csproj +++ b/src/Tools.Analyzers.Platform.UnitTests/Tools.Analyzers.Platform.UnitTests.csproj @@ -8,14 +8,10 @@ - + - - - - diff --git a/src/Tools.Analyzers.Platform.UnitTests/Verify.cs b/src/Tools.Analyzers.Platform.UnitTests/Verify.cs index 7a87736b..f9e27340 100644 --- a/src/Tools.Analyzers.Platform.UnitTests/Verify.cs +++ b/src/Tools.Analyzers.Platform.UnitTests/Verify.cs @@ -1,6 +1,6 @@ extern alias CommonAnalyzers; +extern alias PlatformAnalyzers; using System.Reflection; -using Common.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Diagnostics; @@ -8,6 +8,7 @@ using NuGet.Frameworks; using AnalyzerConstants = CommonAnalyzers::Tools.Analyzers.Common.AnalyzerConstants; using Task = System.Threading.Tasks.Task; +using PlatformAnalyzers::Common.Extensions; namespace Tools.Analyzers.Platform.UnitTests; diff --git a/src/Tools.Analyzers.Platform/Reference/System.Diagnostics.CodeAnalysis.cs b/src/Tools.Analyzers.Platform/Reference/System.Diagnostics.CodeAnalysis.cs new file mode 100644 index 00000000..aeb26de7 --- /dev/null +++ b/src/Tools.Analyzers.Platform/Reference/System.Diagnostics.CodeAnalysis.cs @@ -0,0 +1,30 @@ +#define INTERNAL_NULLABLE_ATTRIBUTES + +// ReSharper disable once CheckNamespace +namespace System.Diagnostics.CodeAnalysis; + +/// +/// HACK: This code is to enable the use of the '[NotNullWhen]' attribute that is not present in netstandard20 +/// Specifies that when a method returns , the parameter will not be null even if the +/// corresponding type allows it. +/// +[AttributeUsage(AttributeTargets.Parameter)] +#if INTERNAL_NULLABLE_ATTRIBUTES +internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) + { + ReturnValue = returnValue; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } +} \ No newline at end of file diff --git a/src/Tools.Analyzers.Platform/Tools.Analyzers.Platform.csproj b/src/Tools.Analyzers.Platform/Tools.Analyzers.Platform.csproj index d1e627a9..eb9dd8d3 100644 --- a/src/Tools.Analyzers.Platform/Tools.Analyzers.Platform.csproj +++ b/src/Tools.Analyzers.Platform/Tools.Analyzers.Platform.csproj @@ -1,14 +1,17 @@ - net8.0 + netstandard2.0 + $(DefineConstants);ANALYZERS_PLATFORM + latest + enable true true true - $(NoWarn),RS2007;NU5128 + $(NoWarn),RS2007,NU5128 @@ -28,6 +31,15 @@ + + + Reference\Common\Annotations.cs + + + Reference\Common\Extensions\ObjectExtensions.cs + + + ResXFileCodeGenerator @@ -43,9 +55,15 @@ - + $(GetTargetPathDependsOn);GetDependencyTargetPaths + <_TargetFramework>8.0.2 + <_AspNetFrameworkInstallFolder>C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\$(_TargetFramework) + <_FrameworkInstallFolder>C:\Program Files\dotnet\shared\Microsoft.NETCore.App\$(_TargetFramework) diff --git a/src/Tools.Generators.Common.UnitTests/FeatureFlagGeneratorSpec.cs b/src/Tools.Generators.Common.UnitTests/FeatureFlagGeneratorSpec.cs index 1933ed95..fd8cdd1e 100644 --- a/src/Tools.Generators.Common.UnitTests/FeatureFlagGeneratorSpec.cs +++ b/src/Tools.Generators.Common.UnitTests/FeatureFlagGeneratorSpec.cs @@ -1,11 +1,13 @@ +extern alias CommonGenerator; using System.Reflection; using System.Text; using FluentAssertions; -using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using Xunit; +using FeatureFlagGenerator = CommonGenerator::Tools.Generators.Common.FeatureFlagGenerator; +using UsedImplicitly = CommonGenerator::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Generators.Common.UnitTests; diff --git a/src/Tools.Generators.Common.UnitTests/Tools.Generators.Common.UnitTests.csproj b/src/Tools.Generators.Common.UnitTests/Tools.Generators.Common.UnitTests.csproj index 3b406434..43f5c4a5 100644 --- a/src/Tools.Generators.Common.UnitTests/Tools.Generators.Common.UnitTests.csproj +++ b/src/Tools.Generators.Common.UnitTests/Tools.Generators.Common.UnitTests.csproj @@ -6,14 +6,11 @@ - - + + - - - diff --git a/src/Tools.Generators.Common/Reference/System.Diagnostics.CodeAnalysis.cs b/src/Tools.Generators.Common/Reference/System.Diagnostics.CodeAnalysis.cs new file mode 100644 index 00000000..aeb26de7 --- /dev/null +++ b/src/Tools.Generators.Common/Reference/System.Diagnostics.CodeAnalysis.cs @@ -0,0 +1,30 @@ +#define INTERNAL_NULLABLE_ATTRIBUTES + +// ReSharper disable once CheckNamespace +namespace System.Diagnostics.CodeAnalysis; + +/// +/// HACK: This code is to enable the use of the '[NotNullWhen]' attribute that is not present in netstandard20 +/// Specifies that when a method returns , the parameter will not be null even if the +/// corresponding type allows it. +/// +[AttributeUsage(AttributeTargets.Parameter)] +#if INTERNAL_NULLABLE_ATTRIBUTES +internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) + { + ReturnValue = returnValue; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } +} \ No newline at end of file diff --git a/src/Tools.Generators.Common/Tools.Generators.Common.csproj b/src/Tools.Generators.Common/Tools.Generators.Common.csproj index d6e5e61e..41853ee5 100644 --- a/src/Tools.Generators.Common/Tools.Generators.Common.csproj +++ b/src/Tools.Generators.Common/Tools.Generators.Common.csproj @@ -22,6 +22,9 @@ + + Reference\Common\Annotations.cs + Reference\Common\FeatureFlags\Flag.cs diff --git a/src/Tools.Generators.Web.Api.Authorization.UnitTests/AuthorizationAttributeGeneratorSpec.cs b/src/Tools.Generators.Web.Api.Authorization.UnitTests/AuthorizationAttributeGeneratorSpec.cs index 0d6a9357..e1bfd20d 100644 --- a/src/Tools.Generators.Web.Api.Authorization.UnitTests/AuthorizationAttributeGeneratorSpec.cs +++ b/src/Tools.Generators.Web.Api.Authorization.UnitTests/AuthorizationAttributeGeneratorSpec.cs @@ -1,9 +1,11 @@ +extern alias WebApiAuthorizationGenerator; using System.Reflection; using FluentAssertions; -using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; +using AuthorizationAttributeGenerator = WebApiAuthorizationGenerator::Tools.Generators.Web.Api.Authorization.AuthorizationAttributeGenerator; +using UsedImplicitly = WebApiAuthorizationGenerator::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Generators.Web.Api.Authorization.UnitTests; diff --git a/src/Tools.Generators.Web.Api.Authorization.UnitTests/Tools.Generators.Web.Api.Authorization.UnitTests.csproj b/src/Tools.Generators.Web.Api.Authorization.UnitTests/Tools.Generators.Web.Api.Authorization.UnitTests.csproj index 8789af64..979cadac 100644 --- a/src/Tools.Generators.Web.Api.Authorization.UnitTests/Tools.Generators.Web.Api.Authorization.UnitTests.csproj +++ b/src/Tools.Generators.Web.Api.Authorization.UnitTests/Tools.Generators.Web.Api.Authorization.UnitTests.csproj @@ -6,14 +6,11 @@ - - + + - - - diff --git a/src/Tools.Generators.Web.Api.Authorization/Reference/System.Diagnostics.CodeAnalysis.cs b/src/Tools.Generators.Web.Api.Authorization/Reference/System.Diagnostics.CodeAnalysis.cs new file mode 100644 index 00000000..aeb26de7 --- /dev/null +++ b/src/Tools.Generators.Web.Api.Authorization/Reference/System.Diagnostics.CodeAnalysis.cs @@ -0,0 +1,30 @@ +#define INTERNAL_NULLABLE_ATTRIBUTES + +// ReSharper disable once CheckNamespace +namespace System.Diagnostics.CodeAnalysis; + +/// +/// HACK: This code is to enable the use of the '[NotNullWhen]' attribute that is not present in netstandard20 +/// Specifies that when a method returns , the parameter will not be null even if the +/// corresponding type allows it. +/// +[AttributeUsage(AttributeTargets.Parameter)] +#if INTERNAL_NULLABLE_ATTRIBUTES +internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) + { + ReturnValue = returnValue; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } +} \ No newline at end of file diff --git a/src/Tools.Generators.Web.Api.Authorization/Tools.Generators.Web.Api.Authorization.csproj b/src/Tools.Generators.Web.Api.Authorization/Tools.Generators.Web.Api.Authorization.csproj index 4769c66e..c4653166 100644 --- a/src/Tools.Generators.Web.Api.Authorization/Tools.Generators.Web.Api.Authorization.csproj +++ b/src/Tools.Generators.Web.Api.Authorization/Tools.Generators.Web.Api.Authorization.csproj @@ -22,6 +22,9 @@ + + Reference\Common\Annotations.cs + Reference\Common\Extensions\CollectionExtensions.cs diff --git a/src/Tools.Generators.Web.Api.UnitTests/MinimalApiMediatRGeneratorSpec.cs b/src/Tools.Generators.Web.Api.UnitTests/MinimalApiMediatRGeneratorSpec.cs index 89660ffa..4194f1ee 100644 --- a/src/Tools.Generators.Web.Api.UnitTests/MinimalApiMediatRGeneratorSpec.cs +++ b/src/Tools.Generators.Web.Api.UnitTests/MinimalApiMediatRGeneratorSpec.cs @@ -1,11 +1,11 @@ extern alias Generators; using System.Reflection; using FluentAssertions; -using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Xunit; using MinimalApiMediatRGenerator = Generators::Tools.Generators.Web.Api.MinimalApiMediatRGenerator; +using UsedImplicitly = Generators::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Generators.Web.Api.UnitTests; diff --git a/src/Tools.Generators.Web.Api.UnitTests/Tools.Generators.Web.Api.UnitTests.csproj b/src/Tools.Generators.Web.Api.UnitTests/Tools.Generators.Web.Api.UnitTests.csproj index b8d69d3b..a1751be5 100644 --- a/src/Tools.Generators.Web.Api.UnitTests/Tools.Generators.Web.Api.UnitTests.csproj +++ b/src/Tools.Generators.Web.Api.UnitTests/Tools.Generators.Web.Api.UnitTests.csproj @@ -7,13 +7,10 @@ - + - - - diff --git a/src/Tools.Generators.Web.Api.UnitTests/WebApiAssemblyVisitorSpec.cs b/src/Tools.Generators.Web.Api.UnitTests/WebApiAssemblyVisitorSpec.cs index 5d2a570f..fccabb6d 100644 --- a/src/Tools.Generators.Web.Api.UnitTests/WebApiAssemblyVisitorSpec.cs +++ b/src/Tools.Generators.Web.Api.UnitTests/WebApiAssemblyVisitorSpec.cs @@ -2,7 +2,6 @@ using System.Collections.Immutable; using System.Reflection; using FluentAssertions; -using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Moq; @@ -11,6 +10,7 @@ using IWebRequest = Generators::Infrastructure.Web.Api.Interfaces.IWebRequest; using ServiceOperation = Generators::Infrastructure.Web.Api.Interfaces.ServiceOperation; using WebApiAssemblyVisitor = Generators::Tools.Generators.Web.Api.WebApiAssemblyVisitor; +using UsedImplicitly = Generators::JetBrains.Annotations.UsedImplicitlyAttribute; namespace Tools.Generators.Web.Api.UnitTests; diff --git a/src/Tools.Generators.Web.Api/Reference/System.Diagnostics.CodeAnalysis.cs b/src/Tools.Generators.Web.Api/Reference/System.Diagnostics.CodeAnalysis.cs new file mode 100644 index 00000000..aeb26de7 --- /dev/null +++ b/src/Tools.Generators.Web.Api/Reference/System.Diagnostics.CodeAnalysis.cs @@ -0,0 +1,30 @@ +#define INTERNAL_NULLABLE_ATTRIBUTES + +// ReSharper disable once CheckNamespace +namespace System.Diagnostics.CodeAnalysis; + +/// +/// HACK: This code is to enable the use of the '[NotNullWhen]' attribute that is not present in netstandard20 +/// Specifies that when a method returns , the parameter will not be null even if the +/// corresponding type allows it. +/// +[AttributeUsage(AttributeTargets.Parameter)] +#if INTERNAL_NULLABLE_ATTRIBUTES +internal +#else + public +#endif + sealed class NotNullWhenAttribute : Attribute +{ + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) + { + ReturnValue = returnValue; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } +} \ No newline at end of file diff --git a/src/Tools.Generators.Web.Api/Tools.Generators.Web.Api.csproj b/src/Tools.Generators.Web.Api/Tools.Generators.Web.Api.csproj index cbb3a3e2..578b6323 100644 --- a/src/Tools.Generators.Web.Api/Tools.Generators.Web.Api.csproj +++ b/src/Tools.Generators.Web.Api/Tools.Generators.Web.Api.csproj @@ -22,6 +22,9 @@ + + Reference\Common\Annotations.cs + Reference\Common\Extensions\StringExtensions.cs diff --git a/src/UnitTesting.CodeAnalysis.Common/UnitTesting.CodeAnalysis.Common.csproj b/src/UnitTesting.CodeAnalysis.Common/UnitTesting.CodeAnalysis.Common.csproj new file mode 100644 index 00000000..746fcd1a --- /dev/null +++ b/src/UnitTesting.CodeAnalysis.Common/UnitTesting.CodeAnalysis.Common.csproj @@ -0,0 +1,29 @@ + + + + net8.0 + true + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + +