提交 00f38309 编写于 作者: M Manish Vasani

Add support to use editorconfig for set severity command in the Analyzers node context menu

1. Renamed "Set Rule Set Severity" command to "Set severity". Also renamed "Info" and "Hidden" sub-menus to "Suggestion" and "Silent" respectively to align with our editorconfig severity terminology.
2. The set severity command handler checks if the project uses no ruleset or the default built-in ruleset, and if so it adds or updates editorconfig to configure severity. Otherwise, we continue using specified ruleset for configuration.
3. Updated the effective ruleset severity computation for the rule nodes under Analyzers node to account for severity settings from editorconfig (analyzer config documents).
上级 baa0dcc0
......@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
......@@ -12,6 +13,7 @@
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
......@@ -80,7 +82,26 @@ private enum ConfigurationKind
/// <paramref name="severity"/>.
/// </summary>
public static Task<Solution> ConfigureSeverityAsync(
string severity,
ReportDiagnostic severity,
Diagnostic diagnostic,
Project project,
CancellationToken cancellationToken)
{
if (severity == ReportDiagnostic.Default)
{
severity = diagnostic.DefaultSeverity.ToReportDiagnostic();
}
return ConfigureSeverityAsync(severity.ToEditorConfigString(), diagnostic, project, cancellationToken);
}
/// <summary>
/// Updates or adds an .editorconfig <see cref="AnalyzerConfigDocument"/> to the given <paramref name="project"/>
/// so that the severity of the given <paramref name="diagnostic"/> is configured to be the given
/// <paramref name="editorConfigSeverity"/>.
/// </summary>
public static Task<Solution> ConfigureSeverityAsync(
string editorConfigSeverity,
Diagnostic diagnostic,
Project project,
CancellationToken cancellationToken)
......@@ -93,12 +114,12 @@ private enum ConfigurationKind
if (!codeStyleOptionValues.IsEmpty)
{
return ConfigureCodeStyleOptionsAsync(
codeStyleOptionValues.Select(t => (t.optionName, t.currentOptionValue, severity)),
codeStyleOptionValues.Select(t => (t.optionName, t.currentOptionValue, editorConfigSeverity)),
diagnostic, project, configurationKind: ConfigurationKind.Severity, cancellationToken);
}
else
{
updater = new ConfigurationUpdater(optionNameOpt: null, newOptionValueOpt: null, severity,
updater = new ConfigurationUpdater(optionNameOpt: null, newOptionValueOpt: null, editorConfigSeverity,
configurationKind: ConfigurationKind.Severity, diagnostic, project, cancellationToken);
return updater.ConfigureAsync();
}
......@@ -143,16 +164,14 @@ private enum ConfigurationKind
private async Task<Solution> ConfigureAsync()
{
var solution = _project.Solution;
// Find existing .editorconfig or generate a new one if none exists.
var editorConfigDocument = FindOrGenerateEditorConfig(solution);
var editorConfigDocument = FindOrGenerateEditorConfig();
if (editorConfigDocument == null)
{
return solution;
return _project.Solution;
}
solution = editorConfigDocument.Project.Solution;
var solution = editorConfigDocument.Project.Solution;
var headers = new Dictionary<string, TextLine>();
var originalText = await editorConfigDocument.GetTextAsync(_cancellationToken).ConfigureAwait(false);
......@@ -165,52 +184,15 @@ private async Task<Solution> ConfigureAsync()
: solution;
}
private AnalyzerConfigDocument FindOrGenerateEditorConfig(Solution solution)
private AnalyzerConfigDocument FindOrGenerateEditorConfig()
{
if (_project.AnalyzerConfigDocuments.Any())
{
var diagnosticFilePath = PathUtilities.GetDirectoryName(_diagnostic.Location.SourceTree?.FilePath ?? _project.FilePath);
if (!PathUtilities.IsAbsolute(diagnosticFilePath))
{
return null;
}
// Currently, we use a simple heuristic to find existing .editorconfig file.
// We start from the directory of the source file where the diagnostic was reported and walk up
// the directory tree to find an .editorconfig file.
// In future, we might change this algorithm, or allow end users to customize it based on options.
var bestPath = string.Empty;
AnalyzerConfigDocument bestAnalyzerConfigDocument = null;
foreach (var analyzerConfigDocument in _project.AnalyzerConfigDocuments)
{
var analyzerConfigDirectory = PathUtilities.GetDirectoryName(analyzerConfigDocument.FilePath);
if (diagnosticFilePath.StartsWith(analyzerConfigDirectory) &&
analyzerConfigDirectory.Length > bestPath.Length)
{
bestPath = analyzerConfigDirectory;
bestAnalyzerConfigDocument = analyzerConfigDocument;
}
}
if (bestAnalyzerConfigDocument != null)
{
return bestAnalyzerConfigDocument;
}
}
// Did not find any existing .editorconfig, so create one at root of the project.
if (!PathUtilities.IsAbsolute(_project.FilePath))
var analyzerConfigPath = _project.TryGetAnalyzerConfigPathForDiagnosticConfiguration(_diagnostic);
if (analyzerConfigPath == null)
{
return null;
}
var projectFilePath = PathUtilities.GetDirectoryName(_project.FilePath);
var newEditorConfigPath = PathUtilities.CombineAbsoluteAndRelativePaths(projectFilePath, ".editorconfig");
var id = DocumentId.CreateNewId(_project.Id);
var documentInfo = DocumentInfo.Create(id, ".editorconfig", filePath: newEditorConfigPath);
var newSolution = solution.AddAnalyzerConfigDocuments(ImmutableArray.Create(documentInfo));
return newSolution.GetProject(_project.Id).GetAnalyzerConfigDocument(id);
return _project.GetOrCreateAnalyzerConfigDocument(analyzerConfigPath);
}
private static ImmutableArray<(string optionName, string currentOptionValue, string currentSeverity)> GetCodeStyleOptionValuesForDiagnostic(
......
......@@ -194,18 +194,18 @@
<Button guid="guidRoslynGrpId" id="cmdidSetSeverityInfo" priority="400" type="Button">
<Parent guid="guidRoslynGrpId" id="grpDiagnosticSeverityItems" />
<Strings>
<ButtonText>&amp;Info</ButtonText>
<CanonicalName>Info</CanonicalName>
<LocCanonicalName>Info</LocCanonicalName>
<ButtonText>&amp;Suggestion</ButtonText>
<CanonicalName>Suggestion</CanonicalName>
<LocCanonicalName>Suggestion</LocCanonicalName>
<CommandName>SetSeverityInfo</CommandName>
</Strings>
</Button>
<Button guid="guidRoslynGrpId" id="cmdidSetSeverityHidden" priority="500" type="Button">
<Parent guid="guidRoslynGrpId" id="grpDiagnosticSeverityItems" />
<Strings>
<ButtonText>&amp;Hidden</ButtonText>
<CanonicalName>Hidden</CanonicalName>
<LocCanonicalName>Hidden</LocCanonicalName>
<ButtonText>&amp;Silent</ButtonText>
<CanonicalName>Silent</CanonicalName>
<LocCanonicalName>Silent</LocCanonicalName>
<CommandName>SetSeverityHidden</CommandName>
</Strings>
</Button>
......@@ -346,10 +346,10 @@
<Menu guid="guidRoslynGrpId" id="cmdidSetSeveritySubMenu" priority="50" type="Menu">
<Parent guid="guidRoslynGrpId" id="grpDiagnosticSeverity" />
<Strings>
<ButtonText>Set Rule Set Severity</ButtonText>
<CommandName>Set Rule Set Severity</CommandName>
<CanonicalName>Set Rule Set Severity</CanonicalName>
<LocCanonicalName>Set Rule Set Severity</LocCanonicalName>
<ButtonText>Set severity</ButtonText>
<CommandName>Set severity</CommandName>
<CanonicalName>Set severity</CanonicalName>
<LocCanonicalName>Set severity</LocCanonicalName>
</Strings>
</Menu>
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Informace</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Informace</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Informace</target>
<source>Suggestion</source>
<target state="needs-review-translation">Informace</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Skryté</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Skryté</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Skryté</target>
<source>Silent</source>
<target state="needs-review-translation">Skryté</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Nastavit závažnost sady pravidel</target>
<source>Set severity</source>
<target state="needs-review-translation">Nastavit závažnost sady pravidel</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Nastavit závažnost sady pravidel</target>
<source>Set severity</source>
<target state="needs-review-translation">Nastavit závažnost sady pravidel</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Nastavit závažnost sady pravidel</target>
<source>Set severity</source>
<target state="needs-review-translation">Nastavit závažnost sady pravidel</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Info</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Info</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Info</target>
<source>Suggestion</source>
<target state="needs-review-translation">Info</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Ausgeblendet</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Ausgeblendet</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Ausgeblendet</target>
<source>Silent</source>
<target state="needs-review-translation">Ausgeblendet</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Schweregrad für Regelsatz festlegen</target>
<source>Set severity</source>
<target state="needs-review-translation">Schweregrad für Regelsatz festlegen</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Schweregrad für Regelsatz festlegen</target>
<source>Set severity</source>
<target state="needs-review-translation">Schweregrad für Regelsatz festlegen</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Schweregrad für Regelsatz festlegen</target>
<source>Set severity</source>
<target state="needs-review-translation">Schweregrad für Regelsatz festlegen</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Información</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Información</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Información</target>
<source>Suggestion</source>
<target state="needs-review-translation">Información</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Oculto</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Oculto</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Oculto</target>
<source>Silent</source>
<target state="needs-review-translation">Oculto</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Configurar gravedad del conjunto de reglas</target>
<source>Set severity</source>
<target state="needs-review-translation">Configurar gravedad del conjunto de reglas</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Configurar gravedad del conjunto de reglas</target>
<source>Set severity</source>
<target state="needs-review-translation">Configurar gravedad del conjunto de reglas</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Configurar gravedad del conjunto de reglas</target>
<source>Set severity</source>
<target state="needs-review-translation">Configurar gravedad del conjunto de reglas</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Informations</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Informations</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Info</target>
<source>Suggestion</source>
<target state="needs-review-translation">Info</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Masqué</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Masqué</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Masqué</target>
<source>Silent</source>
<target state="needs-review-translation">Masqué</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Définir la gravité de l'ensemble de règles</target>
<source>Set severity</source>
<target state="needs-review-translation">Définir la gravité de l'ensemble de règles</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Définir la gravité de l'ensemble de règles</target>
<source>Set severity</source>
<target state="needs-review-translation">Définir la gravité de l'ensemble de règles</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Définir la gravité de l'ensemble de règles</target>
<source>Set severity</source>
<target state="needs-review-translation">Définir la gravité de l'ensemble de règles</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">In&amp;formazioni</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">In&amp;formazioni</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Info</target>
<source>Suggestion</source>
<target state="needs-review-translation">Info</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Nascosto</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Nascosto</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Nascosto</target>
<source>Silent</source>
<target state="needs-review-translation">Nascosto</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Imposta gravit?? set di regole</target>
<source>Set severity</source>
<target state="needs-review-translation">Imposta gravit?? set di regole</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Imposta gravit?? set di regole</target>
<source>Set severity</source>
<target state="needs-review-translation">Imposta gravit?? set di regole</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Imposta gravit?? set di regole</target>
<source>Set severity</source>
<target state="needs-review-translation">Imposta gravit?? set di regole</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">情報(&amp;I)</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">情報(&amp;I)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">情報</target>
<source>Suggestion</source>
<target state="needs-review-translation">情報</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">非表示(&amp;H)</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">非表示(&amp;H)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">非表示</target>
<source>Silent</source>
<target state="needs-review-translation">非表示</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">ルール セットの重要度を設定</target>
<source>Set severity</source>
<target state="needs-review-translation">ルール セットの重要度を設定</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">ルール セットの重要度を設定</target>
<source>Set severity</source>
<target state="needs-review-translation">ルール セットの重要度を設定</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">ルール セットの重要度を設定</target>
<source>Set severity</source>
<target state="needs-review-translation">ルール セットの重要度を設定</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">정보(&amp;I)</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">정보(&amp;I)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">정보</target>
<source>Suggestion</source>
<target state="needs-review-translation">정보</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">숨김(&amp;H)</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">숨김(&amp;H)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">숨김</target>
<source>Silent</source>
<target state="needs-review-translation">숨김</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">규칙 집합 심각도 설정</target>
<source>Set severity</source>
<target state="needs-review-translation">규칙 집합 심각도 설정</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">규칙 집합 심각도 설정</target>
<source>Set severity</source>
<target state="needs-review-translation">규칙 집합 심각도 설정</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">규칙 집합 심각도 설정</target>
<source>Set severity</source>
<target state="needs-review-translation">규칙 집합 심각도 설정</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Informacje</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Informacje</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Informacje</target>
<source>Suggestion</source>
<target state="needs-review-translation">Informacje</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Ukryte</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Ukryte</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Ukryty</target>
<source>Silent</source>
<target state="needs-review-translation">Ukryty</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Ustaw ważność zestawu reguł</target>
<source>Set severity</source>
<target state="needs-review-translation">Ustaw ważność zestawu reguł</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Ustaw ważność zestawu reguł</target>
<source>Set severity</source>
<target state="needs-review-translation">Ustaw ważność zestawu reguł</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Ustaw ważność zestawu reguł</target>
<source>Set severity</source>
<target state="needs-review-translation">Ustaw ważność zestawu reguł</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Informações</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Informações</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Informação</target>
<source>Suggestion</source>
<target state="needs-review-translation">Informação</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Oculto</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Oculto</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Oculto</target>
<source>Silent</source>
<target state="needs-review-translation">Oculto</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Definir Regra Definir Gravidade</target>
<source>Set severity</source>
<target state="needs-review-translation">Definir Regra Definir Gravidade</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Definir Regra Definir Gravidade</target>
<source>Set severity</source>
<target state="needs-review-translation">Definir Regra Definir Gravidade</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Definir Regra Definir Gravidade</target>
<source>Set severity</source>
<target state="needs-review-translation">Definir Regra Definir Gravidade</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Информация</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Информация</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Информация</target>
<source>Suggestion</source>
<target state="needs-review-translation">Информация</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Скрытый</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Скрытый</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Скрытый</target>
<source>Silent</source>
<target state="needs-review-translation">Скрытый</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Установить серьезность набора правил</target>
<source>Set severity</source>
<target state="needs-review-translation">Установить серьезность набора правил</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Установить серьезность набора правил</target>
<source>Set severity</source>
<target state="needs-review-translation">Установить серьезность набора правил</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Установить серьезность набора правил</target>
<source>Set severity</source>
<target state="needs-review-translation">Установить серьезность набора правил</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">&amp;Bilgi</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">&amp;Bilgi</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">Bilgi</target>
<source>Suggestion</source>
<target state="needs-review-translation">Bilgi</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">&amp;Gizli</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">&amp;Gizli</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">Gizli</target>
<source>Silent</source>
<target state="needs-review-translation">Gizli</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">Kural Kümesi Önem Derecesini Ayarla</target>
<source>Set severity</source>
<target state="needs-review-translation">Kural Kümesi Önem Derecesini Ayarla</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">Kural Kümesi Önem Derecesini Ayarla</target>
<source>Set severity</source>
<target state="needs-review-translation">Kural Kümesi Önem Derecesini Ayarla</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">Kural Kümesi Önem Derecesini Ayarla</target>
<source>Set severity</source>
<target state="needs-review-translation">Kural Kümesi Önem Derecesini Ayarla</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">信息(&amp;I)</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">信息(&amp;I)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">信息</target>
<source>Suggestion</source>
<target state="needs-review-translation">信息</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">隐藏(&amp;H)</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">隐藏(&amp;H)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">隐藏</target>
<source>Silent</source>
<target state="needs-review-translation">隐藏</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">设置规则集严重性</target>
<source>Set severity</source>
<target state="needs-review-translation">设置规则集严重性</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">设置规则集严重性</target>
<source>Set severity</source>
<target state="needs-review-translation">设置规则集严重性</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">设置规则集严重性</target>
<source>Set severity</source>
<target state="needs-review-translation">设置规则集严重性</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
......@@ -148,13 +148,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|ButtonText">
<source>&amp;Info</source>
<target state="translated">資訊(&amp;I)</target>
<source>&amp;Suggestion</source>
<target state="needs-review-translation">資訊(&amp;I)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|LocCanonicalName">
<source>Info</source>
<target state="translated">資訊</target>
<source>Suggestion</source>
<target state="needs-review-translation">資訊</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityInfo|CommandName">
......@@ -163,13 +163,13 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|ButtonText">
<source>&amp;Hidden</source>
<target state="translated">隱藏(&amp;H)</target>
<source>&amp;Silent</source>
<target state="needs-review-translation">隱藏(&amp;H)</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|LocCanonicalName">
<source>Hidden</source>
<target state="translated">隱藏</target>
<source>Silent</source>
<target state="needs-review-translation">隱藏</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeverityHidden|CommandName">
......@@ -333,18 +333,18 @@
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|ButtonText">
<source>Set Rule Set Severity</source>
<target state="translated">設定規則集合嚴重性</target>
<source>Set severity</source>
<target state="needs-review-translation">設定規則集合嚴重性</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|CommandName">
<source>Set Rule Set Severity</source>
<target state="translated">設定規則集合嚴重性</target>
<source>Set severity</source>
<target state="needs-review-translation">設定規則集合嚴重性</target>
<note />
</trans-unit>
<trans-unit id="cmdidSetSeveritySubMenu|LocCanonicalName">
<source>Set Rule Set Severity</source>
<target state="translated">設定規則集合嚴重性</target>
<source>Set severity</source>
<target state="needs-review-translation">設定規則集合嚴重性</target>
<note />
</trans-unit>
<trans-unit id="cmdidAddSuppressionsContextMenu|ButtonText">
......
// 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.Collections.Immutable;
using System.ComponentModel.Composition;
......@@ -12,6 +13,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Notification;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.Internal.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.CodeAnalysis;
using Microsoft.VisualStudio.ComponentModelHost;
......@@ -22,6 +24,7 @@
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
using VSLangProj140;
using Project = Microsoft.CodeAnalysis.Project;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
{
......@@ -172,7 +175,10 @@ private bool ShouldShowAnalyzerContextMenu(IEnumerable<object> items)
private void UpdateAnalyzerContextMenu()
{
_removeMenuItem.Enabled = _allowProjectSystemOperations;
if (_removeMenuItem != null)
{
_removeMenuItem.Enabled = _allowProjectSystemOperations;
}
}
public IContextMenuController DiagnosticContextMenuController
......@@ -265,28 +271,25 @@ private void UpdateSeverityMenuItemsChecked()
foreach (var group in groups)
{
var ruleSetPath = workspace.TryGetRuleSetPathForProject(group.Key);
var project = workspace.CurrentSolution.GetProject(group.Key);
if (project == null)
{
continue;
}
if (ruleSetPath != null)
var analyzerConfigSpecificDiagnosticOptions = project.GetAnalyzerConfigSpecialDiagnosticOptions();
foreach (var diagnosticItem in group)
{
var ruleSetManager = workspace.Services.GetRequiredService<VisualStudioRuleSetManager>();
using (var ruleSet = ruleSetManager.GetOrCreateRuleSet(ruleSetPath))
var severity = ReportDiagnostic.Default;
if (project.CompilationOptions.SpecificDiagnosticOptions.ContainsKey(diagnosticItem.Descriptor.Id) ||
analyzerConfigSpecificDiagnosticOptions.ContainsKey(diagnosticItem.Descriptor.Id))
{
var specificOptions = ruleSet.Target.Value.GetSpecificDiagnosticOptions();
foreach (var diagnosticItem in group)
{
if (specificOptions.TryGetValue(diagnosticItem.Descriptor.Id, out var ruleSetSeverity))
{
selectedItemSeverities.Add(ruleSetSeverity);
}
else
{
// The rule has no setting.
selectedItemSeverities.Add(ReportDiagnostic.Default);
}
}
// Severity is overridden by end user.
severity = diagnosticItem.Descriptor.GetEffectiveSeverity(project.CompilationOptions, analyzerConfigSpecificDiagnosticOptions);
}
selectedItemSeverities.Add(severity);
}
}
......@@ -320,11 +323,6 @@ private void UpdateSeverityMenuItemsChecked()
}
}
private bool AnyDiagnosticsWithSeverity(ReportDiagnostic severity)
{
return _tracker.SelectedDiagnosticItems.Any(item => item.EffectiveSeverity == severity);
}
private void UpdateSeverityMenuItemsEnabled()
{
var configurable = !_tracker.SelectedDiagnosticItems.Any(item => item.Descriptor.CustomTags.Contains(WellKnownDiagnosticTags.NotConfigurable));
......@@ -421,18 +419,46 @@ private void SetSeverityHandler(object sender, EventArgs args)
var projectId = selectedDiagnostic.ProjectId;
var pathToRuleSet = workspace.TryGetRuleSetPathForProject(projectId);
if (pathToRuleSet == null)
var project = workspace.CurrentSolution.GetProject(projectId);
var pathToAnalyzerConfigDoc = project?.TryGetAnalyzerConfigPathForProjectConfiguration();
if (pathToRuleSet == null && pathToAnalyzerConfigDoc == null)
{
SendUnableToUpdateRuleSetNotification(workspace, SolutionExplorerShim.No_rule_set_file_is_specified_or_the_file_does_not_exist);
continue;
}
var componentModel = (IComponentModel)_serviceProvider.GetService(typeof(SComponentModel));
var waitIndicator = componentModel.GetService<IWaitIndicator>();
try
{
var envDteProject = workspace.TryGetDTEProject(projectId);
if (SdkUiUtilities.IsBuiltInRuleSet(pathToRuleSet, _serviceProvider))
if (pathToRuleSet == null || SdkUiUtilities.IsBuiltInRuleSet(pathToRuleSet, _serviceProvider))
{
// If project is using the default built-in ruleset or no ruleset, then prefer .editorconfig for severity configuration.
if (pathToAnalyzerConfigDoc != null)
{
waitIndicator.Wait(
title: SolutionExplorerShim.Updating_severity,
message: SolutionExplorerShim.Updating_severity,
allowCancel: true,
action: c =>
{
var newSolution = selectedDiagnostic.GetSolutionWithUpdatedAnalyzerConfigSeverityAsync(selectedAction.Value, project, c.CancellationToken).WaitAndGetResult(c.CancellationToken);
_workspace.TryApplyChanges(newSolution, c.ProgressTracker);
});
continue;
}
// Otherwise, fall back to using ruleset.
if (pathToRuleSet == null)
{
SendUnableToUpdateRuleSetNotification(workspace, SolutionExplorerShim.No_rule_set_file_is_specified_or_the_file_does_not_exist);
continue;
}
pathToRuleSet = CreateCopyOfRuleSetForProject(pathToRuleSet, envDteProject);
if (pathToRuleSet == null)
{
......@@ -444,8 +470,6 @@ private void SetSeverityHandler(object sender, EventArgs args)
fileInfo.IsReadOnly = false;
}
var componentModel = (IComponentModel)_serviceProvider.GetService(typeof(SComponentModel));
var waitIndicator = componentModel.GetService<IWaitIndicator>();
waitIndicator.Wait(
title: SolutionExplorerShim.Rule_Set,
message: string.Format(SolutionExplorerShim.Checking_out_0_for_editing, Path.GetFileName(pathToRuleSet)),
......@@ -458,7 +482,7 @@ private void SetSeverityHandler(object sender, EventArgs args)
}
});
selectedDiagnostic.SetSeverity(selectedAction.Value, pathToRuleSet);
selectedDiagnostic.SetRuleSetSeverity(selectedAction.Value, pathToRuleSet);
}
catch (Exception e)
{
......
......@@ -2,13 +2,17 @@
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeFixes.Configuration;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
{
......@@ -106,12 +110,7 @@ private void NotifyPropertyChanged(string propertyName)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
internal void SetSeverity(ReportDiagnostic value, string pathToRuleSet)
{
UpdateRuleSetFile(pathToRuleSet, value);
}
private void UpdateRuleSetFile(string pathToRuleSet, ReportDiagnostic value)
internal void SetRuleSetSeverity(ReportDiagnostic value, string pathToRuleSet)
{
var ruleSetDocument = XDocument.Load(pathToRuleSet);
......@@ -119,5 +118,12 @@ private void UpdateRuleSetFile(string pathToRuleSet, ReportDiagnostic value)
ruleSetDocument.Save(pathToRuleSet);
}
internal Task<Solution> GetSolutionWithUpdatedAnalyzerConfigSeverityAsync(ReportDiagnostic value, Project project, CancellationToken cancellationToken)
{
var effectiveSeverity = value.ToDiagnosticSeverity() ?? _descriptor.DefaultSeverity;
var diagnostic = Diagnostic.Create(_descriptor, Location.None, effectiveSeverity, additionalLocations: null, properties: null);
return ConfigurationUpdater.ConfigureSeverityAsync(value, diagnostic, project, cancellationToken);
}
}
}
......@@ -8,35 +8,35 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Internal.Log;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
{
using Workspace = Microsoft.CodeAnalysis.Workspace;
internal abstract partial class BaseDiagnosticItemSource : IAttachedCollectionSource
{
protected static readonly DiagnosticDescriptorComparer s_comparer = new DiagnosticDescriptorComparer();
protected readonly Workspace _workspace;
protected readonly ProjectId _projectId;
protected readonly IAnalyzersCommandHandler _commandHandler;
protected readonly IDiagnosticAnalyzerService _diagnosticAnalyzerService;
private static readonly DiagnosticDescriptorComparer s_comparer = new DiagnosticDescriptorComparer();
protected BulkObservableCollection<BaseDiagnosticItem> _diagnosticItems;
private readonly IDiagnosticAnalyzerService _diagnosticAnalyzerService;
protected ReportDiagnostic _generalDiagnosticOption;
protected ImmutableDictionary<string, ReportDiagnostic> _specificDiagnosticOptions;
private BulkObservableCollection<BaseDiagnosticItem> _diagnosticItems;
private ReportDiagnostic _generalDiagnosticOption;
private ImmutableDictionary<string, ReportDiagnostic> _specificDiagnosticOptions;
private ImmutableDictionary<string, ReportDiagnostic> _analyzerConfigSpecificDiagnosticOptions;
public BaseDiagnosticItemSource(Workspace workspace, ProjectId projectId, IAnalyzersCommandHandler commandHandler, IDiagnosticAnalyzerService diagnosticAnalyzerService)
{
_workspace = workspace;
_projectId = projectId;
_commandHandler = commandHandler;
Workspace = workspace;
ProjectId = projectId;
CommandHandler = commandHandler;
_diagnosticAnalyzerService = diagnosticAnalyzerService;
}
public Workspace Workspace { get; }
public ProjectId ProjectId { get; }
protected IAnalyzersCommandHandler CommandHandler { get; }
public abstract AnalyzerReference AnalyzerReference { get; }
protected abstract BaseDiagnosticItem CreateItem(DiagnosticDescriptor diagnostic, ReportDiagnostic effectiveSeverity);
......@@ -56,7 +56,7 @@ public bool HasItems
return false;
}
var project = _workspace.CurrentSolution.GetProject(_projectId);
var project = Workspace.CurrentSolution.GetProject(ProjectId);
return AnalyzerReference.GetAnalyzers(project.Language).Length > 0;
}
}
......@@ -67,14 +67,15 @@ public IEnumerable Items
{
if (_diagnosticItems == null)
{
var project = _workspace.CurrentSolution.GetProject(_projectId);
var project = Workspace.CurrentSolution.GetProject(ProjectId);
_generalDiagnosticOption = project.CompilationOptions.GeneralDiagnosticOption;
_specificDiagnosticOptions = project.CompilationOptions.SpecificDiagnosticOptions;
_analyzerConfigSpecificDiagnosticOptions = project.GetAnalyzerConfigSpecialDiagnosticOptions();
_diagnosticItems = new BulkObservableCollection<BaseDiagnosticItem>();
_diagnosticItems.AddRange(GetDiagnosticItems(project.Language, project.CompilationOptions));
_diagnosticItems.AddRange(GetDiagnosticItems(project.Language, project.CompilationOptions, _analyzerConfigSpecificDiagnosticOptions));
_workspace.WorkspaceChanged += OnWorkspaceChangedLookForOptionsChanges;
Workspace.WorkspaceChanged += OnWorkspaceChangedLookForOptionsChanges;
}
Logger.Log(
......@@ -85,7 +86,7 @@ public IEnumerable Items
}
}
private IEnumerable<BaseDiagnosticItem> GetDiagnosticItems(string language, CompilationOptions options)
private IEnumerable<BaseDiagnosticItem> GetDiagnosticItems(string language, CompilationOptions options, ImmutableDictionary<string, ReportDiagnostic> analyzerConfigSpecificDiagnosticOptions)
{
// Within an analyzer assembly, an individual analyzer may report multiple different diagnostics
// with the same ID. Or, multiple analyzers may report diagnostics with the same ID. Or a
......@@ -103,7 +104,7 @@ private IEnumerable<BaseDiagnosticItem> GetDiagnosticItems(string language, Comp
.Select(g =>
{
var selectedDiagnostic = g.OrderBy(d => d, s_comparer).First();
var effectiveSeverity = selectedDiagnostic.GetEffectiveSeverity(options);
var effectiveSeverity = selectedDiagnostic.GetEffectiveSeverity(options, analyzerConfigSpecificDiagnosticOptions);
return CreateItem(selectedDiagnostic, effectiveSeverity);
});
}
......@@ -114,35 +115,57 @@ private void OnWorkspaceChangedLookForOptionsChanges(object sender, WorkspaceCha
e.Kind == WorkspaceChangeKind.SolutionReloaded ||
e.Kind == WorkspaceChangeKind.SolutionRemoved)
{
_workspace.WorkspaceChanged -= OnWorkspaceChangedLookForOptionsChanges;
Workspace.WorkspaceChanged -= OnWorkspaceChangedLookForOptionsChanges;
}
else if (e.ProjectId == _projectId)
else if (e.ProjectId == ProjectId)
{
if (e.Kind == WorkspaceChangeKind.ProjectRemoved)
{
_workspace.WorkspaceChanged -= OnWorkspaceChangedLookForOptionsChanges;
Workspace.WorkspaceChanged -= OnWorkspaceChangedLookForOptionsChanges;
}
else if (e.Kind == WorkspaceChangeKind.ProjectChanged)
{
var project = e.NewSolution.GetProject(_projectId);
var newGeneralDiagnosticOption = project.CompilationOptions.GeneralDiagnosticOption;
var newSpecificDiagnosticOptions = project.CompilationOptions.SpecificDiagnosticOptions;
OnProjectConfigurationChanged();
}
else if (e.DocumentId != null)
{
switch (e.Kind)
{
case WorkspaceChangeKind.AnalyzerConfigDocumentAdded:
case WorkspaceChangeKind.AnalyzerConfigDocumentChanged:
case WorkspaceChangeKind.AnalyzerConfigDocumentReloaded:
case WorkspaceChangeKind.AnalyzerConfigDocumentRemoved:
OnProjectConfigurationChanged();
break;
}
}
}
return;
// Local functions.
void OnProjectConfigurationChanged()
{
var project = e.NewSolution.GetProject(ProjectId);
var newGeneralDiagnosticOption = project.CompilationOptions.GeneralDiagnosticOption;
var newSpecificDiagnosticOptions = project.CompilationOptions.SpecificDiagnosticOptions;
var newAnalyzerConfigSpecificDiagnosticOptions = project.GetAnalyzerConfigSpecialDiagnosticOptions();
if (newGeneralDiagnosticOption != _generalDiagnosticOption ||
!object.ReferenceEquals(newSpecificDiagnosticOptions, _specificDiagnosticOptions) ||
!object.ReferenceEquals(newAnalyzerConfigSpecificDiagnosticOptions, _analyzerConfigSpecificDiagnosticOptions))
{
_generalDiagnosticOption = newGeneralDiagnosticOption;
_specificDiagnosticOptions = newSpecificDiagnosticOptions;
_analyzerConfigSpecificDiagnosticOptions = newAnalyzerConfigSpecificDiagnosticOptions;
if (newGeneralDiagnosticOption != _generalDiagnosticOption ||
!object.ReferenceEquals(newSpecificDiagnosticOptions, _specificDiagnosticOptions))
foreach (var item in _diagnosticItems)
{
_generalDiagnosticOption = newGeneralDiagnosticOption;
_specificDiagnosticOptions = newSpecificDiagnosticOptions;
foreach (var item in _diagnosticItems)
{
var effectiveSeverity = item.Descriptor.GetEffectiveSeverity(project.CompilationOptions);
item.UpdateEffectiveSeverity(effectiveSeverity);
}
var effectiveSeverity = item.Descriptor.GetEffectiveSeverity(project.CompilationOptions, newAnalyzerConfigSpecificDiagnosticOptions);
item.UpdateEffectiveSeverity(effectiveSeverity);
}
}
}
}
}
}
......@@ -11,8 +11,6 @@
namespace Microsoft.VisualStudio.LanguageServices.Implementation.SolutionExplorer
{
using Workspace = Microsoft.CodeAnalysis.Workspace;
internal partial class CpsDiagnosticItemSource : BaseDiagnosticItemSource, INotifyPropertyChanged
{
private readonly IVsHierarchyItem _item;
......@@ -28,18 +26,16 @@ public CpsDiagnosticItemSource(Workspace workspace, string projectPath, ProjectI
_item = item;
_projectDirectoryPath = Path.GetDirectoryName(projectPath);
_analyzerReference = TryGetAnalyzerReference(_workspace.CurrentSolution);
_analyzerReference = TryGetAnalyzerReference(Workspace.CurrentSolution);
if (_analyzerReference == null)
{
// The workspace doesn't know about the project and/or the analyzer yet.
// Hook up an event handler so we can update when it does.
_workspace.WorkspaceChanged += OnWorkspaceChangedLookForAnalyzer;
Workspace.WorkspaceChanged += OnWorkspaceChangedLookForAnalyzer;
}
}
public IContextMenuController DiagnosticItemContextMenuController => _commandHandler.DiagnosticContextMenuController;
public Workspace Workspace => _workspace;
public ProjectId ProjectId => _projectId;
public IContextMenuController DiagnosticItemContextMenuController => CommandHandler.DiagnosticContextMenuController;
public override object SourceItem => _item;
......@@ -55,23 +51,23 @@ private void OnWorkspaceChangedLookForAnalyzer(object sender, WorkspaceChangeEve
e.Kind == WorkspaceChangeKind.SolutionReloaded ||
e.Kind == WorkspaceChangeKind.SolutionRemoved)
{
_workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
Workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
}
else if (e.Kind == WorkspaceChangeKind.SolutionAdded)
{
_analyzerReference = TryGetAnalyzerReference(e.NewSolution);
if (_analyzerReference != null)
{
_workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
Workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems)));
}
}
else if (e.ProjectId == _projectId)
else if (e.ProjectId == ProjectId)
{
if (e.Kind == WorkspaceChangeKind.ProjectRemoved)
{
_workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
Workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
}
else if (e.Kind == WorkspaceChangeKind.ProjectAdded
|| e.Kind == WorkspaceChangeKind.ProjectChanged)
......@@ -79,7 +75,7 @@ private void OnWorkspaceChangedLookForAnalyzer(object sender, WorkspaceChangeEve
_analyzerReference = TryGetAnalyzerReference(e.NewSolution);
if (_analyzerReference != null)
{
_workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
Workspace.WorkspaceChanged -= OnWorkspaceChangedLookForAnalyzer;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(HasItems)));
}
......@@ -89,7 +85,7 @@ private void OnWorkspaceChangedLookForAnalyzer(object sender, WorkspaceChangeEve
private AnalyzerReference TryGetAnalyzerReference(Solution solution)
{
var project = solution.GetProject(_projectId);
var project = solution.GetProject(ProjectId);
if (project == null)
{
......
......@@ -30,7 +30,7 @@ public override AnalyzerReference AnalyzerReference
protected override BaseDiagnosticItem CreateItem(DiagnosticDescriptor diagnostic, ReportDiagnostic effectiveSeverity)
{
return new LegacyDiagnosticItem(_item, diagnostic, effectiveSeverity, _commandHandler.DiagnosticContextMenuController);
return new LegacyDiagnosticItem(_item, diagnostic, effectiveSeverity, CommandHandler.DiagnosticContextMenuController);
}
}
}
......@@ -321,6 +321,15 @@ internal class SolutionExplorerShim {
}
}
/// <summary>
/// Looks up a localized string similar to Updating severity.
/// </summary>
internal static string Updating_severity {
get {
return ResourceManager.GetString("Updating_severity", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Warning.
/// </summary>
......
......@@ -207,4 +207,7 @@
<data name="Title" xml:space="preserve">
<value>Title</value>
</data>
<data name="Updating_severity" xml:space="preserve">
<value>Updating severity</value>
</data>
</root>
\ No newline at end of file
......@@ -62,6 +62,11 @@
<target state="translated">Chyba</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Upozornění</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Fehler</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Warnung</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Fehler</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Advertencia</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Erreur</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Avertissement</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Errore</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Avviso</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">エラー</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">警告</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">오류</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">경고</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Błąd</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Ostrzeżenie</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Erro</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Aviso</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Ошибка</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Предупреждение</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">Hata</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">Uyarı</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">错误</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">警告</target>
......
......@@ -62,6 +62,11 @@
<target state="translated">錯誤</target>
<note />
</trans-unit>
<trans-unit id="Updating_severity">
<source>Updating severity</source>
<target state="new">Updating severity</target>
<note />
</trans-unit>
<trans-unit id="Warning">
<source>Warning</source>
<target state="translated">警告</target>
......
// 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 Roslyn.Utilities;
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.CodeStyle
{
internal static class NotificationOptionExtensions
{
public static string ToEditorConfigString(this NotificationOption notificationOption)
{
return notificationOption.Severity switch
{
ReportDiagnostic.Suppress => EditorConfigSeverityStrings.None,
ReportDiagnostic.Hidden => EditorConfigSeverityStrings.Silent,
ReportDiagnostic.Info => EditorConfigSeverityStrings.Suggestion,
ReportDiagnostic.Warn => EditorConfigSeverityStrings.Warning,
ReportDiagnostic.Error => EditorConfigSeverityStrings.Error,
_ => throw ExceptionUtilities.UnexpectedValue(notificationOption.Severity)
};
}
=> notificationOption.Severity.ToEditorConfigString();
}
}
// 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 Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
{
internal static class ReportDiagnosticExtensions
{
public static string ToEditorConfigString(this ReportDiagnostic reportDiagnostic)
{
return reportDiagnostic switch
{
ReportDiagnostic.Suppress => EditorConfigSeverityStrings.None,
ReportDiagnostic.Hidden => EditorConfigSeverityStrings.Silent,
ReportDiagnostic.Info => EditorConfigSeverityStrings.Suggestion,
ReportDiagnostic.Warn => EditorConfigSeverityStrings.Warning,
ReportDiagnostic.Error => EditorConfigSeverityStrings.Error,
_ => throw ExceptionUtilities.UnexpectedValue(reportDiagnostic)
};
}
}
}
// 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;
namespace Microsoft.CodeAnalysis.Shared.Extensions
{
internal static class DiagnosticDescriptorExtensions
{
/// <summary>
/// Gets project-level effective severity of the given <paramref name="descriptor"/> accounting for severity configurations from both the following sources:
/// 1. Compilation options from ruleset file, if any, and command line options such as /nowarn, /warnaserror, etc.
/// 2. Analyzer config documents at the project root directory or in ancestor directories.
/// </summary>
public static ReportDiagnostic GetEffectiveSeverity(this DiagnosticDescriptor descriptor, CompilationOptions compilationOptions, ImmutableDictionary<string, ReportDiagnostic> analyzerConfigSpecificDiagnosticOptions)
{
var effectiveSeverity = descriptor.GetEffectiveSeverity(compilationOptions);
// Apply analyzer config options on top of compilation options, unless the diagnostic is explicitly suppressed by compilation options (/nowarn).
var isSuppressedByCompilationOptions = effectiveSeverity == ReportDiagnostic.Suppress &&
compilationOptions.SpecificDiagnosticOptions.ContainsKey(descriptor.Id);
if (!isSuppressedByCompilationOptions &&
analyzerConfigSpecificDiagnosticOptions.TryGetValue(descriptor.Id, out var reportDiagnostic))
{
effectiveSeverity = reportDiagnostic;
}
return effectiveSeverity;
}
/// <summary>
/// Gets project-level effective severity of the given <paramref name="descriptor"/> accounting for severity configurations from both the following sources:
/// 1. Compilation options from ruleset file, if any, and command line options such as /nowarn, /warnaserror, etc.
/// 2. Analyzer config documents at the project root directory or in ancestor directories.
/// </summary>
public static ReportDiagnostic GetEffectiveSeverity(this DiagnosticDescriptor descriptor, Project project)
=> descriptor.GetEffectiveSeverity(project.CompilationOptions, project.GetAnalyzerConfigSpecialDiagnosticOptions());
}
}
// 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.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.Shared.Extensions
{
......@@ -38,5 +43,80 @@ public static async Task<VersionStamp> GetVersionAsync(this Project project, Can
return version.GetNewerVersion(latestVersion);
}
public static string TryGetAnalyzerConfigPathForProjectConfiguration(this Project project)
=> TryGetAnalyzerConfigPathForProjectOrDiagnosticConfiguration(project, diagnosticOpt: null);
public static string TryGetAnalyzerConfigPathForDiagnosticConfiguration(this Project project, Diagnostic diagnostic)
{
Debug.Assert(diagnostic != null);
return TryGetAnalyzerConfigPathForProjectOrDiagnosticConfiguration(project, diagnostic);
}
private static string TryGetAnalyzerConfigPathForProjectOrDiagnosticConfiguration(Project project, Diagnostic diagnosticOpt)
{
if (project.AnalyzerConfigDocuments.Any())
{
var diagnosticFilePath = PathUtilities.GetDirectoryName(diagnosticOpt?.Location.SourceTree?.FilePath ?? project.FilePath);
if (!PathUtilities.IsAbsolute(diagnosticFilePath))
{
return null;
}
// Currently, we use a simple heuristic to find existing .editorconfig file.
// We start from the directory of the source file where the diagnostic was reported and walk up
// the directory tree to find an .editorconfig file.
// In future, we might change this algorithm, or allow end users to customize it based on options.
var bestPath = string.Empty;
AnalyzerConfigDocument bestAnalyzerConfigDocument = null;
foreach (var analyzerConfigDocument in project.AnalyzerConfigDocuments)
{
var analyzerConfigDirectory = PathUtilities.GetDirectoryName(analyzerConfigDocument.FilePath);
if (diagnosticFilePath.StartsWith(analyzerConfigDirectory) &&
analyzerConfigDirectory.Length > bestPath.Length)
{
bestPath = analyzerConfigDirectory;
bestAnalyzerConfigDocument = analyzerConfigDocument;
}
}
if (bestAnalyzerConfigDocument != null)
{
return bestAnalyzerConfigDocument.FilePath;
}
}
// Did not find any existing .editorconfig, so create one at root of the project.
if (!PathUtilities.IsAbsolute(project.FilePath))
{
return null;
}
var projectFilePath = PathUtilities.GetDirectoryName(project.FilePath);
return PathUtilities.CombineAbsoluteAndRelativePaths(projectFilePath, ".editorconfig");
}
public static AnalyzerConfigDocument TryGetExistingAnalyzerConfigDocumentAtPath(this Project project, string analyzerConfigPath)
{
Debug.Assert(analyzerConfigPath != null);
Debug.Assert(PathUtilities.IsAbsolute(analyzerConfigPath));
return project.AnalyzerConfigDocuments.FirstOrDefault(d => d.FilePath == analyzerConfigPath);
}
public static AnalyzerConfigDocument GetOrCreateAnalyzerConfigDocument(this Project project, string analyzerConfigPath)
{
var existingAnalyzerConfigDocument = project.TryGetExistingAnalyzerConfigDocumentAtPath(analyzerConfigPath);
if (existingAnalyzerConfigDocument != null)
{
return existingAnalyzerConfigDocument;
}
var id = DocumentId.CreateNewId(project.Id);
var documentInfo = DocumentInfo.Create(id, ".editorconfig", filePath: analyzerConfigPath);
var newSolution = project.Solution.AddAnalyzerConfigDocuments(ImmutableArray.Create(documentInfo));
return newSolution.GetProject(project.Id).GetAnalyzerConfigDocument(id);
}
}
}
......@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Threading;
......@@ -603,6 +604,9 @@ public Project RemoveAnalyzerConfigDocument(DocumentId documentId)
return this.Solution.RemoveAnalyzerConfigDocument(documentId).GetProject(this.Id);
}
internal ImmutableDictionary<string, ReportDiagnostic> GetAnalyzerConfigSpecialDiagnosticOptions()
=> _projectState.GetAnalyzerConfigSpecialDiagnosticOptions();
private string GetDebuggerDisplay()
{
return this.Name;
......
......@@ -260,6 +260,37 @@ public AnalyzerOptions AnalyzerOptions
}
}
public ImmutableDictionary<string, ReportDiagnostic> GetAnalyzerConfigSpecialDiagnosticOptions()
{
// We need to find the analyzer config options at the root of the project.
// Currently, there is no compiler API to query analyzer config options for a directory in a language agnostic fashion.
// So, we use a dummy language-specific file name appended to the project directory to query analyzer config options.
var projectDirectory = PathUtilities.GetDirectoryName(_projectInfo.FilePath);
if (!PathUtilities.IsAbsolute(projectDirectory))
{
return ImmutableDictionary<string, ReportDiagnostic>.Empty;
}
var fileName = Guid.NewGuid().ToString();
string sourceFilePath;
switch (_projectInfo.Language)
{
case LanguageNames.CSharp:
sourceFilePath = PathUtilities.CombineAbsoluteAndRelativePaths(projectDirectory, $"{fileName}.cs");
break;
case LanguageNames.VisualBasic:
sourceFilePath = PathUtilities.CombineAbsoluteAndRelativePaths(projectDirectory, $"{fileName}.vb");
break;
default:
return ImmutableDictionary<string, ReportDiagnostic>.Empty;
}
return _lazyAnalyzerConfigSet.GetValue(CancellationToken.None).GetOptionsForSourcePath(sourceFilePath).TreeOptions;
}
private sealed class WorkspaceAnalyzerConfigOptionsProvider : AnalyzerConfigOptionsProvider
{
private readonly ProjectState _projectState;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册