From 82a5b7e91077ee38fdded3d17f68e708912dae28 Mon Sep 17 00:00:00 2001 From: xtqqczze <45661989+xtqqczze@users.noreply.github.com> Date: Mon, 19 Jul 2021 15:43:28 +0100 Subject: [PATCH 01/37] Delete IDE dispose analyzer rules The IDE dispose analyzer rules have been deleted from Roslyn: https://github.com/dotnet/roslyn/commit/eeba499ecf839ec35bca25062d69d2fc5c4885b9 --- .editorconfig | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.editorconfig b/.editorconfig index 554c51394f..8dc9a28f94 100644 --- a/.editorconfig +++ b/.editorconfig @@ -80,11 +80,6 @@ dotnet_style_prefer_inferred_tuple_names = true:suggestion dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion dotnet_style_prefer_simplified_interpolation = true:suggestion -# Dispose rules (CA2000 and CA2213) ported to IDE analyzers. We already execute the CA rules on the repo, so disable the IDE ones. -dotnet_diagnostic.IDE0067.severity = none -dotnet_diagnostic.IDE0068.severity = none -dotnet_diagnostic.IDE0069.severity = none - ### CSharp code style settings ### [*.cs] From af5cc6febdcf21713c15f8d5631775ad01ff91b0 Mon Sep 17 00:00:00 2001 From: Rikki Gibson Date: Mon, 19 Jul 2021 13:40:08 -0700 Subject: [PATCH 02/37] Remove dead code in CA1069 analyzer (#5253) --- .../ApiDesignGuidelines/EnumShouldNotHaveDuplicatedValues.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EnumShouldNotHaveDuplicatedValues.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EnumShouldNotHaveDuplicatedValues.cs index d23ed946b3..1b84a27877 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EnumShouldNotHaveDuplicatedValues.cs +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/EnumShouldNotHaveDuplicatedValues.cs @@ -134,7 +134,6 @@ void visitInitializerValue(IOperation operation) void endVisitEnumSymbol(SymbolAnalysisContext context) { - var enumSymbol = (INamedTypeSymbol)context.Symbol; // visit any duplicates which didn't have an initializer foreach (var field in duplicates) { From 0b0fd2c98a584c72dacb571be78db2f8a718c33b Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Tue, 20 Jul 2021 11:30:03 -0700 Subject: [PATCH 03/37] Initial add of richnav indexing --- azure-pipelines-richnav.yml | 41 +++++++++++++++++++++++++++++++++++++ azure-pipelines.yml | 27 ++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 azure-pipelines-richnav.yml diff --git a/azure-pipelines-richnav.yml b/azure-pipelines-richnav.yml new file mode 100644 index 0000000000..a546995afb --- /dev/null +++ b/azure-pipelines-richnav.yml @@ -0,0 +1,41 @@ +# Branches that trigger a build on commit +trigger: + - main + - release/* + +variables: + - name: _TeamName + value: Roslyn + - name: _DotNetArtifactsCategory + value: .NETCore + +stages: +- stage: build + displayName: Build + jobs: + - template: /eng/common/templates/jobs/jobs.yml + parameters: + enableRichCodeNavigation: true + richCodeNavigationEnvironment: "production" + richCodeNavigationLanguage: "csharp" + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: true + enableTelemetry: true + enableSourceBuild: true + jobs: + - job: Debug_Build + pool: + name: NetCoreInternal-Pool + queue: BuildPool.Windows.10.Amd64.VS2019.Pre + variables: + - group: DotNet-Blob-Feed + - group: Publish-Build-Assets + - name: _BuildConfig + value: Debug + steps: + - checkout: self + clean: true + - script: eng\common\CIBuild.cmd + -configuration $(_BuildConfig) + displayName: Build and Test diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e90ed77c0b..2a2dd29ad4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,6 +13,33 @@ pr: - 2.9.x jobs: + - template: /eng/common/templates/jobs/jobs.yml + parameters: + enableRichCodeNavigation: true + richCodeNavigationEnvironment: "production" + richCodeNavigationLanguage: "csharp" + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: true + enableTelemetry: true + enableSourceBuild: true + jobs: + - job: Debug_Build + pool: + name: NetCoreInternal-Pool + queue: BuildPool.Windows.10.Amd64.VS2019.Pre + variables: + - group: DotNet-Blob-Feed + - group: Publish-Build-Assets + - name: _BuildConfig + value: Debug + steps: + - checkout: self + clean: true + - script: eng\common\CIBuild.cmd + -configuration $(_BuildConfig) + displayName: Build and Test + - job: Windows strategy: maxParallel: 4 From ef8324877dfc1dd1b375444a44d0e19f18fe6b40 Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Tue, 20 Jul 2021 16:50:29 -0700 Subject: [PATCH 04/37] Update yml spacing --- azure-pipelines.yml | 52 ++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2a2dd29ad4..86f27db8c7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -13,32 +13,32 @@ pr: - 2.9.x jobs: - - template: /eng/common/templates/jobs/jobs.yml - parameters: - enableRichCodeNavigation: true - richCodeNavigationEnvironment: "production" - richCodeNavigationLanguage: "csharp" - enableMicrobuild: true - enablePublishBuildArtifacts: true - enablePublishTestResults: true - enableTelemetry: true - enableSourceBuild: true - jobs: - - job: Debug_Build - pool: - name: NetCoreInternal-Pool - queue: BuildPool.Windows.10.Amd64.VS2019.Pre - variables: - - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - - name: _BuildConfig - value: Debug - steps: - - checkout: self - clean: true - - script: eng\common\CIBuild.cmd - -configuration $(_BuildConfig) - displayName: Build and Test +- template: /eng/common/templates/jobs/jobs.yml + parameters: + enableRichCodeNavigation: true + richCodeNavigationEnvironment: "production" + richCodeNavigationLanguage: "csharp" + enableMicrobuild: true + enablePublishBuildArtifacts: true + enablePublishTestResults: true + enableTelemetry: true + enableSourceBuild: true + jobs: + - job: Debug_Build + pool: + name: NetCoreInternal-Pool + queue: BuildPool.Windows.10.Amd64.VS2019.Pre + variables: + - group: DotNet-Blob-Feed + - group: Publish-Build-Assets + - name: _BuildConfig + value: Debug + steps: + - checkout: self + clean: true + - script: eng\common\CIBuild.cmd + -configuration $(_BuildConfig) + displayName: Build and Test - job: Windows strategy: From dd83d4b0d2752140308150519652dc5fcd8dab41 Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Tue, 20 Jul 2021 16:56:56 -0700 Subject: [PATCH 05/37] Remove unauthorized settings --- azure-pipelines.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 86f27db8c7..0b2cafd1e6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,19 +18,12 @@ jobs: enableRichCodeNavigation: true richCodeNavigationEnvironment: "production" richCodeNavigationLanguage: "csharp" - enableMicrobuild: true - enablePublishBuildArtifacts: true - enablePublishTestResults: true - enableTelemetry: true - enableSourceBuild: true jobs: - job: Debug_Build pool: name: NetCoreInternal-Pool queue: BuildPool.Windows.10.Amd64.VS2019.Pre variables: - - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - name: _BuildConfig value: Debug steps: From a059cd90026f2a925f0b0b1edbbebf1f4d4b7e99 Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Tue, 20 Jul 2021 16:57:22 -0700 Subject: [PATCH 06/37] Update pool --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0b2cafd1e6..b8bc78cf29 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,7 +21,7 @@ jobs: jobs: - job: Debug_Build pool: - name: NetCoreInternal-Pool + name: NetCorePublic-Pool queue: BuildPool.Windows.10.Amd64.VS2019.Pre variables: - name: _BuildConfig From 0296b4ac1ca4a88f9cb420d99797766805bfdee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 22 Jul 2021 11:12:39 +0200 Subject: [PATCH 07/37] Remove some empty statements --- .../Security/JsonNetTypeNameHandling.cs | 2 +- .../IdentifiersShouldNotHaveIncorrectSuffixTests.cs | 1 - .../Performance/DoNotUseCountWhenAnyCanBeUsedTests.Code.cs | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/JsonNetTypeNameHandling.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/JsonNetTypeNameHandling.cs index 187fb92052..c62f86f80a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/JsonNetTypeNameHandling.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Security/JsonNetTypeNameHandling.cs @@ -102,7 +102,7 @@ bool IsOtherThanNone(IFieldReferenceOperation fieldReferenceOperation) } return fieldReferenceOperation.Field.Name != "None"; - }; + } }); } } diff --git a/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/IdentifiersShouldNotHaveIncorrectSuffixTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/IdentifiersShouldNotHaveIncorrectSuffixTests.cs index f1aff8188a..74b316f8c5 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/IdentifiersShouldNotHaveIncorrectSuffixTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/IdentifiersShouldNotHaveIncorrectSuffixTests.cs @@ -1751,7 +1751,6 @@ public void MyMethodEx() { } IdentifiersShouldNotHaveIncorrectSuffixAnalyzer.MemberNewerVersionRule, IdentifiersShouldNotHaveIncorrectSuffixAnalyzer.ExSuffix, "MyMethodEx")); - ; } [Fact] diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseCountWhenAnyCanBeUsedTests.Code.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseCountWhenAnyCanBeUsedTests.Code.cs index 819f81ec93..77cf670a77 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseCountWhenAnyCanBeUsedTests.Code.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Performance/DoNotUseCountWhenAnyCanBeUsedTests.Code.cs @@ -148,7 +148,7 @@ class C builder .Append(AsyncKeyword) .Append(' '); - }; + } return builder .Append(@"void M() @@ -282,7 +282,7 @@ End Function builder .Append(AsyncKeyword) .Append(' '); - }; + } return builder .Append(@"Sub M() From 39ca8641a1ada3a4800db3a17d3d477419d4b67c Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Thu, 22 Jul 2021 11:59:59 -0700 Subject: [PATCH 08/37] Attempt to fix test step in build pipeline --- azure-pipelines-richnav.yml | 2 +- azure-pipelines.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines-richnav.yml b/azure-pipelines-richnav.yml index a546995afb..6f5b29755f 100644 --- a/azure-pipelines-richnav.yml +++ b/azure-pipelines-richnav.yml @@ -26,7 +26,7 @@ stages: jobs: - job: Debug_Build pool: - name: NetCoreInternal-Pool + name: NetCorePublic-Pool queue: BuildPool.Windows.10.Amd64.VS2019.Pre variables: - group: DotNet-Blob-Feed diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b8bc78cf29..3466ef52f9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -22,7 +22,7 @@ jobs: - job: Debug_Build pool: name: NetCorePublic-Pool - queue: BuildPool.Windows.10.Amd64.VS2019.Pre + queue: BuildPool.Windows.10.Amd64.VS2019.Pre.Open variables: - name: _BuildConfig value: Debug From 4ad3a6148a958fe115b6d27d7ec7ccfd1d51d7ec Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Thu, 22 Jul 2021 13:06:07 -0700 Subject: [PATCH 09/37] Add richnav nuget source --- NuGet.config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NuGet.config b/NuGet.config index 6ff54a6347..3ee8cb2e15 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,8 @@ + + From c0fbdbfbbdb60f09e672c2701c9c07201f490202 Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Thu, 22 Jul 2021 14:08:31 -0700 Subject: [PATCH 10/37] RichNav run worked in main yml -- removing from there and copying it to richnav solo yml --- azure-pipelines-richnav.yml | 45 ++++++++++++++++--------------------- azure-pipelines.yml | 22 +----------------- 2 files changed, 20 insertions(+), 47 deletions(-) diff --git a/azure-pipelines-richnav.yml b/azure-pipelines-richnav.yml index 6f5b29755f..43cb0eee36 100644 --- a/azure-pipelines-richnav.yml +++ b/azure-pipelines-richnav.yml @@ -13,29 +13,22 @@ stages: - stage: build displayName: Build jobs: - - template: /eng/common/templates/jobs/jobs.yml - parameters: - enableRichCodeNavigation: true - richCodeNavigationEnvironment: "production" - richCodeNavigationLanguage: "csharp" - enableMicrobuild: true - enablePublishBuildArtifacts: true - enablePublishTestResults: true - enableTelemetry: true - enableSourceBuild: true - jobs: - - job: Debug_Build - pool: - name: NetCorePublic-Pool - queue: BuildPool.Windows.10.Amd64.VS2019.Pre - variables: - - group: DotNet-Blob-Feed - - group: Publish-Build-Assets - - name: _BuildConfig - value: Debug - steps: - - checkout: self - clean: true - - script: eng\common\CIBuild.cmd - -configuration $(_BuildConfig) - displayName: Build and Test +- template: /eng/common/templates/jobs/jobs.yml + parameters: + enableRichCodeNavigation: true + richCodeNavigationEnvironment: "production" + richCodeNavigationLanguage: "csharp" + jobs: + - job: Debug_Build + pool: + name: NetCorePublic-Pool + queue: BuildPool.Windows.10.Amd64.VS2019.Pre.Open + variables: + - name: _BuildConfig + value: Debug + steps: + - checkout: self + clean: true + - script: eng\common\CIBuild.cmd + -configuration $(_BuildConfig) + displayName: Build and Test diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 3466ef52f9..8630354bf5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -12,27 +12,7 @@ pr: - features/* - 2.9.x -jobs: -- template: /eng/common/templates/jobs/jobs.yml - parameters: - enableRichCodeNavigation: true - richCodeNavigationEnvironment: "production" - richCodeNavigationLanguage: "csharp" - jobs: - - job: Debug_Build - pool: - name: NetCorePublic-Pool - queue: BuildPool.Windows.10.Amd64.VS2019.Pre.Open - variables: - - name: _BuildConfig - value: Debug - steps: - - checkout: self - clean: true - - script: eng\common\CIBuild.cmd - -configuration $(_BuildConfig) - displayName: Build and Test - +jobs: - job: Windows strategy: maxParallel: 4 From 2ef6f112e1c7b171ee7cb4a0f807a5528411a5a7 Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Thu, 22 Jul 2021 14:09:09 -0700 Subject: [PATCH 11/37] Remove added whitespace --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8630354bf5..e90ed77c0b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -12,7 +12,7 @@ pr: - features/* - 2.9.x -jobs: +jobs: - job: Windows strategy: maxParallel: 4 From 50e3c65fc551b35aaa21e6e943e6cf1baa68324d Mon Sep 17 00:00:00 2001 From: Briana Eng Date: Thu, 22 Jul 2021 14:10:13 -0700 Subject: [PATCH 12/37] Remove unused vars, rename displayName for clarity --- azure-pipelines-richnav.yml | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/azure-pipelines-richnav.yml b/azure-pipelines-richnav.yml index 43cb0eee36..4937cc6d93 100644 --- a/azure-pipelines-richnav.yml +++ b/azure-pipelines-richnav.yml @@ -3,12 +3,6 @@ trigger: - main - release/* -variables: - - name: _TeamName - value: Roslyn - - name: _DotNetArtifactsCategory - value: .NETCore - stages: - stage: build displayName: Build @@ -31,4 +25,4 @@ stages: clean: true - script: eng\common\CIBuild.cmd -configuration $(_BuildConfig) - displayName: Build and Test + displayName: Build and Index From d36599d59dffb849cd07f728059f47a3c837f7b0 Mon Sep 17 00:00:00 2001 From: Prashanth Govindarajan Date: Tue, 27 Jul 2021 15:34:51 -0700 Subject: [PATCH 13/37] Fix TODOs and update unit tests with diagnostics (#5287) * Fix TODOs and update unit tests with diagnostics * Address comments * sq * Address feedback --- .../Runtime/DetectPreviewFeatureAnalyzer.cs | 93 +- .../Runtime/DetectPreviewFeatureUnitTests.cs | 1009 +++++++++-------- src/Utilities/Compiler/WellKnownTypeNames.cs | 2 +- 3 files changed, 585 insertions(+), 519 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureAnalyzer.cs index 6d8a6237ce..a632ef967b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureAnalyzer.cs @@ -3,6 +3,7 @@ using System.Collections.Concurrent; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; +using System.Linq; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; @@ -82,13 +83,22 @@ public override void Initialize(AnalysisContext context) ConcurrentDictionary requiresPreviewFeaturesSymbols = new(); ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType = new(); - if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesRuntimeFeatureVirtualStaticsInInterfaces, out INamedTypeSymbol? runtimeFeatureTypeVirtualStaticsInInterfaces)) + IFieldSymbol? virtualStaticsInInterfaces = null; + if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesRuntimeFeature, out INamedTypeSymbol? runtimeFeatureType)) { - ProcessPreviewAttribute(runtimeFeatureTypeVirtualStaticsInInterfaces, requiresPreviewFeaturesSymbols); + virtualStaticsInInterfaces = runtimeFeatureType + .GetMembers("VirtualStaticsInInterfaces") + .OfType() + .FirstOrDefault(); + + if (virtualStaticsInInterfaces != null) + { + ProcessPreviewAttribute(virtualStaticsInInterfaces, requiresPreviewFeaturesSymbols, previewFeaturesAttribute); + } } // Handle user side invocation/references to preview features - context.RegisterOperationAction(context => BuildSymbolInformationFromOperations(context, requiresPreviewFeaturesSymbols), + context.RegisterOperationAction(context => BuildSymbolInformationFromOperations(context, requiresPreviewFeaturesSymbols, previewFeaturesAttribute), OperationKind.Invocation, OperationKind.ObjectCreation, OperationKind.PropertyReference, @@ -102,11 +112,14 @@ public override void Initialize(AnalysisContext context) ); // Handle library side definitions of preview features - context.RegisterSymbolAction(context => AnalyzeSymbol(context, requiresPreviewFeaturesSymbols, requiresPreviewFeaturesSymbolsToUsageType, runtimeFeatureTypeVirtualStaticsInInterfaces), s_symbols); + context.RegisterSymbolAction(context => AnalyzeSymbol(context, requiresPreviewFeaturesSymbols, requiresPreviewFeaturesSymbolsToUsageType, virtualStaticsInInterfaces, previewFeaturesAttribute), s_symbols); }); } - private static bool ProcessTypeSymbolAttributes(ITypeSymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols, ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType) + private static bool ProcessTypeSymbolAttributes(ITypeSymbol symbol, + ConcurrentDictionary requiresPreviewFeaturesSymbols, + ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType, + INamedTypeSymbol previewFeatureAttributeSymbol) { ImmutableArray interfaces = symbol.Interfaces; foreach (INamedTypeSymbol anInterface in interfaces) @@ -123,13 +136,15 @@ private static bool ProcessTypeSymbolAttributes(ITypeSymbol symbol, ConcurrentDi INamedTypeSymbol? baseType = symbol.BaseType; if (baseType != null) { - return ProcessPreviewAttribute(baseType, requiresPreviewFeaturesSymbols); + return ProcessPreviewAttribute(baseType, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol); } return false; } - private static bool ProcessContainingTypePreviewAttributes(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols) + private static bool ProcessContainingTypePreviewAttributes(ISymbol symbol, + ConcurrentDictionary requiresPreviewFeaturesSymbols, + INamedTypeSymbol previewFeatureAttributeSymbol) { INamedTypeSymbol? containingType = symbol.ContainingType; // Namespaces do not have attributes @@ -140,23 +155,27 @@ private static bool ProcessContainingTypePreviewAttributes(ISymbol symbol, Concu if (containingType != null) { - return ProcessPreviewAttribute(containingType, requiresPreviewFeaturesSymbols); + return ProcessPreviewAttribute(containingType, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol); } return false; } - private static bool SymbolIsStaticAndAbstract(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols) + private static bool SymbolIsStaticAndAbstract(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols, INamedTypeSymbol previewFeatureAttributeSymbol) { - return symbol.IsStatic && symbol.IsAbstract && !ProcessContainingTypePreviewAttributes(symbol, requiresPreviewFeaturesSymbols); + // Static Abstract is only legal on interfaces. Anything else is likely a compile error and we shouldn't tag such cases. + return symbol.IsStatic && symbol.IsAbstract && symbol.ContainingType != null && symbol.ContainingType.TypeKind == TypeKind.Interface && !ProcessContainingTypePreviewAttributes(symbol, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol); } - private static bool ProcessPropertyOrMethodAttributes(ISymbol propertyOrMethodSymbol, ConcurrentDictionary requiresPreviewFeaturesSymbols, ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType, INamedTypeSymbol? runtimeFeatureType) + private static bool ProcessPropertyOrMethodAttributes(ISymbol propertyOrMethodSymbol, + ConcurrentDictionary requiresPreviewFeaturesSymbols, + ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType, + IFieldSymbol? virtualStaticsInInterfaces, + INamedTypeSymbol previewFeatureAttributeSymbol) { - if (SymbolIsStaticAndAbstract(propertyOrMethodSymbol, requiresPreviewFeaturesSymbols)) + if (SymbolIsStaticAndAbstract(propertyOrMethodSymbol, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol)) { - // TODO: This needs to be tagged only on interfaces. A static abstract method on an abstract class is illegal and we shouldn't tag such cases. - if (runtimeFeatureType != null && ProcessPreviewAttribute(runtimeFeatureType, requiresPreviewFeaturesSymbols)) + if (virtualStaticsInInterfaces != null && ProcessPreviewAttribute(virtualStaticsInInterfaces, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol)) { requiresPreviewFeaturesSymbolsToUsageType.GetOrAdd(propertyOrMethodSymbol, PreviewFeatureUsageType.StaticAbstract); return true; @@ -165,7 +184,7 @@ private static bool ProcessPropertyOrMethodAttributes(ISymbol propertyOrMethodSy if (propertyOrMethodSymbol.IsImplementationOfAnyImplicitInterfaceMember(out ISymbol baseInterfaceMember)) { - if (ProcessPreviewAttribute(baseInterfaceMember, requiresPreviewFeaturesSymbols) || ProcessContainingTypePreviewAttributes(baseInterfaceMember, requiresPreviewFeaturesSymbols)) + if (ProcessPreviewAttribute(baseInterfaceMember, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol) || ProcessContainingTypePreviewAttributes(baseInterfaceMember, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol)) { return true; } @@ -174,7 +193,7 @@ private static bool ProcessPropertyOrMethodAttributes(ISymbol propertyOrMethodSy if (propertyOrMethodSymbol.IsOverride) { ISymbol? overridden = propertyOrMethodSymbol.GetOverriddenMember(); - if (overridden != null && ProcessPreviewAttribute(overridden, requiresPreviewFeaturesSymbols)) + if (overridden != null && ProcessPreviewAttribute(overridden, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol)) { return true; } @@ -183,20 +202,24 @@ private static bool ProcessPropertyOrMethodAttributes(ISymbol propertyOrMethodSy return false; } - private static void AnalyzeSymbol(SymbolAnalysisContext context, ConcurrentDictionary requiresPreviewFeaturesSymbols, ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType, INamedTypeSymbol? runtimeFeatureType) + private static void AnalyzeSymbol(SymbolAnalysisContext context, + ConcurrentDictionary requiresPreviewFeaturesSymbols, + ConcurrentDictionary requiresPreviewFeaturesSymbolsToUsageType, + IFieldSymbol? virtualStaticsInInterfaces, + INamedTypeSymbol previewFeatureAttributeSymbol) { ISymbol symbol = context.Symbol; // Don't report diagnostics on symbols that are marked as Preview - if (ProcessPreviewAttribute(symbol, requiresPreviewFeaturesSymbols)) + if (ProcessPreviewAttribute(symbol, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol)) { return; } var reportDiagnostic = symbol switch { - ITypeSymbol typeSymbol => ProcessTypeSymbolAttributes(typeSymbol, requiresPreviewFeaturesSymbols, requiresPreviewFeaturesSymbolsToUsageType), - IPropertySymbol or IMethodSymbol => ProcessPropertyOrMethodAttributes(symbol, requiresPreviewFeaturesSymbols, requiresPreviewFeaturesSymbolsToUsageType, runtimeFeatureType), + ITypeSymbol typeSymbol => ProcessTypeSymbolAttributes(typeSymbol, requiresPreviewFeaturesSymbols, requiresPreviewFeaturesSymbolsToUsageType, previewFeatureAttributeSymbol), + IPropertySymbol or IMethodSymbol => ProcessPropertyOrMethodAttributes(symbol, requiresPreviewFeaturesSymbols, requiresPreviewFeaturesSymbolsToUsageType, virtualStaticsInInterfaces, previewFeatureAttributeSymbol), _ => false }; @@ -220,9 +243,9 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, ConcurrentDicti } } - private static void BuildSymbolInformationFromOperations(OperationAnalysisContext context, ConcurrentDictionary requiresPreviewFeaturesSymbols) + private static void BuildSymbolInformationFromOperations(OperationAnalysisContext context, ConcurrentDictionary requiresPreviewFeaturesSymbols, INamedTypeSymbol previewFeatureAttributeSymbol) { - if (OperationUsesPreviewFeatures(context, requiresPreviewFeaturesSymbols, out ISymbol? symbol)) + if (OperationUsesPreviewFeatures(context, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol, out ISymbol? symbol)) { IOperation operation = context.Operation; if (operation is ICatchClauseOperation catchClauseOperation) @@ -234,18 +257,19 @@ private static void BuildSymbolInformationFromOperations(OperationAnalysisContex } } - private static bool OperationUsesPreviewFeatures(OperationAnalysisContext context, ConcurrentDictionary requiresPreviewFeaturesSymbols, [NotNullWhen(true)] out ISymbol? symbol) + private static bool OperationUsesPreviewFeatures(OperationAnalysisContext context, ConcurrentDictionary requiresPreviewFeaturesSymbols, INamedTypeSymbol previewFeatureAttributeSymbol, [NotNullWhen(true)] out ISymbol? symbol) { IOperation operation = context.Operation; ISymbol containingSymbol = context.ContainingSymbol; - if (OperationUsesPreviewFeatures(containingSymbol, requiresPreviewFeaturesSymbols) || OperationUsesPreviewFeatures(containingSymbol.ContainingSymbol, requiresPreviewFeaturesSymbols)) + if (OperationUsesPreviewFeatures(containingSymbol, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol) || + OperationUsesPreviewFeatures(containingSymbol.ContainingSymbol, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol)) { symbol = null; return false; } symbol = GetOperationSymbol(operation); - return symbol != null && OperationUsesPreviewFeatures(symbol, requiresPreviewFeaturesSymbols); + return symbol != null && OperationUsesPreviewFeatures(symbol, requiresPreviewFeaturesSymbols, previewFeatureAttributeSymbol); } private static ISymbol? GetOperationSymbol(IOperation operation) @@ -264,27 +288,16 @@ private static bool OperationUsesPreviewFeatures(OperationAnalysisContext contex _ => null, }; - private static bool OperationUsesPreviewFeatures(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols) + private static bool OperationUsesPreviewFeatures(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols, INamedTypeSymbol previewFeatureAttribute) { - return ProcessContainingTypePreviewAttributes(symbol, requiresPreviewFeaturesSymbols) || ProcessPreviewAttribute(symbol, requiresPreviewFeaturesSymbols); + return ProcessContainingTypePreviewAttributes(symbol, requiresPreviewFeaturesSymbols, previewFeatureAttribute) || ProcessPreviewAttribute(symbol, requiresPreviewFeaturesSymbols, previewFeatureAttribute); } - private static bool ProcessPreviewAttribute(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols) + private static bool ProcessPreviewAttribute(ISymbol symbol, ConcurrentDictionary requiresPreviewFeaturesSymbols, INamedTypeSymbol? previewFeatureAttribute) { if (!requiresPreviewFeaturesSymbols.TryGetValue(symbol, out bool existing)) { - bool ret = false; - // TODO: Use symbol.HasAttribute(RequiresPreviewFeaturesAttribute) once we consume the latest sdk - ImmutableArray attributes = symbol.GetAttributes(); - foreach (AttributeData attribute in attributes) - { - string attributeName = attribute.AttributeClass.Name; - if (attributeName == RequiresPreviewFeaturesAttribute) - { - ret = true; - break; - } - } + bool ret = symbol.HasAttribute(previewFeatureAttribute); requiresPreviewFeaturesSymbols.GetOrAdd(symbol, ret); return ret; } diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureUnitTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureUnitTests.cs index 2935932958..d0b8ac0526 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureUnitTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/DetectPreviewFeatureUnitTests.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Threading.Tasks; -using Microsoft.CodeAnalysis.Testing; using Test.Utilities; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< @@ -12,9 +11,9 @@ namespace Microsoft.NetCore.Analyzers.Runtime.UnitTests { public class DetectPreviewFeatureUnitTests { - private static async Task TestCS(string csInput) + private static VerifyCS.Test TestCS(string csInput) { - await new VerifyCS.Test + return new VerifyCS.Test { LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp10, TestState = @@ -24,14 +23,13 @@ private static async Task TestCS(string csInput) csInput } }, - MarkupOptions = MarkupOptions.UseFirstDescriptor, ReferenceAssemblies = AdditionalMetadataReferences.Net60, - }.RunAsync(); + }; } - private static async Task TestCSPreview(string csInput) + private static VerifyCS.Test TestCSPreview(string csInput) { - await new VerifyCS.Test + return new VerifyCS.Test { LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.Preview, TestState = @@ -41,9 +39,8 @@ private static async Task TestCSPreview(string csInput) csInput } }, - MarkupOptions = MarkupOptions.UseFirstDescriptor, ReferenceAssemblies = AdditionalMetadataReferences.Net60, - }.RunAsync(); + }; } [Fact] @@ -59,7 +56,7 @@ public class Program static void Main(string[] args) { var a = new Fraction(); - var b = [|+a|]; + var b = {|#0:+a|}; } } @@ -71,7 +68,9 @@ public readonly struct Fraction } "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("op_UnaryPlus")); + await test.RunAsync(); } [Fact] @@ -97,7 +96,7 @@ static void Main(string[] args) { Console.WriteLine(""Foo""); } - catch [|(DerivedException ex)|] + catch {|#0:(DerivedException ex)|} { throw; } @@ -106,234 +105,250 @@ static void Main(string[] args) } "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("DerivedException")); + await test.RunAsync(); } [Fact] public async Task TestArrayOrPreviewTypes() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - public class Program - { - static void Main(string[] args) - { - Lib[] array = [|new Lib[] { }|]; - } - } + public class Program + { + static void Main(string[] args) + { + Lib[] array = {|#0:new Lib[] { }|}; + } + } - [RequiresPreviewFeatures] - public class Lib - { - } -} -"; + [RequiresPreviewFeatures] + public class Lib + { + } + } + "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Lib")); + await test.RunAsync(); } [Fact] public async Task TestPreviewMethodBinaryOperator() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - public class Program - { - static void Main(string[] args) - { - var a = new Fraction(); - var b = new Fraction(); - b = [|b + a|]; - } - } + public class Program + { + static void Main(string[] args) + { + var a = new Fraction(); + var b = new Fraction(); + b = {|#0:b + a|}; + } + } - public readonly struct Fraction - { - [RequiresPreviewFeatures] - public static Fraction operator +(Fraction a, Fraction b) => a; - } -} -"; - await TestCS(csInput); + public readonly struct Fraction + { + [RequiresPreviewFeatures] + public static Fraction operator +(Fraction a, Fraction b) => a; + } + } + "; + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("op_Addition")); + await test.RunAsync(); } [Fact] public async Task TestUnmarkedPreviewPropertyCallingPreviewProperty() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" -[RequiresPreviewFeatures] -public class Program -{ - public bool CallSite => UnmarkedPreviewClass.SomeStaticProperty; -} - -public class UnmarkedPreviewClass -{ [RequiresPreviewFeatures] - public static bool SomeStaticProperty => false; -} -} -"; + public class Program + { + public bool CallSite => UnmarkedPreviewClass.SomeStaticProperty; + } - await TestCS(csInput); + public class UnmarkedPreviewClass + { + [RequiresPreviewFeatures] + public static bool SomeStaticProperty => false; + } + } + "; + + var test = TestCS(csInput); + await test.RunAsync(); } [Fact] public async Task TestUnmarkedPreviewMethodCallingPreviewMethod() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" -[RequiresPreviewFeatures] -public class Program -{ - public bool CallSite() - { - return UnmarkedPreviewClass.SomeStaticMethod(); - } -} - -public class UnmarkedPreviewClass -{ [RequiresPreviewFeatures] - public static bool SomeStaticMethod() + public class Program { - return false; + public bool CallSite() + { + return UnmarkedPreviewClass.SomeStaticMethod(); + } } -} -} -"; - await TestCS(csInput); + public class UnmarkedPreviewClass + { + [RequiresPreviewFeatures] + public static bool SomeStaticMethod() + { + return false; + } + } + } + "; + + var test = TestCS(csInput); + await test.RunAsync(); } [Fact] public async Task TestPreviewMethodCallingPreviewMethod() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" -public class Program -{ - [RequiresPreviewFeatures] - public virtual void PreviewMethod() { } - - [RequiresPreviewFeatures] - void CallSite() - { - PreviewMethod(); - } -} -} -"; + public class Program + { + [RequiresPreviewFeatures] + public virtual void PreviewMethod() { } - await TestCS(csInput); + [RequiresPreviewFeatures] + void CallSite() + { + PreviewMethod(); + } + } + } + "; + + var test = TestCS(csInput); + await test.RunAsync(); } [Fact] public async Task TestDerivedClassExtendsUnmarkedClass() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - public partial class UnmarkedPreviewClass - { - [RequiresPreviewFeatures] - public virtual void UnmarkedVirtualMethodInPreviewClass() { } - } + public partial class UnmarkedPreviewClass + { + [RequiresPreviewFeatures] + public virtual void UnmarkedVirtualMethodInPreviewClass() { } + } - public partial class Derived : UnmarkedPreviewClass - { - public override void [|UnmarkedVirtualMethodInPreviewClass|]() - { - throw new NotImplementedException(); + public partial class Derived : UnmarkedPreviewClass + { + public override void {|#0:UnmarkedVirtualMethodInPreviewClass|}() + { + throw new NotImplementedException(); + } + } } - } -} -"; + "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("UnmarkedVirtualMethodInPreviewClass")); + await test.RunAsync(); } [Fact] public async Task TestMethodInvocation_Simple() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - public class Program - { - [RequiresPreviewFeatures] - public virtual void PreviewMethod() - { + public class Program + { + [RequiresPreviewFeatures] + public virtual void PreviewMethod() + { - } + } - static void Main(string[] args) - { - var prog = new Program(); - [|prog.PreviewMethod()|]; - } - } -}"; + static void Main(string[] args) + { + var prog = new Program(); + {|#0:prog.PreviewMethod()|}; + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("PreviewMethod")); + await test.RunAsync(); } [Fact] public async Task TestMethodInvocation_DeclareDerivedMethod() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - public class Program - { - [RequiresPreviewFeatures] - public virtual void PreviewMethod() - { + public class Program + { + [RequiresPreviewFeatures] + public virtual void PreviewMethod() + { - } + } - static void Main(string[] args) - { - } - } + static void Main(string[] args) + { + } + } - public class Derived : Program - { - public Derived() : base() - { - } + public class Derived : Program + { + public Derived() : base() + { + } - public override void [|PreviewMethod|]() - { - [|base.PreviewMethod()|]; - } - } -}"; + public override void {|#0:PreviewMethod|}() + { + {|#1:base.PreviewMethod()|}; + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("PreviewMethod")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(1).WithArguments("PreviewMethod")); + await test.RunAsync(); } [Theory] @@ -342,140 +357,186 @@ public Derived() : base() public async Task TestClassOrStruct(string classOrStruct) { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @$" - [RequiresPreviewFeatures] - {classOrStruct} Program - {{ - static void Main(string[] args) - {{ - new Program(); - }} - }} -}}"; + [RequiresPreviewFeatures] + {classOrStruct} Program + {{ + static void Main(string[] args) + {{ + new Program(); + }} + }} + }}"; - await TestCS(csInput); + var test = TestCS(csInput); + await test.RunAsync(); } [Fact] public async Task TestAbstractClass() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class [|Program|] : AbClass - { - static void Main(string[] args) - { - Program prog = new Program(); - prog.Bar(); - [|prog.FooBar()|]; - [|prog.BarImplemented()|]; - } + class {|#0:Program|} : AbClass + { + static void Main(string[] args) + { + Program prog = new Program(); + prog.Bar(); + {|#1:prog.FooBar()|}; + {|#2:prog.BarImplemented()|}; + } - public override void [|Bar|]() - { - throw new NotImplementedException(); - } + public override void {|#3:Bar|}() + { + throw new NotImplementedException(); + } - [RequiresPreviewFeatures] - public override void FooBar() - { - throw new NotImplementedException(); - } - } + [RequiresPreviewFeatures] + public override void FooBar() + { + throw new NotImplementedException(); + } + } - [RequiresPreviewFeatures] - public abstract class AbClass - { - [RequiresPreviewFeatures] - public abstract void Bar(); + [RequiresPreviewFeatures] + public abstract class AbClass + { + [RequiresPreviewFeatures] + public abstract void Bar(); - [RequiresPreviewFeatures] - public abstract void FooBar(); + [RequiresPreviewFeatures] + public abstract void FooBar(); - [RequiresPreviewFeatures] - public void BarImplemented() => throw new NotImplementedException(); - } -}"; + [RequiresPreviewFeatures] + public void BarImplemented() => throw new NotImplementedException(); + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Program")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(1).WithArguments("FooBar")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(2).WithArguments("BarImplemented")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(3).WithArguments("Bar")); + await test.RunAsync(); } [Fact] public async Task TestUnmarkedPreviewProperty() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program : IProgram - { - static void Main(string[] args) - { - new Program(); - } + class Program : IProgram + { + static void Main(string[] args) + { + new Program(); + } - public bool [|MarkedPropertyInInterface|] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } // [] if not opted in yet - } + public bool {|#0:MarkedPropertyInInterface|} { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } // [] if not opted in yet + } - public interface IProgram - { - [RequiresPreviewFeatures] - bool MarkedPropertyInInterface { get; set; } - } -} + public interface IProgram + { + [RequiresPreviewFeatures] + bool MarkedPropertyInInterface { get; set; } + } + } - "; + "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("MarkedPropertyInInterface")); + await test.RunAsync(); } [Fact] public async Task TestUnmarkedPreviewInterface() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program : IProgram - { - static void Main(string[] args) - { - new Program(); + class Program : IProgram + { + static void Main(string[] args) + { + new Program(); + } + + public void {|#0:MarkedMethodInInterface|}() + { + throw new NotImplementedException(); + } + } + + public interface IProgram + { + [RequiresPreviewFeatures] + void MarkedMethodInInterface(); + } + } + + "; + + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("MarkedMethodInInterface")); + await test.RunAsync(); + } - public void [|MarkedMethodInInterface|]() + [Fact] + public async Task TestPreviewLanguageFeatures() { - throw new NotImplementedException(); - } - } + var csInput = @" + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + +@" - public interface IProgram - { - [RequiresPreviewFeatures] - void MarkedMethodInInterface(); - } -} + class Program : IProgram + { + static void Main(string[] args) + { + new Program(); + } + + public static bool StaticMethod() => throw null; + public static bool AProperty => throw null; + } - "; + public interface IProgram + { + public static abstract bool {|#0:StaticMethod|}(); + public static abstract bool {|#1:AProperty|} { {|#2:get|}; } + } + } - await TestCS(csInput); + "; + var test = TestCSPreview(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.StaticAbstractIsPreviewFeatureRule).WithLocation(0).WithArguments("StaticMethod")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.StaticAbstractIsPreviewFeatureRule).WithLocation(1).WithArguments("AProperty")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.StaticAbstractIsPreviewFeatureRule).WithLocation(2).WithArguments("get")); + await test.RunAsync(); } - [Fact(Skip = "Not yet working")] - public async Task TestPreviewLanguageFeatures() + [Fact] + public async Task TestMarkedPreviewInterface() { var csInput = @" using System.Runtime.Versioning; using System; @@ -490,225 +551,210 @@ static void Main(string[] args) new Program(); } - public static bool StaticMethod() => throw null; - public static bool AProperty => throw null; + public void {|#0:UnmarkedMethodInMarkedInterface|}() { } + } + [RequiresPreviewFeatures] public interface IProgram { - public static abstract bool [|StaticMethod|](); - public static abstract bool [|AProperty|] { [|get|]; } + public void UnmarkedMethodInMarkedInterface() { } } } "; - await TestCSPreview(csInput); - } - - [Fact] - public async Task TestMarkedPreviewInterface() - { - var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + -@" - - class Program : IProgram - { - static void Main(string[] args) - { - new Program(); - } - - public void [|UnmarkedMethodInMarkedInterface|]() { } - - } - - [RequiresPreviewFeatures] - public interface IProgram - { - public void UnmarkedMethodInMarkedInterface() { } - } -} - - "; - - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("UnmarkedMethodInMarkedInterface")); + await test.RunAsync(); } [Fact] public async Task TestMarkedEmptyPreviewInterface() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class [|Program|] : IProgram - { - static void Main(string[] args) - { - new Program(); - } - } + class {|#0:Program|} : IProgram + { + static void Main(string[] args) + { + new Program(); + } + } - [RequiresPreviewFeatures] - public interface IProgram - { - } -} + [RequiresPreviewFeatures] + public interface IProgram + { + } + } - "; + "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.ImplementsEmptyPreviewInterfaceRule).WithLocation(0).WithArguments("Program")); + await test.RunAsync(); } [Fact] public async Task TestInterfaceMethodInvocation() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program : IProgram - { - static void Main(string[] args) - { - Program progObject = new Program(); - IProgram prog = progObject; - [|prog.Foo()|]; - [|prog.FooDelegate()|]; - bool prop = [|prog.AProperty|]; - bool anotherProp = [|progObject.AnotherInterfaceProperty|]; - Console.WriteLine(""prop.ToString() + anotherProp.ToString()""); - } + class Program : IProgram + { + static void Main(string[] args) + { + Program progObject = new Program(); + IProgram prog = progObject; + {|#0:prog.Foo()|}; + {|#1:prog.FooDelegate()|}; + bool prop = {|#2:prog.AProperty|}; + bool anotherProp = {|#3:progObject.AnotherInterfaceProperty|}; + Console.WriteLine(""prop.ToString() + anotherProp.ToString()""); + } - public IProgram.IProgramDelegate [|FooDelegate|]() - { - throw new NotImplementedException(); - } + public IProgram.IProgramDelegate {|#4:FooDelegate|}() + { + throw new NotImplementedException(); + } - [RequiresPreviewFeatures] - public bool AnotherInterfaceProperty { get; set; } - } + [RequiresPreviewFeatures] + public bool AnotherInterfaceProperty { get; set; } + } - public interface IProgram - { - [RequiresPreviewFeatures] - public bool AProperty => true; + public interface IProgram + { + [RequiresPreviewFeatures] + public bool AProperty => true; - public bool AnotherInterfaceProperty { get; set; } + public bool AnotherInterfaceProperty { get; set; } - public delegate void IProgramDelegate(); + public delegate void IProgramDelegate(); - [RequiresPreviewFeatures] - public void Foo() - { - throw new NotImplementedException(); - } + [RequiresPreviewFeatures] + public void Foo() + { + throw new NotImplementedException(); + } - [RequiresPreviewFeatures] - public IProgramDelegate FooDelegate(); + [RequiresPreviewFeatures] + public IProgramDelegate FooDelegate(); - } -} + } + } - "; + "; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Foo")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(1).WithArguments("FooDelegate")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(2).WithArguments("AProperty")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(3).WithArguments("AnotherInterfaceProperty")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(4).WithArguments("FooDelegate")); + await test.RunAsync(); } [Fact] public async Task TestField() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program - { - [RequiresPreviewFeatures] - private bool _field; + class Program + { + [RequiresPreviewFeatures] + private bool _field; - public Program() - { - [|_field|] = true; - } + public Program() + { + {|#0:_field|} = true; + } - static void Main(string[] args) - { - } - } -}"; + static void Main(string[] args) + { + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("_field")); + await test.RunAsync(); } [Fact] public async Task TestProperty() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program - { - [RequiresPreviewFeatures] - private bool Foo => true; + class Program + { + [RequiresPreviewFeatures] + private bool Foo => true; - [RequiresPreviewFeatures] - public virtual bool AProperty => true; + [RequiresPreviewFeatures] + public virtual bool AProperty => true; - static void Main(string[] args) - { - Program prog = new Program(); - bool foo = [|prog.Foo|]; + static void Main(string[] args) + { + Program prog = new Program(); + bool foo = {|#0:prog.Foo|}; - Derived derived = new Derived(); - bool prop = derived.AProperty; - } - } + Derived derived = new Derived(); + bool prop = derived.AProperty; + } + } - class Derived: Program - { - public override bool [|AProperty|] => true; - } -}"; + class Derived: Program + { + public override bool {|#1:AProperty|} => true; + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Foo")); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(1).WithArguments("AProperty")); + await test.RunAsync(); } [Fact] public async Task TestDelegate() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program - { - [RequiresPreviewFeatures] - public delegate void Del(); + class Program + { + [RequiresPreviewFeatures] + public delegate void Del(); - static void Main(string[] args) - { - Del del = [|new(() => { })|]; - } - } -}"; + static void Main(string[] args) + { + Del del = {|#0:new(() => { })|}; + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Del")); + await test.RunAsync(); } @@ -716,126 +762,133 @@ static void Main(string[] args) public async Task TestEnumValue() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - enum AnEnum - { - [RequiresPreviewFeatures] - Foo, - Bar - } + enum AnEnum + { + [RequiresPreviewFeatures] + Foo, + Bar + } - class Program - { - public Program() - { - } + class Program + { + public Program() + { + } - static void Main(string[] args) - { - AnEnum fooEnum = [|AnEnum.Foo|]; - } - } -}"; + static void Main(string[] args) + { + AnEnum fooEnum = {|#0:AnEnum.Foo|}; + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Foo")); + await test.RunAsync(); } [Fact] public async Task TestEnumValue_NoDiagnostic() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - enum AnEnum - { - Foo, - [RequiresPreviewFeatures] - Bar - } + enum AnEnum + { + Foo, + [RequiresPreviewFeatures] + Bar + } - class Program - { - public Program() - { - } + class Program + { + public Program() + { + } - static void Main(string[] args) - { - AnEnum fooEnum = AnEnum.Foo; - } - } -}"; + static void Main(string[] args) + { + AnEnum fooEnum = AnEnum.Foo; + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + await test.RunAsync(); } [Fact] public async Task TestEnum() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - [RequiresPreviewFeatures] - enum AnEnum - { - Foo, - Bar - } + [RequiresPreviewFeatures] + enum AnEnum + { + Foo, + Bar + } - class Program - { - public Program() - { - } + class Program + { + public Program() + { + } - static void Main(string[] args) - { - AnEnum fooEnum = [|AnEnum.Foo|]; - } - } -}"; + static void Main(string[] args) + { + AnEnum fooEnum = {|#0:AnEnum.Foo|}; + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("Foo")); + await test.RunAsync(); } [Fact] public async Task TestEvent() { var csInput = @" -using System.Runtime.Versioning; using System; -namespace Preview_Feature_Scratch -{" + + using System.Runtime.Versioning; using System; + namespace Preview_Feature_Scratch + {" + @" - class Program - { - public Program() - { - } + class Program + { + public Program() + { + } - public delegate void SampleEventHandler(object sender, bool e); + public delegate void SampleEventHandler(object sender, bool e); - [RequiresPreviewFeatures] - public static event SampleEventHandler SampleEvent; + [RequiresPreviewFeatures] + public static event SampleEventHandler SampleEvent; - static void Main(string[] args) - { - [|SampleEvent|]?.Invoke(new Program(), new bool()); - } - } -}"; + static void Main(string[] args) + { + {|#0:SampleEvent|}?.Invoke(new Program(), new bool()); + } + } + }"; - await TestCS(csInput); + var test = TestCS(csInput); + test.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(DetectPreviewFeatureAnalyzer.GeneralPreviewFeatureAttributeRule).WithLocation(0).WithArguments("SampleEvent")); + await test.RunAsync(); } } } \ No newline at end of file diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index 74530ab189..438d3134a4 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -264,7 +264,7 @@ internal static class WellKnownTypeNames public const string SystemRuntimeCompilerServicesINotifyCompletion = "System.Runtime.CompilerServices.INotifyCompletion"; public const string SystemRuntimeCompilerServicesInternalsVisibleToAttribute = "System.Runtime.CompilerServices.InternalsVisibleToAttribute"; public const string SystemRuntimeCompilerServicesRestrictedInternalsVisibleToAttribute = "System.Runtime.CompilerServices.RestrictedInternalsVisibleToAttribute"; - public const string SystemRuntimeCompilerServicesRuntimeFeatureVirtualStaticsInInterfaces = "System.Runtime.CompilerServices.RuntimeFeature.VirtualStaticsInInterfaces"; + public const string SystemRuntimeCompilerServicesRuntimeFeature = "System.Runtime.CompilerServices.RuntimeFeature"; public const string SystemRuntimeCompilerServicesTypeForwardedToAttribute = "System.Runtime.CompilerServices.TypeForwardedToAttribute"; public const string SystemRuntimeExceptionServicesHandleProcessCorruptedStateExceptionsAttribute = "System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute"; public const string SystemRuntimeInteropServicesCharSet = "System.Runtime.InteropServices.CharSet"; From 12a3544a59e233ea765aee7eec51fdbfb4b22d83 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 15 Jul 2021 09:51:55 -0700 Subject: [PATCH 14/37] Add Logging Analyzer --- .../CSharp/AnalyzerReleases.Unshipped.md | 10 + .../Runtime/LogValuesFormatter.cs | 198 ++++++++++ .../Runtime/LoggerMessageDefineAnalyzer.cs | 372 ++++++++++++++++++ ...icrosoftCodeQualityAnalyzersResources.resx | 46 +++ ...rosoftCodeQualityAnalyzersResources.cs.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.de.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.es.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.fr.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.it.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.ja.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.ko.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.pl.xlf | 75 ++++ ...oftCodeQualityAnalyzersResources.pt-BR.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.ru.xlf | 75 ++++ ...rosoftCodeQualityAnalyzersResources.tr.xlf | 75 ++++ ...tCodeQualityAnalyzersResources.zh-Hans.xlf | 75 ++++ ...tCodeQualityAnalyzersResources.zh-Hant.xlf | 75 ++++ .../Microsoft.CodeAnalysis.NetAnalyzers.md | 60 +++ .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 105 +++++ src/NetAnalyzers/RulesMissingDocumentation.md | 6 +- .../Runtime/LoggerMessageDefineTests.cs | 201 ++++++++++ .../AdditionalMetadataReferences.cs | 3 + .../DiagnosticCategoryAndIdRanges.txt | 6 +- src/Utilities/Compiler/WellKnownTypeNames.cs | 3 + 24 files changed, 1981 insertions(+), 4 deletions(-) create mode 100644 src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs create mode 100644 src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs diff --git a/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md index cdf4f1397e..1bde512058 100644 --- a/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md @@ -1 +1,11 @@ ; Please do not edit this file manually, it should only be updated through code fix application. + +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +CA1727 | Naming | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727) +CA1848 | Performance | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848) +CA2253 | Usage | Info | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253) +CA2254 | Usage | Info | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254) +CA2255 | Usage | Warning | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) \ No newline at end of file diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs new file mode 100644 index 0000000000..bd902a94f9 --- /dev/null +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs @@ -0,0 +1,198 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Globalization; +using System.Text; + +namespace Microsoft.Extensions.Logging +{ + /// + /// Formatter to convert the named format items like {NamedformatItem} to string format. + /// + internal class LogValuesFormatter + { + private const string NullValue = "(null)"; + private static readonly object[] EmptyArray = Array.Empty(); + private static readonly char[] FormatDelimiters = { ',', ':' }; + private readonly string _format; + + public LogValuesFormatter(string format) + { + OriginalFormat = format; + + var sb = new StringBuilder(); + var scanIndex = 0; + var endIndex = format.Length; + + while (scanIndex < endIndex) + { + var openBraceIndex = FindBraceIndex(format, '{', scanIndex, endIndex); + var closeBraceIndex = FindBraceIndex(format, '}', openBraceIndex, endIndex); + + if (closeBraceIndex == endIndex) + { + sb.Append(format, scanIndex, endIndex - scanIndex); + scanIndex = endIndex; + } + else + { + // Format item syntax : { index[,alignment][ :formatString] }. + var formatDelimiterIndex = FindIndexOfAny(format, FormatDelimiters, openBraceIndex, closeBraceIndex); + + sb.Append(format, scanIndex, openBraceIndex - scanIndex + 1); + sb.Append(ValueNames.Count.ToString(CultureInfo.InvariantCulture)); + ValueNames.Add(format.Substring(openBraceIndex + 1, formatDelimiterIndex - openBraceIndex - 1)); + sb.Append(format, formatDelimiterIndex, closeBraceIndex - formatDelimiterIndex + 1); + + scanIndex = closeBraceIndex + 1; + } + } + + _format = sb.ToString(); + } + + public string OriginalFormat { get; private set; } + public List ValueNames { get; } = new List(); + + private static int FindBraceIndex(string format, char brace, int startIndex, int endIndex) + { + // Example: {{prefix{{{Argument}}}suffix}}. + var braceIndex = endIndex; + var scanIndex = startIndex; + var braceOccurrenceCount = 0; + + while (scanIndex < endIndex) + { + if (braceOccurrenceCount > 0 && format[scanIndex] != brace) + { + if (braceOccurrenceCount % 2 == 0) + { + // Even number of '{' or '}' found. Proceed search with next occurrence of '{' or '}'. + braceOccurrenceCount = 0; + braceIndex = endIndex; + } + else + { + // An unescaped '{' or '}' found. + break; + } + } + else if (format[scanIndex] == brace) + { + if (brace == '}') + { + if (braceOccurrenceCount == 0) + { + // For '}' pick the first occurrence. + braceIndex = scanIndex; + } + } + else + { + // For '{' pick the last occurrence. + braceIndex = scanIndex; + } + + braceOccurrenceCount++; + } + + scanIndex++; + } + + return braceIndex; + } + + private static int FindIndexOfAny(string format, char[] chars, int startIndex, int endIndex) + { + var findIndex = format.IndexOfAny(chars, startIndex, endIndex - startIndex); + return findIndex == -1 ? endIndex : findIndex; + } + + public string Format(object[] values) + { + if (values != null) + { + for (int i = 0; i < values.Length; i++) + { + values[i] = FormatArgument(values[i]); + } + } + + return string.Format(CultureInfo.InvariantCulture, _format, values ?? EmptyArray); + } + + internal string Format() + { + return _format; + } + + internal string Format(object arg0) + { + return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0)); + } + + internal string Format(object arg0, object arg1) + { + return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1)); + } + + internal string Format(object arg0, object arg1, object arg2) + { + return string.Format(CultureInfo.InvariantCulture, _format, FormatArgument(arg0), FormatArgument(arg1), FormatArgument(arg2)); + } + + public KeyValuePair GetValue(object[] values, int index) + { + if (index < 0 || index > ValueNames.Count) + { +#pragma warning disable CA2201 // Do not raise reserved exception types + throw new IndexOutOfRangeException(nameof(index)); +#pragma warning restore CA2201 // Do not raise reserved exception types + } + + if (ValueNames.Count > index) + { + return new KeyValuePair(ValueNames[index], values[index]); + } + + return new KeyValuePair("{OriginalFormat}", OriginalFormat); + } + + public IEnumerable> GetValues(object[] values) + { + var valueArray = new KeyValuePair[values.Length + 1]; + for (var index = 0; index != ValueNames.Count; ++index) + { + valueArray[index] = new KeyValuePair(ValueNames[index], values[index]); + } + + valueArray[^1] = new KeyValuePair("{OriginalFormat}", OriginalFormat); + return valueArray; + } + + private static object FormatArgument(object value) + { + if (value == null) + { + return NullValue; + } + + // since 'string' implements IEnumerable, special case it + if (value is string) + { + return value; + } + + // if the value implements IEnumerable, build a comma separated string. + if (value is IEnumerable enumerable) + { + return string.Join(", ", enumerable.Cast().Select(o => o ?? NullValue)); + } + + return value; + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs new file mode 100644 index 0000000000..bcb2d1e74a --- /dev/null +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -0,0 +1,372 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Immutable; +using System.Linq; +using System.Threading; +using Analyzer.Utilities; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeQuality.Analyzers; +using Microsoft.Extensions.Logging; + +namespace Microsoft.NetCore.CSharp.Analyzers.Runtime +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer + { + internal const string CA1727RuleId = "CA1727"; + internal const string CA1848RuleId = "CA1848"; + internal const string CA2253RuleId = "CA2253"; + internal const string CA2254RuleId = "CA2254"; + internal const string CA2255RuleId = "CA2255"; + + private static readonly LocalizableString s_localizableTitleCA1727 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUsePascalCasedLogMessageTokensTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageCA1727 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUsePascalCasedLogMessageTokensMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionCA1727 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUsePascalCasedLogMessageTokensDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + + private static readonly LocalizableString s_localizableTitleCA1848 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUseCompiledLogMessagesTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageCA1848 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUseCompiledLogMessagesMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionCA1848 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUseCompiledLogMessagesDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + + private static readonly LocalizableString s_localizableTitleCA2253 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticNumericsInFormatStringTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageCA2253 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticNumericsInFormatStringMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionCA2253 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticNumericsInFormatStringDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + + private static readonly LocalizableString s_localizableTitleCA2254 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticConcatenationInFormatStringTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageCA2254 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticConcatenationInFormatStringMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionCA2254 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticConcatenationInFormatStringDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + + private static readonly LocalizableString s_localizableTitleCA2255 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageCA2255 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionCA2255 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + + internal static DiagnosticDescriptor CA1727Rule = DiagnosticDescriptorHelper.Create(CA1727RuleId, + s_localizableTitleCA1727, + s_localizableMessageCA1727, + DiagnosticCategory.Naming, + RuleLevel.Disabled, + description: s_localizableDescriptionCA1727, + isPortedFxCopRule: true, + isDataflowRule: false, + // isEnabledByDefaultInAggressiveMode: false, + isReportedAtCompilationEnd: true); + + internal static DiagnosticDescriptor CA1848Rule = DiagnosticDescriptorHelper.Create(CA1848RuleId, + s_localizableTitleCA1848, + s_localizableMessageCA1848, + DiagnosticCategory.Performance, + RuleLevel.Disabled, + description: s_localizableDescriptionCA1848, + isPortedFxCopRule: true, + isDataflowRule: false, + // isEnabledByDefaultInAggressiveMode: false, + isReportedAtCompilationEnd: true); + + internal static DiagnosticDescriptor CA2253Rule = DiagnosticDescriptorHelper.Create(CA2253RuleId, + s_localizableTitleCA2253, + s_localizableMessageCA2253, + DiagnosticCategory.Usage, + RuleLevel.IdeSuggestion, + description: s_localizableDescriptionCA2253, + isPortedFxCopRule: true, + isDataflowRule: false, + isReportedAtCompilationEnd: true); + + internal static DiagnosticDescriptor CA2254Rule = DiagnosticDescriptorHelper.Create(CA2254RuleId, + s_localizableTitleCA2254, + s_localizableMessageCA2254, + DiagnosticCategory.Usage, + RuleLevel.IdeSuggestion, + description: s_localizableDescriptionCA2254, + isPortedFxCopRule: true, + isDataflowRule: false, + isReportedAtCompilationEnd: true); + + internal static DiagnosticDescriptor CA2255Rule = DiagnosticDescriptorHelper.Create(CA2255RuleId, + s_localizableTitleCA2255, + s_localizableMessageCA2255, + DiagnosticCategory.Usage, + RuleLevel.BuildWarning, + description: s_localizableDescriptionCA2255, + isPortedFxCopRule: true, + isDataflowRule: false, + isReportedAtCompilationEnd: true); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(CA1727Rule, CA1848Rule, CA2253Rule, CA2254Rule, CA2255Rule); + + public override void Initialize(AnalysisContext context) + { + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + + context.EnableConcurrentExecution(); + + context.RegisterCompilationStartAction(context => + { + var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation); + + if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftExtensionsLoggingLoggerExtensions, out var loggerExtensionsType) || + !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftExtensionsLoggingILogger, out var loggerType) || + !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftExtensionsLoggingLoggerMessage, out var loggerMessageType)) + { + return; + } + + context.RegisterSyntaxNodeAction(context => AnalyzeInvocation(context, loggerType, loggerExtensionsType, loggerMessageType), SyntaxKind.InvocationExpression); + }); + } + + private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxContext, INamedTypeSymbol loggerType, INamedTypeSymbol loggerExtensionsType, INamedTypeSymbol loggerMessageType) + { + var invocation = (InvocationExpressionSyntax)syntaxContext.Node; + + var symbolInfo = ModelExtensions.GetSymbolInfo(syntaxContext.SemanticModel, invocation, syntaxContext.CancellationToken); + if (symbolInfo.Symbol?.Kind != SymbolKind.Method) + { + return; + } + + var methodSymbol = (IMethodSymbol)symbolInfo.Symbol; + + if (methodSymbol.ContainingType == loggerExtensionsType) + { + syntaxContext.ReportDiagnostic(Diagnostic.Create(CA1848Rule, invocation.GetLocation(), methodSymbol.Name)); + } + else if (!methodSymbol.ContainingType.Equals(loggerType) && !methodSymbol.ContainingType.Equals(loggerMessageType)) + { + return; + } + + if (FindLogParameters(methodSymbol, out var messageArgument, out var paramsArgument)) + { + int paramsCount = 0; + ExpressionSyntax? formatExpression = null; + bool argsIsArray = false; + + if (methodSymbol.ContainingType == loggerMessageType) + { + // For LoggerMessage.Define, count type parameters on the invocation instead of arguments + paramsCount = methodSymbol.TypeParameters.Length; + var arg = invocation.ArgumentList.Arguments.FirstOrDefault(argument => + { + var parameter = DetermineParameter(argument, syntaxContext.SemanticModel, syntaxContext.CancellationToken); + return Equals(parameter, messageArgument); + }); + formatExpression = arg.Expression; + } + else + { + foreach (var argument in invocation.ArgumentList.Arguments) + { + var parameter = DetermineParameter(argument, syntaxContext.SemanticModel, syntaxContext.CancellationToken); + if (Equals(parameter, messageArgument)) + { + formatExpression = argument.Expression; + } + else if (Equals(parameter, paramsArgument)) + { + var parameterType = syntaxContext.SemanticModel.GetTypeInfo(argument.Expression).ConvertedType; + if (parameterType == null) + { + return; + } + + //Detect if current argument can be passed directly to args + argsIsArray = parameterType.TypeKind == TypeKind.Array && ((IArrayTypeSymbol)parameterType).ElementType.SpecialType == SpecialType.System_Object; + + paramsCount++; + } + } + } + + if (formatExpression is not null) + { + AnalyzeFormatArgument(syntaxContext, formatExpression, paramsCount, argsIsArray); + } + } + } + + private void AnalyzeFormatArgument(SyntaxNodeAnalysisContext syntaxContext, ExpressionSyntax formatExpression, int paramsCount, bool argsIsArray) + { + var text = TryGetFormatText(formatExpression, syntaxContext.SemanticModel); + if (text == null) + { + syntaxContext.ReportDiagnostic(Diagnostic.Create(CA2254Rule, formatExpression.GetLocation())); + return; + } + + LogValuesFormatter formatter; + try + { + formatter = new LogValuesFormatter(text); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types + { + return; + } + + foreach (var valueName in formatter.ValueNames) + { + if (int.TryParse(valueName, out _)) + { + syntaxContext.ReportDiagnostic(Diagnostic.Create(CA2253Rule, formatExpression.GetLocation())); + } + else if (char.IsLower(valueName[0])) + { + syntaxContext.ReportDiagnostic(Diagnostic.Create(CA1727Rule, formatExpression.GetLocation())); + } + } + + var argsPassedDirectly = argsIsArray && paramsCount == 1; + if (!argsPassedDirectly && paramsCount != formatter.ValueNames.Count) + { + syntaxContext.ReportDiagnostic(Diagnostic.Create(CA2255Rule, formatExpression.GetLocation())); + } + } + + private string? TryGetFormatText(ExpressionSyntax? argumentExpression, SemanticModel semanticModel) + { + if (argumentExpression is null) + return null; + + switch (argumentExpression) + { + case LiteralExpressionSyntax literal when literal.Token.IsKind(SyntaxKind.StringLiteralToken): + return literal.Token.ValueText; + case InterpolatedStringExpressionSyntax interpolated: + var text = ""; + foreach (var interpolatedStringContentSyntax in interpolated.Contents) + { + if (interpolatedStringContentSyntax is InterpolatedStringTextSyntax textSyntax) + { + text += textSyntax.TextToken.ValueText; + } + else + { + return null; + } + } + return text; + case InvocationExpressionSyntax invocation when IsNameOfInvocation(invocation): + // return placeholder from here because actual value is not required for analysis and is hard to get + return "NAMEOF"; + case ParenthesizedExpressionSyntax parenthesized: + return TryGetFormatText(parenthesized.Expression, semanticModel); + case BinaryExpressionSyntax binary when binary.OperatorToken.IsKind(SyntaxKind.PlusToken): + var leftText = TryGetFormatText(binary.Left, semanticModel); + var rightText = TryGetFormatText(binary.Right, semanticModel); + + if (leftText != null && rightText != null) + { + return leftText + rightText; + } + + return null; + default: + var constant = semanticModel.GetConstantValue(argumentExpression); + if (constant.HasValue && constant.Value is string constantString) + { + return constantString; + } + return null; + } + } + + private static bool FindLogParameters(IMethodSymbol methodSymbol, out IParameterSymbol? message, out IParameterSymbol? arguments) + { + message = null; + arguments = null; + foreach (var parameter in methodSymbol.Parameters) + { + if (parameter.Type.SpecialType == SpecialType.System_String && + string.Equals(parameter.Name, "message", StringComparison.Ordinal) || + string.Equals(parameter.Name, "messageFormat", StringComparison.Ordinal) || + string.Equals(parameter.Name, "formatString", StringComparison.Ordinal)) + { + message = parameter; + } + + // When calling logger.BeginScope("{Param}") generic overload would be selected + if (parameter.Type.SpecialType == SpecialType.System_String && + methodSymbol.Name.Equals("BeginScope") && + string.Equals(parameter.Name, "state", StringComparison.Ordinal)) + { + message = parameter; + } + + if (parameter.IsParams && + string.Equals(parameter.Name, "args", StringComparison.Ordinal)) + { + arguments = parameter; + } + } + return message != null; + } + + private static bool IsNameOfInvocation(InvocationExpressionSyntax invocation) + { + return invocation.Expression is IdentifierNameSyntax identifierName && + (identifierName.Identifier.IsKind(SyntaxKind.NameOfKeyword) || + identifierName.Identifier.ToString() == SyntaxFacts.GetText(SyntaxKind.NameOfKeyword)); + } + + private static IParameterSymbol? DetermineParameter( + ArgumentSyntax argument, + SemanticModel semanticModel, + CancellationToken cancellationToken) + { + if (argument.Parent is not BaseArgumentListSyntax argumentList) + { + return null; + } + + if (argumentList.Parent is not ExpressionSyntax invocableExpression) + { + return null; + } + + if (semanticModel.GetSymbolInfo(invocableExpression, cancellationToken).Symbol is not IMethodSymbol symbol) + { + return null; + } + + var parameters = symbol.Parameters; + + // Handle named argument + if (argument.NameColon != null && !argument.NameColon.IsMissing) + { + var name = argument.NameColon.Name.Identifier.ValueText; + return parameters.FirstOrDefault(p => p.Name == name); + } + + // Handle positional argument + var index = argumentList.Arguments.IndexOf(argument); + if (index < 0) + { + return null; + } + + if (index < parameters.Length) + { + return parameters[index]; + } + + var lastParameter = parameters.LastOrDefault(); + if (lastParameter == null) + { + return null; + } + + if (lastParameter.IsParams) + { + return lastParameter; + } + + return null; + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx index 9e261c345b..5729773054 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx @@ -171,6 +171,52 @@ Abstract type '{0}' should not have public constructors + + Numerics should not be used in logging format string + + + Numerics should not be used in logging format string + + + Numerics should not be used in logging format string + + + Logging format string parameter count mismatch + + + Logging format string parameter count mismatch + + + Logging format string parameter count mismatch + + + Use compiled log messages + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + Logging format string should not be dynamically generated + + + Logging format string should not be dynamically generated + + + Logging format string should not be dynamically generated + + + Use PascalCase for log message tokens + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + Mark assemblies with CLSCompliant diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf index 87b8206176..bd5d9479b7 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf @@ -242,6 +242,81 @@ Odeberte finalizační metodu z typu {0}, přepište Dispose(bool disposing) a vložte finalizační logiku do cesty kódu, kde je disposing hodnoty false. V opačném případě by to mohlo vést k duplicitním voláním Dispose, protože základní typ {1} také poskytuje finalizační metodu. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Použít AttributeUsageAttribute diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf index d359c6a1d5..cb89a972b3 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf @@ -242,6 +242,81 @@ Entfernen Sie den Finalizer vom Typ "{0}", setzen Sie "Dispose(bool disposing)" außer Kraft, und platzieren Sie die Finalisierungslogik im Codepfad, wenn "disposing" FALSE lautet. Andernfalls kann es zu doppelten Dispose-Aufrufen kommen, weil der Basistyp "{1}" ebenfalls einen Finalizer bereitstellt. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' "AttributeUsageAttribute" anwenden diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf index e9dbcc7d38..a9272a9b3c 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf @@ -242,6 +242,81 @@ Elimine el finalizador del tipo "{0}", reemplace el valor de "Dispose(bool disposing)" y coloque la lógica de finalización en la ruta de código de manera que el valor de "disposing" se establezca como falso. De lo contrario, se duplicarían las invocaciones de "Dispose" ya que el tipo Base "{1}" también ofrece un finalizador. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Aplicar "AttributeUsageAttribute" diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf index be3e3f97ef..8c02a4bbc3 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf @@ -242,6 +242,81 @@ Supprimez le finaliseur du type '{0}', remplacez Dispose(bool disposing) et placez la logique de finalisation dans le chemin de code où 'disposing' est false. Sinon, vous risquez d'avoir des invocations de Dispose en double, car le type de base '{1}' fournit aussi un finaliseur. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Appliquer 'AttributeUsageAttribute' diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf index b769feac85..d5eca7c316 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf @@ -242,6 +242,81 @@ Rimuovere il finalizzatore dal tipo '{0}', eseguire l'override di Dispose(bool disposing) e inserire la logica di finalizzazione nel percorso del codice in cui 'disposing' è false. In caso contrario, potrebbero verificarsi chiamate duplicate a Dispose perché il tipo di base '{1}' fornisce anche un finalizzatore. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Applica 'AttributeUsageAttribute' diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf index ab418f7a76..a09b9ee5a9 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf @@ -242,6 +242,81 @@ 型 '{0}' からファイナライザーを削除し、Dispose(bool disposing) をオーバーライドします。その後、'disposing' が false のコード パスに finalization 論理を配置します。その他の場合、基本型 '{1}' でもファイナライザーが提供されるため、Dispose 呼び出しが重複する可能性があります。 + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' 'AttributeUsageAttribute' の適用 diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf index 55def52730..e334404cd8 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf @@ -242,6 +242,81 @@ '{0}' 형식에서 종료자를 제거하고 Dispose(bool disposing)를 재정의한 후 종료 논리를 'disposing'이 false인 코드 경로에 추가하세요. 그렇지 않으면, 기본 형식 '{1}'도 종료자를 제공할 때 중복된 Dispose 호출이 발생할 수 있습니다. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' 'AttributeUsageAttribute' 적용 diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf index 40079f3b0f..2df6763d77 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf @@ -242,6 +242,81 @@ Usuń finalizator z typu „{0}”, przesłoń funkcję Dispose(bool disposing) i umieść logikę finalizacji w ścieżce kodu, gdzie element „disposing” ma wartość false. W przeciwnym razie mogą pojawić się zduplikowane wywołania funkcji Dispose, ponieważ typ bazowy „{1}” także udostępnia finalizator. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Zastosuj element „AttributeUsageAttribute” diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf index a8122ce931..88b1309650 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf @@ -242,6 +242,81 @@ Remova o finalizador do tipo '{0}', substitua Dispose(bool disposing) e coloque a lógica de finalização no caminho do código em que 'disposing' é false. Caso contrário, ele poderá duplicar invocações Dispose, já que o tipo Base '{1}' também fornece um finalizador. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Aplicar 'AttributeUsageAttribute' diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf index bb97a74a40..b06380cac2 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf @@ -242,6 +242,81 @@ Удалите метод завершения из типа '{0}', переопределите Dispose(bool disposing) и поместите логику завершения в путь кода, туда где 'disposing' имеет значение false. В противном случае это может привести к дублированию вызовов метода Dispose, так как базовый тип '{1}' также предоставляет метод завершения. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' Применить "AttributeUsageAttribute" diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf index e4c6f74dba..99c2363f22 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf @@ -242,6 +242,81 @@ '{0}' türünden sonlandırıcıyı kaldırın, Dispose(bool disposing) metodunu geçersiz kılın ve sonlandırma mantığını 'disposing' değerinin false olduğu kod yoluna yerleştirin. Aksi takdirde, '{1}' Temel türü de bir sonlandırıcı sağladığından yinelenen Dispose çağrılarına yol açabilir. + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' 'AttributeUsageAttribute' uygula diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf index 3509e1072b..8d26bd9fbf 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf @@ -242,6 +242,81 @@ 从类型“{0}”中删除终结器,替代 Dispose(bool disposing),并在 "disposing" 为 false 的代码路径中放置终结逻辑。否则,它可能导致出现重复的 Dispose 调用,因为基类型“{1}”也提供终结器。 + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' 应用 "AttributeUsageAttribute" diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf index 6d0827b7af..ce8145974d 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf @@ -242,6 +242,81 @@ 從類型 '{0}' 移除完成項,覆寫 Dispose(bool disposing),然後在程式碼路徑中放置完成項邏輯,其中 'disposing' 為 false。否則這可能導致 Dispose 引動過程重複,原因是基底類型 ‘{1}’ 也提供了完成項。 + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string should not be dynamically generated + Logging format string should not be dynamically generated + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Logging format string parameter count mismatch + Logging format string parameter count mismatch + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + Numerics should not be used in logging format string + Numerics should not be used in logging format string + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + + + + Use compiled log messages + Use compiled log messages + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + + + + Use PascalCase for log message tokens + Use PascalCase for log message tokens + + Apply 'AttributeUsageAttribute' 套用 'AttributeUsageAttribute' diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index fa2136ccfd..d31c8ba91e 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -972,6 +972,18 @@ Consistent naming of parameters in an override hierarchy increases the usability |CodeFix|True| --- +## [CA1727](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727): Use PascalCase for log message tokens + +For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + +|Item|Value| +|-|-| +|Category|Naming| +|Enabled|False| +|Severity|Warning| +|CodeFix|False| +--- + ## [CA1802](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1802): Use literals where appropriate A field is declared static and read-only (Shared and ReadOnly in Visual Basic), and is initialized by using a value that is computable at compile time. Because the value that is assigned to the targeted field is computable at compile time, change the declaration to a const (Const in Visual Basic) field so that the value is computed at compile time instead of at run?time. @@ -1428,6 +1440,18 @@ It is more efficient to use 'AsSpan' and 'string.Concat', instead of 'Substring' |CodeFix|True| --- +## [CA1848](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848): Use compiled log messages + +For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + +|Item|Value| +|-|-| +|Category|Performance| +|Enabled|False| +|Severity|Warning| +|CodeFix|False| +--- + ## [CA2000](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2000): Dispose objects before losing scope If a disposable object is not explicitly disposed before all references to it are out of scope, the object will be disposed at some indeterminate time when the garbage collector runs the finalizer of the object. Because an exceptional event might occur that will prevent the finalizer of the object from running, the object should be explicitly disposed instead. @@ -2016,6 +2040,42 @@ An assembly has to opt into preview features before using them. |CodeFix|False| --- +## [CA2253](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253): Numerics should not be used in logging format string + +Numerics should not be used in logging format string + +|Item|Value| +|-|-| +|Category|Usage| +|Enabled|True| +|Severity|Info| +|CodeFix|False| +--- + +## [CA2254](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254): Logging format string should not be dynamically generated + +Logging format string should not be dynamically generated + +|Item|Value| +|-|-| +|Category|Usage| +|Enabled|True| +|Severity|Info| +|CodeFix|False| +--- + +## [CA2255](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255): Logging format string parameter count mismatch + +Logging format string parameter count mismatch + +|Item|Value| +|-|-| +|Category|Usage| +|Enabled|True| +|Severity|Warning| +|CodeFix|False| +--- + ## [CA2300](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2300): Do not use insecure deserializer BinaryFormatter The method '{0}' is insecure when deserializing untrusted data. If you need to instead detect BinaryFormatter deserialization without a SerializationBinder set, then disable rule CA2300, and enable rules CA2301 and CA2302. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 9f2435c84c..8cfe91d34c 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -107,6 +107,27 @@ ] } }, + "CA1727": { + "id": "CA1727", + "shortDescription": "Use PascalCase for log message tokens", + "fullDescription": "For consistency with logs emitted from other components, use 'PascalCase' for log message tokens", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727", + "properties": { + "category": "Naming", + "isEnabledByDefault": false, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "PortedFromFxCop", + "Telemetry", + "EnabledRuleInAggressiveMode", + "CompilationEnd" + ] + } + }, "CA1802": { "id": "CA1802", "shortDescription": "Use literals where appropriate", @@ -246,6 +267,27 @@ ] } }, + "CA1848": { + "id": "CA1848", + "shortDescription": "Use compiled log messages", + "fullDescription": "For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848", + "properties": { + "category": "Performance", + "isEnabledByDefault": false, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "PortedFromFxCop", + "Telemetry", + "EnabledRuleInAggressiveMode", + "CompilationEnd" + ] + } + }, "CA2014": { "id": "CA2014", "shortDescription": "Do not use stackalloc in loops", @@ -304,6 +346,69 @@ ] } }, + "CA2253": { + "id": "CA2253", + "shortDescription": "Numerics should not be used in logging format string", + "fullDescription": "Numerics should not be used in logging format string", + "defaultLevel": "note", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "PortedFromFxCop", + "Telemetry", + "EnabledRuleInAggressiveMode", + "CompilationEnd" + ] + } + }, + "CA2254": { + "id": "CA2254", + "shortDescription": "Logging format string should not be dynamically generated", + "fullDescription": "Logging format string should not be dynamically generated", + "defaultLevel": "note", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "PortedFromFxCop", + "Telemetry", + "EnabledRuleInAggressiveMode", + "CompilationEnd" + ] + } + }, + "CA2255": { + "id": "CA2255", + "shortDescription": "Logging format string parameter count mismatch", + "fullDescription": "Logging format string parameter count mismatch", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#" + ], + "tags": [ + "PortedFromFxCop", + "Telemetry", + "EnabledRuleInAggressiveMode", + "CompilationEnd" + ] + } + }, "CA2352": { "id": "CA2352", "shortDescription": "Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks", diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index c6eb1c62bb..7ded8fe098 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -4,9 +4,13 @@ Rule ID | Missing Help Link | Title | --------|-------------------|-------| CA1418 | | Use valid platform string | CA1419 | | Provide a public parameterless constructor for concrete types derived from 'System.Runtime.InteropServices.SafeHandle' | +CA1727 | | Use PascalCase for log message tokens | CA1839 | | Use 'Environment.ProcessPath' | CA1840 | | Use 'Environment.CurrentManagedThreadId' | CA1842 | | Do not use 'WhenAll' with a single task | CA1843 | | Do not use 'WaitAll' with a single task | -CA2251 | | Use 'string.Equals' | +CA1848 | | Use compiled log messages | CA2252 | | This API requires opting into preview features | +CA2253 | | Numerics should not be used in logging format string | +CA2254 | | Logging format string should not be dynamically generated | +CA2255 | | Logging format string parameter count mismatch | diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs new file mode 100644 index 0000000000..3aa66814c3 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -0,0 +1,201 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.Text; +using Test.Utilities; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.NetCore.CSharp.Analyzers.Runtime.LoggerMessageDefineAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.Extensions.Logging.Analyzer +{ + public class FormatStringAnalyzerTests + { + [Theory] + [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA2253:""{0}""|}", "1")] + public async Task CA2253IsProducedForNumericFormatArgument(string format) + { + // Make sure CA1727 is enabled for this test so we can verify it does not trigger on numeric arguments. + await TriggerCodeAsync(format); + } + + [Theory] + [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @"{|CA2254:$""{string.Empty}""|}", "")] + [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @"{|CA2254:""string"" + 2|}", "")] + public async Task CA2254IsProducedForDynamicFormatArgument(string format) + { + await TriggerCodeAsync(format); + } + + [Theory] + [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{string}""|}|}", "1, 2", 2)] + [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", "1, 2", 2)] + [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs_IgnoresCA1848ForBeginScope), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", "", 0)] + [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs_IgnoresCA1848ForBeginScope), @"{|CA2255:{|CA1727:""{"" + Const + ""}""|}|}", "", 0)] + public async Task CA2255IsProducedForFormatArgumentCountMismatch(string format) + { + await TriggerCodeAsync(format); + } + + [Theory] + [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:""{camelCase}""|}", "1")] + public async Task CA1727IsProducedForCamelCasedFormatArgument(string format) + { + await TriggerCodeAsync(format); + } + + [Theory] + // Concat would be optimized by compiler + [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @"nameof(ILogger) + "" string""", "")] + [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @""" string"" + "" string""", "")] + [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @"$"" string"" + $"" string""", "")] + [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:""{st"" + ""ring}""|}", "1")] + + // we are unable to parse expressions + [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:{|CA1727:""{string} {string}""|}|}", "new object[] { 1 }")] + + // CA2253 is not enabled by default. + [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:""{camelCase}""|}", "1")] + public async Task TemplateDiagnosticsAreNotProduced(string format) + { + await TriggerCodeAsync(format); + } + + [Theory] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.DefineScope({|CA2255:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.DefineScope({|CA2255:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.DefineScope({|CA2255:""{One} {Two}""|});")] + public async Task CA2255IsProducedForDefineMessageTypeParameterMismatch(string expression) + { + await TriggerCodeAsync(expression); + } + + [Theory] + [InlineData("LogTrace", @"""This is a test {Message}""")] + [InlineData("LogDebug", @"""This is a test {Message}""")] + [InlineData("LogInformation", @"""This is a test {Message}""")] + [InlineData("LogWarning", @"""This is a test {Message}""")] + [InlineData("LogError", @"""This is a test {Message}""")] + [InlineData("LogCritical", @"""This is a test {Message}""")] + [InlineData("BeginScope", @"""This is a test {Message}""")] + public async Task CA1848IsProducedForInvocationsOfAllLoggerExtensions(string method, string template) + { + var expression = @$"{{|CA1848:logger.{method}({template},""Foo"")|}};"; + await TriggerCodeAsync(expression); + } + + public static IEnumerable GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope(string template, string arguments) + { + return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: true).Concat(GenerateDefineUsages(template)); + } + + public static IEnumerable GenerateTemplateAndDefineUsages(string template, string arguments) + { + return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: false).Concat(GenerateDefineUsages(template)); + } + + public static IEnumerable GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs_IgnoresCA1848ForBeginScope(string template, string arguments, int numArgs) + { + return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: true).Concat(GenerateDefineUsages(template, numArgs)); + } + + public static IEnumerable GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs(string template, string arguments, int numArgs) + { + return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: false).Concat(GenerateDefineUsages(template, numArgs)); + } + + private static IEnumerable GenerateDefineUsages(string template, int numArgs = -1) + { + TestFileMarkupParser.GetSpans(template, out _, out ImmutableDictionary> spans); + var spanCount = spans.Sum(pair => string.IsNullOrEmpty(pair.Key) ? 0 : pair.Value.Count()); + + var numberOfArguments = template.Count(c => c == '{') - spanCount; + if (numArgs != -1) + { + numberOfArguments = numArgs; + } + + yield return new[] { $"LoggerMessage.{GenerateGenericInvocation(numberOfArguments, "DefineScope")}({template});" }; + yield return new[] { $"LoggerMessage.{GenerateGenericInvocation(numberOfArguments, "Define")}(LogLevel.Information, 42, {template});" }; + } + + public static IEnumerable GenerateTemplateUsages(string template, string arguments, bool ignoreCA1848ForBeginScope) + { + var templateAndArguments = template; + if (!string.IsNullOrEmpty(arguments)) + { + templateAndArguments = $"{template}, {arguments}"; + } + var methods = new[] { "LogTrace", "LogError", "LogWarning", "LogInformation", "LogDebug", "LogCritical" }; + var formats = new[] + { + "", + "0, ", + "1, new System.Exception(), ", + "2, null, " + }; + foreach (var method in methods) + { + foreach (var format in formats) + { + yield return new[] { $"{{|CA1848:logger.{method}({format}{templateAndArguments})|}};" }; + } + } + + if (ignoreCA1848ForBeginScope) + { + yield return new[] { $"logger.BeginScope({templateAndArguments});" }; + } + else + { + yield return new[] { $"{{|CA1848:logger.BeginScope({templateAndArguments})|}};" }; + } + } + + private static string GenerateGenericInvocation(int i, string method) + { + if (i > 0) + { + var types = string.Join(", ", Enumerable.Range(0, i).Select(_ => "int")); + method += $"<{types}>"; + } + + return method; + } + + private async Task TriggerCodeAsync(string expression) + { + string code = @$" +using Microsoft.Extensions.Logging; +public class Program +{{ + public const string Const = ""const""; + public static void Main() + {{ + ILogger logger = null; + {expression} + }} +}}"; + await new VerifyCS.Test + { + LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9, + TestState = + { + Sources = { code } + }, + ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithMELogging, + }.RunAsync(); + } + } +} \ No newline at end of file diff --git a/src/Test.Utilities/AdditionalMetadataReferences.cs b/src/Test.Utilities/AdditionalMetadataReferences.cs index a004c22362..ef10c88230 100644 --- a/src/Test.Utilities/AdditionalMetadataReferences.cs +++ b/src/Test.Utilities/AdditionalMetadataReferences.cs @@ -39,6 +39,9 @@ public static class AdditionalMetadataReferences public static ReferenceAssemblies DefaultWithNewtonsoftJson12 { get; } = Default .AddPackages(ImmutableArray.Create(new PackageIdentity("Newtonsoft.Json", "12.0.1"))); + public static ReferenceAssemblies DefaultWithMELogging { get; } = Default + .AddPackages(ImmutableArray.Create(new PackageIdentity("Microsoft.Extensions.Logging", "5.0.0"))); + public static ReferenceAssemblies DefaultWithWinForms { get; } = ReferenceAssemblies.NetFramework.Net472.WindowsForms; public static ReferenceAssemblies DefaultWithWinHttpHandler { get; } = ReferenceAssemblies.NetStandard.NetStandard20 diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index 2277f4be70..7b74f90ea2 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -12,10 +12,10 @@ Design: CA2210, CA1000-CA1070 Globalization: CA2101, CA1300-CA1310 Mobility: CA1600-CA1601 -Performance: HA, CA1800-CA1847 +Performance: HA, CA1800-CA1848 Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5403 -Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2252 -Naming: CA1700-CA1726 +Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2255 +Naming: CA1700-CA1727 Interoperability: CA1400-CA1419 Maintainability: CA1500-CA1509 Reliability: CA9998-CA9999, CA2000-CA2016 diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index 438d3134a4..bf044d19b1 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -62,6 +62,9 @@ internal static class WellKnownTypeNames public const string MicrosoftCodeAnalysisVisualBasicExtensions = "Microsoft.CodeAnalysis.VisualBasicExtensions"; public const string MicrosoftEntityFrameworkCoreEntityFrameworkQueryableExtensions = "Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions"; public const string MicrosoftEntityFrameworkCoreRelationalQueryableExtensions = "Microsoft.EntityFrameworkCore.RelationalQueryableExtensions"; + public const string MicrosoftExtensionsLoggingILogger = "Microsoft.Extensions.Logging.ILogger"; + public const string MicrosoftExtensionsLoggingLoggerExtensions = "Microsoft.Extensions.Logging.LoggerExtensions"; + public const string MicrosoftExtensionsLoggingLoggerMessage = "Microsoft.Extensions.Logging.LoggerMessage"; public const string MicrosoftSecurityApplicationAntiXss = "Microsoft.Security.Application.AntiXss"; public const string MicrosoftSecurityApplicationAntiXssEncoder = "Microsoft.Security.Application.AntiXssEncoder"; public const string MicrosoftSecurityApplicationEncoder = "Microsoft.Security.Application.Encoder"; From 6c5e4ad8ea85a3dd3e333d4ff675986db3928a7c Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 15 Jul 2021 10:38:09 -0700 Subject: [PATCH 15/37] Convert to IOperation analysis --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 140 +++++------------- 1 file changed, 35 insertions(+), 105 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index bcb2d1e74a..1abe97c6cb 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -3,12 +3,10 @@ using System; using System.Collections.Immutable; using System.Linq; -using System.Threading; using Analyzer.Utilities; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; -using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeQuality.Analyzers; using Microsoft.Extensions.Logging; @@ -114,25 +112,19 @@ public override void Initialize(AnalysisContext context) return; } - context.RegisterSyntaxNodeAction(context => AnalyzeInvocation(context, loggerType, loggerExtensionsType, loggerMessageType), SyntaxKind.InvocationExpression); + context.RegisterOperationAction(context => AnalyzeInvocation(context, loggerType, loggerExtensionsType, loggerMessageType), OperationKind.Invocation); }); } - private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxContext, INamedTypeSymbol loggerType, INamedTypeSymbol loggerExtensionsType, INamedTypeSymbol loggerMessageType) + private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbol loggerType, INamedTypeSymbol loggerExtensionsType, INamedTypeSymbol loggerMessageType) { - var invocation = (InvocationExpressionSyntax)syntaxContext.Node; + var invocation = (IInvocationOperation)context.Operation; - var symbolInfo = ModelExtensions.GetSymbolInfo(syntaxContext.SemanticModel, invocation, syntaxContext.CancellationToken); - if (symbolInfo.Symbol?.Kind != SymbolKind.Method) - { - return; - } - - var methodSymbol = (IMethodSymbol)symbolInfo.Symbol; + var methodSymbol = invocation.TargetMethod; if (methodSymbol.ContainingType == loggerExtensionsType) { - syntaxContext.ReportDiagnostic(Diagnostic.Create(CA1848Rule, invocation.GetLocation(), methodSymbol.Name)); + context.ReportDiagnostic(Diagnostic.Create(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); } else if (!methodSymbol.ContainingType.Equals(loggerType) && !methodSymbol.ContainingType.Equals(loggerMessageType)) { @@ -142,32 +134,32 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxContext, INamedTy if (FindLogParameters(methodSymbol, out var messageArgument, out var paramsArgument)) { int paramsCount = 0; - ExpressionSyntax? formatExpression = null; + IOperation? formatExpression = null; bool argsIsArray = false; if (methodSymbol.ContainingType == loggerMessageType) { // For LoggerMessage.Define, count type parameters on the invocation instead of arguments paramsCount = methodSymbol.TypeParameters.Length; - var arg = invocation.ArgumentList.Arguments.FirstOrDefault(argument => + var arg = invocation.Arguments.FirstOrDefault(argument => { - var parameter = DetermineParameter(argument, syntaxContext.SemanticModel, syntaxContext.CancellationToken); + var parameter = argument.Parameter; return Equals(parameter, messageArgument); }); - formatExpression = arg.Expression; + formatExpression = arg.Value; } else { - foreach (var argument in invocation.ArgumentList.Arguments) + foreach (var argument in invocation.Arguments) { - var parameter = DetermineParameter(argument, syntaxContext.SemanticModel, syntaxContext.CancellationToken); + var parameter = argument.Parameter; if (Equals(parameter, messageArgument)) { - formatExpression = argument.Expression; + formatExpression = argument.Value; } else if (Equals(parameter, paramsArgument)) { - var parameterType = syntaxContext.SemanticModel.GetTypeInfo(argument.Expression).ConvertedType; + var parameterType = argument.Parameter.Type;// TODO test if (parameterType == null) { return; @@ -183,17 +175,17 @@ private void AnalyzeInvocation(SyntaxNodeAnalysisContext syntaxContext, INamedTy if (formatExpression is not null) { - AnalyzeFormatArgument(syntaxContext, formatExpression, paramsCount, argsIsArray); + AnalyzeFormatArgument(context, formatExpression, paramsCount, argsIsArray); } } } - private void AnalyzeFormatArgument(SyntaxNodeAnalysisContext syntaxContext, ExpressionSyntax formatExpression, int paramsCount, bool argsIsArray) + private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation formatExpression, int paramsCount, bool argsIsArray) { - var text = TryGetFormatText(formatExpression, syntaxContext.SemanticModel); + var text = TryGetFormatText(formatExpression); if (text == null) { - syntaxContext.ReportDiagnostic(Diagnostic.Create(CA2254Rule, formatExpression.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(CA2254Rule, formatExpression.Syntax.GetLocation())); return; } @@ -213,37 +205,37 @@ private void AnalyzeFormatArgument(SyntaxNodeAnalysisContext syntaxContext, Expr { if (int.TryParse(valueName, out _)) { - syntaxContext.ReportDiagnostic(Diagnostic.Create(CA2253Rule, formatExpression.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(CA2253Rule, formatExpression.Syntax.GetLocation())); } else if (char.IsLower(valueName[0])) { - syntaxContext.ReportDiagnostic(Diagnostic.Create(CA1727Rule, formatExpression.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(CA1727Rule, formatExpression.Syntax.GetLocation())); } } var argsPassedDirectly = argsIsArray && paramsCount == 1; if (!argsPassedDirectly && paramsCount != formatter.ValueNames.Count) { - syntaxContext.ReportDiagnostic(Diagnostic.Create(CA2255Rule, formatExpression.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(CA2255Rule, formatExpression.Syntax.GetLocation())); } } - private string? TryGetFormatText(ExpressionSyntax? argumentExpression, SemanticModel semanticModel) + private string? TryGetFormatText(IOperation? argumentExpression) { if (argumentExpression is null) return null; switch (argumentExpression) { - case LiteralExpressionSyntax literal when literal.Token.IsKind(SyntaxKind.StringLiteralToken): - return literal.Token.ValueText; - case InterpolatedStringExpressionSyntax interpolated: + case ILiteralOperation { ConstantValue: { HasValue: true, Value: string constantValue } }: + return constantValue; + case IInterpolatedStringOperation interpolated: var text = ""; - foreach (var interpolatedStringContentSyntax in interpolated.Contents) + foreach (var interpolatedStringContent in interpolated.Parts) { - if (interpolatedStringContentSyntax is InterpolatedStringTextSyntax textSyntax) + if (interpolatedStringContent is IInterpolatedStringTextOperation textSyntax) { - text += textSyntax.TextToken.ValueText; + text += textSyntax.Text; } else { @@ -251,14 +243,14 @@ private void AnalyzeFormatArgument(SyntaxNodeAnalysisContext syntaxContext, Expr } } return text; - case InvocationExpressionSyntax invocation when IsNameOfInvocation(invocation): + case INameOfOperation: // return placeholder from here because actual value is not required for analysis and is hard to get return "NAMEOF"; - case ParenthesizedExpressionSyntax parenthesized: - return TryGetFormatText(parenthesized.Expression, semanticModel); - case BinaryExpressionSyntax binary when binary.OperatorToken.IsKind(SyntaxKind.PlusToken): - var leftText = TryGetFormatText(binary.Left, semanticModel); - var rightText = TryGetFormatText(binary.Right, semanticModel); + case IParenthesizedOperation parenthesized: + return TryGetFormatText(parenthesized.Operand); + case IBinaryOperation { OperatorKind: BinaryOperatorKind.Add } binary: + var leftText = TryGetFormatText(binary.LeftOperand); + var rightText = TryGetFormatText(binary.RightOperand); if (leftText != null && rightText != null) { @@ -267,7 +259,7 @@ private void AnalyzeFormatArgument(SyntaxNodeAnalysisContext syntaxContext, Expr return null; default: - var constant = semanticModel.GetConstantValue(argumentExpression); + var constant = argumentExpression.ConstantValue; if (constant.HasValue && constant.Value is string constantString) { return constantString; @@ -306,67 +298,5 @@ private static bool FindLogParameters(IMethodSymbol methodSymbol, out IParameter } return message != null; } - - private static bool IsNameOfInvocation(InvocationExpressionSyntax invocation) - { - return invocation.Expression is IdentifierNameSyntax identifierName && - (identifierName.Identifier.IsKind(SyntaxKind.NameOfKeyword) || - identifierName.Identifier.ToString() == SyntaxFacts.GetText(SyntaxKind.NameOfKeyword)); - } - - private static IParameterSymbol? DetermineParameter( - ArgumentSyntax argument, - SemanticModel semanticModel, - CancellationToken cancellationToken) - { - if (argument.Parent is not BaseArgumentListSyntax argumentList) - { - return null; - } - - if (argumentList.Parent is not ExpressionSyntax invocableExpression) - { - return null; - } - - if (semanticModel.GetSymbolInfo(invocableExpression, cancellationToken).Symbol is not IMethodSymbol symbol) - { - return null; - } - - var parameters = symbol.Parameters; - - // Handle named argument - if (argument.NameColon != null && !argument.NameColon.IsMissing) - { - var name = argument.NameColon.Name.Identifier.ValueText; - return parameters.FirstOrDefault(p => p.Name == name); - } - - // Handle positional argument - var index = argumentList.Arguments.IndexOf(argument); - if (index < 0) - { - return null; - } - - if (index < parameters.Length) - { - return parameters[index]; - } - - var lastParameter = parameters.LastOrDefault(); - if (lastParameter == null) - { - return null; - } - - if (lastParameter.IsParams) - { - return lastParameter; - } - - return null; - } } } \ No newline at end of file From a45c883dc287a174922cef6845ebd621c6e53ab9 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Thu, 15 Jul 2021 20:42:09 -0700 Subject: [PATCH 16/37] Updated tests based on refactor --- .../Runtime/LoggerMessageDefineTests.cs | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 3aa66814c3..16ea00a0a2 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -34,10 +34,16 @@ public async Task CA2254IsProducedForDynamicFormatArgument(string format) } [Theory] - [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{string}""|}|}", "1, 2", 2)] - [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", "1, 2", 2)] - [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs_IgnoresCA1848ForBeginScope), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", "", 0)] - [MemberData(nameof(GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs_IgnoresCA1848ForBeginScope), @"{|CA2255:{|CA1727:""{"" + Const + ""}""|}|}", "", 0)] + /* Expected CA2255 but not triggered. TODO: either remove test cases or add expected support in analyzer + [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{string}""|}", "1, 2", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{str"" + ""ing}""|}", "1, 2", false)] + //Some cases fail: [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{"" + nameof(ILogger) + ""}""|}", "", true)] + //Some cases fail: [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{"" + Const + ""}""|}", "", true)] + */ + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{string}""|}|}", 2)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", 2)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", 0)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{"" + Const + ""}""|}|}", 0)] public async Task CA2255IsProducedForFormatArgumentCountMismatch(string format) { await TriggerCodeAsync(format); @@ -105,17 +111,12 @@ public static IEnumerable GenerateTemplateAndDefineUsages(string templ return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: false).Concat(GenerateDefineUsages(template)); } - public static IEnumerable GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs_IgnoresCA1848ForBeginScope(string template, string arguments, int numArgs) + public static IEnumerable GenerateDefineUsages(string template) { - return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: true).Concat(GenerateDefineUsages(template, numArgs)); + return GenerateDefineUsagesWithExplicitNumberOfArgs(template, numArgs: -1); } - public static IEnumerable GenerateTemplateAndDefineUsagesWithExplicitNumberOfArgs(string template, string arguments, int numArgs) - { - return GenerateTemplateUsages(template, arguments, ignoreCA1848ForBeginScope: false).Concat(GenerateDefineUsages(template, numArgs)); - } - - private static IEnumerable GenerateDefineUsages(string template, int numArgs = -1) + public static IEnumerable GenerateDefineUsagesWithExplicitNumberOfArgs(string template, int numArgs) { TestFileMarkupParser.GetSpans(template, out _, out ImmutableDictionary> spans); var spanCount = spans.Sum(pair => string.IsNullOrEmpty(pair.Key) ? 0 : pair.Value.Count()); @@ -153,14 +154,9 @@ public static IEnumerable GenerateTemplateUsages(string template, stri } } - if (ignoreCA1848ForBeginScope) - { - yield return new[] { $"logger.BeginScope({templateAndArguments});" }; - } - else - { - yield return new[] { $"{{|CA1848:logger.BeginScope({templateAndArguments})|}};" }; - } + yield return ignoreCA1848ForBeginScope + ? (new[] { $"logger.BeginScope({templateAndArguments});" }) + : (new[] { $"{{|CA1848:logger.BeginScope({templateAndArguments})|}};" }); } private static string GenerateGenericInvocation(int i, string method) From 3892a17da8e95c2e6d30137a1950154fa4d7b7a1 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 16 Jul 2021 10:57:12 -0700 Subject: [PATCH 17/37] minor code cleanup --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 1abe97c6cb..1e38229f4f 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -121,30 +121,39 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo var invocation = (IInvocationOperation)context.Operation; var methodSymbol = invocation.TargetMethod; + var containingType = methodSymbol.ContainingType; - if (methodSymbol.ContainingType == loggerExtensionsType) +#pragma warning disable RS1024 // Compare symbols correctly + if (containingType.Equals(loggerExtensionsType)) +#pragma warning restore RS1024 // Compare symbols correctly { context.ReportDiagnostic(Diagnostic.Create(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); } - else if (!methodSymbol.ContainingType.Equals(loggerType) && !methodSymbol.ContainingType.Equals(loggerMessageType)) +#pragma warning disable RS1024 // Compare symbols correctly + else if (!containingType.Equals(loggerType) && !containingType.Equals(loggerMessageType)) +#pragma warning restore RS1024 // Compare symbols correctly { return; } if (FindLogParameters(methodSymbol, out var messageArgument, out var paramsArgument)) { - int paramsCount = 0; + var paramsCount = 0; IOperation? formatExpression = null; - bool argsIsArray = false; + var argsIsArray = false; - if (methodSymbol.ContainingType == loggerMessageType) +#pragma warning disable RS1024 // Compare symbols correctly + if (containingType.Equals(loggerMessageType)) +#pragma warning restore RS1024 // Compare symbols correctly { // For LoggerMessage.Define, count type parameters on the invocation instead of arguments paramsCount = methodSymbol.TypeParameters.Length; var arg = invocation.Arguments.FirstOrDefault(argument => { var parameter = argument.Parameter; +#pragma warning disable RS1024 // Compare symbols correctly return Equals(parameter, messageArgument); +#pragma warning restore RS1024 // Compare symbols correctly }); formatExpression = arg.Value; } @@ -153,11 +162,15 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo foreach (var argument in invocation.Arguments) { var parameter = argument.Parameter; +#pragma warning disable RS1024 // Compare symbols correctly if (Equals(parameter, messageArgument)) +#pragma warning restore RS1024 // Compare symbols correctly { formatExpression = argument.Value; } +#pragma warning disable RS1024 // Compare symbols correctly else if (Equals(parameter, paramsArgument)) +#pragma warning restore RS1024 // Compare symbols correctly { var parameterType = argument.Parameter.Type;// TODO test if (parameterType == null) From e86185d4e1d119bff6501b3db0d7f9f92440e84b Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 16 Jul 2021 14:31:00 -0700 Subject: [PATCH 18/37] PR feedback --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 26 ++++++------------- ...icrosoftCodeQualityAnalyzersResources.resx | 3 +-- ...rosoftCodeQualityAnalyzersResources.cs.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.de.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.es.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.fr.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.it.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.ja.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.ko.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.pl.xlf | 4 +-- ...oftCodeQualityAnalyzersResources.pt-BR.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.ru.xlf | 4 +-- ...rosoftCodeQualityAnalyzersResources.tr.xlf | 4 +-- ...tCodeQualityAnalyzersResources.zh-Hans.xlf | 4 +-- ...tCodeQualityAnalyzersResources.zh-Hant.xlf | 4 +-- 15 files changed, 35 insertions(+), 46 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 1e38229f4f..0b35d53283 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -123,15 +123,13 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo var methodSymbol = invocation.TargetMethod; var containingType = methodSymbol.ContainingType; -#pragma warning disable RS1024 // Compare symbols correctly - if (containingType.Equals(loggerExtensionsType)) -#pragma warning restore RS1024 // Compare symbols correctly + if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) { context.ReportDiagnostic(Diagnostic.Create(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); } -#pragma warning disable RS1024 // Compare symbols correctly - else if (!containingType.Equals(loggerType) && !containingType.Equals(loggerMessageType)) -#pragma warning restore RS1024 // Compare symbols correctly + else if ( + !containingType.Equals(loggerType, SymbolEqualityComparer.Default) && + !containingType.Equals(loggerMessageType, SymbolEqualityComparer.Default)) { return; } @@ -142,18 +140,14 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo IOperation? formatExpression = null; var argsIsArray = false; -#pragma warning disable RS1024 // Compare symbols correctly - if (containingType.Equals(loggerMessageType)) -#pragma warning restore RS1024 // Compare symbols correctly + if (containingType.Equals(loggerMessageType, SymbolEqualityComparer.Default)) { // For LoggerMessage.Define, count type parameters on the invocation instead of arguments paramsCount = methodSymbol.TypeParameters.Length; var arg = invocation.Arguments.FirstOrDefault(argument => { var parameter = argument.Parameter; -#pragma warning disable RS1024 // Compare symbols correctly - return Equals(parameter, messageArgument); -#pragma warning restore RS1024 // Compare symbols correctly + return parameter.Equals(messageArgument, SymbolEqualityComparer.Default); }); formatExpression = arg.Value; } @@ -162,15 +156,11 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo foreach (var argument in invocation.Arguments) { var parameter = argument.Parameter; -#pragma warning disable RS1024 // Compare symbols correctly - if (Equals(parameter, messageArgument)) -#pragma warning restore RS1024 // Compare symbols correctly + if (parameter.Equals(messageArgument, SymbolEqualityComparer.Default)) { formatExpression = argument.Value; } -#pragma warning disable RS1024 // Compare symbols correctly - else if (Equals(parameter, paramsArgument)) -#pragma warning restore RS1024 // Compare symbols correctly + else if (parameter.Equals(paramsArgument, SymbolEqualityComparer.Default)) { var parameterType = argument.Parameter.Type;// TODO test if (parameterType == null) diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx index 5729773054..177c074f30 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx @@ -196,7 +196,7 @@ For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages Logging format string should not be dynamically generated @@ -216,7 +216,6 @@ For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - Mark assemblies with CLSCompliant diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf index bd5d9479b7..78e3a15d0e 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf index cb89a972b3..280b4becea 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf index a9272a9b3c..f6ee7d7f2c 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf index 8c02a4bbc3..4b0247cdd0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf index d5eca7c316..f82eb8e2f7 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf index a09b9ee5a9..9cd3da0dab 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf index e334404cd8..b7abca3083 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf index 2df6763d77..7edd451f6b 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf index 88b1309650..8f6db9d384 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf index b06380cac2..a1904ab1ff 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf index 99c2363f22..604edb0e88 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf index 8d26bd9fbf..4de73232d6 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf index ce8145974d..b2ee3cb127 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf @@ -288,8 +288,8 @@ - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages From 3479c9f9b9baa77036935a05383f8f4a5b0df3a5 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Fri, 16 Jul 2021 15:17:38 -0700 Subject: [PATCH 19/37] Use CreateDiagnostic extension method --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 0b35d53283..f5a02ae447 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -4,6 +4,7 @@ using System.Collections.Immutable; using System.Linq; using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; @@ -125,7 +126,7 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) { - context.ReportDiagnostic(Diagnostic.Create(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); + context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); } else if ( !containingType.Equals(loggerType, SymbolEqualityComparer.Default) && @@ -188,7 +189,7 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation var text = TryGetFormatText(formatExpression); if (text == null) { - context.ReportDiagnostic(Diagnostic.Create(CA2254Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, formatExpression.Syntax.GetLocation())); return; } @@ -208,18 +209,18 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation { if (int.TryParse(valueName, out _)) { - context.ReportDiagnostic(Diagnostic.Create(CA2253Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2253Rule, formatExpression.Syntax.GetLocation())); } else if (char.IsLower(valueName[0])) { - context.ReportDiagnostic(Diagnostic.Create(CA1727Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA1727Rule, formatExpression.Syntax.GetLocation())); } } var argsPassedDirectly = argsIsArray && paramsCount == 1; if (!argsPassedDirectly && paramsCount != formatter.ValueNames.Count) { - context.ReportDiagnostic(Diagnostic.Create(CA2255Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2255Rule, formatExpression.Syntax.GetLocation())); } } From c9d0820c0d0b4199b3ab1c0d42d85765b9d3e746 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 19 Jul 2021 10:48:42 -0700 Subject: [PATCH 20/37] update auto generated files --- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md | 2 +- src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index d31c8ba91e..78729bbbee 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -1442,7 +1442,7 @@ It is more efficient to use 'AsSpan' and 'string.Concat', instead of 'Substring' ## [CA1848](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848): Use compiled log messages -For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. +For improved performance, use pre-compiled log messages |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 8cfe91d34c..598c4e19d5 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -270,7 +270,7 @@ "CA1848": { "id": "CA1848", "shortDescription": "Use compiled log messages", - "fullDescription": "For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message.", + "fullDescription": "For improved performance, use pre-compiled log messages", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848", "properties": { From 2b3cc7703cd17fd2d94b633eb8bdc8a5b153b798 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 19 Jul 2021 12:30:10 -0700 Subject: [PATCH 21/37] Fix "Run markdownlint" error --- src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md index 1bde512058..be0a0bedcc 100644 --- a/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md @@ -8,4 +8,4 @@ CA1727 | Naming | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https: CA1848 | Performance | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848) CA2253 | Usage | Info | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253) CA2254 | Usage | Info | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254) -CA2255 | Usage | Warning | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) \ No newline at end of file +CA2255 | Usage | Warning | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) From ebed92dc2147d4ea3872a99d1a6917602e62f6d3 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 19 Jul 2021 12:52:34 -0700 Subject: [PATCH 22/37] isPortedFxCopRule set false by default --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 12 +++++------- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 5 ----- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index f5a02ae447..0f59b7ed46 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -48,9 +48,8 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer DiagnosticCategory.Naming, RuleLevel.Disabled, description: s_localizableDescriptionCA1727, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false, - // isEnabledByDefaultInAggressiveMode: false, isReportedAtCompilationEnd: true); internal static DiagnosticDescriptor CA1848Rule = DiagnosticDescriptorHelper.Create(CA1848RuleId, @@ -59,9 +58,8 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer DiagnosticCategory.Performance, RuleLevel.Disabled, description: s_localizableDescriptionCA1848, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false, - // isEnabledByDefaultInAggressiveMode: false, isReportedAtCompilationEnd: true); internal static DiagnosticDescriptor CA2253Rule = DiagnosticDescriptorHelper.Create(CA2253RuleId, @@ -70,7 +68,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer DiagnosticCategory.Usage, RuleLevel.IdeSuggestion, description: s_localizableDescriptionCA2253, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false, isReportedAtCompilationEnd: true); @@ -80,7 +78,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer DiagnosticCategory.Usage, RuleLevel.IdeSuggestion, description: s_localizableDescriptionCA2254, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false, isReportedAtCompilationEnd: true); @@ -90,7 +88,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer DiagnosticCategory.Usage, RuleLevel.BuildWarning, description: s_localizableDescriptionCA2255, - isPortedFxCopRule: true, + isPortedFxCopRule: false, isDataflowRule: false, isReportedAtCompilationEnd: true); diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 598c4e19d5..32480ac362 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -121,7 +121,6 @@ "C#" ], "tags": [ - "PortedFromFxCop", "Telemetry", "EnabledRuleInAggressiveMode", "CompilationEnd" @@ -281,7 +280,6 @@ "C#" ], "tags": [ - "PortedFromFxCop", "Telemetry", "EnabledRuleInAggressiveMode", "CompilationEnd" @@ -360,7 +358,6 @@ "C#" ], "tags": [ - "PortedFromFxCop", "Telemetry", "EnabledRuleInAggressiveMode", "CompilationEnd" @@ -381,7 +378,6 @@ "C#" ], "tags": [ - "PortedFromFxCop", "Telemetry", "EnabledRuleInAggressiveMode", "CompilationEnd" @@ -402,7 +398,6 @@ "C#" ], "tags": [ - "PortedFromFxCop", "Telemetry", "EnabledRuleInAggressiveMode", "CompilationEnd" From 6dba13398d609c4764a70b742809118be51994a3 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Mon, 19 Jul 2021 17:52:41 -0700 Subject: [PATCH 23/37] isReportedAtCompilationEnd set to false --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 10 +++++----- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 15 +++++---------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 0f59b7ed46..5019e8e57d 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -50,7 +50,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer description: s_localizableDescriptionCA1727, isPortedFxCopRule: false, isDataflowRule: false, - isReportedAtCompilationEnd: true); + isReportedAtCompilationEnd: false); internal static DiagnosticDescriptor CA1848Rule = DiagnosticDescriptorHelper.Create(CA1848RuleId, s_localizableTitleCA1848, @@ -60,7 +60,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer description: s_localizableDescriptionCA1848, isPortedFxCopRule: false, isDataflowRule: false, - isReportedAtCompilationEnd: true); + isReportedAtCompilationEnd: false); internal static DiagnosticDescriptor CA2253Rule = DiagnosticDescriptorHelper.Create(CA2253RuleId, s_localizableTitleCA2253, @@ -70,7 +70,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer description: s_localizableDescriptionCA2253, isPortedFxCopRule: false, isDataflowRule: false, - isReportedAtCompilationEnd: true); + isReportedAtCompilationEnd: false); internal static DiagnosticDescriptor CA2254Rule = DiagnosticDescriptorHelper.Create(CA2254RuleId, s_localizableTitleCA2254, @@ -80,7 +80,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer description: s_localizableDescriptionCA2254, isPortedFxCopRule: false, isDataflowRule: false, - isReportedAtCompilationEnd: true); + isReportedAtCompilationEnd: false); internal static DiagnosticDescriptor CA2255Rule = DiagnosticDescriptorHelper.Create(CA2255RuleId, s_localizableTitleCA2255, @@ -90,7 +90,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer description: s_localizableDescriptionCA2255, isPortedFxCopRule: false, isDataflowRule: false, - isReportedAtCompilationEnd: true); + isReportedAtCompilationEnd: false); public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(CA1727Rule, CA1848Rule, CA2253Rule, CA2254Rule, CA2255Rule); diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 32480ac362..5cdce16d85 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -122,8 +122,7 @@ ], "tags": [ "Telemetry", - "EnabledRuleInAggressiveMode", - "CompilationEnd" + "EnabledRuleInAggressiveMode" ] } }, @@ -281,8 +280,7 @@ ], "tags": [ "Telemetry", - "EnabledRuleInAggressiveMode", - "CompilationEnd" + "EnabledRuleInAggressiveMode" ] } }, @@ -359,8 +357,7 @@ ], "tags": [ "Telemetry", - "EnabledRuleInAggressiveMode", - "CompilationEnd" + "EnabledRuleInAggressiveMode" ] } }, @@ -379,8 +376,7 @@ ], "tags": [ "Telemetry", - "EnabledRuleInAggressiveMode", - "CompilationEnd" + "EnabledRuleInAggressiveMode" ] } }, @@ -399,8 +395,7 @@ ], "tags": [ "Telemetry", - "EnabledRuleInAggressiveMode", - "CompilationEnd" + "EnabledRuleInAggressiveMode" ] } }, From 2e85d6d1af988ddf28b6e7bac80429d0dbfc0c63 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 22 Jul 2021 15:37:51 -0700 Subject: [PATCH 24/37] Rename test class to match file name --- .../Runtime/LoggerMessageDefineTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 16ea00a0a2..44b221d777 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -15,7 +15,7 @@ namespace Microsoft.Extensions.Logging.Analyzer { - public class FormatStringAnalyzerTests + public class LoggerMessageDefineTests { [Theory] [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA2253:""{0}""|}", "1")] From fbb89d55f224e603734fd3d859b8b91405694721 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 22 Jul 2021 15:41:41 -0700 Subject: [PATCH 25/37] Update INameOfOperation handling to use correct constant value --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 2 ++ .../Runtime/LoggerMessageDefineTests.cs | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 5019e8e57d..c426ca4af5 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -245,6 +245,8 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation } } return text; + case INameOfOperation { ConstantValue: { HasValue: true, Value: string constantValue } }: + return constantValue; case INameOfOperation: // return placeholder from here because actual value is not required for analysis and is hard to get return "NAMEOF"; diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 44b221d777..0c8b517b10 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -34,12 +34,10 @@ public async Task CA2254IsProducedForDynamicFormatArgument(string format) } [Theory] - /* Expected CA2255 but not triggered. TODO: either remove test cases or add expected support in analyzer [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{string}""|}", "1, 2", false)] [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{str"" + ""ing}""|}", "1, 2", false)] //Some cases fail: [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{"" + nameof(ILogger) + ""}""|}", "", true)] //Some cases fail: [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{"" + Const + ""}""|}", "", true)] - */ [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{string}""|}|}", 2)] [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", 2)] [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", 0)] From 41a7fd9a1783e0de741dffc2d9132228d01483ef Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Thu, 22 Jul 2021 16:27:15 -0700 Subject: [PATCH 26/37] Update IOperation to understand params arguments --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 12 ++++++++++-- .../Runtime/LoggerMessageDefineTests.cs | 11 ++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index c426ca4af5..85bc76ddbf 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -168,9 +168,17 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo } //Detect if current argument can be passed directly to args - argsIsArray = parameterType.TypeKind == TypeKind.Array && ((IArrayTypeSymbol)parameterType).ElementType.SpecialType == SpecialType.System_Object; + argsIsArray = argument.ArgumentKind == ArgumentKind.ParamArray && parameterType.TypeKind == TypeKind.Array && ((IArrayTypeSymbol)parameterType).ElementType.SpecialType == SpecialType.System_Object; - paramsCount++; + if (argument.ArgumentKind == ArgumentKind.ParamArray + && argument.Value is IArrayCreationOperation arrayCreation) + { + paramsCount += arrayCreation.Initializer.ElementValues.Length; + } + else + { + paramsCount++; + } } } } diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 0c8b517b10..aeae8a9b3f 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -34,10 +34,10 @@ public async Task CA2254IsProducedForDynamicFormatArgument(string format) } [Theory] - [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{string}""|}", "1, 2", false)] - [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{str"" + ""ing}""|}", "1, 2", false)] - //Some cases fail: [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{"" + nameof(ILogger) + ""}""|}", "", true)] - //Some cases fail: [MemberData(nameof(GenerateTemplateUsages), @"{|CA1727:""{"" + Const + ""}""|}", "", true)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:""{string}""|}|}", "1, 2", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", "1, 2", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", "", true)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:""{"" + Const + ""}""|}|}", "", true)] [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{string}""|}|}", 2)] [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", 2)] [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", 0)] @@ -62,7 +62,8 @@ public async Task CA1727IsProducedForCamelCasedFormatArgument(string format) [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:""{st"" + ""ring}""|}", "1")] // we are unable to parse expressions - [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:{|CA1727:""{string} {string}""|}|}", "new object[] { 1 }")] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:{|CA1727:""{string} {string}""|}|}|}", "new object[] { 1 }", false)] + [MemberData(nameof(GenerateDefineUsages), @"{|CA1727:{|CA1727:""{string} {string}""|}|}")] // CA2253 is not enabled by default. [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:""{camelCase}""|}", "1")] From d7e7ee349f6352e9616c37e6eeefca6ffc8db466 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 27 Jul 2021 11:46:56 -0700 Subject: [PATCH 27/37] move analyzer from csharp to core --- .../CSharp/AnalyzerReleases.Unshipped.md | 10 - .../Core/AnalyzerReleases.Unshipped.md | 5 + ...icrosoftCodeQualityAnalyzersResources.resx | 12 +- ...rosoftCodeQualityAnalyzersResources.cs.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.de.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.es.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.fr.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.it.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.ja.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.ko.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.pl.xlf | 24 +-- ...oftCodeQualityAnalyzersResources.pt-BR.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.ru.xlf | 24 +-- ...rosoftCodeQualityAnalyzersResources.tr.xlf | 24 +-- ...tCodeQualityAnalyzersResources.zh-Hans.xlf | 24 +-- ...tCodeQualityAnalyzersResources.zh-Hant.xlf | 24 +-- .../Runtime/LogValuesFormatter.cs | 0 .../Runtime/LoggerMessageDefineAnalyzer.cs | 6 +- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 10 +- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 195 +++++++++--------- .../Runtime/LoggerMessageDefineTests.cs | 4 +- 21 files changed, 278 insertions(+), 276 deletions(-) rename src/NetAnalyzers/{CSharp => Core}/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs (100%) rename src/NetAnalyzers/{CSharp => Core}/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs (99%) diff --git a/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md index be0a0bedcc..cdf4f1397e 100644 --- a/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/CSharp/AnalyzerReleases.Unshipped.md @@ -1,11 +1 @@ ; Please do not edit this file manually, it should only be updated through code fix application. - -### New Rules - -Rule ID | Category | Severity | Notes ---------|----------|----------|------- -CA1727 | Naming | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727) -CA1848 | Performance | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848) -CA2253 | Usage | Info | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253) -CA2254 | Usage | Info | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254) -CA2255 | Usage | Warning | Descriptors, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index dbceb35681..916f038975 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -6,6 +6,7 @@ Rule ID | Category | Severity | Notes --------|----------|----------|------- CA1418 | Interoperability | Warning | UseValidPlatformString, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1418) CA1419 | Interoperability | Info | ProvidePublicParameterlessSafeHandleConstructor, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1419) +CA1727 | Naming | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727) CA1839 | Performance | Info | UseEnvironmentMembers, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1839) CA1840 | Performance | Info | UseEnvironmentMembers, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1840) CA1841 | Performance | Info | PreferDictionaryContainsMethods, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1841) @@ -15,9 +16,13 @@ CA1844 | Performance | Info | ProvideStreamMemoryBasedAsyncOverrides, [Documenta CA1845 | Performance | Info | UseSpanBasedStringConcat, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1845) CA1846 | Performance | Info | PreferAsSpanOverSubstring, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1846) CA1847 | Performance | Info | UseStringContainsCharOverloadWithSingleCharactersAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1847) +CA1848 | Performance | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848) CA2250 | Usage | Info | UseCancellationTokenThrowIfCancellationRequested, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2250) CA2251 | Usage | Hidden | UseStringEqualsOverStringCompare, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2251) CA2252 | Usage | Info | DetectPreviewFeatureAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2252) +CA2253 | Usage | Info | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253) +CA2254 | Usage | Info | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254) +CA2255 | Usage | Warning | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) ### Removed Rules diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx index 177c074f30..06ddddc7f0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx @@ -178,7 +178,7 @@ Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. Logging format string parameter count mismatch @@ -187,16 +187,16 @@ Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. Use compiled log messages - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. Logging format string should not be dynamically generated @@ -205,7 +205,7 @@ Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. Use PascalCase for log message tokens @@ -214,7 +214,7 @@ For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. Mark assemblies with CLSCompliant diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf index 78e3a15d0e..7cb09a29b0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf index 280b4becea..3adf2cff54 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf index f6ee7d7f2c..f5d2f12870 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf index 4b0247cdd0..993db0e5d7 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf index f82eb8e2f7..fcb5d4febd 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf index 9cd3da0dab..a027cf8081 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf index b7abca3083..977646c789 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf index 7edd451f6b..292193f3eb 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf index 8f6db9d384..952aed93c2 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf index a1904ab1ff..450c4c4682 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf index 604edb0e88..1202e4a54c 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf index 4de73232d6..914d0d82e7 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf index b2ee3cb127..7c16d8c0f4 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf @@ -243,8 +243,8 @@ - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Logging format string should not be dynamically generated. + Logging format string should not be dynamically generated. @@ -258,8 +258,8 @@ - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Logging format string parameter count mismatch. + Logging format string parameter count mismatch. @@ -273,8 +273,8 @@ - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Numerics should not be used in logging format string. + Numerics should not be used in logging format string. @@ -288,13 +288,13 @@ - For improved performance, use pre-compiled log messages - For improved performance, use pre-compiled log messages + For improved performance, use pre-compiled log messages. + For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message. + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message @@ -303,8 +303,8 @@ - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs similarity index 100% rename from src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs rename to src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LogValuesFormatter.cs diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs similarity index 99% rename from src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs rename to src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 85bc76ddbf..a022ecd2a1 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -11,9 +11,9 @@ using Microsoft.CodeQuality.Analyzers; using Microsoft.Extensions.Logging; -namespace Microsoft.NetCore.CSharp.Analyzers.Runtime +namespace Microsoft.NetCore.Analyzers.Runtime { - [DiagnosticAnalyzer(LanguageNames.CSharp)] + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer { internal const string CA1727RuleId = "CA1727"; @@ -237,7 +237,7 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation switch (argumentExpression) { - case ILiteralOperation { ConstantValue: { HasValue: true, Value: string constantValue } }: + case ILiteralOperation { ConstantValue: { HasValue: false, Value: string constantValue } }: return constantValue; case IInterpolatedStringOperation interpolated: var text = ""; diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 78729bbbee..4fecaf4a41 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -974,7 +974,7 @@ Consistent naming of parameters in an override hierarchy increases the usability ## [CA1727](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727): Use PascalCase for log message tokens -For consistency with logs emitted from other components, use 'PascalCase' for log message tokens +For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. |Item|Value| |-|-| @@ -1442,7 +1442,7 @@ It is more efficient to use 'AsSpan' and 'string.Concat', instead of 'Substring' ## [CA1848](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848): Use compiled log messages -For improved performance, use pre-compiled log messages +For improved performance, use pre-compiled log messages. |Item|Value| |-|-| @@ -2042,7 +2042,7 @@ An assembly has to opt into preview features before using them. ## [CA2253](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253): Numerics should not be used in logging format string -Numerics should not be used in logging format string +Numerics should not be used in logging format string. |Item|Value| |-|-| @@ -2054,7 +2054,7 @@ Numerics should not be used in logging format string ## [CA2254](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254): Logging format string should not be dynamically generated -Logging format string should not be dynamically generated +Logging format string should not be dynamically generated. |Item|Value| |-|-| @@ -2066,7 +2066,7 @@ Logging format string should not be dynamically generated ## [CA2255](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255): Logging format string parameter count mismatch -Logging format string parameter count mismatch +Logging format string parameter count mismatch. |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 5cdce16d85..8de21a4929 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -107,25 +107,6 @@ ] } }, - "CA1727": { - "id": "CA1727", - "shortDescription": "Use PascalCase for log message tokens", - "fullDescription": "For consistency with logs emitted from other components, use 'PascalCase' for log message tokens", - "defaultLevel": "warning", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727", - "properties": { - "category": "Naming", - "isEnabledByDefault": false, - "typeName": "LoggerMessageDefineAnalyzer", - "languages": [ - "C#" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, "CA1802": { "id": "CA1802", "shortDescription": "Use literals where appropriate", @@ -265,25 +246,6 @@ ] } }, - "CA1848": { - "id": "CA1848", - "shortDescription": "Use compiled log messages", - "fullDescription": "For improved performance, use pre-compiled log messages", - "defaultLevel": "warning", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848", - "properties": { - "category": "Performance", - "isEnabledByDefault": false, - "typeName": "LoggerMessageDefineAnalyzer", - "languages": [ - "C#" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, "CA2014": { "id": "CA2014", "shortDescription": "Do not use stackalloc in loops", @@ -342,63 +304,6 @@ ] } }, - "CA2253": { - "id": "CA2253", - "shortDescription": "Numerics should not be used in logging format string", - "fullDescription": "Numerics should not be used in logging format string", - "defaultLevel": "note", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253", - "properties": { - "category": "Usage", - "isEnabledByDefault": true, - "typeName": "LoggerMessageDefineAnalyzer", - "languages": [ - "C#" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, - "CA2254": { - "id": "CA2254", - "shortDescription": "Logging format string should not be dynamically generated", - "fullDescription": "Logging format string should not be dynamically generated", - "defaultLevel": "note", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254", - "properties": { - "category": "Usage", - "isEnabledByDefault": true, - "typeName": "LoggerMessageDefineAnalyzer", - "languages": [ - "C#" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, - "CA2255": { - "id": "CA2255", - "shortDescription": "Logging format string parameter count mismatch", - "fullDescription": "Logging format string parameter count mismatch", - "defaultLevel": "warning", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255", - "properties": { - "category": "Usage", - "isEnabledByDefault": true, - "typeName": "LoggerMessageDefineAnalyzer", - "languages": [ - "C#" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, "CA2352": { "id": "CA2352", "shortDescription": "Unsafe DataSet or DataTable in serializable type can be vulnerable to remote code execution attacks", @@ -2107,6 +2012,26 @@ ] } }, + "CA1727": { + "id": "CA1727", + "shortDescription": "Use PascalCase for log message tokens", + "fullDescription": "For consistency with logs emitted from other components, use 'PascalCase' for log message tokens.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727", + "properties": { + "category": "Naming", + "isEnabledByDefault": false, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA1806": { "id": "CA1806", "shortDescription": "Do not ignore method results", @@ -2737,6 +2662,26 @@ ] } }, + "CA1848": { + "id": "CA1848", + "shortDescription": "Use compiled log messages", + "fullDescription": "For improved performance, use pre-compiled log messages.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848", + "properties": { + "category": "Performance", + "isEnabledByDefault": false, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA2000": { "id": "CA2000", "shortDescription": "Dispose objects before losing scope", @@ -3645,6 +3590,66 @@ ] } }, + "CA2253": { + "id": "CA2253", + "shortDescription": "Numerics should not be used in logging format string", + "fullDescription": "Numerics should not be used in logging format string.", + "defaultLevel": "note", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, + "CA2254": { + "id": "CA2254", + "shortDescription": "Logging format string should not be dynamically generated", + "fullDescription": "Logging format string should not be dynamically generated.", + "defaultLevel": "note", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, + "CA2255": { + "id": "CA2255", + "shortDescription": "Logging format string parameter count mismatch", + "fullDescription": "Logging format string parameter count mismatch.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA2300": { "id": "CA2300", "shortDescription": "Do not use insecure deserializer BinaryFormatter", diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index aeae8a9b3f..7238704f01 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -10,7 +10,7 @@ using Test.Utilities; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< - Microsoft.NetCore.CSharp.Analyzers.Runtime.LoggerMessageDefineAnalyzer, + Microsoft.NetCore.Analyzers.Runtime.LoggerMessageDefineAnalyzer, Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; namespace Microsoft.Extensions.Logging.Analyzer @@ -19,6 +19,8 @@ public class LoggerMessageDefineTests { [Theory] [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA2253:""{0}""|}", "1")] + [InlineData(@"{|CA1848:logger.LogTrace({|CA2253:""{0}""|}, 1)|};")] + [InlineData(@"{|CA1848:logger.LogTrace({|CA2253:""{0}""|}, ""1"")|};")] public async Task CA2253IsProducedForNumericFormatArgument(string format) { // Make sure CA1727 is enabled for this test so we can verify it does not trigger on numeric arguments. From 63bf4c45e10cc3e410a6e4771745f74cdbbbeb51 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 27 Jul 2021 12:03:36 -0700 Subject: [PATCH 28/37] Apply API review feedback. - Switch category to Reliability for fifth diagnostic - Switch severity to hidden from disabled for first two --- .../Core/AnalyzerReleases.Unshipped.md | 6 +-- .../Runtime/LoggerMessageDefineAnalyzer.cs | 26 +++++----- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 32 ++++++------- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 48 +++++++++---------- src/NetAnalyzers/RulesMissingDocumentation.md | 2 +- .../Runtime/LoggerMessageDefineTests.cs | 38 +++++++-------- .../DiagnosticCategoryAndIdRanges.txt | 4 +- 7 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index 916f038975..161d3a219c 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -6,7 +6,7 @@ Rule ID | Category | Severity | Notes --------|----------|----------|------- CA1418 | Interoperability | Warning | UseValidPlatformString, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1418) CA1419 | Interoperability | Info | ProvidePublicParameterlessSafeHandleConstructor, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1419) -CA1727 | Naming | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727) +CA1727 | Naming | Hidden | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727) CA1839 | Performance | Info | UseEnvironmentMembers, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1839) CA1840 | Performance | Info | UseEnvironmentMembers, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1840) CA1841 | Performance | Info | PreferDictionaryContainsMethods, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1841) @@ -16,13 +16,13 @@ CA1844 | Performance | Info | ProvideStreamMemoryBasedAsyncOverrides, [Documenta CA1845 | Performance | Info | UseSpanBasedStringConcat, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1845) CA1846 | Performance | Info | PreferAsSpanOverSubstring, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1846) CA1847 | Performance | Info | UseStringContainsCharOverloadWithSingleCharactersAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1847) -CA1848 | Performance | Disabled | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848) +CA1848 | Performance | Hidden | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848) +CA2017 | Reliability | Warning | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017) CA2250 | Usage | Info | UseCancellationTokenThrowIfCancellationRequested, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2250) CA2251 | Usage | Hidden | UseStringEqualsOverStringCompare, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2251) CA2252 | Usage | Info | DetectPreviewFeatureAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2252) CA2253 | Usage | Info | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253) CA2254 | Usage | Info | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254) -CA2255 | Usage | Warning | LoggerMessageDefineAnalyzer, [Documentation](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255) ### Removed Rules diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index a022ecd2a1..b0789a2332 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -20,7 +20,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer internal const string CA1848RuleId = "CA1848"; internal const string CA2253RuleId = "CA2253"; internal const string CA2254RuleId = "CA2254"; - internal const string CA2255RuleId = "CA2255"; + internal const string CA2017RuleId = "CA2017"; private static readonly LocalizableString s_localizableTitleCA1727 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUsePascalCasedLogMessageTokensTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); private static readonly LocalizableString s_localizableMessageCA1727 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticUsePascalCasedLogMessageTokensMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); @@ -38,15 +38,15 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer private static readonly LocalizableString s_localizableMessageCA2254 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticConcatenationInFormatStringMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); private static readonly LocalizableString s_localizableDescriptionCA2254 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticConcatenationInFormatStringDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); - private static readonly LocalizableString s_localizableTitleCA2255 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); - private static readonly LocalizableString s_localizableMessageCA2255 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); - private static readonly LocalizableString s_localizableDescriptionCA2255 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableTitleCA2017 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableMessageCA2017 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); + private static readonly LocalizableString s_localizableDescriptionCA2017 = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.LoggerMessageDiagnosticFormatParameterCountMismatchDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources)); internal static DiagnosticDescriptor CA1727Rule = DiagnosticDescriptorHelper.Create(CA1727RuleId, s_localizableTitleCA1727, s_localizableMessageCA1727, DiagnosticCategory.Naming, - RuleLevel.Disabled, + RuleLevel.IdeHidden_BulkConfigurable, description: s_localizableDescriptionCA1727, isPortedFxCopRule: false, isDataflowRule: false, @@ -56,7 +56,7 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer s_localizableTitleCA1848, s_localizableMessageCA1848, DiagnosticCategory.Performance, - RuleLevel.Disabled, + RuleLevel.IdeHidden_BulkConfigurable, description: s_localizableDescriptionCA1848, isPortedFxCopRule: false, isDataflowRule: false, @@ -82,17 +82,17 @@ public sealed class LoggerMessageDefineAnalyzer : DiagnosticAnalyzer isDataflowRule: false, isReportedAtCompilationEnd: false); - internal static DiagnosticDescriptor CA2255Rule = DiagnosticDescriptorHelper.Create(CA2255RuleId, - s_localizableTitleCA2255, - s_localizableMessageCA2255, - DiagnosticCategory.Usage, + internal static DiagnosticDescriptor CA2017Rule = DiagnosticDescriptorHelper.Create(CA2017RuleId, + s_localizableTitleCA2017, + s_localizableMessageCA2017, + DiagnosticCategory.Reliability, RuleLevel.BuildWarning, - description: s_localizableDescriptionCA2255, + description: s_localizableDescriptionCA2017, isPortedFxCopRule: false, isDataflowRule: false, isReportedAtCompilationEnd: false); - public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(CA1727Rule, CA1848Rule, CA2253Rule, CA2254Rule, CA2255Rule); + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(CA1727Rule, CA1848Rule, CA2253Rule, CA2254Rule, CA2017Rule); public override void Initialize(AnalysisContext context) { @@ -226,7 +226,7 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation var argsPassedDirectly = argsIsArray && paramsCount == 1; if (!argsPassedDirectly && paramsCount != formatter.ValueNames.Count) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2255Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2017Rule, formatExpression.Syntax.GetLocation())); } } diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 4fecaf4a41..13492bd39d 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -979,8 +979,8 @@ For consistency with logs emitted from other components, use 'PascalCase' for lo |Item|Value| |-|-| |Category|Naming| -|Enabled|False| -|Severity|Warning| +|Enabled|True| +|Severity|Hidden| |CodeFix|False| --- @@ -1447,8 +1447,8 @@ For improved performance, use pre-compiled log messages. |Item|Value| |-|-| |Category|Performance| -|Enabled|False| -|Severity|Warning| +|Enabled|True| +|Severity|Hidden| |CodeFix|False| --- @@ -1584,6 +1584,18 @@ Forward the 'CancellationToken' parameter to methods to ensure the operation can |CodeFix|True| --- +## [CA2017](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017): Logging format string parameter count mismatch + +Logging format string parameter count mismatch. + +|Item|Value| +|-|-| +|Category|Reliability| +|Enabled|True| +|Severity|Warning| +|CodeFix|False| +--- + ## [CA2100](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2100): Review SQL queries for security vulnerabilities SQL queries that directly use user input can be vulnerable to SQL injection attacks. Review this SQL query for potential vulnerabilities, and consider using a parameterized SQL query. @@ -2064,18 +2076,6 @@ Logging format string should not be dynamically generated. |CodeFix|False| --- -## [CA2255](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255): Logging format string parameter count mismatch - -Logging format string parameter count mismatch. - -|Item|Value| -|-|-| -|Category|Usage| -|Enabled|True| -|Severity|Warning| -|CodeFix|False| ---- - ## [CA2300](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2300): Do not use insecure deserializer BinaryFormatter The method '{0}' is insecure when deserializing untrusted data. If you need to instead detect BinaryFormatter deserialization without a SerializationBinder set, then disable rule CA2300, and enable rules CA2301 and CA2302. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 8de21a4929..09b3b65142 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -2016,11 +2016,11 @@ "id": "CA1727", "shortDescription": "Use PascalCase for log message tokens", "fullDescription": "For consistency with logs emitted from other components, use 'PascalCase' for log message tokens.", - "defaultLevel": "warning", + "defaultLevel": "hidden", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727", "properties": { "category": "Naming", - "isEnabledByDefault": false, + "isEnabledByDefault": true, "typeName": "LoggerMessageDefineAnalyzer", "languages": [ "C#", @@ -2666,11 +2666,11 @@ "id": "CA1848", "shortDescription": "Use compiled log messages", "fullDescription": "For improved performance, use pre-compiled log messages.", - "defaultLevel": "warning", + "defaultLevel": "hidden", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848", "properties": { "category": "Performance", - "isEnabledByDefault": false, + "isEnabledByDefault": true, "typeName": "LoggerMessageDefineAnalyzer", "languages": [ "C#", @@ -2865,6 +2865,26 @@ ] } }, + "CA2017": { + "id": "CA2017", + "shortDescription": "Logging format string parameter count mismatch", + "fullDescription": "Logging format string parameter count mismatch.", + "defaultLevel": "warning", + "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017", + "properties": { + "category": "Reliability", + "isEnabledByDefault": true, + "typeName": "LoggerMessageDefineAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA2100": { "id": "CA2100", "shortDescription": "Review SQL queries for security vulnerabilities", @@ -3630,26 +3650,6 @@ ] } }, - "CA2255": { - "id": "CA2255", - "shortDescription": "Logging format string parameter count mismatch", - "fullDescription": "Logging format string parameter count mismatch.", - "defaultLevel": "warning", - "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2255", - "properties": { - "category": "Usage", - "isEnabledByDefault": true, - "typeName": "LoggerMessageDefineAnalyzer", - "languages": [ - "C#", - "Visual Basic" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, "CA2300": { "id": "CA2300", "shortDescription": "Do not use insecure deserializer BinaryFormatter", diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index 7ded8fe098..c4eeb0d728 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -10,7 +10,7 @@ CA1840 | | Do not use 'WhenAll' with a single task | CA1843 | | Do not use 'WaitAll' with a single task | CA1848 | | Use compiled log messages | +CA2017 | | Logging format string parameter count mismatch | CA2252 | | This API requires opting into preview features | CA2253 | | Numerics should not be used in logging format string | CA2254 | | Logging format string should not be dynamically generated | -CA2255 | | Logging format string parameter count mismatch | diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 7238704f01..3831b17844 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -36,15 +36,15 @@ public async Task CA2254IsProducedForDynamicFormatArgument(string format) } [Theory] - [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:""{string}""|}|}", "1, 2", false)] - [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", "1, 2", false)] - [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", "", true)] - [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:""{"" + Const + ""}""|}|}", "", true)] - [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{string}""|}|}", 2)] - [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{str"" + ""ing}""|}|}", 2)] - [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:""{"" + nameof(ILogger) + ""}""|}", 0)] - [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2255:{|CA1727:""{"" + Const + ""}""|}|}", 0)] - public async Task CA2255IsProducedForFormatArgumentCountMismatch(string format) + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2017:{|CA1727:""{string}""|}|}", "1, 2", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2017:{|CA1727:""{str"" + ""ing}""|}|}", "1, 2", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2017:""{"" + nameof(ILogger) + ""}""|}", "", true)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2017:{|CA1727:""{"" + Const + ""}""|}|}", "", true)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2017:{|CA1727:""{string}""|}|}", 2)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2017:{|CA1727:""{str"" + ""ing}""|}|}", 2)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2017:""{"" + nameof(ILogger) + ""}""|}", 0)] + [MemberData(nameof(GenerateDefineUsagesWithExplicitNumberOfArgs), @"{|CA2017:{|CA1727:""{"" + Const + ""}""|}|}", 0)] + public async Task CA2017IsProducedForFormatArgumentCountMismatch(string format) { await TriggerCodeAsync(format); } @@ -64,7 +64,7 @@ public async Task CA1727IsProducedForCamelCasedFormatArgument(string format) [MemberData(nameof(GenerateTemplateAndDefineUsages), @"{|CA1727:""{st"" + ""ring}""|}", "1")] // we are unable to parse expressions - [MemberData(nameof(GenerateTemplateUsages), @"{|CA2255:{|CA1727:{|CA1727:""{string} {string}""|}|}|}", "new object[] { 1 }", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2017:{|CA1727:{|CA1727:""{string} {string}""|}|}|}", "new object[] { 1 }", false)] [MemberData(nameof(GenerateDefineUsages), @"{|CA1727:{|CA1727:""{string} {string}""|}|}")] // CA2253 is not enabled by default. @@ -75,15 +75,15 @@ public async Task TemplateDiagnosticsAreNotProduced(string format) } [Theory] - [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] - [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] - [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] - [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two}""|});")] - [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2255:""{One} {Two} {Three}""|});")] - [InlineData(@"LoggerMessage.DefineScope({|CA2255:""{One} {Two} {Three}""|});")] - [InlineData(@"LoggerMessage.DefineScope({|CA2255:""{One} {Two} {Three}""|});")] - [InlineData(@"LoggerMessage.DefineScope({|CA2255:""{One} {Two}""|});")] - public async Task CA2255IsProducedForDefineMessageTypeParameterMismatch(string expression) + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2017:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2017:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2017:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2017:""{One} {Two}""|});")] + [InlineData(@"LoggerMessage.Define(LogLevel.Information, 42, {|CA2017:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.DefineScope({|CA2017:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.DefineScope({|CA2017:""{One} {Two} {Three}""|});")] + [InlineData(@"LoggerMessage.DefineScope({|CA2017:""{One} {Two}""|});")] + public async Task CA2017IsProducedForDefineMessageTypeParameterMismatch(string expression) { await TriggerCodeAsync(expression); } diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index 7b74f90ea2..811d4f6e2f 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -14,11 +14,11 @@ Globalization: CA2101, CA1300-CA1310 Mobility: CA1600-CA1601 Performance: HA, CA1800-CA1848 Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5403 -Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2255 +Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2254 Naming: CA1700-CA1727 Interoperability: CA1400-CA1419 Maintainability: CA1500-CA1509 -Reliability: CA9998-CA9999, CA2000-CA2016 +Reliability: CA9998-CA9999, CA2000-CA2017 Documentation: CA1200-CA1200 # Microsoft CodeAnalysis API rules From 7c668b7c6818ffbf0d8e69b27ee1a1f7ab69058d Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 27 Jul 2021 12:44:47 -0700 Subject: [PATCH 29/37] narrow down scope of 4th diagnostic to LogTrace and friends --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 13 +++++++++---- .../Runtime/LoggerMessageDefineTests.cs | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index b0789a2332..57043fd13a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -121,9 +121,11 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo var methodSymbol = invocation.TargetMethod; var containingType = methodSymbol.ContainingType; + bool usingLoggerExtensionsTypes = false; - if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) + if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) // the condition I want { + usingLoggerExtensionsTypes = true; context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); } else if ( @@ -185,17 +187,20 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo if (formatExpression is not null) { - AnalyzeFormatArgument(context, formatExpression, paramsCount, argsIsArray); + AnalyzeFormatArgument(context, formatExpression, paramsCount, argsIsArray, usingLoggerExtensionsTypes); } } } - private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation formatExpression, int paramsCount, bool argsIsArray) + private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation formatExpression, int paramsCount, bool argsIsArray, bool usingLoggerExtensionsTypes) { var text = TryGetFormatText(formatExpression); if (text == null) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, formatExpression.Syntax.GetLocation())); + if (usingLoggerExtensionsTypes) + { + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, formatExpression.Syntax.GetLocation())); + } return; } diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 3831b17844..40fe6c209b 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -28,8 +28,8 @@ public async Task CA2253IsProducedForNumericFormatArgument(string format) } [Theory] - [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @"{|CA2254:$""{string.Empty}""|}", "")] - [MemberData(nameof(GenerateTemplateAndDefineUsageIgnoresCA1848ForBeginScope), @"{|CA2254:""string"" + 2|}", "")] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2254:$""{string.Empty}""|}", "11", false)] + [MemberData(nameof(GenerateTemplateUsages), @"{|CA2254:""string"" + 2|}", "11", false)] public async Task CA2254IsProducedForDynamicFormatArgument(string format) { await TriggerCodeAsync(format); From 88ed19ac1a62485d0be69c96dcbb394f87f6f44b Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 27 Jul 2021 18:06:19 -0700 Subject: [PATCH 30/37] updating messages to become a bit more clear --- ...icrosoftCodeQualityAnalyzersResources.resx | 30 +++++----- ...rosoftCodeQualityAnalyzersResources.cs.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.de.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.es.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.fr.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.it.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.ja.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.ko.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.pl.xlf | 60 +++++++++---------- ...oftCodeQualityAnalyzersResources.pt-BR.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.ru.xlf | 60 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.tr.xlf | 60 +++++++++---------- ...tCodeQualityAnalyzersResources.zh-Hans.xlf | 60 +++++++++---------- ...tCodeQualityAnalyzersResources.zh-Hant.xlf | 60 +++++++++---------- .../Runtime/LoggerMessageDefineAnalyzer.cs | 18 +++--- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 20 +++---- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 20 +++---- src/NetAnalyzers/RulesMissingDocumentation.md | 10 ++-- 18 files changed, 441 insertions(+), 437 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx index 06ddddc7f0..02fb8fb6ac 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx @@ -172,49 +172,49 @@ Abstract type '{0}' should not have public constructors - Numerics should not be used in logging format string + Named holes should not be numeric values - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. - Logging format string parameter count mismatch + Parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. - Use compiled log messages + Use the LoggerMessage delegates - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. - Logging format string should not be dynamically generated + Template should be a static expression - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. - Use PascalCase for log message tokens + Use PascalCase for named holes - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. Mark assemblies with CLSCompliant diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf index 7cb09a29b0..9d17212611 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf index 3adf2cff54..a5e13581a0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf index f5d2f12870..30ba8ca441 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf index 993db0e5d7..be5fe03980 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf index fcb5d4febd..172b6e2927 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf index a027cf8081..cf8b65c595 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf index 977646c789..70a3e51e34 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf index 292193f3eb..18dafad8f8 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf index 952aed93c2..092e57f2d3 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf index 450c4c4682..9958b0e59b 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf index 1202e4a54c..52eda13298 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf index 914d0d82e7..06522a6e28 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf index 7c16d8c0f4..89091c703e 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf @@ -243,78 +243,78 @@ - Logging format string should not be dynamically generated. - Logging format string should not be dynamically generated. + The logging message template should not vary between calls. + The logging message template should not vary between calls. - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + The logging message template should not vary between calls to '{0}' + The logging message template should not vary between calls to '{0}' - Logging format string should not be dynamically generated - Logging format string should not be dynamically generated + Template should be a static expression + Template should be a static expression - Logging format string parameter count mismatch. - Logging format string parameter count mismatch. + Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named holes. - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named holes - Logging format string parameter count mismatch - Logging format string parameter count mismatch + Parameter count mismatch + Parameter count mismatch - Numerics should not be used in logging format string. - Numerics should not be used in logging format string. + Named holes in the logging message template should not be comprised of only numeric characters. + Named holes in the logging message template should not be comprised of only numeric characters. - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes in the logging message template should not be comprised of only numeric characters + Named holes in the logging message template should not be comprised of only numeric characters - Numerics should not be used in logging format string - Numerics should not be used in logging format string + Named holes should not be numeric values + Named holes should not be numeric values - For improved performance, use pre-compiled log messages. - For improved performance, use pre-compiled log messages. + For improved performance, use the LoggerMessage delegates. + For improved performance, use the LoggerMessage delegates. - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message - For improved performance, use pre-compiled log messages instead of calling '{0}' with a string message + For improved performance, use the LoggerMessage delegates instead of calling '{0}' + For improved performance, use the LoggerMessage delegates instead of calling '{0}' - Use compiled log messages - Use compiled log messages + Use the LoggerMessage delegates + Use the LoggerMessage delegates - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. + Use PascalCase for named holes in the logging message template. + Use PascalCase for named holes in the logging message template. - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens - For consistency with logs emitted from other components, use 'PascalCase' for log message tokens + Use PascalCase for named holes in the logging message template + Use PascalCase for named holes in the logging message template - Use PascalCase for log message tokens - Use PascalCase for log message tokens + Use PascalCase for named holes + Use PascalCase for named holes diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 57043fd13a..12261307b6 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -126,7 +126,7 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) // the condition I want { usingLoggerExtensionsTypes = true; - context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, invocation.Syntax.GetLocation(), methodSymbol.Name)); + context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(invocation)), methodSymbol.Name)); } else if ( !containingType.Equals(loggerType, SymbolEqualityComparer.Default) && @@ -187,19 +187,19 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo if (formatExpression is not null) { - AnalyzeFormatArgument(context, formatExpression, paramsCount, argsIsArray, usingLoggerExtensionsTypes); + AnalyzeFormatArgument(context, formatExpression, paramsCount, argsIsArray, usingLoggerExtensionsTypes, methodSymbol); } } } - private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation formatExpression, int paramsCount, bool argsIsArray, bool usingLoggerExtensionsTypes) + private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation formatExpression, int paramsCount, bool argsIsArray, bool usingLoggerExtensionsTypes, IMethodSymbol methodSymbol) { var text = TryGetFormatText(formatExpression); if (text == null) { if (usingLoggerExtensionsTypes) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(formatExpression)), methodSymbol.Name)); } return; } @@ -220,21 +220,25 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation { if (int.TryParse(valueName, out _)) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2253Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2253Rule)); } else if (char.IsLower(valueName[0])) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA1727Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA1727Rule)); } } var argsPassedDirectly = argsIsArray && paramsCount == 1; if (!argsPassedDirectly && paramsCount != formatter.ValueNames.Count) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2017Rule, formatExpression.Syntax.GetLocation())); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2017Rule)); } } + private static SymbolDisplayFormat GetLanguageSpecificFormat(IOperation operation) => + operation.Language == LanguageNames.CSharp ? + SymbolDisplayFormat.CSharpShortErrorMessageFormat : SymbolDisplayFormat.VisualBasicShortErrorMessageFormat; + private string? TryGetFormatText(IOperation? argumentExpression) { if (argumentExpression is null) diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 13492bd39d..a1bdce91c8 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -972,9 +972,9 @@ Consistent naming of parameters in an override hierarchy increases the usability |CodeFix|True| --- -## [CA1727](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727): Use PascalCase for log message tokens +## [CA1727](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727): Use PascalCase for named holes -For consistency with logs emitted from other components, use 'PascalCase' for log message tokens. +Use PascalCase for named holes in the logging message template. |Item|Value| |-|-| @@ -1440,9 +1440,9 @@ It is more efficient to use 'AsSpan' and 'string.Concat', instead of 'Substring' |CodeFix|True| --- -## [CA1848](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848): Use compiled log messages +## [CA1848](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848): Use the LoggerMessage delegates -For improved performance, use pre-compiled log messages. +For improved performance, use the LoggerMessage delegates. |Item|Value| |-|-| @@ -1584,9 +1584,9 @@ Forward the 'CancellationToken' parameter to methods to ensure the operation can |CodeFix|True| --- -## [CA2017](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017): Logging format string parameter count mismatch +## [CA2017](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017): Parameter count mismatch -Logging format string parameter count mismatch. +Number of parameters supplied in the logging message template do not match the number of named holes. |Item|Value| |-|-| @@ -2052,9 +2052,9 @@ An assembly has to opt into preview features before using them. |CodeFix|False| --- -## [CA2253](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253): Numerics should not be used in logging format string +## [CA2253](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253): Named holes should not be numeric values -Numerics should not be used in logging format string. +Named holes in the logging message template should not be comprised of only numeric characters. |Item|Value| |-|-| @@ -2064,9 +2064,9 @@ Numerics should not be used in logging format string. |CodeFix|False| --- -## [CA2254](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254): Logging format string should not be dynamically generated +## [CA2254](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254): Template should be a static expression -Logging format string should not be dynamically generated. +The logging message template should not vary between calls. |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 09b3b65142..9020ba55df 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -2014,8 +2014,8 @@ }, "CA1727": { "id": "CA1727", - "shortDescription": "Use PascalCase for log message tokens", - "fullDescription": "For consistency with logs emitted from other components, use 'PascalCase' for log message tokens.", + "shortDescription": "Use PascalCase for named holes", + "fullDescription": "Use PascalCase for named holes in the logging message template.", "defaultLevel": "hidden", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727", "properties": { @@ -2664,8 +2664,8 @@ }, "CA1848": { "id": "CA1848", - "shortDescription": "Use compiled log messages", - "fullDescription": "For improved performance, use pre-compiled log messages.", + "shortDescription": "Use the LoggerMessage delegates", + "fullDescription": "For improved performance, use the LoggerMessage delegates.", "defaultLevel": "hidden", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1848", "properties": { @@ -2867,8 +2867,8 @@ }, "CA2017": { "id": "CA2017", - "shortDescription": "Logging format string parameter count mismatch", - "fullDescription": "Logging format string parameter count mismatch.", + "shortDescription": "Parameter count mismatch", + "fullDescription": "Number of parameters supplied in the logging message template do not match the number of named holes.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017", "properties": { @@ -3612,8 +3612,8 @@ }, "CA2253": { "id": "CA2253", - "shortDescription": "Numerics should not be used in logging format string", - "fullDescription": "Numerics should not be used in logging format string.", + "shortDescription": "Named holes should not be numeric values", + "fullDescription": "Named holes in the logging message template should not be comprised of only numeric characters.", "defaultLevel": "note", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253", "properties": { @@ -3632,8 +3632,8 @@ }, "CA2254": { "id": "CA2254", - "shortDescription": "Logging format string should not be dynamically generated", - "fullDescription": "Logging format string should not be dynamically generated.", + "shortDescription": "Template should be a static expression", + "fullDescription": "The logging message template should not vary between calls.", "defaultLevel": "note", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2254", "properties": { diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index c4eeb0d728..fec3df2202 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -4,13 +4,13 @@ Rule ID | Missing Help Link | Title | --------|-------------------|-------| CA1418 | | Use valid platform string | CA1419 | | Provide a public parameterless constructor for concrete types derived from 'System.Runtime.InteropServices.SafeHandle' | -CA1727 | | Use PascalCase for log message tokens | +CA1727 | | Use PascalCase for named holes | CA1839 | | Use 'Environment.ProcessPath' | CA1840 | | Use 'Environment.CurrentManagedThreadId' | CA1842 | | Do not use 'WhenAll' with a single task | CA1843 | | Do not use 'WaitAll' with a single task | -CA1848 | | Use compiled log messages | -CA2017 | | Logging format string parameter count mismatch | +CA1848 | | Use the LoggerMessage delegates | +CA2017 | | Parameter count mismatch | CA2252 | | This API requires opting into preview features | -CA2253 | | Numerics should not be used in logging format string | -CA2254 | | Logging format string should not be dynamically generated | +CA2253 | | Named holes should not be numeric values | +CA2254 | | Template should be a static expression | From 0e517e5cbce5c66549f1aec978a9cefb4e51d099 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Tue, 27 Jul 2021 18:13:49 -0700 Subject: [PATCH 31/37] Apply nit feedback --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 12261307b6..7a43f52b5a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; @@ -123,7 +124,7 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo var containingType = methodSymbol.ContainingType; bool usingLoggerExtensionsTypes = false; - if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) // the condition I want + if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) { usingLoggerExtensionsTypes = true; context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(invocation)), methodSymbol.Name)); @@ -163,7 +164,7 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo } else if (parameter.Equals(paramsArgument, SymbolEqualityComparer.Default)) { - var parameterType = argument.Parameter.Type;// TODO test + var parameterType = argument.Parameter.Type; if (parameterType == null) { return; @@ -289,7 +290,7 @@ private static SymbolDisplayFormat GetLanguageSpecificFormat(IOperation operatio } } - private static bool FindLogParameters(IMethodSymbol methodSymbol, out IParameterSymbol? message, out IParameterSymbol? arguments) + private static bool FindLogParameters(IMethodSymbol methodSymbol, [NotNullWhen(true)] out IParameterSymbol? message, out IParameterSymbol? arguments) { message = null; arguments = null; From 24f5bfb23e45bda918fa1b0adb9ca8f47a859f3a Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Wed, 28 Jul 2021 10:02:41 -0700 Subject: [PATCH 32/37] nit feedback --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 4 ++-- .../Runtime/LoggerMessageDefineTests.cs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 7a43f52b5a..ad6da11527 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -127,7 +127,7 @@ private void AnalyzeInvocation(OperationAnalysisContext context, INamedTypeSymbo if (containingType.Equals(loggerExtensionsType, SymbolEqualityComparer.Default)) { usingLoggerExtensionsTypes = true; - context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(invocation)), methodSymbol.Name)); + context.ReportDiagnostic(invocation.CreateDiagnostic(CA1848Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(invocation)))); } else if ( !containingType.Equals(loggerType, SymbolEqualityComparer.Default) && @@ -200,7 +200,7 @@ private void AnalyzeFormatArgument(OperationAnalysisContext context, IOperation { if (usingLoggerExtensionsTypes) { - context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(formatExpression)), methodSymbol.Name)); + context.ReportDiagnostic(formatExpression.CreateDiagnostic(CA2254Rule, methodSymbol.ToDisplayString(GetLanguageSpecificFormat(formatExpression)))); } return; } diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs index 40fe6c209b..a32cc02d66 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineTests.cs @@ -187,10 +187,7 @@ public static void Main() await new VerifyCS.Test { LanguageVersion = CodeAnalysis.CSharp.LanguageVersion.CSharp9, - TestState = - { - Sources = { code } - }, + TestCode = code, ReferenceAssemblies = AdditionalMetadataReferences.DefaultWithMELogging, }.RunAsync(); } From 87443d4de05f8401e0067362618d0a3e54dc5a36 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Wed, 28 Jul 2021 10:12:01 -0700 Subject: [PATCH 33/37] if to else if --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index ad6da11527..22bfb7ac04 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -303,16 +303,14 @@ private static bool FindLogParameters(IMethodSymbol methodSymbol, [NotNullWhen(t { message = parameter; } - // When calling logger.BeginScope("{Param}") generic overload would be selected - if (parameter.Type.SpecialType == SpecialType.System_String && + else if (parameter.Type.SpecialType == SpecialType.System_String && methodSymbol.Name.Equals("BeginScope") && string.Equals(parameter.Name, "state", StringComparison.Ordinal)) { message = parameter; } - - if (parameter.IsParams && + else if (parameter.IsParams && string.Equals(parameter.Name, "args", StringComparison.Ordinal)) { arguments = parameter; From 0c84b5913fd41eb3a232609758d544265c0ee202 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Wed, 28 Jul 2021 10:33:34 -0700 Subject: [PATCH 34/37] rename: named hole -> named placeholder --- ...icrosoftCodeQualityAnalyzersResources.resx | 16 +++++----- ...rosoftCodeQualityAnalyzersResources.cs.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.de.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.es.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.fr.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.it.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.ja.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.ko.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.pl.xlf | 32 +++++++++---------- ...oftCodeQualityAnalyzersResources.pt-BR.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.ru.xlf | 32 +++++++++---------- ...rosoftCodeQualityAnalyzersResources.tr.xlf | 32 +++++++++---------- ...tCodeQualityAnalyzersResources.zh-Hans.xlf | 32 +++++++++---------- ...tCodeQualityAnalyzersResources.zh-Hant.xlf | 32 +++++++++---------- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 10 +++--- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 10 +++--- src/NetAnalyzers/RulesMissingDocumentation.md | 4 +-- 17 files changed, 228 insertions(+), 228 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx index 02fb8fb6ac..b9ce33c889 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx @@ -172,22 +172,22 @@ Abstract type '{0}' should not have public constructors - Named holes should not be numeric values + Named placeholders should not be numeric values - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. Parameter count mismatch - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. Use the LoggerMessage delegates @@ -208,13 +208,13 @@ The logging message template should not vary between calls. - Use PascalCase for named holes + Use PascalCase for named placeholders - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. Mark assemblies with CLSCompliant diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf index 9d17212611..7fe6c80d77 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf index a5e13581a0..84126376c8 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf index 30ba8ca441..6379a18e5a 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf index be5fe03980..dd9f9a1faf 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf index 172b6e2927..9a52ae20c8 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf index cf8b65c595..3993774afb 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf index 70a3e51e34..3d4dcb1df1 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf index 18dafad8f8..7d0fe430f6 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf index 092e57f2d3..11776712eb 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf index 9958b0e59b..2982c8cd89 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf index 52eda13298..1ae08b88e3 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf index 06522a6e28..8679a0ab9d 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf index 89091c703e..4826b3bbc0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf @@ -258,13 +258,13 @@ - Number of parameters supplied in the logging message template do not match the number of named holes. - Number of parameters supplied in the logging message template do not match the number of named holes. + Number of parameters supplied in the logging message template do not match the number of named placeholders. + Number of parameters supplied in the logging message template do not match the number of named placeholders. - Number of parameters supplied in the logging message template do not match the number of named holes - Number of parameters supplied in the logging message template do not match the number of named holes + Number of parameters supplied in the logging message template do not match the number of named placeholders + Number of parameters supplied in the logging message template do not match the number of named placeholders @@ -273,18 +273,18 @@ - Named holes in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. + Named placeholders in the logging message template should not be comprised of only numeric characters. - Named holes in the logging message template should not be comprised of only numeric characters - Named holes in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters + Named placeholders in the logging message template should not be comprised of only numeric characters - Named holes should not be numeric values - Named holes should not be numeric values + Named placeholders should not be numeric values + Named placeholders should not be numeric values @@ -303,18 +303,18 @@ - Use PascalCase for named holes in the logging message template. - Use PascalCase for named holes in the logging message template. + Use PascalCase for named placeholders in the logging message template. + Use PascalCase for named placeholders in the logging message template. - Use PascalCase for named holes in the logging message template - Use PascalCase for named holes in the logging message template + Use PascalCase for named placeholders in the logging message template + Use PascalCase for named placeholders in the logging message template - Use PascalCase for named holes - Use PascalCase for named holes + Use PascalCase for named placeholders + Use PascalCase for named placeholders diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index a1bdce91c8..b8cdd70e3c 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -972,9 +972,9 @@ Consistent naming of parameters in an override hierarchy increases the usability |CodeFix|True| --- -## [CA1727](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727): Use PascalCase for named holes +## [CA1727](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727): Use PascalCase for named placeholders -Use PascalCase for named holes in the logging message template. +Use PascalCase for named placeholders in the logging message template. |Item|Value| |-|-| @@ -1586,7 +1586,7 @@ Forward the 'CancellationToken' parameter to methods to ensure the operation can ## [CA2017](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017): Parameter count mismatch -Number of parameters supplied in the logging message template do not match the number of named holes. +Number of parameters supplied in the logging message template do not match the number of named placeholders. |Item|Value| |-|-| @@ -2052,9 +2052,9 @@ An assembly has to opt into preview features before using them. |CodeFix|False| --- -## [CA2253](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253): Named holes should not be numeric values +## [CA2253](https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253): Named placeholders should not be numeric values -Named holes in the logging message template should not be comprised of only numeric characters. +Named placeholders in the logging message template should not be comprised of only numeric characters. |Item|Value| |-|-| diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index 9020ba55df..1c022d4418 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -2014,8 +2014,8 @@ }, "CA1727": { "id": "CA1727", - "shortDescription": "Use PascalCase for named holes", - "fullDescription": "Use PascalCase for named holes in the logging message template.", + "shortDescription": "Use PascalCase for named placeholders", + "fullDescription": "Use PascalCase for named placeholders in the logging message template.", "defaultLevel": "hidden", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1727", "properties": { @@ -2868,7 +2868,7 @@ "CA2017": { "id": "CA2017", "shortDescription": "Parameter count mismatch", - "fullDescription": "Number of parameters supplied in the logging message template do not match the number of named holes.", + "fullDescription": "Number of parameters supplied in the logging message template do not match the number of named placeholders.", "defaultLevel": "warning", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2017", "properties": { @@ -3612,8 +3612,8 @@ }, "CA2253": { "id": "CA2253", - "shortDescription": "Named holes should not be numeric values", - "fullDescription": "Named holes in the logging message template should not be comprised of only numeric characters.", + "shortDescription": "Named placeholders should not be numeric values", + "fullDescription": "Named placeholders in the logging message template should not be comprised of only numeric characters.", "defaultLevel": "note", "helpUri": "https://docs.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2253", "properties": { diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index fec3df2202..d18df7912d 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -4,7 +4,7 @@ Rule ID | Missing Help Link | Title | --------|-------------------|-------| CA1418 | | Use valid platform string | CA1419 | | Provide a public parameterless constructor for concrete types derived from 'System.Runtime.InteropServices.SafeHandle' | -CA1727 | | Use PascalCase for named holes | +CA1727 | | Use PascalCase for named placeholders | CA1839 | | Use 'Environment.ProcessPath' | CA1840 | | Use 'Environment.CurrentManagedThreadId' | CA1842 | | Do not use 'WhenAll' with a single task | @@ -12,5 +12,5 @@ CA1843 | | Use the LoggerMessage delegates | CA2017 | | Parameter count mismatch | CA2252 | | This API requires opting into preview features | -CA2253 | | Named holes should not be numeric values | +CA2253 | | Named placeholders should not be numeric values | CA2254 | | Template should be a static expression | From cf7cc42b2e4df292ef42f1ff768e79cfb1761396 Mon Sep 17 00:00:00 2001 From: Maryam Ariyan Date: Wed, 28 Jul 2021 10:46:18 -0700 Subject: [PATCH 35/37] fix paranthesis issue --- .../Runtime/LoggerMessageDefineAnalyzer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs index 22bfb7ac04..8d9a218281 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Runtime/LoggerMessageDefineAnalyzer.cs @@ -297,9 +297,9 @@ private static bool FindLogParameters(IMethodSymbol methodSymbol, [NotNullWhen(t foreach (var parameter in methodSymbol.Parameters) { if (parameter.Type.SpecialType == SpecialType.System_String && - string.Equals(parameter.Name, "message", StringComparison.Ordinal) || + (string.Equals(parameter.Name, "message", StringComparison.Ordinal) || string.Equals(parameter.Name, "messageFormat", StringComparison.Ordinal) || - string.Equals(parameter.Name, "formatString", StringComparison.Ordinal)) + string.Equals(parameter.Name, "formatString", StringComparison.Ordinal))) { message = parameter; } From c19648eaec4ab5a69065aca8105a12599407799e Mon Sep 17 00:00:00 2001 From: Jonathon Marolf Date: Wed, 28 Jul 2021 11:04:03 -0700 Subject: [PATCH 36/37] do not update the label --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index ae7e7e2157..199a69e37f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -3,7 +3,7 @@ 3.3.3 beta1 6.0.0 - preview7 + rc1 $(VersionPrefix)