From 361da32d778a46c10dfc389cb805b312aef4507b Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Fri, 27 Mar 2020 10:46:18 -0700 Subject: [PATCH 1/6] Add a new diagnostic/code fix to prompt analyzer authors to enable release tracking analyzers Also updated the documentation accordingly. --- ...soft.CodeAnalysis.Analyzers.Package.csproj | 1 + .../Microsoft.CodeAnalysis.Analyzers.targets | 9 + .../CodeAnalysisDiagnosticsResources.resx | 9 + .../Core/DiagnosticIds.cs | 1 + .../DiagnosticDescriptorCreationAnalyzer.cs | 8 +- ...criptorCreationAnalyzer_ReleaseTracking.cs | 15 +- .../Fixers/AnalyzerReleaseTrackingFix.cs | 36 +++- .../Microsoft.CodeAnalysis.Analyzers.csproj | 3 + .../CodeAnalysisDiagnosticsResources.cs.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.de.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.es.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.fr.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.it.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.ja.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.ko.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.pl.xlf | 15 ++ ...CodeAnalysisDiagnosticsResources.pt-BR.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.ru.xlf | 15 ++ .../CodeAnalysisDiagnosticsResources.tr.xlf | 15 ++ ...deAnalysisDiagnosticsResources.zh-Hans.xlf | 15 ++ ...deAnalysisDiagnosticsResources.zh-Hant.xlf | 15 ++ .../Microsoft.CodeAnalysis.Analyzers.md | 9 + .../Microsoft.CodeAnalysis.Analyzers.sarif | 171 ++++++++++++++++++ .../ReleaseTrackingAnalyzers.Help.md | 13 +- .../ReleaseTrackingAnalyzerTests.cs | 66 ++++++- .../enable-analyzer-release-tracking.png | Bin 0 -> 113291 bytes 26 files changed, 529 insertions(+), 7 deletions(-) create mode 100644 nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.targets create mode 100644 src/Microsoft.CodeAnalysis.Analyzers/enable-analyzer-release-tracking.png diff --git a/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.Package.csproj b/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.Package.csproj index 5ca2d53f94..bc876651de 100644 --- a/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.Package.csproj +++ b/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.Package.csproj @@ -21,6 +21,7 @@ + diff --git a/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.targets b/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.targets new file mode 100644 index 0000000000..0a99c914e2 --- /dev/null +++ b/nuget/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.targets @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/CodeAnalysisDiagnosticsResources.resx b/src/Microsoft.CodeAnalysis.Analyzers/Core/CodeAnalysisDiagnosticsResources.resx index 019118a8e6..5aedb4ca86 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/CodeAnalysisDiagnosticsResources.resx +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/CodeAnalysisDiagnosticsResources.resx @@ -494,4 +494,13 @@ Invalid entry in analyzer release file. + + Enable analyzer release tracking + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + \ No newline at end of file diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/DiagnosticIds.cs b/src/Microsoft.CodeAnalysis.Analyzers/Core/DiagnosticIds.cs index bb4f95dba7..28dbaa8274 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/DiagnosticIds.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/DiagnosticIds.cs @@ -44,5 +44,6 @@ internal static class DiagnosticIds public const string RemoveDuplicateEntriesForAnalyzerReleaseRuleId = "RS2005"; public const string RemoveDuplicateEntriesBetweenAnalyzerReleasesRuleId = "RS2006"; public const string InvalidEntryInAnalyzerReleasesFileRuleId = "RS2007"; + public const string EnableAnalyzerReleaseTrackingRuleId = "RS2008"; } } diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer.cs b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer.cs index 8ef1a0f2fa..8e32edc20d 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer.cs @@ -147,7 +147,8 @@ public sealed partial class DiagnosticDescriptorCreationAnalyzer : DiagnosticAna InvalidEntryInAnalyzerReleasesFileRule, InvalidHeaderInAnalyzerReleasesFileRule, InvalidUndetectedEntryInAnalyzerReleasesFileRule, - InvalidRemovedOrChangedWithoutPriorNewEntryInAnalyzerReleasesFileRule); + InvalidRemovedOrChangedWithoutPriorNewEntryInAnalyzerReleasesFileRule, + EnableAnalyzerReleaseTrackingRule); public override void Initialize(AnalysisContext context) { @@ -505,6 +506,11 @@ ConcurrentDictionary> UpdateNamedTypeFactory(str AnalyzeAnalyzerReleases(ruleId, argument, category, analyzerName, helpLink, isEnabledByDefault, defaultSeverity, shippedData, unshippedData, operationAnalysisContext.ReportDiagnostic); } + else if (shippedData == null && unshippedData == null) + { + var diagnostic = argument.CreateDiagnostic(EnableAnalyzerReleaseTrackingRule, ruleId); + operationAnalysisContext.ReportDiagnostic(diagnostic); + } } else { diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer_ReleaseTracking.cs b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer_ReleaseTracking.cs index 5344cb4139..4241a9d54a 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer_ReleaseTracking.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer_ReleaseTracking.cs @@ -159,6 +159,17 @@ public sealed partial class DiagnosticDescriptorCreationAnalyzer helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", customTags: WellKnownDiagnosticTags.Telemetry); + internal static readonly DiagnosticDescriptor EnableAnalyzerReleaseTrackingRule = new DiagnosticDescriptor( + id: DiagnosticIds.EnableAnalyzerReleaseTrackingRuleId, + title: CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleTitle, + messageFormat: CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleMessage, + category: DiagnosticCategory.MicrosoftCodeAnalysisReleaseTracking, + defaultSeverity: DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleDescription, + helpLinkUri: "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + customTags: WellKnownDiagnosticTags.Telemetry); + private static bool TryGetReleaseTrackingData( ImmutableArray additionalTexts, CancellationToken cancellationToken, @@ -169,8 +180,8 @@ private static bool TryGetReleaseTrackingData( if (!TryGetReleaseTrackingFiles(additionalTexts, cancellationToken, out var shippedText, out var unshippedText)) { // TODO: Report a diagnostic that both must be specified if either shippedText or unshippedText is non-null. - shippedData = default; - unshippedData = default; + shippedData = shippedText != null ? ReleaseTrackingData.Default : null; + unshippedData = unshippedText != null ? ReleaseTrackingData.Default : null; invalidFileDiagnostics = null; return false; } diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.cs b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.cs index 143892bed9..ba744f003f 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.cs @@ -24,8 +24,16 @@ public sealed partial class AnalyzerReleaseTrackingFix : CodeFixProvider private const string EntryFieldSeparator = "|"; private static readonly string[] s_entryFieldSeparators = new[] { EntryFieldSeparator }; + internal const string ShippedAnalyzerReleaseTrackingFileDefaultContent = @"; Shipped analyzer releases +" + CommonAnalyzerReleaseTrackingContent; + internal const string UnshippedAnalyzerReleaseTrackingFileDefaultContent = @"; Unshipped analyzer release +" + CommonAnalyzerReleaseTrackingContent; + private const string CommonAnalyzerReleaseTrackingContent = @"; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md + +"; + public override ImmutableArray FixableDiagnosticIds => - ImmutableArray.Create(DiagnosticIds.DeclareDiagnosticIdInAnalyzerReleaseRuleId, DiagnosticIds.UpdateDiagnosticIdInAnalyzerReleaseRuleId); + ImmutableArray.Create(DiagnosticIds.DeclareDiagnosticIdInAnalyzerReleaseRuleId, DiagnosticIds.UpdateDiagnosticIdInAnalyzerReleaseRuleId, DiagnosticIds.EnableAnalyzerReleaseTrackingRuleId); public override FixAllProvider GetFixAllProvider() => new ReleaseTrackingFixAllProvider(); @@ -65,6 +73,13 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) } break; + case DiagnosticIds.EnableAnalyzerReleaseTrackingRuleId: + codeAction = CodeAction.Create( + CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleTitle, + cancellationToken => AddAnalyzerReleaseTrackingFilesAsync(context.Document.Project), + equivalenceKey: CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleTitle); + break; + default: Debug.Fail($"Unsupported diagnostic ID {diagnostic.Id}"); continue; @@ -79,6 +94,25 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context) return Task.CompletedTask; } + private static Task AddAnalyzerReleaseTrackingFilesAsync(Project project) + { + project = AddAdditionalDocument(project, DiagnosticDescriptorCreationAnalyzer.ShippedFileName, ShippedAnalyzerReleaseTrackingFileDefaultContent); + project = AddAdditionalDocument(project, DiagnosticDescriptorCreationAnalyzer.UnshippedFileName, UnshippedAnalyzerReleaseTrackingFileDefaultContent); + return Task.FromResult(project.Solution); + + // Local functions. + static Project AddAdditionalDocument(Project project, string name, string fileContent) + { + TextDocument? additionalDocument = project.AdditionalDocuments.FirstOrDefault(doc => string.Equals(doc.Name, name, StringComparison.OrdinalIgnoreCase)); + if (additionalDocument == null) + { + project = project.AddAdditionalDocument(name, fileContent).Project; + } + + return project; + } + } + private static bool IsAddEntryToUnshippedFileDiagnostic(Diagnostic diagnostic, [NotNullWhen(returnValue: true)] out string? entryToAdd) { if (diagnostic.Properties != null && diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/Microsoft.CodeAnalysis.Analyzers.csproj b/src/Microsoft.CodeAnalysis.Analyzers/Core/Microsoft.CodeAnalysis.Analyzers.csproj index 5920a7d054..eab29554e1 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/Microsoft.CodeAnalysis.Analyzers.csproj +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/Microsoft.CodeAnalysis.Analyzers.csproj @@ -13,6 +13,9 @@ + + + \ No newline at end of file diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.cs.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.cs.xlf index 9770e62625..328f6c829d 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.cs.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.cs.xlf @@ -102,6 +102,21 @@ Nepoužívejte rezervovaná ID diagnostiky. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Povolit souběžné provádění diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.de.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.de.xlf index 0762b74943..479735a557 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.de.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.de.xlf @@ -102,6 +102,21 @@ Verwenden Sie keine reservierten Diagnose-IDs. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Gleichzeitige Ausführung aktivieren diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.es.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.es.xlf index 9b48bb21ea..46c4bcf271 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.es.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.es.xlf @@ -102,6 +102,21 @@ No use identificadores de diagnóstico reservados. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Habilitar la ejecución simultánea diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.fr.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.fr.xlf index 3d6a0bb22a..45f263281d 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.fr.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.fr.xlf @@ -102,6 +102,21 @@ N'utilisez pas d'ID de diagnostic réservés. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Activer l'exécution simultanée diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.it.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.it.xlf index 5b638741c5..7cc17cc7fa 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.it.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.it.xlf @@ -102,6 +102,21 @@ Non usare ID diagnostica riservati. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Abilita l'esecuzione simultanea diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ja.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ja.xlf index 25244f3ae0..7cb2d06626 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ja.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ja.xlf @@ -102,6 +102,21 @@ 予約済みの診断 ID を使用しないでください。 + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution 同時実行を有効にします diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ko.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ko.xlf index 52f0e49219..4918e02fa1 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ko.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ko.xlf @@ -102,6 +102,21 @@ 예약된 진단 ID를 사용하지 마세요. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution 동시 실행 사용 diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pl.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pl.xlf index e853404c07..291fa92e6a 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pl.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pl.xlf @@ -102,6 +102,21 @@ Nie używaj zastrzeżonych identyfikatorów diagnostycznych. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Włącz wykonywanie współbieżne diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pt-BR.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pt-BR.xlf index fcd40106e4..3dfc7bca21 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pt-BR.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.pt-BR.xlf @@ -102,6 +102,21 @@ Não use IDs de diagnóstico reservadas. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Habilitar execução simultânea diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ru.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ru.xlf index 12af31951b..a15b117f90 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ru.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.ru.xlf @@ -102,6 +102,21 @@ Не используйте зарезервированные идентификаторы диагностики. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Включение параллельного выполнения diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.tr.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.tr.xlf index 448debf45f..206af370a0 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.tr.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.tr.xlf @@ -102,6 +102,21 @@ Ayrılmış tanılama kimlikleri kullanmayın. + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution Eşzamanlı yürütmeyi etkinleştir diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hans.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hans.xlf index 5ff1e05607..7257afacd4 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hans.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hans.xlf @@ -102,6 +102,21 @@ 不要使用保留的诊断 ID。 + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution 启用并发执行 diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hant.xlf b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hant.xlf index 3cde5eef26..9f09f0fc9d 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hant.xlf +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/xlf/CodeAnalysisDiagnosticsResources.zh-Hant.xlf @@ -102,6 +102,21 @@ 請勿使用保留的診斷識別碼。 + + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. + + + + Enable analyzer release tracking for the analyzer project containing rule '{0}' + Enable analyzer release tracking for the analyzer project containing rule '{0}' + + + + Enable analyzer release tracking + Enable analyzer release tracking + + Enable concurrent execution 啟用同時執行 diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.md b/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.md index 6524bbc816..93bbc8f526 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.md +++ b/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.md @@ -31,3 +31,12 @@ RS1027 | Types marked with DiagnosticAnalyzerAttribute(s) should inherit from Di RS1028 | Provide non-null 'customTags' value to diagnostic descriptor constructor. | MicrosoftCodeAnalysisDocumentation | False | Warning | False | The 'customTags' value is used as a way to enable specific actions and filters on diagnostic descriptors based on the specific values of the tags. Every Roslyn analyzer should have at least one tag from the 'WellKnownDiagnosticTags' class. | RS1029 | Do not use reserved diagnostic IDs. | MicrosoftCodeAnalysisDesign | True | Warning | False | DiagnosticId for analyzers should not use reserved IDs. | RS1030 | Do not invoke Compilation.GetSemanticModel() method within a diagnostic analyzer | MicrosoftCodeAnalysisCorrectness | True | Warning | False | 'GetSemanticModel' is an expensive method to invoke within a diagnostic analyzer because it creates a completely new semantic model, which does not share compilation data with the compiler or other analyzers. This incurs an additional performance cost during semantic analysis. Instead, consider registering a different analyzer action which allows used of a shared 'SemanticModel', such as 'RegisterOperationAction', 'RegisterSyntaxNodeAction', or 'RegisterSemanticModelAction'. | +[RS2000](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Add analyzer diagnostic IDs to analyzer release. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | True | All supported analyzer diagnostic IDs should be part of an analyzer release. | +[RS2001](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Ensure up-to-date entry for analyzer diagnostic IDs are added to analyzer release. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | True | Ensure up-to-date entry for analyzer diagnostic IDs are added to analyzer release. | +[RS2002](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Do not add removed analyzer diagnostic IDs to unshipped analyzer release. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | False | Entries for analyzer diagnostic IDs that are no longer reported and never shipped can be removed from unshipped analyzer release. | +[RS2003](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Shipped diagnostic IDs that are no longer reported should have an entry in the 'Removed Rules' table in unshipped file. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | False | Shipped diagnostic IDs that are no longer reported should have an entry in the 'Removed Rules' table in unshipped file. | +[RS2004](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Diagnostic IDs marked as removed in analyzer release file should not be reported by analyzers. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | False | Diagnostic IDs marked as removed in analyzer release file should not be reported by analyzers. | +[RS2005](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Remove duplicate entries for diagnostic ID in the same analyzer release. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | False | Remove duplicate entries for diagnostic ID in the same analyzer release. | +[RS2006](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Remove duplicate entries for diagnostic ID between analyzer releases. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | False | Remove duplicate entries for diagnostic ID between analyzer releases. | +[RS2007](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Invalid entry in analyzer release file. | MicrosoftCodeAnalysisReleaseTracking | True | Warning | False | Invalid entry in analyzer release file. | +[RS2008](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) | Enable analyzer release tracking | MicrosoftCodeAnalysisReleaseTracking | True | Warning | True | Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md. | diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.sarif b/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.sarif index f497d7cd79..6cf202597d 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.sarif +++ b/src/Microsoft.CodeAnalysis.Analyzers/Microsoft.CodeAnalysis.Analyzers.sarif @@ -365,6 +365,177 @@ "Telemetry" ] } + }, + "RS2000": { + "id": "RS2000", + "shortDescription": "Add analyzer diagnostic IDs to analyzer release.", + "fullDescription": "All supported analyzer diagnostic IDs should be part of an analyzer release.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2001": { + "id": "RS2001", + "shortDescription": "Ensure up-to-date entry for analyzer diagnostic IDs are added to analyzer release.", + "fullDescription": "Ensure up-to-date entry for analyzer diagnostic IDs are added to analyzer release.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2002": { + "id": "RS2002", + "shortDescription": "Do not add removed analyzer diagnostic IDs to unshipped analyzer release.", + "fullDescription": "Entries for analyzer diagnostic IDs that are no longer reported and never shipped can be removed from unshipped analyzer release.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2003": { + "id": "RS2003", + "shortDescription": "Shipped diagnostic IDs that are no longer reported should have an entry in the 'Removed Rules' table in unshipped file.", + "fullDescription": "Shipped diagnostic IDs that are no longer reported should have an entry in the 'Removed Rules' table in unshipped file.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2004": { + "id": "RS2004", + "shortDescription": "Diagnostic IDs marked as removed in analyzer release file should not be reported by analyzers.", + "fullDescription": "Diagnostic IDs marked as removed in analyzer release file should not be reported by analyzers.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2005": { + "id": "RS2005", + "shortDescription": "Remove duplicate entries for diagnostic ID in the same analyzer release.", + "fullDescription": "Remove duplicate entries for diagnostic ID in the same analyzer release.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2006": { + "id": "RS2006", + "shortDescription": "Remove duplicate entries for diagnostic ID between analyzer releases.", + "fullDescription": "Remove duplicate entries for diagnostic ID between analyzer releases.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2007": { + "id": "RS2007", + "shortDescription": "Invalid entry in analyzer release file.", + "fullDescription": "Invalid entry in analyzer release file.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } + }, + "RS2008": { + "id": "RS2008", + "shortDescription": "Enable analyzer release tracking", + "fullDescription": "Enabling release tracking for analyzer packages helps in tracking and documenting the analyzer diagnostics that ship and/or change with each analyzer release. See details at https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md.", + "defaultLevel": "warning", + "helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md", + "properties": { + "category": "MicrosoftCodeAnalysisReleaseTracking", + "isEnabledByDefault": true, + "typeName": "DiagnosticDescriptorCreationAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry" + ] + } } } }, diff --git a/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md b/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md index 285676900d..fae4a32d8b 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md +++ b/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md @@ -1,5 +1,6 @@ # Release tracking analyzer +## Overview Release tracking analyzer enables third party analyzer packages to define analyzer releases with associated versions. Each release can track the following changes: 1. Additions: Set of new analyzer rules that shipped for the first time in this release. 2. Removals: Set of old analyzer rules that shipped in an earlier release, but are removed starting this release. @@ -18,6 +19,7 @@ Release tracking analyzer provides the diagnostics and code fixes to enable anal 1. Create these two files and pass mark them as additional files for their analyzer project (steps explained in next section), and 2. Move all the entries from unshipped file to the shipped file after each release. +## Example Consider the following example: 1. `AnalyzerReleases.Shipped.md`: @@ -112,13 +114,20 @@ CA6000 | Design | Warning | CA6000_AnalyzerName ``` -# How to enable Release Tracking analyzer +## How to enable Release Tracking analyzer -The following files have to be added to any project referencing this package to enable analysis: +The following additional files have to be added to any project referencing this package to enable analysis: - `AnalyzerReleases.Shipped.md` - `AnalyzerReleases.Unshipped.md` +This can be done in couple of ways, which is detailed in below sections. + +### Using the light bulb + +![Enable analyzer release tracking](./enable-analyzer-release-tracking.png) + +### Manual steps This can be done by: - In Visual Studio, right click project in Solution Explorer, and choose "Add -> New Items", then select "Text File" in "Add new item" dialog. diff --git a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs index 8e1f772b0a..9eebfdb109 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs @@ -28,7 +28,7 @@ public async Task TestNoDeclaredAnalyzers() await VerifyCSharpAsync(source, shippedText, unshippedText); } - [InlineData(@"""Id1""", null, null)] + [InlineData(@"{|RS2008:""Id1""|}", null, null)] [InlineData(@"""Id1""", "", null)] [InlineData(@"""Id1""", null, "")] [InlineData(@"{|RS2000:""Id1""|}", "", "")] @@ -55,6 +55,70 @@ public override void Initialize(AnalysisContext context) {{ }} await VerifyCSharpAsync(source, shippedText, unshippedText); } + [Fact] + public async Task TestCodeFixToEnableAnalyzerReleaseTracking() + { + var source = @" +using System; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +class MyAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor descriptor1 = + new DiagnosticDescriptor({|RS2008:""Id1""|}, ""Title1"", ""Message1"", ""Category1"", DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(descriptor1); + public override void Initialize(AnalysisContext context) { } +}"; + + var fixedSource = @" +using System; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +class MyAnalyzer : DiagnosticAnalyzer +{ + private static readonly DiagnosticDescriptor descriptor1 = + new DiagnosticDescriptor(""Id1"", ""Title1"", ""Message1"", ""Category1"", DiagnosticSeverity.Warning, isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(descriptor1); + public override void Initialize(AnalysisContext context) { } +}"; + var test = new CSharpCodeFixVerifier.Test() + { + ReferenceAssemblies = AdditionalMetadataReferences.Default, + CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck, + TestState = + { + Sources = { source }, + }, + FixedState = + { + Sources = { fixedSource }, + AdditionalFiles = { + (DiagnosticDescriptorCreationAnalyzer.ShippedFileName, + AnalyzerReleaseTrackingFix.ShippedAnalyzerReleaseTrackingFileDefaultContent), + (DiagnosticDescriptorCreationAnalyzer.UnshippedFileName, + AnalyzerReleaseTrackingFix.UnshippedAnalyzerReleaseTrackingFileDefaultContent) + }, + ExpectedDiagnostics = + { + new DiagnosticResult(DiagnosticDescriptorCreationAnalyzer.DeclareDiagnosticIdInAnalyzerReleaseRule) + .WithArguments("Id1") + .WithLocation(11, 34), + } + }, + }; + + test.SolutionTransforms.Add(DisableNonReleaseTrackingWarnings); + await test.RunAsync(); + } + // Unshipped release with existing new rules table. [InlineData("", DefaultUnshippedHeader + "Id1 | Category1 | Warning |")] // Shipped release with existing new rules table. diff --git a/src/Microsoft.CodeAnalysis.Analyzers/enable-analyzer-release-tracking.png b/src/Microsoft.CodeAnalysis.Analyzers/enable-analyzer-release-tracking.png new file mode 100644 index 0000000000000000000000000000000000000000..a15e0d6d9cbe058f4223492b7cc27432724d8a14 GIT binary patch literal 113291 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 Date: Fri, 27 Mar 2020 12:28:32 -0700 Subject: [PATCH 2/6] Fix unit test and add FixAll support --- ...alyzerReleaseTrackingFix.FixAllProvider.cs | 37 +++++++++++++++++++ .../ReleaseTrackingAnalyzerTests.cs | 11 ++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.FixAllProvider.cs b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.FixAllProvider.cs index d81abd39ae..0ee97af155 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.FixAllProvider.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/Fixers/AnalyzerReleaseTrackingFix.FixAllProvider.cs @@ -1,5 +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; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; @@ -57,6 +58,12 @@ public ReleaseTrackingFixAllProvider() { } return null; } + if (fixAllContext.CodeActionEquivalenceKey == CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleTitle) + { + var projectIds = diagnosticsToFix.Select(d => d.Key.Id).ToImmutableArray(); + return new FixAllAddAdditionalDocumentsAction(projectIds, fixAllContext.Solution); + } + return new FixAllAdditionalDocumentChangeAction(fixAllContext.Scope, fixAllContext.Solution, diagnosticsToFix, fixAllContext.CodeActionEquivalenceKey); } @@ -101,6 +108,10 @@ protected override async Task GetChangedSolutionAsync(CancellationToke var newText = await UpdateEntriesInUnshippedFileForDiagnosticsAsync(unshippedDocument, diagnostics, cancellationToken).ConfigureAwait(false); updatedUnshippedText.Add((unshippedDocument.Id, newText)); } + else + { + throw new NotImplementedException(); + } } Solution newSolution = _solution; @@ -141,6 +152,32 @@ private static async Task UpdateEntriesInUnshippedFileForDiagnostics return await UpdateEntriesInUnshippedFileAsync(unshippedDataDocument, entriesToUpdate, cancellationToken).ConfigureAwait(false); } } + + private sealed class FixAllAddAdditionalDocumentsAction : CodeAction + { + private readonly ImmutableArray _projectIds; + private readonly Solution _solution; + + public FixAllAddAdditionalDocumentsAction(ImmutableArray projectIds, Solution solution) + { + _projectIds = projectIds; + _solution = solution; + } + + public override string Title => CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleTitle; + public override string EquivalenceKey => CodeAnalysisDiagnosticsResources.EnableAnalyzerReleaseTrackingRuleTitle; + + protected override async Task GetChangedSolutionAsync(CancellationToken cancellationToken) + { + var newSolution = _solution; + foreach (var projectId in _projectIds) + { + newSolution = await AddAnalyzerReleaseTrackingFilesAsync(newSolution.GetProject(projectId)).ConfigureAwait(false); + } + + return newSolution; + } + } } } } diff --git a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs index 9eebfdb109..fe8fd8e16b 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs @@ -92,7 +92,8 @@ public override void Initialize(AnalysisContext context) { } var test = new CSharpCodeFixVerifier.Test() { ReferenceAssemblies = AdditionalMetadataReferences.Default, - CodeFixTestBehaviors = CodeFixTestBehaviors.FixOne | CodeFixTestBehaviors.SkipFixAllCheck, + NumberOfIncrementalIterations = 2, + NumberOfFixAllIterations = 2, TestState = { Sources = { source }, @@ -104,13 +105,7 @@ public override void Initialize(AnalysisContext context) { } (DiagnosticDescriptorCreationAnalyzer.ShippedFileName, AnalyzerReleaseTrackingFix.ShippedAnalyzerReleaseTrackingFileDefaultContent), (DiagnosticDescriptorCreationAnalyzer.UnshippedFileName, - AnalyzerReleaseTrackingFix.UnshippedAnalyzerReleaseTrackingFileDefaultContent) - }, - ExpectedDiagnostics = - { - new DiagnosticResult(DiagnosticDescriptorCreationAnalyzer.DeclareDiagnosticIdInAnalyzerReleaseRule) - .WithArguments("Id1") - .WithLocation(11, 34), + AnalyzerReleaseTrackingFix.UnshippedAnalyzerReleaseTrackingFileDefaultContent + DefaultUnshippedHeader + "Id1 | Category1 | Warning | MyAnalyzer") } }, }; From bebd64817aff78bf0060d6c1e2d9936a061d4a44 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Fri, 27 Mar 2020 17:15:44 -0700 Subject: [PATCH 3/6] Fix unit tests --- ...agnosticDescriptorCreationAnalyzerTests.cs | 126 +++++++++++++----- 1 file changed, 91 insertions(+), 35 deletions(-) diff --git a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzerTests.cs b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzerTests.cs index 18111bf90f..9ac69eb342 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzerTests.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzerTests.cs @@ -1,5 +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.Collections.Immutable; using System.Threading.Tasks; using Analyzer.Utilities; using Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers; @@ -22,7 +23,7 @@ public class DiagnosticDescriptorCreationAnalyzerTests [Fact] public async Task RS1007_RS1015_CSharp_VerifyDiagnostic() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -54,7 +55,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1007_RS1015_VisualBasic_VerifyDiagnostic() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -83,7 +84,7 @@ End Class [Fact] public async Task RS1007_RS1015_CSharp_VerifyDiagnostic_NamedArgumentCases() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -121,7 +122,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1007_RS1015_VisualBasic_VerifyDiagnostic_NamedArgumentCases() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -154,7 +155,7 @@ End Class [Fact] public async Task RS1007_RS1015_CSharp_NoDiagnosticCases() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -195,7 +196,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1007_RS1015_VisualBasic_NoDiagnosticCases() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -232,7 +233,7 @@ End Class [Fact] public async Task RS1017_RS1019_CSharp_VerifyDiagnostic() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -294,7 +295,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1017_RS1019_CSharp_VerifyDiagnostic_CreateHelper() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -353,7 +354,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1017_RS1019_VisualBasic_VerifyDiagnostic() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -403,7 +404,7 @@ End Class [Fact] public async Task RS1017_RS1019_VisualBasic_VerifyDiagnostic_CreateHelper() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -450,7 +451,7 @@ End Class [Fact] public async Task RS1017_RS1019_CSharp_NoDiagnosticCases() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -493,7 +494,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1017_RS1019_CSharp_NoDiagnosticCases_CreateHelper() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -533,7 +534,7 @@ public override void Initialize(AnalysisContext context) [Fact] public async Task RS1017_RS1019_VisualBasic_NoDiagnosticCases() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -567,7 +568,7 @@ End Class [Fact] public async Task RS1017_RS1019_VisualBasic_NoDiagnosticCases_CreateHelper() { - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -676,7 +677,8 @@ public override void Initialize(AnalysisContext context) GetCSharpRS1028ResultAt(28, 9), GetCSharpRS1018ExpectedDiagnostic(28, 34, "MyThirdPrefix", "CategoryWithPrefixRangeAndId", "MyFirstPrefixXXXX, MySecondPrefix0-MySecondPrefix99, MySecondPrefix300-MySecondPrefix300", AdditionalFileName) } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -751,7 +753,8 @@ public override void Initialize(AnalysisContext context) GetCSharpRS1018ExpectedDiagnostic(25, 43, "MySecondPrefix400", "CategoryWithPrefixRangeAndId", "MyFirstPrefixXXXX, MySecondPrefix0-MySecondPrefix99, MySecondPrefix300-MySecondPrefix300", AdditionalFileName), GetCSharpRS1018ExpectedDiagnostic(28, 43, "MyThirdPrefix", "CategoryWithPrefixRangeAndId", "MyFirstPrefixXXXX, MySecondPrefix0-MySecondPrefix99, MySecondPrefix300-MySecondPrefix300", AdditionalFileName) } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -818,7 +821,8 @@ End Class GetBasicRS1028ResultAt(17, 71), GetBasicRS1018ExpectedDiagnostic(17, 92, "MyThirdPrefix", "CategoryWithPrefixRangeAndId", "MyFirstPrefixXXXX, MySecondPrefix0-MySecondPrefix99, MySecondPrefix300-MySecondPrefix300", AdditionalFileName), } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -880,7 +884,8 @@ End Class GetBasicRS1018ExpectedDiagnostic(16, 101, "MySecondPrefix400", "CategoryWithPrefixRangeAndId", "MyFirstPrefixXXXX, MySecondPrefix0-MySecondPrefix99, MySecondPrefix300-MySecondPrefix300", AdditionalFileName), GetBasicRS1018ExpectedDiagnostic(17, 101, "MyThirdPrefix", "CategoryWithPrefixRangeAndId", "MyFirstPrefixXXXX, MySecondPrefix0-MySecondPrefix99, MySecondPrefix300-MySecondPrefix300", AdditionalFileName), } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -962,7 +967,8 @@ public override void Initialize(AnalysisContext context) GetCSharpRS1028ResultAt(31, 9), GetCSharpRS1028ResultAt(34, 9), } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -1033,7 +1039,8 @@ public override void Initialize(AnalysisContext context) { Sources = { source }, AdditionalFiles = { (AdditionalFileName, additionalText) } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -1098,7 +1105,8 @@ End Class GetBasicRS1028ResultAt(18, 71), GetBasicRS1028ResultAt(19, 71), } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -1153,7 +1161,8 @@ End Class { Sources = { source }, AdditionalFiles = { (AdditionalFileName, additionalText) } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -1260,7 +1269,8 @@ Category with spaces GetCSharpRS1028ResultAt(25, 9), GetCSharpRS1028ResultAt(28, 9), } - } + }, + SolutionTransforms = { WithoutEnableReleaseTrackingWarning } }.RunAsync(); } @@ -1270,7 +1280,7 @@ Category with spaces [Fact] public async Task ReportOnMissingCustomTags() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using Microsoft.CodeAnalysis; public class MyAnalyzer { @@ -1288,7 +1298,7 @@ public void SomeMethod() GetCSharpRS1015ExpectedDiagnostic(6, 50), GetCSharpRS1028ResultAt(6, 50)); - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports Microsoft.CodeAnalysis Public Class MyAnalyzer Friend Shared Rule1 As DiagnosticDescriptor = New DiagnosticDescriptor("""", """", """", """", DiagnosticSeverity.Warning, False) @@ -1307,7 +1317,7 @@ End Sub [Fact] public async Task DoNotReportOnNamedCustomTags() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using Microsoft.CodeAnalysis; public class MyAnalyzer { @@ -1329,7 +1339,7 @@ public void SomeMethod() [Fact] public async Task DoNotReportOnCustomTags() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using Microsoft.CodeAnalysis; public class MyAnalyzer { @@ -1349,7 +1359,7 @@ public void SomeMethod() GetCSharpRS1007ExpectedDiagnostic(8, 50), GetCSharpRS1015ExpectedDiagnostic(8, 132)); - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports Microsoft.CodeAnalysis Public Class MyAnalyzer Friend Shared Rule1 As DiagnosticDescriptor = New DiagnosticDescriptor("""", """", """", """", DiagnosticSeverity.Warning, False, Nothing, Nothing, """") @@ -1372,7 +1382,7 @@ End Sub [Fact, WorkItem(1727, "https://github.com/dotnet/roslyn-analyzers/issues/1727")] public async Task RS1029_AlreadyUsedId_Diagnostic() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -1420,7 +1430,7 @@ public override void Initialize(AnalysisContext context) GetCSharpRS1029ResultAt(25, 34, "CS00000000000000000000"), GetCSharpRS1029ResultAt(28, 34, "BC00000000000000000000")); - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -1458,7 +1468,7 @@ End Sub [Fact, WorkItem(1727, "https://github.com/dotnet/roslyn-analyzers/issues/1727")] public async Task RS1029_DiagnosticIdSimilarButNotReserved_NoDiagnostic() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -1500,7 +1510,7 @@ public override void Initialize(AnalysisContext context) } }"); - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -1532,7 +1542,7 @@ End Sub [Fact, WorkItem(1727, "https://github.com/dotnet/roslyn-analyzers/issues/1727")] public async Task RS1029_DiagnosticIdSimilarButTooShort_NoDiagnostic() { - await VerifyCS.VerifyAnalyzerAsync(@" + await VerifyCSharpAnalyzerAsync(@" using System; using System.Collections.Immutable; using Microsoft.CodeAnalysis; @@ -1565,7 +1575,7 @@ public override void Initialize(AnalysisContext context) } }"); - await VerifyVB.VerifyAnalyzerAsync(@" + await VerifyBasicAnalyzerAsync(@" Imports System Imports System.Collections.Immutable Imports Microsoft.CodeAnalysis @@ -1641,6 +1651,7 @@ public override void Initialize(AnalysisContext context) SolutionTransforms = { (solution, projectId) => solution.GetProject(projectId).WithAssemblyName(assemblyName).Solution, + WithoutEnableReleaseTrackingWarning, }, }.RunAsync(); @@ -1671,7 +1682,8 @@ End Sub SolutionTransforms = { (solution, projectId) => solution.GetProject(projectId).WithAssemblyName(assemblyName).Solution, - }, + WithoutEnableReleaseTrackingWarning, + } }.RunAsync(); } @@ -1760,6 +1772,50 @@ private static DiagnosticResult GetBasicRS1029ResultAt(int line, int column, str .WithLocation(line, column) .WithArguments(ruleId); + private static async Task VerifyCSharpAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var test = new VerifyCS.Test + { + TestState = + { + Sources = { source }, + }, + ReferenceAssemblies = AdditionalMetadataReferences.Default, + TestBehaviors = TestBehaviors.SkipGeneratedCodeCheck + }; + + test.SolutionTransforms.Add(WithoutEnableReleaseTrackingWarning); + test.ExpectedDiagnostics.AddRange(expected); + await test.RunAsync(); + } + + private static async Task VerifyBasicAnalyzerAsync(string source, params DiagnosticResult[] expected) + { + var test = new VerifyVB.Test + { + TestState = + { + Sources = { source }, + }, + ReferenceAssemblies = AdditionalMetadataReferences.Default, + TestBehaviors = TestBehaviors.SkipGeneratedCodeCheck + }; + + test.SolutionTransforms.Add(WithoutEnableReleaseTrackingWarning); + test.ExpectedDiagnostics.AddRange(expected); + await test.RunAsync(); + } + + private static readonly ImmutableDictionary s_enableReleaseTrackingWarningDisabled = ImmutableDictionary.Empty + .Add(DiagnosticDescriptorCreationAnalyzer.EnableAnalyzerReleaseTrackingRule.Id, ReportDiagnostic.Suppress); + + private static Solution WithoutEnableReleaseTrackingWarning(Solution solution, ProjectId projectId) + { + var compilationOptions = solution.GetProject(projectId)!.CompilationOptions!; + compilationOptions = compilationOptions.WithSpecificDiagnosticOptions(compilationOptions.SpecificDiagnosticOptions.SetItems(s_enableReleaseTrackingWarningDisabled)); + return solution.WithProjectCompilationOptions(projectId, compilationOptions); + } + private const string AdditionalFileName = "DiagnosticCategoryAndIdRanges.txt"; private const string CSharpDiagnosticDescriptorCreationHelper = @" From a9beea0a12ff70e7f312d5d1202c825fa2110cb7 Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Fri, 27 Mar 2020 19:21:52 -0700 Subject: [PATCH 4/6] Add unshipped entry for analyzer --- .../Core/AnalyzerReleases.Unshipped.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.CodeAnalysis.Analyzers/Core/AnalyzerReleases.Unshipped.md b/src/Microsoft.CodeAnalysis.Analyzers/Core/AnalyzerReleases.Unshipped.md index aeb06e5d10..1d943a6228 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/Microsoft.CodeAnalysis.Analyzers/Core/AnalyzerReleases.Unshipped.md @@ -15,4 +15,5 @@ RS2003 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCr RS2004 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCreationAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) RS2005 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCreationAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) RS2006 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCreationAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) -RS2007 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCreationAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) \ No newline at end of file +RS2007 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCreationAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) +RS2008 | MicrosoftCodeAnalysisReleaseTracking | Warning | DiagnosticDescriptorCreationAnalyzer, [Documentation](https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md) \ No newline at end of file From c414cd9b01c6d6ea51cadaf71d5d105eab81eb3a Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Fri, 27 Mar 2020 19:22:51 -0700 Subject: [PATCH 5/6] Address feedback for test --- .../ReleaseTrackingAnalyzerTests.cs | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs index fe8fd8e16b..4a40ed4b23 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs +++ b/src/Microsoft.CodeAnalysis.Analyzers/UnitTests/MetaAnalyzers/ReleaseTrackingAnalyzerTests.cs @@ -74,21 +74,6 @@ class MyAnalyzer : DiagnosticAnalyzer public override void Initialize(AnalysisContext context) { } }"; - var fixedSource = @" -using System; -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; - -[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] -class MyAnalyzer : DiagnosticAnalyzer -{ - private static readonly DiagnosticDescriptor descriptor1 = - new DiagnosticDescriptor(""Id1"", ""Title1"", ""Message1"", ""Category1"", DiagnosticSeverity.Warning, isEnabledByDefault: true); - - public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(descriptor1); - public override void Initialize(AnalysisContext context) { } -}"; var test = new CSharpCodeFixVerifier.Test() { ReferenceAssemblies = AdditionalMetadataReferences.Default, @@ -100,7 +85,7 @@ public override void Initialize(AnalysisContext context) { } }, FixedState = { - Sources = { fixedSource }, + Sources = { source }, AdditionalFiles = { (DiagnosticDescriptorCreationAnalyzer.ShippedFileName, AnalyzerReleaseTrackingFix.ShippedAnalyzerReleaseTrackingFileDefaultContent), From e4d14724a461767e83046daa53c53f4fa08a130a Mon Sep 17 00:00:00 2001 From: Manish Vasani Date: Sun, 29 Mar 2020 09:01:45 -0700 Subject: [PATCH 6/6] Update src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md --- .../ReleaseTrackingAnalyzers.Help.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md b/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md index fae4a32d8b..366993c76e 100644 --- a/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md +++ b/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md @@ -130,7 +130,7 @@ This can be done in couple of ways, which is detailed in below sections. ### Manual steps This can be done by: -- In Visual Studio, right click project in Solution Explorer, and choose "Add -> New Items", then select "Text File" in "Add new item" dialog. +- In Visual Studio, right-click the project in Solution Explorer, choose "Add -> New Item...", and then select "Text File" in the "Add New Item" dialog. Then right-click each file, select "Properties", and choose "C# analyzer additional file" for "Build Action" in the "Properties" window. - Or, create these two files at the location you desire, then add the following text to your project/target file (replace file path with its actual location): ```xml