diff --git a/Directory.Build.targets b/Directory.Build.targets
index 3adec0a4c9b..3dcffa62576 100644
--- a/Directory.Build.targets
+++ b/Directory.Build.targets
@@ -26,7 +26,7 @@
$(NoWarn);AD0001
- $(NoWarn);EXTEXP0001;EXTEXP0002;EXTEXP0003;EXTEXP0004;EXTEXP0005;EXTEXP0006;EXTEXP0007;EXTEXP0008;EXTEXP0009;EXTEXP0010;EXTEXP0011;EXTEXP0012;EXTEXP0013
+ $(NoWarn);EXTEXP0001;EXTEXP0002;EXTEXP0003;EXTEXP0004;EXTEXP0005;EXTEXP0006;EXTEXP0007;EXTEXP0008;EXTEXP0009;EXTEXP0010;EXTEXP0011;EXTEXP0012;EXTEXP0013;EXTEXP0014;EXTEXP0015;EXTEXP0016;EXTEXP0017
$(NoWarn);NU5104
@@ -53,7 +53,7 @@
- <_Parameter1>TBD
+ <_Parameter1>$(StageDevDiagnosticId)
<_Parameter2>UrlFormat = "https://aka.ms/dotnet-extensions-warnings/{0}"
<_Parameter2_IsLiteral>true
diff --git a/NuGet.config b/NuGet.config
index 2f02faaae97..77ef6280040 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -2,6 +2,11 @@
+
+
+
+
+
@@ -14,6 +19,9 @@
+
+
+
diff --git a/README.md b/README.md
index 133a82b9c5d..247bdf69ec3 100644
--- a/README.md
+++ b/README.md
@@ -2,17 +2,14 @@
This repository contains a suite of libraries that provide facilities commonly needed when creating production-ready applications. Initially developed to support high-scale and high-availability services within Microsoft, such as Microsoft Teams, these libraries deliver functionality that can help make applications more efficient, more robust, and more manageable.
-The code in this repo is preliminary and will be released in stable form with .NET 8
-
The major functional areas this repo addresses are:
-- Compliance: Mechanisms to help manage application data according to privacy regulations and policies, which includes a data annotation framework, supporting analyzers, audit report generation, and telemetry redaction.
+- Compliance: Mechanisms to help manage application data according to privacy regulations and policies, which includes a data annotation framework, audit report generation, and telemetry redaction.
- Diagnostics: Provides a set of APIs that can be used to gather and report diagnostic information about the health of a service.
- Contextual Options: Extends the .NET Options model to enable experimentations in production.
-- Resilience: Builds on top of the popular Polly library to provide sophisticated resilience pipelines along with support for chaos engineering to make applications robust to transient errors.
+- Resilience: Builds on top of the popular Polly library to provide sophisticated resilience pipelines to make applications robust to transient errors.
- Telemetry: Sophisticated telemetry facilities provide enhanced logging, metering, tracing, and latency measuring functionality.
- AspNetCore extensions: Provides different middlewares and extensions that can be used to build high-performance and high-availability ASP.NET Core services.
-- Cloud Abstractions: A growing set of abstractions representing common cloud-native service types, making it possible to write applications that can work across multiple cloud providers with relative ease.
-- Static Analysis: Provides a set of Roslyn analyzers that can be used to enforce best practices and coding standards.
+- Static Analysis: Curated static analysis settings to help improve your code.
- Testing: Dramatically simplifies testing around common .NET abstractions such as ILogger and the TimeProvider.
[](https://dev.azure.com/dnceng/internal/_build/latest?definitionId=1223&branchName=main)
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index 0fab90d71d3..7f5a245bb87 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -56,12 +56,11 @@ variables:
- name: runAsPublic
value: ${{ eq(variables['System.TeamProject'], 'public') }}
+
- name: _BuildConfig
value: Release
- name: isOfficialBuild
value: ${{ and(ne(variables['runAsPublic'], 'true'), notin(variables['Build.Reason'], 'PullRequest')) }}
- - name: IsDeltaBuild
- value: ${{ eq(variables['Build.Reason'], 'PullRequest') }}
- name: Build.Arcade.ArtifactsPath
value: $(Build.SourcesDirectory)/artifacts/
- name: Build.Arcade.LogsPath
@@ -69,14 +68,6 @@ variables:
- name: Build.Arcade.TestResultsPath
value: $(Build.Arcade.ArtifactsPath)TestResults/$(_BuildConfig)/
- # For full build we can do a shallow build, for a delta build we need the full history.
- - ${{ if eq(variables['IsDeltaBuild'], 'true') }}:
- - name: _FetchDepth
- value: 0
- - ${{ else }}:
- - name: _FetchDepth
- value: 1
-
- ${{ if or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), eq(variables['Build.Reason'], 'Manual')) }}:
- name: PostBuildSign
value: false
@@ -163,7 +154,7 @@ stages:
- checkout: self
clean: true
persistCredentials: true
- fetchDepth: $(_FetchDepth)
+ fetchDepth: 1
steps:
- template: /eng/pipelines/templates/BuildAndTest.yml
@@ -173,7 +164,6 @@ stages:
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
skipQualityGates: ${{ eq(variables['SkipQualityGates'], 'true') }}
- isDeltaBuild: $(IsDeltaBuild)
isWindows: true
warnAsError: 0
@@ -200,7 +190,7 @@ stages:
- checkout: self
clean: true
persistCredentials: true
- fetchDepth: $(_FetchDepth)
+ fetchDepth: 1
steps:
- template: /eng/pipelines/templates/BuildAndTest.yml
@@ -210,7 +200,6 @@ stages:
repoLogPath: $(Build.Arcade.LogsPath)
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
skipQualityGates: ${{ eq(variables['SkipQualityGates'], 'true') }}
- isDeltaBuild: $(IsDeltaBuild)
isWindows: false
warnAsError: 0
@@ -262,8 +251,6 @@ stages:
displayName: Init toolset
- template: /eng/pipelines/templates/VerifyCoverageReport.yml
- parameters:
- isDeltaBuild: $(IsDeltaBuild)
# ----------------------------------------------------------------
@@ -304,7 +291,7 @@ stages:
- checkout: self
clean: true
persistCredentials: true
- fetchDepth: $(_FetchDepth)
+ fetchDepth: 1
steps:
- template: \eng\pipelines\templates\BuildAndTest.yml
@@ -315,7 +302,6 @@ stages:
repoTestResultsPath: $(Build.Arcade.TestResultsPath)
skipTests: true
skipQualityGates: true
- isDeltaBuild: $(IsDeltaBuild)
isWindows: false
diff --git a/bench/.editorconfig b/bench/.editorconfig
index 0d495f075f7..b2c317651b7 100644
--- a/bench/.editorconfig
+++ b/bench/.editorconfig
@@ -1,5 +1,5 @@
# Created by DiagConfig, the diagnostic config generator
-# Generated : 2023-08-07 17:59:53Z
+# Generated : 2023-10-22 00:37:47Z
# Max Tier : 2147483647
# Attributes: general, performance
# Analyzers : ILLink.RoslynAnalyzer, Microsoft.Analyzers.Extra, Microsoft.Analyzers.Local, Microsoft.AspNetCore.App.Analyzers, Microsoft.AspNetCore.Components.Analyzers, Microsoft.CodeAnalysis.CodeStyle, Microsoft.CodeAnalysis.CSharp.CodeStyle, Microsoft.CodeAnalysis.CSharp.NetAnalyzers, Microsoft.CodeAnalysis.NetAnalyzers, Microsoft.VisualStudio.Threading.Analyzers, Microsoft.VisualStudio.Threading.Analyzers.CSharp, SonarAnalyzer.CSharp, StyleCop.Analyzers
@@ -868,7 +868,7 @@ dotnet_diagnostic.CA1860.severity = warning
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861
dotnet_diagnostic.CA1861.severity = suggestion
-# Title : Prefer using 'StringComparer' to perform case-insensitive string comparisons
+# Title : Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
# Category : Performance
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1862
dotnet_diagnostic.CA1862.severity = warning
@@ -903,6 +903,16 @@ dotnet_diagnostic.CA1867.severity = warning
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1868
dotnet_diagnostic.CA1868.severity = warning
+# Title : Cache and reuse 'JsonSerializerOptions' instances
+# Category : Performance
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869
+dotnet_diagnostic.CA1869.severity = warning
+
+# Title : Use a cached 'SearchValues' instance
+# Category : Performance
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1870
+dotnet_diagnostic.CA1870.severity = warning
+
# Title : Dispose objects before losing scope
# Category : Reliability
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2000
@@ -1720,62 +1730,77 @@ dotnet_diagnostic.CA5405.severity = none
# Title : Use source generated logging methods for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0000
dotnet_diagnostic.EA0000.severity = warning
# Title : Perform message formatting in the body of the logging method
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0001
dotnet_diagnostic.EA0001.severity = warning
# Title : Use 'System.TimeProvider' to make the code easier to test
# Category : Reliability
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0002
dotnet_diagnostic.EA0002.severity = none
# Title : Use the character-based overloads of 'String.StartsWith' or 'String.EndsWith'
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0003
dotnet_diagnostic.EA0003.severity = warning
# Title : Make types declared in an executable internal
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0004
dotnet_diagnostic.EA0004.severity = warning
# Title : Consider using an array instead of a collection
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0005
dotnet_diagnostic.EA0005.severity = none
# Title : Replace uses of 'Enum.GetName' and 'Enum.ToString' for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0006
dotnet_diagnostic.EA0006.severity = warning
# Title : Use 'System.ValueTuple' instead of 'System.Tuple' for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0007
dotnet_diagnostic.EA0007.severity = warning
# Title : Use generic collections instead of legacy collections for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0008
dotnet_diagnostic.EA0008.severity = warning
# Title : Use 'System.MemoryExtensions.Split' for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0009
dotnet_diagnostic.EA0009.severity = warning
# Title : Fire-and-forget async call inside a 'using' block
# Category : Correctness
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0010
dotnet_diagnostic.EA0010.severity = warning
# Title : Consider removing unnecessary conditional access operator (?)
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0011
dotnet_diagnostic.EA0011.severity = warning
# Title : Consider removing unnecessary null coalescing assignment (??=)
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0012
dotnet_diagnostic.EA0012.severity = suggestion
# Title : Consider removing unnecessary null coalescing operator (??)
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0013
dotnet_diagnostic.EA0013.severity = suggestion
# Title : The async method doesn't support cancellation
# Category : Resilience
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0014
dotnet_diagnostic.EA0014.severity = none
# Title : Set MSBuild property 'GenerateDocumentationFile' to 'true'
@@ -2408,6 +2433,26 @@ dotnet_diagnostic.IDE0300.severity = none
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0301
dotnet_diagnostic.IDE0301.severity = suggestion
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0302
+dotnet_diagnostic.IDE0302.severity = none
+
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0303
+dotnet_diagnostic.IDE0303.severity = none
+
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0304
+dotnet_diagnostic.IDE0304.severity = none
+
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0305
+dotnet_diagnostic.IDE0305.severity = none
+
# Title : Delegate invocation can be simplified.
# Category : Style
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1005
diff --git a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/EnumStrings.cs b/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/EnumStrings.cs
deleted file mode 100644
index 33d985958d6..00000000000
--- a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/EnumStrings.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using BenchmarkDotNet.Attributes;
-using Microsoft.Extensions.EnumStrings;
-
-namespace Microsoft.Gen.EnumStrings.Bench;
-
-#pragma warning disable CA1822 // Mark members as static
-#pragma warning disable EA0006 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
-
-[MemoryDiagnoser]
-public class EnumStrings
-{
- private static readonly int[] _randomValues = new int[1000];
-
- [EnumStrings]
- internal enum Color
- {
- Red,
- Green,
- Blue,
- }
-
- [Flags]
- [EnumStrings]
- internal enum SmallOptions
- {
- Options1 = 1,
- Options2 = 2,
- Options4 = 4,
- Options8 = 8,
- Options16 = 16,
- }
-
- [Flags]
- [EnumStrings]
- internal enum LargeOptions
- {
- Options1 = 1,
- Options2 = 2,
- Options4 = 4,
- Options8 = 8,
- Options16 = 16,
- Options32 = 32,
- Options64 = 64,
- Options128 = 128,
- }
-
- static EnumStrings()
- {
- var r = new Random();
- for (int i = 0; i < _randomValues.Length; i++)
- {
- _randomValues[i] = r.Next();
- }
- }
-
- [Benchmark]
- public void ToStringColor()
- {
- _ = Color.Red.ToString();
- _ = Color.Green.ToString();
- _ = Color.Blue.ToString();
- }
-
- [Benchmark]
- public void GetNameColor()
- {
- _ = Enum.GetName(Color.Red);
- _ = Enum.GetName(Color.Green);
- _ = Enum.GetName(Color.Blue);
- }
-
- [Benchmark]
- public void ToInvariantStringColor()
- {
- _ = Color.Red.ToInvariantString();
- _ = Color.Green.ToInvariantString();
- _ = Color.Blue.ToInvariantString();
- }
-
- [Benchmark]
- public void ToStringSmallOptions()
- {
- _ = SmallOptions.Options1.ToString();
- _ = SmallOptions.Options2.ToString();
- _ = SmallOptions.Options4.ToString();
- _ = SmallOptions.Options8.ToString();
- _ = SmallOptions.Options16.ToString();
-
- _ = (SmallOptions.Options1 | SmallOptions.Options16).ToString();
- _ = (SmallOptions.Options2 | SmallOptions.Options4).ToString();
- }
-
- [Benchmark]
- public void ToInvariantStringSmallOptions()
- {
- _ = SmallOptions.Options1.ToInvariantString();
- _ = SmallOptions.Options2.ToInvariantString();
- _ = SmallOptions.Options4.ToInvariantString();
- _ = SmallOptions.Options8.ToInvariantString();
- _ = SmallOptions.Options16.ToInvariantString();
-
- _ = (SmallOptions.Options1 | SmallOptions.Options16).ToInvariantString();
- _ = (SmallOptions.Options2 | SmallOptions.Options4).ToInvariantString();
- }
-
- [Benchmark]
- public void ToStringLargeOptions()
- {
- _ = LargeOptions.Options1.ToString();
- _ = LargeOptions.Options2.ToString();
- _ = LargeOptions.Options4.ToString();
- _ = LargeOptions.Options8.ToString();
- _ = LargeOptions.Options16.ToString();
- _ = LargeOptions.Options32.ToString();
- _ = LargeOptions.Options64.ToString();
- _ = LargeOptions.Options128.ToString();
-
- _ = (LargeOptions.Options1 | LargeOptions.Options16).ToString();
- _ = (LargeOptions.Options2 | LargeOptions.Options4).ToString();
- }
-
- [Benchmark]
- public void ToInvariantStringLargeOptions()
- {
- _ = LargeOptions.Options1.ToInvariantString();
- _ = LargeOptions.Options2.ToInvariantString();
- _ = LargeOptions.Options4.ToInvariantString();
- _ = LargeOptions.Options8.ToInvariantString();
- _ = LargeOptions.Options16.ToInvariantString();
- _ = LargeOptions.Options32.ToInvariantString();
- _ = LargeOptions.Options64.ToInvariantString();
- _ = LargeOptions.Options128.ToInvariantString();
-
- _ = (LargeOptions.Options1 | LargeOptions.Options16).ToInvariantString();
- _ = (LargeOptions.Options2 | LargeOptions.Options4).ToInvariantString();
- }
-
- // the next two benchmarks aren't representative of expected real-world use cases, but let's see the impact the code gen has relative to naked Enum.ToString
-
- [Benchmark]
- public void ToStringRandom()
- {
- for (int i = 0; i < _randomValues.Length; i++)
- {
- var o = (LargeOptions)_randomValues[i];
- _ = o.ToString();
- }
- }
-
- [Benchmark]
- public void ToInvariantStringRandom()
- {
- for (int i = 0; i < _randomValues.Length; i++)
- {
- var o = (LargeOptions)_randomValues[i];
- _ = o.ToInvariantString();
- }
- }
-}
diff --git a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/Microsoft.Gen.EnumStrings.PerformanceTests.csproj b/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/Microsoft.Gen.EnumStrings.PerformanceTests.csproj
deleted file mode 100644
index af53a3cc942..00000000000
--- a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/Microsoft.Gen.EnumStrings.PerformanceTests.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Microsoft.Gen.EnumStrings.PerformanceTests
- Benchmarks for Gen.EnumStrings.
- true
- true
-
-
-
-
-
-
-
-
-
-
diff --git a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/Program.cs b/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/Program.cs
deleted file mode 100644
index 9f45ee6d5ea..00000000000
--- a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/Program.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using BenchmarkDotNet.Configs;
-using BenchmarkDotNet.Jobs;
-using BenchmarkDotNet.Running;
-using BenchmarkDotNet.Toolchains.InProcess.Emit;
-
-namespace Microsoft.Gen.EnumStrings.Bench;
-
-internal static class Program
-{
- public static void Main(string[] args)
- {
- var dontRequireSlnToRunBenchmarks = ManualConfig
- .Create(DefaultConfig.Instance)
- .AddJob(Job.MediumRun.WithToolchain(InProcessEmitToolchain.Instance));
-
- BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args, dontRequireSlnToRunBenchmarks);
- }
-}
diff --git a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/README.md b/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/README.md
deleted file mode 100644
index 6c7f983f12b..00000000000
--- a/bench/Generators/Microsoft.Gen.EnumStrings.PerformanceTests/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-```
-BenchmarkDotNet=v0.13.2, OS=Windows 11 (10.0.22621.963)
-Intel Core i7-9700K CPU 3.60GHz (Coffee Lake), 1 CPU, 8 logical and 8 physical cores
-.NET SDK=7.0.100
- [Host] : .NET 7.0.1 (7.0.122.56804), X64 RyuJIT AVX2
-
-Job=MediumRun Toolchain=InProcessEmitToolchain IterationCount=15
-LaunchCount=2 WarmupCount=10
-
-| Method | Mean | Error | StdDev | Gen0 | Allocated |
-|------------------------------ |--------------:|--------------:|--------------:|--------:|----------:|
-| ToStringColor | 40.991 ns | 0.5249 ns | 0.7358 ns | 0.0114 | 72 B |
-| GetNameColor | 33.143 ns | 0.4681 ns | 0.7007 ns | - | - |
-| ToInvariantStringColor | 3.834 ns | 0.0178 ns | 0.0267 ns | - | - |
-| ToStringSmallOptions | 135.437 ns | 1.7399 ns | 2.5503 ns | 0.0470 | 296 B |
-| ToInvariantStringSmallOptions | 12.207 ns | 0.0620 ns | 0.0889 ns | - | - |
-| ToStringLargeOptions | 193.580 ns | 2.6614 ns | 3.8169 ns | 0.0587 | 368 B |
-| ToInvariantStringLargeOptions | 16.424 ns | 0.2146 ns | 0.3145 ns | - | - |
-| ToStringRandom | 72,026.761 ns | 1,205.1409 ns | 1,728.3770 ns | 10.8643 | 68232 B |
-| ToInvariantStringRandom | 64,554.832 ns | 581.9061 ns | 852.9504 ns | 8.0566 | 50758 B |
-```
diff --git a/bench/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware.PerformanceTests/RedactionBenchmark.cs b/bench/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware.PerformanceTests/RedactionBenchmark.cs
index d8aae25fead..30e87512578 100644
--- a/bench/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware.PerformanceTests/RedactionBenchmark.cs
+++ b/bench/Libraries/Microsoft.AspNetCore.Diagnostics.Middleware.PerformanceTests/RedactionBenchmark.cs
@@ -29,8 +29,8 @@ public class RedactionBenchmark
public RedactionBenchmark()
{
- _routeParameterDataClasses.Add("userId", FakeClassifications.PrivateData);
- _routeParameterDataClasses.Add("chatId", FakeClassifications.PrivateData);
+ _routeParameterDataClasses.Add("userId", FakeTaxonomy.PrivateData);
+ _routeParameterDataClasses.Add("chatId", FakeTaxonomy.PrivateData);
_httpPath = "/users/{userId}/chats/{chatId}/test1/test2/{userId}";
_stringBuilderPool = PoolFactory.CreateStringBuilderPool();
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Diagnostics.PerformanceTests/HttpClientFactory.cs b/bench/Libraries/Microsoft.Extensions.Http.Diagnostics.PerformanceTests/HttpClientFactory.cs
index 8f8d3366fcb..8cef086ae76 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Diagnostics.PerformanceTests/HttpClientFactory.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Diagnostics.PerformanceTests/HttpClientFactory.cs
@@ -26,7 +26,7 @@ public static System.Net.Http.HttpClient CreateWithLoggingLogRequest(string file
{
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add(new("application/json"));
- options.RequestHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.RequestHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
})
.AddHttpMessageHandler()
.Services
@@ -49,7 +49,7 @@ public static System.Net.Http.HttpClient CreateWithLoggingLogResponse(string fil
{
options.BodySizeLimit = readLimit;
options.ResponseBodyContentTypes.Add(new("application/json"));
- options.ResponseHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.ResponseHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
})
.AddHttpMessageHandler()
.Services
@@ -73,10 +73,10 @@ public static System.Net.Http.HttpClient CreateWithLoggingLogAll(string fileName
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add(new("application/json"));
- options.RequestHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.RequestHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
options.ResponseBodyContentTypes.Add(new("application/json"));
- options.ResponseHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.ResponseHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
})
.AddHttpMessageHandler()
.Services
@@ -99,7 +99,7 @@ public static System.Net.Http.HttpClient CreateWithLoggingLogRequest_ChunkedEnco
{
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add("application/json");
- options.RequestHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.RequestHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
})
.AddHttpMessageHandler()
.Services
@@ -122,7 +122,7 @@ public static System.Net.Http.HttpClient CreateWithLoggingLogResponse_ChunkedEnc
{
options.BodySizeLimit = readLimit;
options.ResponseBodyContentTypes.Add("application/json");
- options.ResponseHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.ResponseHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
})
.AddHttpMessageHandler()
.Services
@@ -146,10 +146,10 @@ public static System.Net.Http.HttpClient CreateWithLoggingLogAll_ChunkedEncoding
options.BodySizeLimit = readLimit;
options.RequestBodyContentTypes.Add("application/json");
- options.RequestHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.RequestHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
options.ResponseBodyContentTypes.Add("application/json");
- options.ResponseHeadersDataClasses.Add("Content-Type", FakeClassifications.PrivateData);
+ options.ResponseHeadersDataClasses.Add("Content-Type", FakeTaxonomy.PrivateData);
})
.AddHttpMessageHandler()
.Services
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/EmptyHandler.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/EmptyHandler.cs
index 08a53910c2b..21139d6e600 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/EmptyHandler.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/EmptyHandler.cs
@@ -5,7 +5,7 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Microsoft.Extensions.Http.Resilience.Bench;
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
internal sealed class EmptyHandler : DelegatingHandler
{
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HedgingBenchmark.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HedgingBenchmark.cs
index 830e915440f..87444bd4d32 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HedgingBenchmark.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HedgingBenchmark.cs
@@ -8,7 +8,7 @@
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
-namespace Microsoft.Extensions.Http.Resilience.Bench;
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
public class HedgingBenchmark
{
@@ -22,9 +22,7 @@ public void GlobalSetup()
{
var serviceProvider = HttpClientFactory.InitializeServiceProvider(Type);
var factory = serviceProvider.GetRequiredService();
-#pragma warning disable EA0006 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
_client = factory.CreateClient(Type.ToString());
-#pragma warning restore EA0006 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
}
[Params(
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpClientFactory.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpClientFactory.cs
index 787fde93907..93b601ed743 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpClientFactory.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpClientFactory.cs
@@ -11,9 +11,7 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
-#pragma warning disable EA0006 // Replace uses of 'Enum.GetName' and 'Enum.ToString' with the '[EnumStrings]' code generator for improved performance
-
-namespace Microsoft.Extensions.Http.Resilience.Bench;
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
[Flags]
[SuppressMessage("Performance", "EA0004:Make types declared in an executable internal", Justification = "Needs to be public for BenchmarkDotNet consumption")]
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpResilienceBenchmark.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpResilienceBenchmark.cs
index 0cba391425a..be33374a3d2 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpResilienceBenchmark.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/HttpResilienceBenchmark.cs
@@ -8,7 +8,7 @@
using BenchmarkDotNet.Attributes;
using Microsoft.Extensions.DependencyInjection;
-namespace Microsoft.Extensions.Http.Resilience.Bench;
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
public class HttpResilienceBenchmark
{
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Microsoft.Extensions.Http.Resilience.PerformanceTests.csproj b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Microsoft.Extensions.Http.Resilience.PerformanceTests.csproj
index da3c2b88b09..fc10dbcce77 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Microsoft.Extensions.Http.Resilience.PerformanceTests.csproj
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Microsoft.Extensions.Http.Resilience.PerformanceTests.csproj
@@ -1,13 +1,19 @@
- Microsoft.Extensions.Http.Resilience.FaultInjection.PerformanceTests
+ Microsoft.Extensions.Http.Resilience.PerformanceTests
Benchmarks for Microsoft.Extensions.Http.Resilience.
-
+
+
+
+
+
+
+
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/NoRemoteCallHandler.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/NoRemoteCallHandler.cs
index a2d9a00f34e..a834695bf2b 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/NoRemoteCallHandler.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/NoRemoteCallHandler.cs
@@ -5,7 +5,7 @@
using System.Threading;
using System.Threading.Tasks;
-namespace Microsoft.Extensions.Http.Resilience.Bench;
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
internal sealed class NoRemoteCallHandler : DelegatingHandler
{
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Program.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Program.cs
index 3f96d60b9c0..1b0dd707dd6 100644
--- a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Program.cs
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/Program.cs
@@ -7,7 +7,7 @@
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains.InProcess.Emit;
-namespace Microsoft.Extensions.Http.Resilience.FaultInjection.Benchmark
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests
{
internal static class Program
{
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/RetryBenchmark.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/RetryBenchmark.cs
new file mode 100644
index 00000000000..16da92acd4a
--- /dev/null
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/RetryBenchmark.cs
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Polly;
+using Polly.Timeout;
+
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
+
+public class RetryBenchmark
+{
+ private static readonly Uri _uri = new(HttpClientFactory.PrimaryEndpoint);
+
+ private HttpClient _v7 = null!;
+ private HttpClient _v8 = null!;
+ private CancellationToken _cancellationToken;
+
+ private static HttpRequestMessage Request => new(HttpMethod.Post, _uri);
+
+ [GlobalSetup]
+ public void Prepare()
+ {
+ _cancellationToken = new CancellationTokenSource().Token;
+
+ var services = new ServiceCollection();
+
+ // The ResiliencePipelineBuilder added by Polly includes telemetry, which affects the results.
+ // Since Polly v7 does not include telemetry either, let's disable the telemetry for v8 for fair results.
+ services.TryAddTransient();
+
+ services
+ .AddHttpClient("v8")
+ .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler())
+ .AddResilienceHandler("my-retries", builder => builder.AddRetry(new HttpRetryStrategyOptions
+ {
+ BackoffType = DelayBackoffType.Constant,
+ Delay = TimeSpan.FromSeconds(1),
+ MaxRetryAttempts = 3
+ }));
+
+ var builder = Policy.Handle().Or().OrResult(r =>
+ {
+ var statusCode = (int)r.StatusCode;
+
+ return statusCode >= 500 ||
+ r.StatusCode == HttpStatusCode.RequestTimeout ||
+ statusCode == 429;
+ });
+
+ services
+ .AddHttpClient("v7")
+ .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler())
+ .AddPolicyHandler(builder.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1)));
+
+ var factory = services.BuildServiceProvider().GetRequiredService();
+
+ _v7 = factory.CreateClient("v7");
+ _v8 = factory.CreateClient("v8");
+ }
+
+ [Benchmark(Baseline = true)]
+ public Task Retry_Polly_V7()
+ {
+ return _v7!.SendAsync(Request, _cancellationToken);
+ }
+
+ [Benchmark]
+ public Task Retry_Polly_V8()
+ {
+ return _v8!.SendAsync(Request, _cancellationToken);
+ }
+}
diff --git a/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/StandardResilienceBenchmark.cs b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/StandardResilienceBenchmark.cs
new file mode 100644
index 00000000000..d7cc50f090e
--- /dev/null
+++ b/bench/Libraries/Microsoft.Extensions.Http.Resilience.PerformanceTests/StandardResilienceBenchmark.cs
@@ -0,0 +1,81 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using BenchmarkDotNet.Attributes;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Polly;
+using Polly.Timeout;
+
+namespace Microsoft.Extensions.Http.Resilience.PerformanceTests;
+
+public class StandardResilienceBenchmark
+{
+ private static readonly Uri _uri = new(HttpClientFactory.PrimaryEndpoint);
+
+ private HttpClient _v7 = null!;
+ private HttpClient _v8 = null!;
+ private CancellationToken _cancellationToken;
+
+ private static HttpRequestMessage Request => new(HttpMethod.Post, _uri);
+
+ [GlobalSetup]
+ public void Prepare()
+ {
+ _cancellationToken = new CancellationTokenSource().Token;
+
+ var services = new ServiceCollection();
+
+ // The ResiliencePipelineBuilder added by Polly includes telemetry, which affects the results.
+ // Since Polly v7 does not include telemetry either, let's disable the telemetry for v8 for fair results.
+ services.TryAddTransient();
+
+ services
+ .AddHttpClient("v8")
+ .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler())
+ .AddStandardResilienceHandler();
+
+ var builder = Policy.Handle().Or().OrResult(r =>
+ {
+ var statusCode = (int)r.StatusCode;
+
+ return statusCode >= 500 ||
+ r.StatusCode == HttpStatusCode.RequestTimeout ||
+ statusCode == 429;
+ });
+
+ var policy = Policy.WrapAsync(
+ Policy.TimeoutAsync(3),
+ builder.AdvancedCircuitBreakerAsync(0.1, TimeSpan.FromSeconds(30), 100, TimeSpan.FromSeconds(5)),
+ builder.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1)),
+ Policy.BulkheadAsync(1000, 100),
+ Policy.TimeoutAsync(30));
+
+ services
+ .AddHttpClient("v7")
+ .ConfigurePrimaryHttpMessageHandler(() => new NoRemoteCallHandler())
+ .AddPolicyHandler(_ => policy);
+
+ var factory = services.BuildServiceProvider().GetRequiredService();
+
+ _v7 = factory.CreateClient("v7");
+ _v8 = factory.CreateClient("v8");
+ }
+
+ [Benchmark(Baseline = true)]
+ public Task StandardPipeline_Polly_V7()
+ {
+ return _v7!.SendAsync(Request, _cancellationToken);
+ }
+
+ [Benchmark]
+ public Task StandardPipeline_Polly_V8()
+ {
+ return _v8!.SendAsync(Request, _cancellationToken);
+ }
+}
diff --git a/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/Microsoft.Extensions.Resilience.PerformanceTests.csproj b/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/Microsoft.Extensions.Resilience.PerformanceTests.csproj
index f755df01656..a6f614b1cb8 100644
--- a/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/Microsoft.Extensions.Resilience.PerformanceTests.csproj
+++ b/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/Microsoft.Extensions.Resilience.PerformanceTests.csproj
@@ -6,6 +6,6 @@
-
+
diff --git a/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/ResilienceEnrichmentBenchmark.cs b/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/ResilienceEnrichmentBenchmark.cs
index b4b34751790..228a42531f9 100644
--- a/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/ResilienceEnrichmentBenchmark.cs
+++ b/bench/Libraries/Microsoft.Extensions.Resilience.PerformanceTests/ResilienceEnrichmentBenchmark.cs
@@ -23,11 +23,7 @@ public void GlobalSetup()
{
_listener = MetricsUtil.ListenPollyMetrics();
_pipeline = CreateResiliencePipeline(_ => { });
- _pipelineEnriched = CreateResiliencePipeline(services =>
- {
- services.AddResilienceEnricher();
- services.ConfigureFailureResultContext(res => FailureResultContext.Create("dummy", "dummy", "dummy"));
- });
+ _pipelineEnriched = CreateResiliencePipeline(services => services.AddResilienceEnricher());
}
[GlobalCleanup]
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/BenchLogger.cs b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/BenchLogger.cs
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/BenchLogger.cs
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/BenchLogger.cs
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/BenchLoggerProvider.cs b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/BenchLoggerProvider.cs
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/BenchLoggerProvider.cs
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/BenchLoggerProvider.cs
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/ClassicCodeGen.cs b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/ClassicCodeGen.cs
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/ClassicCodeGen.cs
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/ClassicCodeGen.cs
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/ExtendedLoggerBench.cs b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/ExtendedLoggerBench.cs
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/ExtendedLoggerBench.cs
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/ExtendedLoggerBench.cs
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests.csproj b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/Microsoft.Extensions.Telemetry.PerformanceTests.csproj
similarity index 68%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests.csproj
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/Microsoft.Extensions.Telemetry.PerformanceTests.csproj
index 6396bb13fe9..a39e8be6927 100644
--- a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests.csproj
+++ b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/Microsoft.Extensions.Telemetry.PerformanceTests.csproj
@@ -1,13 +1,13 @@
- Microsoft.Extensions.Diagnostics.Extra.Bench
- Benchmarks for Microsoft.Extensions.Diagnostics.Extra.
+ Microsoft.Extensions.Telemetry.Bench
+ Benchmarks for Microsoft.Extensions.Telemetry.
true
true
-
+
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/ModernCodeGen.cs b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/ModernCodeGen.cs
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/ModernCodeGen.cs
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/ModernCodeGen.cs
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/Program.cs b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/Program.cs
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/Program.cs
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/Program.cs
diff --git a/bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/README.md b/bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/README.md
similarity index 100%
rename from bench/Libraries/Microsoft.Extensions.Diagnostics.Extra.PerformanceTests/README.md
rename to bench/Libraries/Microsoft.Extensions.Telemetry.PerformanceTests/README.md
diff --git a/docs/list-of-diagnostics.md b/docs/list-of-diagnostics.md
index 5033c0be651..db04bdd4529 100644
--- a/docs/list-of-diagnostics.md
+++ b/docs/list-of-diagnostics.md
@@ -1,3 +1,63 @@
+
+# ContextualOptions
+
+| Diagnostic ID | Description |
+| :---------------- | :---------- |
+| `CTXOPTGEN000` | Options context classes can't be static |
+| `CTXOPTGEN001` | Options context types must be partial |
+| `CTXOPTGEN002` | The options context type does not have usable properties |
+| `CTXOPTGEN003` | The options context cannot be a ref-like type |
+
+
+# Design
+
+| Diagnostic ID | Description |
+| :---------------- | :---------- |
+| `AUTOCLIENTGEN001` | API client interfaces must not be nested types |
+| `AUTOCLIENTGEN002` | REST API client does not have methods defined |
+| `AUTOCLIENTGEN003` | An API method must not contain more than one REST method attribute |
+| `AUTOCLIENTGEN004` | Invalid API method return type |
+| `AUTOCLIENTGEN005` | API methods can't be generic |
+| `AUTOCLIENTGEN006` | The current HTTP method does not support the body tag |
+| `AUTOCLIENTGEN007` | API methods must not be static |
+| `AUTOCLIENTGEN008` | HTTP method missing |
+| `AUTOCLIENTGEN009` | The API interface cannot be generic |
+| `AUTOCLIENTGEN010` | Invalid API interface name |
+| `AUTOCLIENTGEN011` | Duplicate body attribute |
+| `AUTOCLIENTGEN012` | URL parameter missing from path |
+| `AUTOCLIENTGEN013` | REST API method has more than one cancellation token |
+| `AUTOCLIENTGEN014` | Missing CancellationToken from REST API method |
+| `AUTOCLIENTGEN015` | API method path should not contain query |
+| `AUTOCLIENTGEN016` | A REST API method's request name must be unique |
+| `AUTOCLIENTGEN017` | Invalid HttpClient name |
+| `AUTOCLIENTGEN018` | Invalid dependency name |
+| `AUTOCLIENTGEN019` | Invalid header name |
+| `AUTOCLIENTGEN020` | Invalid header value |
+| `AUTOCLIENTGEN021` | Invalid REST method path |
+| `AUTOCLIENTGEN022` | Invalid request name |
+
+
+# ExtraAnalyzers
+
+| Diagnostic ID | Category | Description |
+| :---------------- | :---------- | :---------- |
+| `EA0000` | Performance | Use source generated logging methods for improved performance |
+| `EA0001` | Performance | Perform message formatting in the body of the logging method |
+| `EA0002` | Reliability | Use 'System.TimeProvider' to make the code easier to test |
+| `EA0003` | Performance | Use the character-based overloads of 'String.StartsWith' or 'String.EndsWith' |
+| `EA0004` | Performance | Make types declared in an executable internal |
+| `EA0005` | Performance | Consider using an array instead of a collection |
+| `EA0006` | Performance | Replace uses of 'Enum.GetName' and 'Enum.ToString' for improved performance |
+| `EA0007` | Performance | Use 'System.ValueTuple' instead of 'System.Tuple' for improved performance |
+| `EA0008` | Performance | Use generic collections instead of legacy collections for improved performance |
+| `EA0009` | Performance | Use 'System.MemoryExtensions.Split' for improved performance |
+| `EA0010` | Correctness | Fire-and-forget async call inside a 'using' block |
+| `EA0011` | Performance | Consider removing unnecessary conditional access operator (?) |
+| `EA0012` | Performance | Consider removing unnecessary null coalescing assignment (??=) |
+| `EA0013` | Performance | Consider removing unnecessary null coalescing operator (??) |
+| `EA0014` | Resilience | The async method doesn't support cancellation |
+
+
# Experiments
As new functionality is introduced to this repo, new in-development APIs are marked as being experimental. Experimental APIs offer no
@@ -28,3 +88,75 @@ if desired.
| `EXTEXP0011` | Document database experiments |
| `EXTEXP0012` | Auto-activation experiments |
| `EXTEXP0013` | HttpLogging middleware experiments |
+| `EXTEXP0014` | ASP.NET Core integration testing experiments |
+| `EXTEXP0015` | Environmental probes experiments |
+| `EXTEXP0016` | Hosting integration testing experiments |
+| `EXTEXP0017` | Contextual options experiments |
+
+
+# LoggerMessage
+
+| Diagnostic ID | Description |
+| :---------------- | :---------- |
+| `LOGGEN000` | Don't include log level parameters as templates |
+| `LOGGEN001` | Couldn't find a required type definition |
+| `LOGGEN002` | Each logging method should use a unique event id |
+| `LOGGEN003` | Logging methods must return void |
+| `LOGGEN004` | A static logging method must have a parameter that implements the "Microsoft.Extensions.Logging.ILogger" interface |
+| `LOGGEN005` | Logging methods must be static |
+| `LOGGEN006` | Logging methods must be partial |
+| `LOGGEN007` | Logging methods can't be generic |
+| `LOGGEN008` | Redundant qualifier in the logging message |
+| `LOGGEN009` | Don't include exception parameters as templates in the logging message |
+| `LOGGEN010` | The logging template has no corresponding method parameter |
+| `LOGGEN011` | A parameter isn't referenced from the logging message |
+| `LOGGEN012` | Logging methods can't have a body |
+| `LOGGEN013` | A "LogLevel" value must be supplied |
+| `LOGGEN014` | Don't include logger parameters as templates |
+| `LOGGEN015` | Couldn't find a field of type "Microsoft.Extensions.Logging.ILogger" |
+| `LOGGEN016` | Multiple fields of type "Microsoft.Extensions.Logging.ILogger" were found |
+| `LOGGEN017` | Can't combine the [LogProperties] or [TagProvider] attributes with data classification attributes |
+| `LOGGEN018` | Can't log properties of a parameter or property |
+| `LOGGEN019` | Method parameter can't be used to log properties |
+| `LOGGEN020` | Logging method parameter type has no public properties to log |
+| `LOGGEN021` | Logging method parameter type has cycles in its type hierarchy |
+| `LOGGEN022` | Tag provider method not found |
+| `LOGGEN023` | Tag provider method is inaccessible |
+| `LOGGEN024` | Property provider method has an invalid signature |
+| `LOGGEN025` | Logging method parameters can't have "ref" or "out" modifiers |
+| `LOGGEN026` | Parameters with a custom tag provider are not subject to redaciton |
+| `LOGGEN027` | Multiple logging methods shouldn't use the same event name |
+| `LOGGEN028` | Logging method parameter's type has a hidden property |
+| `LOGGEN029` | A logging method parameter causes name conflicts |
+| `LOGGEN030` | Logging method doesn't log anything |
+| `LOGGEN031` | A logging message template starts with "@" |
+| `LOGGEN032` | Can only have one of [LogProperties], [TagProvider], and [LogPropertyIgnore] |
+| `LOGGEN033` | Method parameter can't be used with a tag provider |
+| `LOGGEN034` | Attribute can't be used in this context |
+| `LOGGEN035` | The logging method parameter leaks sensitive data |
+
+
+# Metrics
+
+| Diagnostic ID | Description |
+| :---------------- | :---------- |
+| `METGEN000` | Metric method names can't start with an underscore |
+| `METGEN001` | Metric method parameter names can't start with an underscore |
+| `METGEN002` | Metric names must start with an uppercase alphabetic character |
+| `METGEN003` | Multiple metric methods can't use the same metric name |
+| `METGEN004` | Metric methods mustn't use any existing type as the return type |
+| `METGEN005` | The first parameter should be of type `System.Diagnostics.Metrics.Meter` |
+| `METGEN006` | Metric methods must be partial |
+| `METGEN007` | Metric methods can't be generic |
+| `METGEN008` | Metric methods can't have a body |
+| `METGEN009` | Tag names should contain alphanumeric characters and only allowed symbols |
+| `METGEN010` | Metric methods must be static |
+| `METGEN011` | A strong type object contains duplicate tag names |
+| `METGEN012` | A metric class contains an invalid tag name type |
+| `METGEN013` | A metric class contains too many tag names |
+| `METGEN014` | A metering attribute type argument is invalid |
+| `METGEN015` | Metric methods mustn't use any external type as the return type |
+| `METGEN016` | Metric methods mustn't use any generic type as the return type |
+| `METGEN017` | Gauge is not supported yet |
+| `METGEN018` | Xml comment was not parsed correctly |
+| `METGEN019` | A metric class has cycles in its type hierarchy |
diff --git a/eng/Diags/ILLink.RoslynAnalyzer.yml b/eng/Diags/ILLink.RoslynAnalyzer.yml
index b79406b7c38..a86cabf00a2 100644
--- a/eng/Diags/ILLink.RoslynAnalyzer.yml
+++ b/eng/Diags/ILLink.RoslynAnalyzer.yml
@@ -1,12 +1,12 @@
Origin:
AssemblyName: ILLink.RoslynAnalyzer
- Version: 8.0.8.35901
+ Version: 8.0.9.408
Diagnostics:
IL2026:
Metadata:
Category: Trimming
Title: Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2026
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -16,7 +16,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2046
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -36,7 +36,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Either the type on which the MakeGenericType is called can't be statically determined, or the type parameters to be used for generic arguments can't be statically determined.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2055
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -46,7 +46,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Call to 'System.Reflection.MethodInfo.MakeGenericMethod' can not be statically analyzed. It's not possible to guarantee the availability of requirements of the generic method.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2060
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -56,7 +56,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Types that derive from a base class with 'RequiresUnreferencedCodeAttribute' need to explicitly use the 'RequiresUnreferencedCodeAttribute' or suppress this warning
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2109
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -96,7 +96,7 @@ Diagnostics:
Metadata:
Category: SingleFile
Title: "'RequiresAssemblyFilesAttribute' annotations must match across all interface implementations or overrides."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/single-file/warnings/il3003
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -106,7 +106,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The 'DynamicallyAccessedMembersAttribute' is not allowed on methods. It is allowed on method return value or method parameters.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2041
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -116,7 +116,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The parameter of method has a DynamicallyAccessedMembersAttribute, but the value passed to it can not be statically analyzed.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2062
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -126,7 +126,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The return value of method has a DynamicallyAccessedMembersAttribute, but the value returned from the method can not be statically analyzed.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2063
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -136,7 +136,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The field has a DynamicallyAccessedMembersAttribute, but the value assigned to it can not be statically analyzed.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2064
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -146,7 +146,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The method has a DynamicallyAccessedMembersAttribute (which applies to the implicit 'this' parameter), but the value used for the 'this' parameter can not be statically analyzed.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2065
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -156,7 +156,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The generic parameter of type or method has a DynamicallyAccessedMembersAttribute, but the value used for it can not be statically analyzed.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2066
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -166,7 +166,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2067
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -176,7 +176,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The parameter of method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2068
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -186,7 +186,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Value stored in field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The parameter of method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2069
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -196,7 +196,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The parameter of method does not have matching annotations."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2070
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -206,7 +206,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The parameter of method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2071
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -216,7 +216,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2072
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -226,7 +226,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The return value of the source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2073
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -236,7 +236,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Value stored in field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The return value of the source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2074
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -246,7 +246,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2075
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -256,7 +256,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The return value of the source method does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2076
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -266,7 +266,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The source field does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2077
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -276,7 +276,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The source field does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2078
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -286,7 +286,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Value stored in target field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The source field does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2079
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -296,7 +296,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The source field does not have matching annotations."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2080
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -306,7 +306,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The source field does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2081
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -316,7 +316,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The implicit 'this' argument of source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2082
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -326,7 +326,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The implicit 'this' argument of source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2083
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -336,7 +336,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Value stored in target field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The implicit 'this' argument of source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2084
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -346,7 +346,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The implicit 'this' argument of source method does not have matching annotations."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2085
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -356,7 +356,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The implicit 'this' argument of source method does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2086
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -366,7 +366,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target parameter argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2087
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -376,7 +376,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target method return value does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The generic parameter of the source method or type does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2088
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -386,7 +386,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Value stored in target field does not satisfy 'DynamicallyAccessedMembersAttribute' requirements. The generic parameter of the source method or type does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2089
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -396,7 +396,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The generic parameter of the source method or type does not have matching annotations."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2090
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -406,7 +406,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The generic parameter of the source method or type does not have matching annotations.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2091
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -416,7 +416,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Field has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to fields of type 'System.Type' or 'System.String'.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2097
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -426,7 +426,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Parameter of method has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to parameters of type 'System.Type' or 'System.String'.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2098
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -436,7 +436,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Property has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2099
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -446,7 +446,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Return type of method has 'DynamicallyAccessedMembersAttribute', but that attribute can only be applied to properties of type 'System.Type' or 'System.String'.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2106
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -456,7 +456,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Field with 'DynamicallyAccessedMembersAttribute' is accessed via reflection. Trimmer can't guarantee availability of the requirements of the field.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2110
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -466,7 +466,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Method with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2111
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -476,7 +476,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The type passed to the RunClassConstructor is not statically known, Trimmer can't make sure that its static constructor is available.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2059
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -486,7 +486,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'DynamicallyAccessedMemberTypes' on the return value of method don't match overridden return value of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2093
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -496,7 +496,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'DynamicallyAccessedMemberTypes' on the parameter of method don't match overridden parameter of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2092
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -506,7 +506,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'DynamicallyAccessedMemberTypes' on the generic parameter of method or type don't match overridden generic parameter method or type. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2095
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -516,7 +516,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'DynamicallyAccessedMemberTypes' on the implicit 'this' parameter of method don't match overridden implicit 'this' parameter of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2094
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -526,7 +526,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: "'DynamicallyAccessedMembersAttribute' on property conflicts with the same attribute on its accessor."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2043
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -536,7 +536,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Value passed to the parameter of method cannot be statically determined as a property accessor.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2103
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -546,7 +546,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Call to 'Type.GetType' method can perform case insensitive lookup of the type, currently trimming can not guarantee presence of all the matching types.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2096
DefaultSeverity: Warning
Tier: 3
Attributes:
@@ -556,7 +556,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Unrecognized value passed to the parameter of method. It's not possible to guarantee the availability of the target type.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2057
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -566,7 +566,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The value passed as the assembly name or type name to the CreateInstance method can't be statically analyzed.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2032
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -576,7 +576,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: Parameters passed to method cannot be analyzed. Consider using methods 'System.Type.GetType' and `System.Activator.CreateInstance` instead.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2058
DefaultSeverity: Warning
Tier: 2
Attributes:
@@ -586,7 +586,7 @@ Diagnostics:
Metadata:
Category: SingleFile
Title: The use of 'RequiresAssemblyFilesAttribute' on static constructors is disallowed since is a method not callable by the user, is only called by the runtime. Placing the attribute directly on the static constructor will have no effect, instead use 'RequiresUnreferencedCodeAttribute' on the type which will handle warning and silencing from the static constructor.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/single-file/warnings/il3004
DefaultSeverity: Warning
Tier: 3
Attributes:
@@ -596,7 +596,7 @@ Diagnostics:
Metadata:
Category: AOT
Title: Calling members annotated with 'RequiresDynamicCodeAttribute' may break functionality when AOT compiling.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/native-aot/warnings/il3050
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -606,7 +606,7 @@ Diagnostics:
Metadata:
Category: AOT
Title: "'RequiresDynamicCodeAttribute' annotations must match across all interface implementations or overrides."
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/native-aot/warnings/il3051
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -616,7 +616,7 @@ Diagnostics:
Metadata:
Category: AOT
Title: The use of 'RequiresDynamicCodeAttribute' on static constructors is disallowed since is a method not callable by the user, is only called by the runtime. Placing the attribute directly on the static constructor will have no effect, instead use 'RequiresUnreferencedCodeAttribute' on the type which will handle warning and silencing from the static constructor.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/native-aot/warnings/il3056
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -626,7 +626,7 @@ Diagnostics:
Metadata:
Category: Trimming
Title: The use of 'RequiresUnreferencedCodeAttribute' on static constructors is disallowed since is a method not callable by the user, is only called by the runtime. Placing the attribute directly on the static constructor will have no effect, instead use 'RequiresUnreferencedCodeAttribute' on the type which will handle warning and silencing from the static constructor.
- Description: ''
+ Description: https://learn.microsoft.com/dotnet/core/deploying/trimming/trim-warnings/il2116
DefaultSeverity: Warning
Tier: 1
Attributes:
diff --git a/eng/Diags/Microsoft.Analyzers.Extra.yml b/eng/Diags/Microsoft.Analyzers.Extra.yml
index 42a21498cde..ec415a8bd1b 100644
--- a/eng/Diags/Microsoft.Analyzers.Extra.yml
+++ b/eng/Diags/Microsoft.Analyzers.Extra.yml
@@ -7,6 +7,7 @@ Diagnostics:
Category: Performance
Title: Consider removing unnecessary null coalescing assignment (??=)
Description: Using the null coalescing assignment operator (??=) with values which are statically known not to be null causes superfluous null checks to be performed at runtime
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0012
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -17,6 +18,7 @@ Diagnostics:
Category: Performance
Title: Consider removing unnecessary null coalescing operator (??)
Description: Using the null coalescing operator (??) with values which are statically known to be null causes superfluous null checks to be performed at runtime
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0013
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -27,6 +29,7 @@ Diagnostics:
Category: Performance
Title: Make types declared in an executable internal
Description: Making an executable's types internal enables dead code analysis along with other potential optimizations
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0004
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -39,6 +42,7 @@ Diagnostics:
Category: Performance
Title: Perform message formatting in the body of the logging method
Description: Identifies calls to the 'ToString' method as arguments to a logging method
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0001
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -51,6 +55,7 @@ Diagnostics:
Category: Performance
Title: Use the character-based overloads of 'String.StartsWith' or 'String.EndsWith'
Description: When checking for a single character, prefer the character overloads of 'String.StartsWith' and 'String.EndsWith' for improved performance
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0003
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -63,6 +68,7 @@ Diagnostics:
Category: Reliability
Title: Use 'System.TimeProvider' to make the code easier to test
Description: Identifies uses of time dependent APIs that can lead to flaky tests
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0002
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -75,6 +81,7 @@ Diagnostics:
Category: Performance
Title: Replace uses of 'Enum.GetName' and 'Enum.ToString' for improved performance
Description: Replace uses of 'Enum.GetName' and 'Enum.ToString' for improved performance
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0006
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -87,6 +94,7 @@ Diagnostics:
Category: Performance
Title: Use source generated logging methods for improved performance
Description: Identifies calls to legacy logging methods
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0000
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -99,6 +107,7 @@ Diagnostics:
Category: Performance
Title: Use 'System.MemoryExtensions.Split' for improved performance
Description: Use 'System.MemoryExtensions.Split' for improved performance
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0009
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -111,6 +120,7 @@ Diagnostics:
Category: Performance
Title: Use generic collections instead of legacy collections for improved performance
Description: Using generic collections can avoid boxing overhead and provides strong typing
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0008
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -123,6 +133,7 @@ Diagnostics:
Category: Performance
Title: Consider using an array instead of a collection
Description: Dictionaries and sets which use enums and bytes as keys can often be replaced with simple arrays for improved performance
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0005
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -135,6 +146,7 @@ Diagnostics:
Category: Performance
Title: Use 'System.ValueTuple' instead of 'System.Tuple' for improved performance
Description: Using 'System.ValueTuple' avoids allocations and is generally more efficient than 'System.Tuple'
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0007
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -147,6 +159,7 @@ Diagnostics:
Category: Correctness
Title: Fire-and-forget async call inside a 'using' block
Description: When skipping the await keyword for asynchronous operations inside a using block, then a disposable object could be disposed before the asynchronous invocation finishes. This might result in incorrect behavior and very often ends with a runtime exception notifying that the code is trying to operate on a disposed object.
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0010
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -157,6 +170,7 @@ Diagnostics:
Category: Resilience
Title: The async method doesn't support cancellation
Description: Accepting a CancellationToken as a parameter allows caller to express a loss of interest in the result enabling the method to save cycles by finishing early
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0014
DefaultSeverity: Warning
Tier: 1
Attributes:
@@ -169,6 +183,7 @@ Diagnostics:
Category: Performance
Title: Consider removing unnecessary conditional access operator (?)
Description: Using the conditional access operator (?) to access values which are statically known not to be null causes superfluous null checks to be performed at runtime
+ HelpLinkUri: https://aka.ms/dotnet-extensions-warnings/EA0011
DefaultSeverity: Warning
Tier: 1
Attributes:
diff --git a/eng/Diags/Microsoft.AspNetCore.Components.Analyzers.yml b/eng/Diags/Microsoft.AspNetCore.Components.Analyzers.yml
index a7da7ee84a5..17fa4e09ab7 100644
--- a/eng/Diags/Microsoft.AspNetCore.Components.Analyzers.yml
+++ b/eng/Diags/Microsoft.AspNetCore.Components.Analyzers.yml
@@ -1,6 +1,6 @@
Origin:
AssemblyName: Microsoft.AspNetCore.Components.Analyzers
- Version: 8.0.23.35902
+ Version: 8.0.23.50222
Diagnostics:
BL0001:
Metadata:
diff --git a/eng/Diags/Microsoft.CodeAnalysis.CSharp.CodeStyle.yml b/eng/Diags/Microsoft.CodeAnalysis.CSharp.CodeStyle.yml
index e0307e9eea4..2554594006d 100644
--- a/eng/Diags/Microsoft.CodeAnalysis.CSharp.CodeStyle.yml
+++ b/eng/Diags/Microsoft.CodeAnalysis.CSharp.CodeStyle.yml
@@ -1,6 +1,6 @@
Origin:
AssemblyName: Microsoft.CodeAnalysis.CSharp.CodeStyle
- Version: 4.8.8.35803
+ Version: 4.8.9.404
Diagnostics:
IDE0001:
Metadata:
@@ -1785,3 +1785,59 @@ Diagnostics:
Attributes:
general:
Severity: None
+ IDE0304:
+ Metadata:
+ Category: Style
+ Title: Simplify collection initialization
+ Description: ''
+ HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0304
+ CustomTags:
+ - Telemetry
+ - EnforceOnBuild_Recommended
+ DefaultSeverity: None
+ Tier: 1
+ Attributes:
+ general:
+ Severity: None
+ IDE0305:
+ Metadata:
+ Category: Style
+ Title: Simplify collection initialization
+ Description: ''
+ HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0305
+ CustomTags:
+ - Telemetry
+ - EnforceOnBuild_Recommended
+ DefaultSeverity: None
+ Tier: 1
+ Attributes:
+ general:
+ Severity: None
+ IDE0303:
+ Metadata:
+ Category: Style
+ Title: Simplify collection initialization
+ Description: ''
+ HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0303
+ CustomTags:
+ - Telemetry
+ - EnforceOnBuild_Recommended
+ DefaultSeverity: None
+ Tier: 1
+ Attributes:
+ general:
+ Severity: None
+ IDE0302:
+ Metadata:
+ Category: Style
+ Title: Simplify collection initialization
+ Description: ''
+ HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0302
+ CustomTags:
+ - Telemetry
+ - EnforceOnBuild_Recommended
+ DefaultSeverity: None
+ Tier: 1
+ Attributes:
+ general:
+ Severity: None
diff --git a/eng/Diags/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.yml b/eng/Diags/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.yml
index 43490bdc8f0..422d307d8f7 100644
--- a/eng/Diags/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.yml
+++ b/eng/Diags/Microsoft.CodeAnalysis.CSharp.NetAnalyzers.yml
@@ -1,6 +1,6 @@
Origin:
AssemblyName: Microsoft.CodeAnalysis.CSharp.NetAnalyzers
- Version: 8.0.8.35701
+ Version: 8.0.8.47201
Diagnostics:
CA1001:
Metadata:
@@ -597,3 +597,19 @@ Diagnostics:
Attributes:
general:
Severity: Warning
+ CA1870:
+ Metadata:
+ Category: Performance
+ Title: Use a cached 'SearchValues' instance
+ Description: Using a cached 'SearchValues' instance is more efficient than passing values to 'IndexOfAny'/'ContainsAny' directly.
+ HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1870
+ CustomTags:
+ - Telemetry
+ - EnabledRuleInAggressiveMode
+ DefaultSeverity: Suggestion
+ Tier: 1
+ Attributes:
+ general:
+ Severity: None
+ performance:
+ Severity: Warning
diff --git a/eng/Diags/Microsoft.CodeAnalysis.CodeStyle.yml b/eng/Diags/Microsoft.CodeAnalysis.CodeStyle.yml
index 656ea970d10..5a7aafdcf79 100644
--- a/eng/Diags/Microsoft.CodeAnalysis.CodeStyle.yml
+++ b/eng/Diags/Microsoft.CodeAnalysis.CodeStyle.yml
@@ -1,6 +1,6 @@
Origin:
AssemblyName: Microsoft.CodeAnalysis.CodeStyle
- Version: 4.8.8.35803
+ Version: 4.8.9.404
Diagnostics:
IDE0033:
Metadata:
diff --git a/eng/Diags/Microsoft.CodeAnalysis.NetAnalyzers.yml b/eng/Diags/Microsoft.CodeAnalysis.NetAnalyzers.yml
index 59edace3dd4..8a8c6e81b2b 100644
--- a/eng/Diags/Microsoft.CodeAnalysis.NetAnalyzers.yml
+++ b/eng/Diags/Microsoft.CodeAnalysis.NetAnalyzers.yml
@@ -1,6 +1,6 @@
Origin:
AssemblyName: Microsoft.CodeAnalysis.NetAnalyzers
- Version: 8.0.8.35701
+ Version: 8.0.8.47201
Diagnostics:
CA1000:
Metadata:
@@ -4514,8 +4514,8 @@ Diagnostics:
CA1862:
Metadata:
Category: Performance
- Title: Prefer using 'StringComparer' to perform case-insensitive string comparisons
- Description: Avoid calling 'ToLower', 'ToUpper', 'ToLowerInvariant' and 'ToUpperInvariant' to perform case-insensitive string comparisons when using 'CompareTo', because they lead to an allocation. Instead, use 'StringComparer' to perform case-insensitive comparisons.
+ Title: Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
+ Description: Avoid calling 'ToLower', 'ToUpper', 'ToLowerInvariant' and 'ToUpperInvariant' to perform case-insensitive string comparisons, as in 'string.ToLower() == string.ToLower()', because they lead to an allocation. Instead, use 'string.Equals(string, StringComparison)' to perform case-insensitive comparisons. Switching to using an overload that takes a 'StringComparison' might cause subtle changes in behavior, so it's important to conduct thorough testing after applying the suggestion. Additionally, if a culturally sensitive comparison is not required, consider using 'StringComparison.OrdinalIgnoreCase'.
HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1862
CustomTags:
- Telemetry
@@ -4558,3 +4558,19 @@ Diagnostics:
Attributes:
general:
Severity: Warning
+ CA1869:
+ Metadata:
+ Category: Performance
+ Title: Cache and reuse 'JsonSerializerOptions' instances
+ Description: Avoid creating a new 'JsonSerializerOptions' instance for every serialization operation. Cache and reuse instances instead. Single use 'JsonSerializerOptions' instances can substantially degrade the performance of your application.
+ HelpLinkUri: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869
+ CustomTags:
+ - Telemetry
+ - EnabledRuleInAggressiveMode
+ DefaultSeverity: Suggestion
+ Tier: 1
+ Attributes:
+ general:
+ Severity: None
+ performance:
+ Severity: Warning
diff --git a/eng/MSBuild/Generators.props b/eng/MSBuild/Generators.props
index 433353e8a1b..2a99ec02f95 100644
--- a/eng/MSBuild/Generators.props
+++ b/eng/MSBuild/Generators.props
@@ -3,10 +3,6 @@
-
-
-
-
diff --git a/eng/MSBuild/ProjectStaging.targets b/eng/MSBuild/ProjectStaging.targets
index af5baa16a8e..32f3920db29 100644
--- a/eng/MSBuild/ProjectStaging.targets
+++ b/eng/MSBuild/ProjectStaging.targets
@@ -1,12 +1,13 @@
-
+
+
@@ -17,8 +18,8 @@
- DEVELOPMENT BUILD - DO NOT USE IN PRODUCTION - $(Description)
- OBSOLETE PACKAGE - $(Description)
+ Experimental package. $(Description)
+ Obsolete Package. $(Description)
diff --git a/eng/Tools/.editorconfig b/eng/Tools/.editorconfig
index d4e6af326f8..cf14cfec647 100644
--- a/eng/Tools/.editorconfig
+++ b/eng/Tools/.editorconfig
@@ -1,5 +1,5 @@
# Created by DiagConfig, the diagnostic config generator
-# Generated : 2023-08-07 17:59:54Z
+# Generated : 2023-10-22 00:37:48Z
# Max Tier : 2147483647
# Attributes: general
# Analyzers : ILLink.RoslynAnalyzer, Microsoft.Analyzers.Extra, Microsoft.Analyzers.Local, Microsoft.AspNetCore.App.Analyzers, Microsoft.AspNetCore.Components.Analyzers, Microsoft.CodeAnalysis.CodeStyle, Microsoft.CodeAnalysis.CSharp.CodeStyle, Microsoft.CodeAnalysis.CSharp.NetAnalyzers, Microsoft.CodeAnalysis.NetAnalyzers, Microsoft.VisualStudio.Threading.Analyzers, Microsoft.VisualStudio.Threading.Analyzers.CSharp, SonarAnalyzer.CSharp, StyleCop.Analyzers
@@ -866,7 +866,7 @@ dotnet_diagnostic.CA1860.severity = none
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1861
dotnet_diagnostic.CA1861.severity = suggestion
-# Title : Prefer using 'StringComparer' to perform case-insensitive string comparisons
+# Title : Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
# Category : Performance
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1862
dotnet_diagnostic.CA1862.severity = none
@@ -901,6 +901,16 @@ dotnet_diagnostic.CA1867.severity = warning
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1868
dotnet_diagnostic.CA1868.severity = suggestion
+# Title : Cache and reuse 'JsonSerializerOptions' instances
+# Category : Performance
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1869
+dotnet_diagnostic.CA1869.severity = none
+
+# Title : Use a cached 'SearchValues' instance
+# Category : Performance
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1870
+dotnet_diagnostic.CA1870.severity = none
+
# Title : Dispose objects before losing scope
# Category : Reliability
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2000
@@ -1718,62 +1728,77 @@ dotnet_diagnostic.CA5405.severity = none
# Title : Use source generated logging methods for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0000
dotnet_diagnostic.EA0000.severity = none
# Title : Perform message formatting in the body of the logging method
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0001
dotnet_diagnostic.EA0001.severity = none
# Title : Use 'System.TimeProvider' to make the code easier to test
# Category : Reliability
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0002
dotnet_diagnostic.EA0002.severity = none
# Title : Use the character-based overloads of 'String.StartsWith' or 'String.EndsWith'
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0003
dotnet_diagnostic.EA0003.severity = none
# Title : Make types declared in an executable internal
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0004
dotnet_diagnostic.EA0004.severity = none
# Title : Consider using an array instead of a collection
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0005
dotnet_diagnostic.EA0005.severity = none
# Title : Replace uses of 'Enum.GetName' and 'Enum.ToString' for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0006
dotnet_diagnostic.EA0006.severity = none
# Title : Use 'System.ValueTuple' instead of 'System.Tuple' for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0007
dotnet_diagnostic.EA0007.severity = none
# Title : Use generic collections instead of legacy collections for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0008
dotnet_diagnostic.EA0008.severity = none
# Title : Use 'System.MemoryExtensions.Split' for improved performance
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0009
dotnet_diagnostic.EA0009.severity = none
# Title : Fire-and-forget async call inside a 'using' block
# Category : Correctness
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0010
dotnet_diagnostic.EA0010.severity = warning
# Title : Consider removing unnecessary conditional access operator (?)
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0011
dotnet_diagnostic.EA0011.severity = warning
# Title : Consider removing unnecessary null coalescing assignment (??=)
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0012
dotnet_diagnostic.EA0012.severity = suggestion
# Title : Consider removing unnecessary null coalescing operator (??)
# Category : Performance
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0013
dotnet_diagnostic.EA0013.severity = suggestion
# Title : The async method doesn't support cancellation
# Category : Resilience
+# Help Link: https://aka.ms/dotnet-extensions-warnings/EA0014
dotnet_diagnostic.EA0014.severity = none
# Title : Set MSBuild property 'GenerateDocumentationFile' to 'true'
@@ -2406,6 +2431,26 @@ dotnet_diagnostic.IDE0300.severity = none
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0301
dotnet_diagnostic.IDE0301.severity = suggestion
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0302
+dotnet_diagnostic.IDE0302.severity = none
+
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0303
+dotnet_diagnostic.IDE0303.severity = none
+
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0304
+dotnet_diagnostic.IDE0304.severity = none
+
+# Title : Simplify collection initialization
+# Category : Style
+# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide0305
+dotnet_diagnostic.IDE0305.severity = none
+
# Title : Delegate invocation can be simplified.
# Category : Style
# Help Link: https://learn.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/ide1005
diff --git a/eng/Tools/ApiChief/Format/FormattingExtensions.cs b/eng/Tools/ApiChief/Format/FormattingExtensions.cs
index 6a84afa9846..c7f973dd038 100644
--- a/eng/Tools/ApiChief/Format/FormattingExtensions.cs
+++ b/eng/Tools/ApiChief/Format/FormattingExtensions.cs
@@ -9,9 +9,9 @@ namespace ApiChief.Format;
internal static class FormattingExtensions
{
- private static readonly HashSet _numberLiterals = new() { 'l', 'L', 'u', 'U', 'f', 'F', 'd', 'D', 'm', 'M' };
- private static readonly HashSet _secondCharInLiterals = new() { 'l', 'L', 'u', 'U' };
- private static readonly HashSet _possibleSpecialCharactersInANumber = new() { '.', 'x', 'X', 'b', 'B' };
+ private static readonly HashSet _numberLiterals = ['l', 'L', 'u', 'U', 'f', 'F', 'd', 'D', 'm', 'M'];
+ private static readonly HashSet _secondCharInLiterals = ['l', 'L', 'u', 'U'];
+ private static readonly HashSet _possibleSpecialCharactersInANumber = ['.', 'x', 'X', 'b', 'B'];
///
/// Ensures a single space between parameters.
diff --git a/eng/Tools/DiagPublisher/DiagPublisher.csproj b/eng/Tools/DiagPublisher/DiagPublisher.csproj
new file mode 100644
index 00000000000..0679bc045d5
--- /dev/null
+++ b/eng/Tools/DiagPublisher/DiagPublisher.csproj
@@ -0,0 +1,23 @@
+
+
+
+ Exe
+ $(LatestTargetFramework)
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/eng/Tools/DiagPublisher/Program.cs b/eng/Tools/DiagPublisher/Program.cs
new file mode 100644
index 00000000000..f0be301b63e
--- /dev/null
+++ b/eng/Tools/DiagPublisher/Program.cs
@@ -0,0 +1,156 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Reflection;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.Gen.AutoClient;
+using Microsoft.Gen.ContextualOptions;
+using Microsoft.Gen.Logging;
+using Microsoft.Gen.Metrics;
+using Microsoft.Shared.DiagnosticIds;
+
+namespace DiagPublisher;
+
+public class Program
+{
+ private static void Main(string[] args)
+ {
+ // Pre-read this type name to avoid
+ // error CS0433: The type 'DiagDescriptorsBase' exists in both 'Microsoft.Gen.AutoClient, ...' and 'Microsoft.Gen.ContextualOptions, ...'
+ string diagDescriptorsBaseName = typeof(Microsoft.Gen.Shared.DiagDescriptorsBase).FullName!;
+
+ string extraAnalyzersDiagDescriptorsName = typeof(Microsoft.Extensions.ExtraAnalyzers.DiagDescriptors).FullName!;
+
+ _ = typeof(AutoClientGenerator).FullName;
+ _ = typeof(ContextualOptionsGenerator).FullName;
+ _ = typeof(LoggingGenerator).FullName;
+ _ = typeof(MetricsGenerator).FullName;
+ _ = typeof(Microsoft.Extensions.ExtraAnalyzers.DiagDescriptors).FullName;
+
+ Dictionary diagnosticIds = [];
+
+ List candidateTypes = [];
+ foreach (Type type in GetCandidateTypes())
+ {
+ if (type.BaseType is null)
+ {
+ continue;
+ }
+
+ if (type.BaseType.FullName == diagDescriptorsBaseName)
+ {
+ // handle DiagDescriptorsBase implementations
+ foreach (DiagnosticDescriptor diagnosticDescriptors in GetDiagnosticDescriptors(type))
+ {
+ if (!diagnosticIds.ContainsKey(diagnosticDescriptors.Category))
+ {
+ StringBuilder sb = new();
+ sb.AppendLine($"# {diagnosticDescriptors.Category}");
+ sb.AppendLine();
+ sb.AppendLine("| Diagnostic ID | Description |");
+ sb.AppendLine("| :---------------- | :---------- |");
+
+ diagnosticIds[diagnosticDescriptors.Category] = sb;
+ }
+
+ diagnosticIds[diagnosticDescriptors.Category].AppendLine($"| `{diagnosticDescriptors.Id}` | {diagnosticDescriptors.Title} |");
+ }
+
+ continue;
+ }
+
+ if (type.FullName == extraAnalyzersDiagDescriptorsName)
+ {
+ // handle ExtraAnalyzers.DiagDescriptors
+ foreach (DiagnosticDescriptor diagnosticDescriptors in GetDiagnosticDescriptors(type))
+ {
+ const string Category = "ExtraAnalyzers";
+
+ if (!diagnosticIds.ContainsKey(Category))
+ {
+ StringBuilder sb = new();
+ sb.AppendLine($"# {Category}");
+ sb.AppendLine();
+ sb.AppendLine("| Diagnostic ID | Category | Description |");
+ sb.AppendLine("| :---------------- | :---------- | :---------- |");
+
+ diagnosticIds[Category] = sb;
+ }
+
+ diagnosticIds[Category].AppendLine($"| `{diagnosticDescriptors.Id}` | {diagnosticDescriptors.Category} | {diagnosticDescriptors.Title} |");
+ }
+
+ continue;
+ }
+ }
+
+
+ foreach (string category in diagnosticIds.Keys.OrderBy(k => k))
+ {
+ Console.WriteLine(diagnosticIds[category].ToString());
+ Console.WriteLine();
+ Console.WriteLine();
+ }
+
+ return;
+
+ static IEnumerable GetCandidateTypes()
+ {
+ foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies().Where(p => !p.IsDynamic))
+ {
+ foreach (Type type in GetLoadableTypes(assembly))
+ {
+ yield return type;
+ }
+ }
+ }
+
+ static IEnumerable GetDiagnosticDescriptors(Type candidateType)
+ {
+ foreach (var member in candidateType.GetMembers())
+ {
+ if (member is PropertyInfo propertyInfo &&
+ propertyInfo.PropertyType.IsAssignableFrom(typeof(DiagnosticDescriptor)))
+ {
+ if (propertyInfo.GetGetMethod() is MethodInfo getMethodInfo &&
+ getMethodInfo.IsStatic)
+ {
+ var descriptor = (DiagnosticDescriptor)propertyInfo.GetValue(null)!;
+
+ if (descriptor.HelpLinkUri != string.Format(DiagnosticIds.UrlFormat, descriptor.Id))
+ {
+ ReportError($"{candidateType.FullName}.{member.Name} {descriptor.Id}: {nameof(DiagnosticDescriptor.HelpLinkUri)} must start with {DiagnosticIds.UrlFormat}");
+ }
+
+ yield return descriptor;
+ }
+ else
+ {
+ ReportError($"{candidateType.FullName}.{member.Name} can't be queried");
+ }
+ }
+ }
+ }
+
+ static IEnumerable GetLoadableTypes(Assembly assembly)
+ {
+ try
+ {
+ return assembly.GetTypes();
+ }
+ catch (ReflectionTypeLoadException e)
+ {
+ return e.Types.Where(t => t is not null)!;
+ }
+ }
+
+ static void ReportError(string message)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.Write("[ERROR]: ");
+ Console.ResetColor();
+ Console.WriteLine(message);
+ }
+ }
+}
diff --git a/eng/Tools/DiagPublisher/README.md b/eng/Tools/DiagPublisher/README.md
new file mode 100644
index 00000000000..caf971e7f02
--- /dev/null
+++ b/eng/Tools/DiagPublisher/README.md
@@ -0,0 +1 @@
+This tool is used to generate or update diagnostic IDs described in /docs/list-of-diagnostics.md.
\ No newline at end of file
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index c6459339e73..f68eebe5b6d 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -1,182 +1,182 @@
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/runtime
- b20f704cc00f390e5560a137deb8f0e64e863e1d
+ 488a8a3521610422e8fbe22d5cc66127f3dce3dc
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/aspnetcore
- 7ffeb436ad029d1e1012372b7bb345ad22770f09
+ 815eb281ecad13eb69cf50516ac7f534b947f2b0
-
+
https://github.com/dotnet/arcade
- e6be64c3e27aeb29f93f6aa751fad972e4ef2d52
+ a57022b44f3ff23de925530ea1d27da9701aed57
-
+
https://github.com/dotnet/arcade
- e6be64c3e27aeb29f93f6aa751fad972e4ef2d52
+ a57022b44f3ff23de925530ea1d27da9701aed57
diff --git a/eng/Versions.props b/eng/Versions.props
index 5267458fc3f..e4c916b058b 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -10,9 +10,9 @@
true
$(MajorVersion).$(MinorVersion).0.0
- false
+ release
true
@@ -28,49 +28,49 @@
-->
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
- 8.0.0-rtm.23478.17
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
+ 8.0.0
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
- 8.0.0-rtm.23510.7
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
+ 8.0.0-rtm.23524.15
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- text/microsoft-resx
-
-
- 2.0
-
-
- System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
-
-
- An API method must not contain more than one REST method attribute
-
-
- An API method must not contain more than one REST method attribute
-
-
- API client interfaces must not be nested types
-
-
- API client interfaces must not be nested types
-
-
- A Body is already defined for this method
-
-
- Duplicate body attribute
-
-
- A REST API method must not receive more than one cancellation token
-
-
- REST API method has more than one cancellation token
-
-
- The request name '{0}' is already in use within this REST API client.
-
-
- A REST API method's request name must be unique
-
-
- The API interface cannot be generic
-
-
- The API interface cannot be generic
-
-
- Invalid API interface name. It should start with an 'I'
-
-
- Invalid API interface name
-
-
- An unsupported character was used in the dependency name
-
-
- Invalid dependency name
-
-
- An unsupported character was used in the header name
-
-
- Invalid header name
-
-
- An unsupported character was used in the header value
-
-
- Invalid header value
-
-
- An unsupported character was used in the HttpClient name
-
-
- Invalid HttpClient name
-
-
- An unsupported character was used in the REST method path
-
-
- Invalid REST method path
-
-
- An unsupported character was used in the request name
-
-
- Invalid request name
-
-
- An API method return type must be of type Task<T>. T must not be nullable.
-
-
- Invalid API method return type
-
-
- API methods cannot be generic
-
-
- API methods can't be generic
-
-
- A REST API method must receive a CancellationToken parameter
-
-
- Missing CancellationToken from REST API method
-
-
- An HTTP method is missing for this API method
-
-
- HTTP method missing
-
-
- The parameter '{0}' is missing in the URL
-
-
- URL parameter missing from path
-
-
- An API method path must not contain '?'. Queries should be defined using the [Query] attribute.
-
-
- API method path should not contain query
-
-
- API methods must not be static
-
-
- API methods must not be static
-
-
- The '{0}' HTTP method does not support the body tag
-
-
- The current HTTP method does not support the body tag
-
-
- REST API client does not have methods defined. This will render the client class useless.
-
-
- REST API client does not have methods defined
-
-
\ No newline at end of file
diff --git a/src/Generators/Microsoft.Gen.AutoClient/SymbolHolder.cs b/src/Generators/Microsoft.Gen.AutoClient/SymbolHolder.cs
deleted file mode 100644
index 5018c12ce85..00000000000
--- a/src/Generators/Microsoft.Gen.AutoClient/SymbolHolder.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Diagnostics.CodeAnalysis;
-using Microsoft.CodeAnalysis;
-
-namespace Microsoft.Gen.AutoClient;
-
-[ExcludeFromCodeCoverage]
-internal sealed record class SymbolHolder(
- INamedTypeSymbol RestApiAttribute,
- INamedTypeSymbol? RestGetAttribute,
- INamedTypeSymbol? RestPostAttribute,
- INamedTypeSymbol? RestPutAttribute,
- INamedTypeSymbol? RestDeleteAttribute,
- INamedTypeSymbol? RestPatchAttribute,
- INamedTypeSymbol? RestOptionsAttribute,
- INamedTypeSymbol? RestHeadAttribute,
- INamedTypeSymbol? RestStaticHeaderAttribute,
- INamedTypeSymbol? RestHeaderAttribute,
- INamedTypeSymbol? RestQueryAttribute,
- INamedTypeSymbol? RestBodyAttribute);
diff --git a/src/Generators/Microsoft.Gen.AutoClient/SymbolLoader.cs b/src/Generators/Microsoft.Gen.AutoClient/SymbolLoader.cs
deleted file mode 100644
index 54ef7ab201e..00000000000
--- a/src/Generators/Microsoft.Gen.AutoClient/SymbolLoader.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.CodeAnalysis;
-
-namespace Microsoft.Gen.AutoClient;
-
-internal static class SymbolLoader
-{
- internal const string RestApiAttribute = "Microsoft.Extensions.Http.AutoClient.AutoClientAttribute";
-
- internal const string RestGetAttribute = "Microsoft.Extensions.Http.AutoClient.GetAttribute";
- internal const string RestPostAttribute = "Microsoft.Extensions.Http.AutoClient.PostAttribute";
- internal const string RestPutAttribute = "Microsoft.Extensions.Http.AutoClient.PutAttribute";
- internal const string RestDeleteAttribute = "Microsoft.Extensions.Http.AutoClient.DeleteAttribute";
- internal const string RestPatchAttribute = "Microsoft.Extensions.Http.AutoClient.PatchAttribute";
- internal const string RestOptionsAttribute = "Microsoft.Extensions.Http.AutoClient.OptionsAttribute";
- internal const string RestHeadAttribute = "Microsoft.Extensions.Http.AutoClient.HeadAttribute";
-
- internal const string RestStaticHeaderAttribute = "Microsoft.Extensions.Http.AutoClient.StaticHeaderAttribute";
- internal const string RestHeaderAttribute = "Microsoft.Extensions.Http.AutoClient.HeaderAttribute";
- internal const string RestQueryAttribute = "Microsoft.Extensions.Http.AutoClient.QueryAttribute";
- internal const string RestBodyAttribute = "Microsoft.Extensions.Http.AutoClient.BodyAttribute";
-
- internal static SymbolHolder? LoadSymbols(Compilation compilation)
- {
- var restApiAttribute = compilation.GetTypeByMetadataName(RestApiAttribute);
-
- var restGetAttribute = compilation.GetTypeByMetadataName(RestGetAttribute);
- var restPostAttribute = compilation.GetTypeByMetadataName(RestPostAttribute);
- var restPutAttribute = compilation.GetTypeByMetadataName(RestPutAttribute);
- var restDeleteAttribute = compilation.GetTypeByMetadataName(RestDeleteAttribute);
- var restPatchAttribute = compilation.GetTypeByMetadataName(RestPatchAttribute);
- var restOptionsAttribute = compilation.GetTypeByMetadataName(RestOptionsAttribute);
- var restHeadAttribute = compilation.GetTypeByMetadataName(RestHeadAttribute);
-
- var restStaticHeaderAttribute = compilation.GetTypeByMetadataName(RestStaticHeaderAttribute);
- var restHeaderAttribute = compilation.GetTypeByMetadataName(RestHeaderAttribute);
- var restQueryAttribute = compilation.GetTypeByMetadataName(RestQueryAttribute);
- var restBodyAttribute = compilation.GetTypeByMetadataName(RestBodyAttribute);
-
- if (restApiAttribute == null)
- {
- // nothing to do if these types aren't available
- return null;
- }
-
- return new(
- restApiAttribute,
- restGetAttribute,
- restPostAttribute,
- restPutAttribute,
- restDeleteAttribute,
- restPatchAttribute,
- restOptionsAttribute,
- restHeadAttribute,
- restStaticHeaderAttribute,
- restHeaderAttribute,
- restQueryAttribute,
- restBodyAttribute);
- }
-}
diff --git a/src/Generators/Microsoft.Gen.ContextualOptions/DiagDescriptors.cs b/src/Generators/Microsoft.Gen.ContextualOptions/DiagDescriptors.cs
index d4ebf8d2095..841b3b4a3f4 100644
--- a/src/Generators/Microsoft.Gen.ContextualOptions/DiagDescriptors.cs
+++ b/src/Generators/Microsoft.Gen.ContextualOptions/DiagDescriptors.cs
@@ -3,34 +3,35 @@
using Microsoft.CodeAnalysis;
using Microsoft.Gen.Shared;
+using Microsoft.Shared.DiagnosticIds;
namespace Microsoft.Gen.ContextualOptions;
internal sealed class DiagDescriptors : DiagDescriptorsBase
{
- private const string Category = "ContextualOptions";
+ private const string Category = nameof(DiagnosticIds.ContextualOptions);
public static DiagnosticDescriptor ContextCannotBeStatic { get; } = Make(
- id: "CTXOPTGEN000",
+ id: DiagnosticIds.ContextualOptions.CTXOPTGEN000,
title: Resources.ContextCannotBeStaticTitle,
messageFormat: Resources.ContextCannotBeStaticMessage,
category: Category);
public static DiagnosticDescriptor ContextMustBePartial { get; } = Make(
- id: "CTXOPTGEN001",
+ id: DiagnosticIds.ContextualOptions.CTXOPTGEN001,
title: Resources.ContextMustBePartialTitle,
messageFormat: Resources.ContextMustBePartialMessage,
category: Category);
public static DiagnosticDescriptor ContextDoesNotHaveValidProperties { get; } = Make(
- id: "CTXOPTGEN002",
+ id: DiagnosticIds.ContextualOptions.CTXOPTGEN002,
title: Resources.ContextDoesNotHaveValidPropertiesTitle,
messageFormat: Resources.ContextDoesNotHaveValidPropertiesMessage,
category: Category,
defaultSeverity: DiagnosticSeverity.Warning);
public static DiagnosticDescriptor ContextCannotBeRefLike { get; } = Make(
- id: "CTXOPTGEN003",
+ id: DiagnosticIds.ContextualOptions.CTXOPTGEN003,
title: Resources.ContextCannotBeRefLikeTitle,
messageFormat: Resources.ContextCannotBeRefLikeMessage,
category: Category);
diff --git a/src/Generators/Microsoft.Gen.EnumStrings/DiagDescriptors.cs b/src/Generators/Microsoft.Gen.EnumStrings/DiagDescriptors.cs
deleted file mode 100644
index 9d4c5d7db9d..00000000000
--- a/src/Generators/Microsoft.Gen.EnumStrings/DiagDescriptors.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Microsoft.CodeAnalysis;
-using Microsoft.Gen.Shared;
-
-namespace Microsoft.Gen.EnumStrings;
-
-internal sealed class DiagDescriptors : DiagDescriptorsBase
-{
- private const string Category = "EnumStrings";
-
- public static DiagnosticDescriptor InvalidExtensionNamespace { get; } = Make(
- id: "ENUMSTRGEN000",
- title: Resources.InvalidExtensionNamespaceTitle,
- messageFormat: Resources.InvalidExtensionNamespaceMessage,
- category: Category);
-
- public static DiagnosticDescriptor IncorrectOverload { get; } = Make(
- id: "ENUMSTRGEN001",
- title: Resources.IncorrectOverloadTitle,
- messageFormat: Resources.IncorrectOverloadMessage,
- category: Category);
-
- public static DiagnosticDescriptor InvalidExtensionClassName { get; } = Make(
- id: "ENUMSTRGEN002",
- title: Resources.InvalidExtensionClassNameTitle,
- messageFormat: Resources.InvalidExtensionClassNameMessage,
- category: Category);
-
- public static DiagnosticDescriptor InvalidExtensionMethodName { get; } = Make(
- id: "ENUMSTRGEN003",
- title: Resources.InvalidExtensionMethodNameTitle,
- messageFormat: Resources.InvalidExtensionMethodNameMessage,
- category: Category);
-
- public static DiagnosticDescriptor InvalidEnumType { get; } = Make(
- id: "ENUMSTRGEN004",
- title: Resources.InvalidEnumTypeTitle,
- messageFormat: Resources.InvalidEnumTypeMessage,
- category: Category);
-}
diff --git a/src/Generators/Microsoft.Gen.EnumStrings/Emitter.cs b/src/Generators/Microsoft.Gen.EnumStrings/Emitter.cs
deleted file mode 100644
index 34b51de7676..00000000000
--- a/src/Generators/Microsoft.Gen.EnumStrings/Emitter.cs
+++ /dev/null
@@ -1,474 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Threading;
-using Microsoft.Gen.EnumStrings.Model;
-using Microsoft.Gen.Shared;
-
-namespace Microsoft.Gen.EnumStrings;
-
-#pragma warning disable LA0002 // Use 'Microsoft.Extensions.Text.NumericExtensions.ToInvariantString' for improved performance
-#pragma warning disable S109 // Magic numbers should not be used
-
-// Stryker disable all
-
-///
-/// Emits fast ToInvariantString extension methods for enums.
-///
-///
-/// The generated code uses different strategies depending on the shape of the enum, and depending on what
-/// symbols are available at compile time.
-///
-/// * If an enum has 1 or 2 entries, the lookup is done with explicit "if" statements.
-///
-/// * If an enum has mostly contiguous values (a common case), then the lookup is done via an array
-///
-/// * If an enum has a set of discontiguous values, then the lookup is done via a dictionary. This will be a frozen dictionary if the
-/// frozen collections are available at compile time, otherwise a classic dictionary.
-///
-/// In all cases, if the initial lookup fails, then we lookup in a static concurrent dictionary as a cache of values from
-/// the original Enum.ToString().
-///
-internal sealed class Emitter : EmitterBase
-{
- // max # entries we keep in the concurrent dictionary
- private const int MaxCacheEntries = 256;
-
- // flags and sparse arrays can grow to this size no questions asked
- private const int ArrayLookupThreshold = 1024;
-
- // sparse arrays can get bigger than the threshold only if they don't exceed this percentage of sparseness.
- private const int MaxSparsePercent = 25;
-
- public string Emit(
- IEnumerable toStringMethods,
- bool frozenDictionaryAvailable,
- CancellationToken cancellationToken)
- {
- foreach (var tsm in toStringMethods.OrderBy(static t => t.ExtensionNamespace + "." + t.ExtensionClass))
- {
- cancellationToken.ThrowIfCancellationRequested();
- GenExtension(tsm, frozenDictionaryAvailable);
- }
-
- return Capture();
- }
-
- // This code was stolen from .NET 6's implementation of Enum.ToString, and adapted for the circumstances
- private static string FlagsName(List names, List enumMemberValues, ulong valueToFormat)
- {
- ulong originalValueToFormat = valueToFormat;
-
- // Values are sorted, so if the incoming value is 0, we can check to see whether
- // the first entry matches it, in which case we can return its name; otherwise,
- // we can just return "0".
- if (valueToFormat == 0)
- {
- return enumMemberValues.Count > 0 && enumMemberValues[0] == 0 ? names[0] : "0";
- }
-
- // With a ulong result value, regardless of the enum's base type, the maximum
- // possible number of consistent name/values we could have is 64, since every
- // value is made up of one or more bits, and when we see values and incorporate
- // their names, we effectively switch off those bits.
- Span foundItems = stackalloc int[64];
-
- // Walk from largest to smallest. It's common to have a flags enum with a single
- // value that matches a single entry, in which case we can just return the existing
- // name string.
- int index = enumMemberValues.Count - 1;
- while (index >= 0)
- {
- if (enumMemberValues[index] == valueToFormat)
- {
- return names[index];
- }
-
- if (enumMemberValues[index] < valueToFormat)
- {
- break;
- }
-
- index--;
- }
-
- // Now look for multiple matches, storing the indices of the values
- // into our span.
- int resultLength = 0;
- int foundItemsCount = 0;
- while (index >= 0)
- {
- ulong currentValue = enumMemberValues[index];
- if (index == 0 && currentValue == 0)
- {
- break;
- }
-
- if ((valueToFormat & currentValue) == currentValue)
- {
- valueToFormat -= currentValue;
- foundItems[foundItemsCount++] = index;
- resultLength += names[index].Length;
- }
-
- index--;
- }
-
- // If we exhausted looking through all the values and we still have
- // a non-zero result, we couldn't match the result to only named values.
- // In that case, we return null and let the call site just generate
- // a string for the integral value.
- if (valueToFormat != 0)
- {
- return originalValueToFormat.ToString(CultureInfo.InvariantCulture);
- }
-
- // We know what strings to concatenate. Do so.
-
- const int SeparatorStringLength = 2; // ", "
- resultLength += SeparatorStringLength * (foundItemsCount - 1);
- char[] result = new char[resultLength];
-
- Span resultSpan = result.AsSpan();
- string name = names[foundItems[--foundItemsCount]];
- for (int i = 0; i < name.Length; i++)
- {
- resultSpan[i] = name[i];
- }
-
- resultSpan = resultSpan.Slice(name.Length);
- while (--foundItemsCount >= 0)
- {
- resultSpan[0] = ',';
- resultSpan[1] = ' ';
- resultSpan = resultSpan.Slice(SeparatorStringLength);
-
- name = names[foundItems[foundItemsCount]];
- for (int i = 0; i < name.Length; i++)
- {
- resultSpan[i] = name[i];
- }
-
- resultSpan = resultSpan.Slice(name.Length);
- }
-
- return new string(result);
- }
-
- private static bool IsBigEnum(ToStringMethod tsm) => tsm.UnderlyingType is "ulong" or "long";
-
- private void GenExtension(ToStringMethod tsm, bool frozenDictionaryAvailable)
- {
- if (tsm.ExtensionNamespace.Length > 0)
- {
- OutLn($"namespace {tsm.ExtensionNamespace}");
- OutOpenBrace();
- }
-
- OutLn();
- OutLn($"/// ");
- OutLn($"/// Extension methods for the enum.");
- OutLn($"/// ");
- OutLn($"{tsm.ExtensionClassModifiers} class {tsm.ExtensionClass}");
- OutOpenBrace();
-
- var names = tsm.MemberNames;
- var values = tsm.MemberValues;
- var lookupType = PickLookupType(tsm, out var flagRange, values);
- var fieldPrefix = "__" + tsm.ExtensionMethod + "_";
-
- GenFields();
- GenMethod();
-
- OutCloseBrace();
-
- if (tsm.ExtensionNamespace.Length > 0)
- {
- OutCloseBrace();
- }
-
- static LookupType PickLookupType(ToStringMethod tsm, out ulong flagRange, List values)
- {
- flagRange = 0;
- var lookupType = LookupType.Nothing;
-
- if (tsm.FlagsEnum)
- {
- foreach (var v in values)
- {
- flagRange |= v;
- }
-
- if (values.Count == 1)
- {
- lookupType = LookupType.Conditionals;
- }
- else if (flagRange < ArrayLookupThreshold)
- {
- lookupType = LookupType.Array;
- }
- else
- {
- lookupType = LookupType.Dictionary;
- }
- }
- else
- {
- if (values.Count < 3)
- {
- lookupType = LookupType.Conditionals;
- }
- else
- {
- var delta = values[values.Count - 1] - values[0] + 1;
- if (delta == (ulong)values.Count)
- {
- lookupType = LookupType.Array;
- }
- else if (values[values.Count - 1] < ArrayLookupThreshold)
- {
- lookupType = LookupType.Array;
- }
- else
- {
- lookupType = LookupType.Array;
-
- var numEmptySlots = delta - (ulong)values.Count;
- var percenEmptySlots = (numEmptySlots * 100) / (ulong)values.Count;
- if (percenEmptySlots > MaxSparsePercent)
- {
- lookupType = LookupType.Dictionary;
- }
- }
- }
- }
-
- return lookupType;
- }
-
- void GenMethod()
- {
- OutLn($"/// ");
- OutLn($"/// Efficiently returns a string representation for a value of the enum.");
- OutLn($"/// ");
- OutLn($"/// The value to use.");
- OutLn($"/// A string representation of the value, equivalent to what ToString would return.");
- OutLn($"/// This function is equivalent to calling ToString on an enum's value, except that it is considerably faster.");
- OutGeneratedCodeAttribute();
- OutLn($"public static string {tsm.ExtensionMethod}(this {tsm.EnumTypeName} value)");
- OutOpenBrace();
-
- var valueType = IsBigEnum(tsm) ? "ulong" : "uint";
- var valueText = IsBigEnum(tsm) ? "v" : "(int)v";
-
- OutLn($"var v = ({valueType})value;");
-
- switch (lookupType)
- {
- case LookupType.Conditionals:
- {
- for (int i = 0; i < values.Count; i++)
- {
- var e = (i > 0) ? "else " : string.Empty;
- OutLn($"{e}if (v == {GetLiteral(values[i])})");
- OutOpenBrace();
- OutLn($"return \"{names[i]}\";");
- OutCloseBrace();
- }
-
- break;
- }
-
- case LookupType.Array:
- {
- if (tsm.FlagsEnum)
- {
- OutLn($"if (v <= {flagRange})");
- OutOpenBrace();
- OutLn($"return {fieldPrefix}LookupArray[v];");
- OutCloseBrace();
- }
- else
- {
- var upper = GetLiteral(values[values.Count - 1]);
- if (values[0] > 0)
- {
- var lower = GetLiteral(values[0]);
- OutLn($"if (v >= {lower} && v <= {upper})");
- OutOpenBrace();
- OutLn($"return {fieldPrefix}LookupArray[v - {lower}];");
- }
- else
- {
- if (IsBigEnum(tsm))
- {
- OutLn($"if (v <= {upper})");
- }
- else
- {
- OutLn($"if (v < {fieldPrefix}LookupArray.Length)");
- }
-
- OutOpenBrace();
- OutLn($"return {fieldPrefix}LookupArray[v];");
- }
-
- OutCloseBrace();
- }
-
- break;
- }
-
- case LookupType.Dictionary:
- {
- OutLn($"if ({fieldPrefix}LookupDictionary.TryGetValue({valueText}, out var lookupResult))");
- OutOpenBrace();
- OutLn($"return lookupResult;");
- OutCloseBrace();
- break;
- }
- }
-
- OutLn();
- OutLn($"{fieldPrefix}CacheDictionary ??= new();");
- OutLn($"if ({fieldPrefix}CacheDictionary.TryGetValue({valueText}, out var cachedResult))");
- OutOpenBrace();
- OutLn("return cachedResult;");
- OutCloseBrace();
-
- OutLn();
- OutLn($"var result = value.ToString();");
-
- OutLn();
- OutLn($"if ({fieldPrefix}ApproximateCacheCount < {MaxCacheEntries})");
- OutOpenBrace();
- OutLn($"_ = global::System.Threading.Interlocked.Increment(ref {fieldPrefix}ApproximateCacheCount);");
- OutLn($"{fieldPrefix}CacheDictionary[{valueText}] = result;");
- OutCloseBrace();
-
- OutLn();
- OutLn($"return result;");
-
- OutCloseBrace();
-
- string GetLiteral(ulong value) => IsBigEnum(tsm) ? value.ToString(CultureInfo.InvariantCulture) + "UL" : ((uint)value).ToString(CultureInfo.InvariantCulture) + "U";
- }
-
- void GenFields()
- {
- if (lookupType == LookupType.Array)
- {
- OutGeneratedCodeAttribute();
- OutLn($"private static readonly string[] {fieldPrefix}LookupArray = new string[]");
- OutOpenBrace();
-
- if (tsm.FlagsEnum)
- {
- for (ulong i = 0; i <= flagRange; i++)
- {
- OutLn($"\"{FlagsName(names, values, i)}\",");
- }
- }
- else
- {
- OutLn($"\"{names[0]}\",");
-
- ulong previous = values[0];
- for (int i = 1; i < values.Count; i++)
- {
- while (previous < values[i] - 1)
- {
- previous++;
- OutLn($"\"{previous.ToString(CultureInfo.InvariantCulture)}\",");
- }
-
- OutLn($"\"{names[i]}\",");
- previous = values[i];
- }
- }
-
- OutCloseBraceWithExtra(";");
- }
- else if (lookupType == LookupType.Dictionary)
- {
- OutGeneratedCodeAttribute();
-
- var isBigEnum = IsBigEnum(tsm);
-
-#pragma warning disable S3358 // Ternary operators should not be nested
-#pragma warning disable S103 // Lines should not be too long
- var decl = frozenDictionaryAvailable
- ? isBigEnum
- ? $"private static readonly global::System.Collections.Frozen.FrozenDictionary {fieldPrefix}LookupDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(new global::System.Collections.Generic.Dictionary({values.Count})"
- : $"private static readonly global::System.Collections.Frozen.FrozenDictionary {fieldPrefix}LookupDictionary = global::System.Collections.Frozen.FrozenDictionary.ToFrozenDictionary(new global::System.Collections.Generic.Dictionary({values.Count})"
- : isBigEnum
- ? $"private static readonly global::System.Collections.Generic.Dictionary {fieldPrefix}LookupDictionary = new({values.Count})"
- : $"private static readonly global::System.Collections.Generic.Dictionary {fieldPrefix}LookupDictionary = new({values.Count})";
-#pragma warning restore S103 // Lines should not be too long
-#pragma warning restore S3358 // Ternary operators should not be nested
-
- OutLn(decl);
- OutOpenBrace();
-
- if (tsm.FlagsEnum)
- {
- for (int i = 0; i < ArrayLookupThreshold; i++)
- {
- OutLn($"{{ {i.ToString(CultureInfo.InvariantCulture)}, \"{FlagsName(names, values, (ulong)i)}\" }},");
- }
-
- for (int i = 0; i < values.Count; i++)
- {
- if (values[i] >= ArrayLookupThreshold)
- {
- if (isBigEnum)
- {
- OutLn($"{{ {values[i].ToString(CultureInfo.InvariantCulture)}, \"{names[i]}\" }},");
- }
- else
- {
- OutLn($"{{ unchecked((int){(values[i] & 0xffffffff).ToString(CultureInfo.InvariantCulture)}), \"{names[i]}\" }},");
- }
- }
- }
- }
- else
- {
- for (int i = 0; i < values.Count; i++)
- {
- if (isBigEnum)
- {
- OutLn($"{{ {values[i].ToString(CultureInfo.InvariantCulture)}, \"{names[i]}\" }},");
- }
- else
- {
- OutLn($"{{ unchecked((int){(values[i] & 0xffffffff).ToString(CultureInfo.InvariantCulture)}), \"{names[i]}\" }},");
- }
- }
- }
-
- OutCloseBraceWithExtra(frozenDictionaryAvailable ? ");" : ";");
- }
-
- var keyType = IsBigEnum(tsm) ? "ulong" : "int";
-
- OutLn();
- OutGeneratedCodeAttribute();
- OutLn($"private static global::System.Collections.Concurrent.ConcurrentDictionary<{keyType}, string>? {fieldPrefix}CacheDictionary;");
- OutLn($"private static volatile int {fieldPrefix}ApproximateCacheCount;");
- OutLn();
- }
- }
-
- private enum LookupType
- {
- Nothing,
- Conditionals,
- Array,
- Dictionary,
- }
-}
diff --git a/src/Generators/Microsoft.Gen.EnumStrings/EnumStringsGenerator.cs b/src/Generators/Microsoft.Gen.EnumStrings/EnumStringsGenerator.cs
deleted file mode 100644
index 8664fcc56fd..00000000000
--- a/src/Generators/Microsoft.Gen.EnumStrings/EnumStringsGenerator.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections.Immutable;
-using System.Text;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.Text;
-
-namespace Microsoft.Gen.EnumStrings;
-
-[Generator]
-public class EnumStringsGenerator : IIncrementalGenerator
-{
- public void Initialize(IncrementalGeneratorInitializationContext context)
- {
- IncrementalValuesProvider typeDeclarations = context.SyntaxProvider
- .ForAttributeWithMetadataName(
- SymbolLoader.EnumStringsAttribute,
- (_, _) => true,
- (context, _) => context.TargetNode);
-
- IncrementalValueProvider<(Compilation, ImmutableArray)> compilationAndTypes =
- context.CompilationProvider.Combine(typeDeclarations.Collect());
-
- context.RegisterSourceOutput(compilationAndTypes, static (spc, source) => HandleAnnotatedNodes(source.Item1, source.Item2, spc));
- }
-
- private static void HandleAnnotatedNodes(Compilation compilation, ImmutableArray nodes, SourceProductionContext context)
- {
- SymbolLoader.Load(compilation, out var symbolHolder);
-
- var parser = new Parser(compilation, context.ReportDiagnostic, symbolHolder!, context.CancellationToken);
-
- var toStringMethods = parser.GetToStringMethods(nodes);
- if (toStringMethods.Count > 0)
- {
- var emitter = new Emitter();
- var result = emitter.Emit(toStringMethods, symbolHolder!.FreezerSymbol != null, context.CancellationToken);
-
- context.AddSource("EnumStrings.g.cs", SourceText.From(result, Encoding.UTF8));
- }
- }
-}
diff --git a/src/Generators/Microsoft.Gen.EnumStrings/Microsoft.Gen.EnumStrings.csproj b/src/Generators/Microsoft.Gen.EnumStrings/Microsoft.Gen.EnumStrings.csproj
deleted file mode 100644
index 8aa639c6c76..00000000000
--- a/src/Generators/Microsoft.Gen.EnumStrings/Microsoft.Gen.EnumStrings.csproj
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
- Microsoft.Gen.EnumStrings
- Code generator to support Microsoft.Extensions.EnumStrings.
- Fundamentals
-
-
-
- cs
- true
-
-
-
- normal
- 100
- 85
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Generators/Microsoft.Gen.EnumStrings/Model/ToStringMethod.cs b/src/Generators/Microsoft.Gen.EnumStrings/Model/ToStringMethod.cs
deleted file mode 100644
index 870c080440c..00000000000
--- a/src/Generators/Microsoft.Gen.EnumStrings/Model/ToStringMethod.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System.Collections.Generic;
-using System.Diagnostics.CodeAnalysis;
-
-namespace Microsoft.Gen.EnumStrings.Model;
-
-[ExcludeFromCodeCoverage]
-internal sealed record class ToStringMethod(
- string EnumTypeName,
- List MemberNames,
- List MemberValues,
- bool FlagsEnum,
- string ExtensionNamespace,
- string ExtensionClass,
- string ExtensionMethod,
- string ExtensionClassModifiers,
- string UnderlyingType);
diff --git a/src/Generators/Microsoft.Gen.EnumStrings/Parser.cs b/src/Generators/Microsoft.Gen.EnumStrings/Parser.cs
deleted file mode 100644
index 3e5bb4c4547..00000000000
--- a/src/Generators/Microsoft.Gen.EnumStrings/Parser.cs
+++ /dev/null
@@ -1,249 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using System;
-using System.Collections.Generic;
-using System.Collections.Immutable;
-using System.Globalization;
-using System.Linq;
-using System.Threading;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CSharp;
-using Microsoft.CodeAnalysis.CSharp.Syntax;
-using Microsoft.Gen.EnumStrings.Model;
-
-namespace Microsoft.Gen.EnumStrings;
-
-///
-/// Holds an internal parser class that extracts necessary information for generating IValidateOptions.
-///
-internal sealed class Parser
-{
- private readonly CancellationToken _cancellationToken;
- private readonly Compilation _compilation;
- private readonly Action _reportDiagnostic;
- private readonly SymbolHolder _symbolHolder;
-
- public Parser(
- Compilation compilation,
- Action reportDiagnostic,
- SymbolHolder symbolHolder,
- CancellationToken cancellationToken)
- {
- _compilation = compilation;
- _cancellationToken = cancellationToken;
- _reportDiagnostic = reportDiagnostic;
- _symbolHolder = symbolHolder;
- }
-
- public IReadOnlyList GetToStringMethods(IEnumerable nodes)
- {
- var results = new List();
-
- foreach (var group in nodes.GroupBy(x => x.SyntaxTree))
- {
- SemanticModel? sm = null;
- foreach (var node in group)
- {
- _cancellationToken.ThrowIfCancellationRequested();
- sm ??= _compilation.GetSemanticModel(node.SyntaxTree);
-
- if (node.IsKind(SyntaxKind.EnumDeclaration))
- {
- // enum-level attribute usage
- var enumDecl = (EnumDeclarationSyntax)node;
- var enumSym = sm.GetDeclaredSymbol(node) as INamedTypeSymbol;
- if (enumSym != null)
- {
- ParseAttributeList(
- enumSym,
- enumSym!.GetAttributes(),
- results);
- }
- }
- else if (node.IsKind(SyntaxKind.CompilationUnit))
- {
- // assembly-level attribute usage
- var compUnitDecl = (CompilationUnitSyntax)node;
- ParseAttributeList(
- null,
- sm.Compilation.Assembly.GetAttributes().Where(ad => ad.ApplicationSyntaxReference!.SyntaxTree == node.SyntaxTree),
- results);
- }
- }
- }
-
- return results;
- }
-
- private static (INamedTypeSymbol? explicitEnumType, string? nspace, string? className, string? methodName, string? classModifiers)
- ExtractAttributeValues(AttributeData args)
- {
- INamedTypeSymbol? explicitEnumType = null;
- string? nspace = null;
- string? className = null;
- string? methodName = null;
- string? classModifiers = null;
-
- // Two constructor shapes:
- //
- // ()
- // (Type enumType)
- if (args.ConstructorArguments.Length > 0)
- {
- explicitEnumType = args.ConstructorArguments[0].Value as INamedTypeSymbol;
- }
-
- foreach (var a in args.NamedArguments)
- {
- switch (a.Key)
- {
- case "ExtensionClassModifiers":
- classModifiers = a.Value.Value as string;
- break;
-
- case "ExtensionNamespace":
- nspace = a.Value.Value as string;
- break;
-
- case "ExtensionClassName":
- className = a.Value.Value as string;
- break;
-
- case "ExtensionMethodName":
- methodName = a.Value.Value as string;
- break;
- }
- }
-
- return (explicitEnumType, nspace, className, methodName, classModifiers);
- }
-
- private static ulong ConvertValue(object obj) =>
- obj switch
- {
- sbyte or short or int or long => (ulong)Convert.ToInt64(obj, CultureInfo.InvariantCulture),
- _ => Convert.ToUInt64(obj, CultureInfo.InvariantCulture),
- };
-
- private static bool IsValidNamespace(string nspace)
- {
- var source = $"namespace {nspace} {{ }}";
- var st = CSharpSyntaxTree.ParseText(source);
- return !st.GetDiagnostics().Any();
- }
-
- private static bool IsValidClassName(string className)
- {
- var source = $"class {className} {{ }}";
- var st = CSharpSyntaxTree.ParseText(source);
- return !st.GetDiagnostics().Any();
- }
-
- private static bool IsValidMethodName(string methodName)
- {
- var source = $"class ___XYZ {{ public void {methodName}() {{ }} }}";
- var st = CSharpSyntaxTree.ParseText(source);
- return !(st.GetDiagnostics().Any() || methodName.Contains('.'));
- }
-
- private void ParseAttributeList(INamedTypeSymbol? implicitEnumType, IEnumerable attrDataList, List results)
- {
- foreach (var ad in attrDataList)
- {
- if (SymbolEqualityComparer.Default.Equals(ad.AttributeClass, _symbolHolder.EnumStringsAttributeSymbol))
- {
- var attrSyntax = ad.ApplicationSyntaxReference?.GetSyntax(_cancellationToken) as AttributeSyntax;
-
- if (attrSyntax != null)
- {
- var (explicitEnumType, nspace, className, methodName, classModifiers) = ExtractAttributeValues(ad);
-
- if (nspace != null && !IsValidNamespace(nspace))
- {
- Diag(DiagDescriptors.InvalidExtensionNamespace, attrSyntax.GetLocation(), nspace);
- }
-
- if (className != null && !IsValidClassName(className))
- {
- Diag(DiagDescriptors.InvalidExtensionClassName, attrSyntax.GetLocation(), className);
- }
-
- if (methodName != null && !IsValidMethodName(methodName))
- {
- Diag(DiagDescriptors.InvalidExtensionMethodName, attrSyntax.GetLocation(), methodName);
- }
-
- var enumType = implicitEnumType ?? explicitEnumType;
-
- if ((implicitEnumType != null && explicitEnumType != null) || enumType == null)
- {
- // must have one and only one enum type
- Diag(DiagDescriptors.IncorrectOverload, attrSyntax.GetLocation());
- return;
- }
-
- if (enumType.TypeKind != TypeKind.Enum)
- {
- Diag(DiagDescriptors.InvalidEnumType, attrSyntax.GetLocation(), enumType);
- return;
- }
-
- var flags = enumType.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, _symbolHolder.FlagsAttributeSymbol));
-
- // get a sorted list of enum members
- IEnumerable> members = enumType
- .GetMembers()
- .OfType()
- .Where(f => f.IsConst)
- .Select(f => new KeyValuePair(f.Name, ConvertValue(f.ConstantValue!)))
- .OrderBy(kvp => kvp.Value);
-
- if (flags)
- {
- members = members
- .Reverse() // flip it so Distinct keeps the last instance of duplicates instead of the first to match what Enum.ToString does
- .Distinct(new EntryComparer())
- .Reverse(); // flip it back to natural order
- }
- else
- {
- members = members.Distinct(new EntryComparer());
- }
-
- var resultingNamespace = nspace ??
- (enumType.ContainingNamespace.IsGlobalNamespace
- ? string.Empty
- : enumType.ContainingNamespace.ToString());
-
- results.Add(new ToStringMethod(
- enumType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat),
- members.Select(kvp => kvp.Key).ToList(),
- members.Select(kvp => kvp.Value).ToList(),
- flags,
- resultingNamespace,
- className ?? enumType.Name + "Extensions",
- methodName ?? "ToInvariantString",
- classModifiers ?? "internal static",
- enumType.EnumUnderlyingType!.ToString()));
- }
- }
- }
- }
-
- private void Diag(DiagnosticDescriptor desc, Location? location)
- {
- _reportDiagnostic(Diagnostic.Create(desc, location, Array.Empty