提交 65268326 编写于 作者: S Sam Harwell

Pass effective severity as a separate argument to Diagnostic.Create

上级 a97916c3
......@@ -132,9 +132,11 @@ public CSharpAddAccessibilityModifiersDiagnosticAnalyzer()
// Have an issue to flag, either add or remove. Report issue to user.
var additionalLocations = ImmutableArray.Create(member.GetLocation());
context.ReportDiagnostic(Diagnostic.Create(
CreateDescriptorWithSeverity(option.Notification.Value),
Descriptor,
name.GetLocation(),
additionalLocations: additionalLocations));
option.Notification.Value,
additionalLocations: additionalLocations,
properties: null));
}
}
}
......@@ -78,8 +78,13 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
}
var firstToken = statement.GetFirstToken();
context.ReportDiagnostic(Diagnostic.Create(GetDescriptorWithSeverity(option.Notification.Value),
firstToken.GetLocation(), SyntaxFacts.GetText(firstToken.Kind())));
context.ReportDiagnostic(Diagnostic.Create(
Descriptor,
firstToken.GetLocation(),
option.Notification.Value,
additionalLocations: null,
properties: null,
SyntaxFacts.GetText(firstToken.Kind())));
}
}
}
......@@ -70,11 +70,11 @@ private void HandleVariableDeclaration(SyntaxNodeAnalysisContext context)
}
// The severity preference is not Hidden, as indicated by IsStylePreferred.
var descriptor = GetDescriptorWithSeverity(typeStyle.Severity);
context.ReportDiagnostic(CreateDiagnostic(descriptor, declarationStatement, declaredType.Span));
var descriptor = Descriptor;
context.ReportDiagnostic(CreateDiagnostic(descriptor, declarationStatement, declaredType.Span, typeStyle.Severity));
}
private Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, SyntaxNode declaration, TextSpan diagnosticSpan)
=> Diagnostic.Create(descriptor, declaration.SyntaxTree.GetLocation(diagnosticSpan));
private Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, SyntaxNode declaration, TextSpan diagnosticSpan, DiagnosticSeverity severity)
=> Diagnostic.Create(descriptor, declaration.SyntaxTree.GetLocation(diagnosticSpan), severity, additionalLocations: null, properties: null);
}
}
......@@ -241,9 +241,11 @@ private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context, INamedTypeSymb
: localDeclarator;
context.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(option.Notification.Value),
Descriptor,
reportNode.GetLocation(),
additionalLocations: allLocations));
option.Notification.Value,
additionalLocations: allLocations,
properties: null));
}
private bool WouldCauseDefiniteAssignmentErrors(
......
......@@ -180,8 +180,9 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
// Put a diagnostic with the appropriate severity on the expression-statement itself.
syntaxContext.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
expressionStatement.GetLocation(),
severity,
additionalLocations, properties));
// If the if-statement extends past the expression statement, then fade out the rest.
......
......@@ -22,7 +22,7 @@ public CSharpOrderModifiersDiagnosticAnalyzer()
protected override void Recurse(
SyntaxTreeAnalysisContext context,
Dictionary<int, int> preferredOrder,
DiagnosticDescriptor descriptor,
DiagnosticSeverity severity,
SyntaxNode root)
{
foreach (var child in root.ChildNodesAndTokens())
......@@ -32,19 +32,19 @@ public CSharpOrderModifiersDiagnosticAnalyzer()
var node = child.AsNode();
if (node is MemberDeclarationSyntax memberDeclaration)
{
CheckModifiers(context, preferredOrder, descriptor, memberDeclaration);
CheckModifiers(context, preferredOrder, severity, memberDeclaration);
// Recurse and check children. Note: we only do this if we're on an actual
// member declaration. Once we hit something that isn't, we don't need to
// keep recursing. This prevents us from actually entering things like method
// bodies.
Recurse(context, preferredOrder, descriptor, node);
Recurse(context, preferredOrder, severity, node);
}
else if (node is AccessorListSyntax accessorList)
{
foreach (var accessor in accessorList.Accessors)
{
CheckModifiers(context, preferredOrder, descriptor, accessor);
CheckModifiers(context, preferredOrder, severity, accessor);
}
}
}
......
......@@ -133,7 +133,7 @@ private void AnalyzeSemanticModel(SemanticModelAnalysisContext context)
// statement in this group.
var additionalLocations = SpecializedCollections.SingletonEnumerable(firstStatementLocation);
var descriptor = fadeOutCode ? UnnecessaryWithSuggestionDescriptor : HiddenDescriptor;
var descriptor = fadeOutCode ? UnnecessaryWithSuggestionDescriptor : Descriptor;
context.ReportDiagnostic(
Diagnostic.Create(descriptor, firstStatementLocation, additionalLocations));
......
......@@ -75,8 +75,11 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
}
context.ReportDiagnostic(Diagnostic.Create(
this.GetDescriptorWithSeverity(severity),
variableDeclaration.Variables[0].Identifier.GetLocation()));
Descriptor,
variableDeclaration.Variables[0].Identifier.GetLocation(),
severity,
additionalLocations: null,
properties: null));
}
private void AnalyzeForEachStatement(
......@@ -90,8 +93,11 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
}
context.ReportDiagnostic(Diagnostic.Create(
this.GetDescriptorWithSeverity(severity),
forEachStatement.Identifier.GetLocation()));
Descriptor,
forEachStatement.Identifier.GetLocation(),
severity,
additionalLocations: null,
properties: null));
}
public static bool TryAnalyzeVariableDeclaration(
......
......@@ -50,9 +50,12 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
// Create a normal diagnostic that covers the entire default expression.
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression).Notification.Value),
defaultExpression.GetLocation()));
Diagnostic.Create(
Descriptor,
defaultExpression.GetLocation(),
optionSet.GetOption(CSharpCodeStyleOptions.PreferSimpleDefaultExpression).Notification.Value,
additionalLocations: null,
properties: null));
// Also fade out the part of the default expression from the open paren through
// the close paren.
......
......@@ -28,7 +28,7 @@ public UseExpressionBodyDiagnosticAnalyzer()
{
_syntaxKinds = _helpers.SelectMany(h => h.SyntaxKinds).ToImmutableArray();
SupportedDiagnostics = _helpers.SelectAsArray(
h => CreateDescriptorWithId(h.DiagnosticId, h.UseExpressionBodyTitle, h.UseExpressionBodyTitle, DiagnosticSeverity.Hidden));
h => CreateDescriptorWithId(h.DiagnosticId, h.UseExpressionBodyTitle, h.UseExpressionBodyTitle));
}
public override DiagnosticAnalyzerCategory GetAnalyzerCategory()
......@@ -97,8 +97,8 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
var additionalLocations = ImmutableArray.Create(declaration.GetLocation());
var properties = ImmutableDictionary<string, string>.Empty.Add(nameof(UseExpressionBody), "");
return Diagnostic.Create(
CreateDescriptorWithId(helper.DiagnosticId, helper.UseExpressionBodyTitle, helper.UseExpressionBodyTitle, severity, GetCustomTags(severity)),
location, additionalLocations: additionalLocations, properties: properties);
CreateDescriptorWithId(helper.DiagnosticId, helper.UseExpressionBodyTitle, helper.UseExpressionBodyTitle),
location, severity, additionalLocations: additionalLocations, properties: properties);
}
var (canOffer, fixesError) = helper.CanOfferUseBlockBody(optionSet, declaration, forAnalyzer: true);
......@@ -118,16 +118,11 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
var additionalLocations = ImmutableArray.Create(declaration.GetLocation());
return Diagnostic.Create(
CreateDescriptorWithId(helper.DiagnosticId, helper.UseBlockBodyTitle, helper.UseBlockBodyTitle, severity, GetCustomTags(severity)),
location, additionalLocations: additionalLocations, properties: properties);
CreateDescriptorWithId(helper.DiagnosticId, helper.UseBlockBodyTitle, helper.UseBlockBodyTitle),
location, severity, additionalLocations: additionalLocations, properties: properties);
}
return null;
}
private static string[] GetCustomTags(DiagnosticSeverity severity)
=> severity == DiagnosticSeverity.Hidden
? new[] { WellKnownDiagnosticTags.NotConfigurable }
: Array.Empty<string>();
}
}
......@@ -48,9 +48,12 @@ private void ReportDiagnosticsIfNeeded(NameColonSyntax nameColon, SyntaxNodeAnal
// Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CodeStyleOptions.PreferInferredTupleNames, context.Compilation.Language).Notification.Value),
nameColon.GetLocation()));
Diagnostic.Create(
Descriptor,
nameColon.GetLocation(),
optionSet.GetOption(CodeStyleOptions.PreferInferredTupleNames, context.Compilation.Language).Notification.Value,
additionalLocations: null,
properties: null));
// Also fade out the part of the name-colon syntax
var fadeSpan = TextSpan.FromBounds(nameColon.Name.SpanStart, nameColon.ColonToken.Span.End);
......@@ -76,9 +79,12 @@ private void ReportDiagnosticsIfNeeded(NameEqualsSyntax nameEquals, SyntaxNodeAn
// Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CodeStyleOptions.PreferInferredAnonymousTypeMemberNames, context.Compilation.Language).Notification.Value),
nameEquals.GetLocation()));
Diagnostic.Create(
Descriptor,
nameEquals.GetLocation(),
optionSet.GetOption(CodeStyleOptions.PreferInferredAnonymousTypeMemberNames, context.Compilation.Language).Notification.Value,
additionalLocations: null,
properties: null));
// Also fade out the part of the name-equals syntax
var fadeSpan = TextSpan.FromBounds(nameEquals.Name.SpanStart, nameEquals.EqualsToken.Span.End);
......
......@@ -135,25 +135,31 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext, INamedTyp
// If the diagnostic is not hidden, then just place the user visible part
// on the local being initialized with the lambda.
syntaxContext.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
localDeclaration.Declaration.Variables[0].Identifier.GetLocation(),
additionalLocations));
severity,
additionalLocations,
properties: null));
}
else
{
// If the diagnostic is hidden, place it on the entire construct.
syntaxContext.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
localDeclaration.GetLocation(),
additionalLocations));
severity,
additionalLocations,
properties: null));
var anonymousFunctionStatement = anonymousFunction.GetAncestor<StatementSyntax>();
if (localDeclaration != anonymousFunctionStatement)
{
syntaxContext.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
anonymousFunctionStatement.GetLocation(),
additionalLocations));
severity,
additionalLocations,
properties: null));
}
}
}
......
......@@ -195,9 +195,11 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
// Put a diagnostic with the appropriate severity on the declaration-statement itself.
syntaxContext.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(styleOption.Notification.Value),
Descriptor,
declarationStatement.GetLocation(),
additionalLocations));
styleOption.Notification.Value,
additionalLocations,
properties: null));
}
// Ensure that all usages of the pattern variable are
......
......@@ -145,9 +145,11 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
// Put a diagnostic with the appropriate severity on the declaration-statement itself.
syntaxContext.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
localDeclarationStatement.GetLocation(),
additionalLocations));
severity,
additionalLocations,
properties: null));
}
public bool TryGetPatternPieces(
......
......@@ -90,7 +90,7 @@ private void SyntaxNodeAction(SyntaxNodeAnalysisContext context)
context.ReportDiagnostic(
Diagnostic.Create(
this.HiddenDescriptor, isExpression.GetLocation()));
this.Descriptor, isExpression.GetLocation()));
}
public (HashSet<CastExpressionSyntax>, string localName) AnalyzeExpression(
......
......@@ -139,8 +139,9 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
var properties = GetProperties(includeInFixAll, equivalenceKey);
context.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
operatorToken.GetLocation(),
severity,
additionalLocations,
properties));
......
......@@ -12,13 +12,7 @@ internal abstract class AbstractCodeStyleDiagnosticAnalyzer : DiagnosticAnalyzer
{
protected readonly string DescriptorId;
/// <summary>
/// Diagnostic descriptors corresponding to each of the DiagnosticSeverities.
/// </summary>
protected readonly DiagnosticDescriptor HiddenDescriptor;
protected readonly DiagnosticDescriptor InfoDescriptor;
protected readonly DiagnosticDescriptor WarningDescriptor;
protected readonly DiagnosticDescriptor ErrorDescriptor;
protected readonly DiagnosticDescriptor Descriptor;
/// <summary>
/// Diagnostic descriptor for code you want to fade out *and* want to have a smart-tag
......@@ -55,51 +49,33 @@ internal abstract class AbstractCodeStyleDiagnosticAnalyzer : DiagnosticAnalyzer
_localizableMessage = message ?? title;
_configurable = configurable;
HiddenDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Hidden);
InfoDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Info);
WarningDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Warning);
ErrorDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Error);
UnnecessaryWithSuggestionDescriptor = CreateUnnecessaryDescriptor(DiagnosticSeverity.Hidden);
UnnecessaryWithoutSuggestionDescriptor = CreateUnnecessaryDescriptor(
descriptorId + "WithoutSuggestion", DiagnosticSeverity.Hidden);
Descriptor = CreateDescriptor();
UnnecessaryWithSuggestionDescriptor = CreateUnnecessaryDescriptor();
UnnecessaryWithoutSuggestionDescriptor = CreateUnnecessaryDescriptor(descriptorId + "WithoutSuggestion");
SupportedDiagnostics = ImmutableArray.Create(
HiddenDescriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor);
Descriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor);
}
protected DiagnosticDescriptor CreateUnnecessaryDescriptor(DiagnosticSeverity severity)
=> CreateUnnecessaryDescriptor(DescriptorId, severity);
protected DiagnosticDescriptor CreateUnnecessaryDescriptor()
=> CreateUnnecessaryDescriptor(DescriptorId);
protected DiagnosticDescriptor CreateUnnecessaryDescriptor(string descriptorId, DiagnosticSeverity severity)
protected DiagnosticDescriptor CreateUnnecessaryDescriptor(string descriptorId)
=> CreateDescriptorWithId(
descriptorId, _localizableTitle, _localizableMessage,
severity, DiagnosticCustomTags.Unnecessary);
DiagnosticCustomTags.Unnecessary);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
protected DiagnosticDescriptor GetDescriptorWithSeverity(DiagnosticSeverity severity)
{
switch (severity)
{
case DiagnosticSeverity.Hidden: return HiddenDescriptor;
case DiagnosticSeverity.Info: return InfoDescriptor;
case DiagnosticSeverity.Warning: return WarningDescriptor;
case DiagnosticSeverity.Error: return ErrorDescriptor;
default: throw new InvalidOperationException();
}
}
protected DiagnosticDescriptor CreateDescriptorWithSeverity(DiagnosticSeverity severity, params string[] customTags)
=> CreateDescriptorWithId(DescriptorId, _localizableTitle, _localizableMessage, severity, customTags);
protected DiagnosticDescriptor CreateDescriptor(params string[] customTags)
=> CreateDescriptorWithId(DescriptorId, _localizableTitle, _localizableMessage, customTags);
protected DiagnosticDescriptor CreateDescriptorWithTitle(LocalizableString title, DiagnosticSeverity severity, params string[] customTags)
=> CreateDescriptorWithId(DescriptorId, title, title, severity, customTags);
protected DiagnosticDescriptor CreateDescriptorWithTitle(LocalizableString title, params string[] customTags)
=> CreateDescriptorWithId(DescriptorId, title, title, customTags);
protected DiagnosticDescriptor CreateDescriptorWithId(
string id, LocalizableString title, LocalizableString message,
DiagnosticSeverity severity, params string[] customTags)
params string[] customTags)
{
if (!_configurable)
{
......@@ -109,7 +85,7 @@ protected DiagnosticDescriptor CreateDescriptorWithTitle(LocalizableString title
return new DiagnosticDescriptor(
id, title, message,
DiagnosticCategory.Style,
severity,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true,
customTags: customTags);
}
......
......@@ -145,7 +145,7 @@ void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
s_localizableTitleNamingStyle,
string.Format(FeaturesResources.Naming_rule_violation_0, failureReason),
DiagnosticCategory.Style,
applicableRule.EnforcementLevel,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true);
var builder = ImmutableDictionary.CreateBuilder<string, string>();
......@@ -153,7 +153,7 @@ void SyntaxNodeAction(SyntaxNodeAnalysisContext syntaxContext)
builder["OptionName"] = nameof(SimplificationOptions.NamingPreferences);
builder["OptionLanguage"] = compilation.Language;
return Diagnostic.Create(descriptor, symbol.Locations.First(), builder.ToImmutable());
return Diagnostic.Create(descriptor, symbol.Locations.First(), applicableRule.EnforcementLevel, additionalLocations: null, builder.ToImmutable());
}
[PerformanceSensitive("https://github.com/dotnet/roslyn/issues/23582", OftenCompletesSynchronously = true)]
......
......@@ -111,16 +111,9 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
}
// earlier we did a context insensitive check to see if this style was preferred in *any* context at all.
// now, we have to make a context sensitive check to see if options settings for our context requires us to report a diagnostic.
if (ShouldReportDiagnostic(predefinedTypeNode, optionSet, language, out var diagnosticId, out var diagnosticSeverity))
if (ShouldReportDiagnostic(predefinedTypeNode, optionSet, language, out var descriptor, out var severity))
{
var descriptor = new DiagnosticDescriptor(diagnosticId,
s_preferFrameworkTypeTitle,
s_preferFrameworkTypeMessage,
DiagnosticCategory.Style,
diagnosticSeverity,
isEnabledByDefault: true);
context.ReportDiagnostic(Diagnostic.Create(descriptor, predefinedTypeNode.GetLocation()));
context.ReportDiagnostic(Diagnostic.Create(descriptor, predefinedTypeNode.GetLocation(), severity, additionalLocations: null, properties: null));
}
}
......@@ -128,7 +121,7 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
/// Detects the context of this occurrence of predefined type and determines if we should report it.
/// </summary>
private bool ShouldReportDiagnostic(TPredefinedTypeSyntax predefinedTypeNode, OptionSet optionSet, string language,
out string diagnosticId, out DiagnosticSeverity severity)
out DiagnosticDescriptor descriptor, out DiagnosticSeverity severity)
{
CodeStyleOption<bool> optionValue;
......@@ -136,12 +129,12 @@ protected void AnalyzeNode(SyntaxNodeAnalysisContext context)
// check the appropriate option and determine if we should report a diagnostic.
if (IsInMemberAccessOrCrefReferenceContext(predefinedTypeNode))
{
diagnosticId = IDEDiagnosticIds.PreferFrameworkTypeInMemberAccessDiagnosticId;
descriptor = s_descriptorPreferFrameworkTypeInMemberAccess;
optionValue = optionSet.GetOption(GetOptionForMemberAccessContext, language);
}
else
{
diagnosticId = IDEDiagnosticIds.PreferFrameworkTypeInDeclarationsDiagnosticId;
descriptor = s_descriptorPreferFrameworkTypeInDeclarations;
optionValue = optionSet.GetOption(GetOptionForDeclarationContext, language);
}
......
......@@ -122,29 +122,32 @@ protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode nod
PerLanguageOption<CodeStyleOption<bool>> option;
DiagnosticDescriptor descriptor;
DiagnosticSeverity severity;
switch (diagnosticId)
{
case IDEDiagnosticIds.SimplifyNamesDiagnosticId:
descriptor = s_descriptorSimplifyNames;
severity = descriptor.DefaultSeverity;
break;
case IDEDiagnosticIds.SimplifyMemberAccessDiagnosticId:
descriptor = s_descriptorSimplifyMemberAccess;
severity = descriptor.DefaultSeverity;
break;
case IDEDiagnosticIds.RemoveQualificationDiagnosticId:
descriptor = GetRemoveQualificationDiagnosticDescriptor(model, node, optionSet, cancellationToken);
(descriptor, severity) = GetRemoveQualificationDiagnosticDescriptor(model, node, optionSet, cancellationToken);
break;
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId:
option = CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInDeclaration;
descriptor = GetApplicablePredefinedTypeDiagnosticDescriptor(
(descriptor, severity) = GetApplicablePredefinedTypeDiagnosticDescriptor(
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId, option, optionSet);
break;
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId:
option = CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess;
descriptor = GetApplicablePredefinedTypeDiagnosticDescriptor(
(descriptor, severity) = GetApplicablePredefinedTypeDiagnosticDescriptor(
IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId, option, optionSet);
break;
......@@ -161,49 +164,48 @@ protected bool TrySimplifyTypeNameExpression(SemanticModel model, SyntaxNode nod
var builder = ImmutableDictionary.CreateBuilder<string, string>();
builder["OptionName"] = nameof(CodeStyleOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess); // TODO: need the actual one
builder["OptionLanguage"] = model.Language;
diagnostic = Diagnostic.Create(descriptor, tree.GetLocation(issueSpan), builder.ToImmutable());
diagnostic = Diagnostic.Create(descriptor, tree.GetLocation(issueSpan), severity, additionalLocations: null, builder.ToImmutable());
return true;
}
private DiagnosticDescriptor GetApplicablePredefinedTypeDiagnosticDescriptor<T>(string id, PerLanguageOption<T> option, OptionSet optionSet) where T : CodeStyleOption<bool>
private (DiagnosticDescriptor descriptor, DiagnosticSeverity severity) GetApplicablePredefinedTypeDiagnosticDescriptor<T>(string id, PerLanguageOption<T> option, OptionSet optionSet) where T : CodeStyleOption<bool>
{
var optionValue = optionSet.GetOption(option, GetLanguageName());
DiagnosticDescriptor descriptor = null;
if (optionValue.Notification.Value != DiagnosticSeverity.Hidden)
{
descriptor = new DiagnosticDescriptor(id,
s_localizableTitleSimplifyNames,
s_localizableMessage,
DiagnosticCategory.Style,
optionValue.Notification.Value,
isEnabledByDefault: true,
customTags: DiagnosticCustomTags.Unnecessary);
switch (id)
{
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInDeclarationsDiagnosticId:
descriptor = s_descriptorPreferIntrinsicTypeInDeclarations;
break;
case IDEDiagnosticIds.PreferIntrinsicPredefinedTypeInMemberAccessDiagnosticId:
descriptor = s_descriptorPreferIntrinsicTypeInMemberAccess;
break;
default:
throw ExceptionUtilities.UnexpectedValue(id);
}
}
return descriptor;
return (descriptor, optionValue.Notification.Value);
}
private DiagnosticDescriptor GetRemoveQualificationDiagnosticDescriptor(SemanticModel model, SyntaxNode node, OptionSet optionSet, CancellationToken cancellationToken)
private (DiagnosticDescriptor descriptor, DiagnosticSeverity severity) GetRemoveQualificationDiagnosticDescriptor(SemanticModel model, SyntaxNode node, OptionSet optionSet, CancellationToken cancellationToken)
{
var symbolInfo = model.GetSymbolInfo(node, cancellationToken);
if (symbolInfo.Symbol == null)
{
return null;
return default;
}
var applicableOption = QualifyMembersHelpers.GetApplicableOptionFromSymbolKind(symbolInfo.Symbol.Kind);
var optionValue = optionSet.GetOption(applicableOption, GetLanguageName());
var severity = optionValue.Notification.Value;
return new DiagnosticDescriptor(
IDEDiagnosticIds.RemoveQualificationDiagnosticId,
s_localizableTitleRemoveThisOrMe,
s_localizableMessage,
DiagnosticCategory.Style,
severity,
isEnabledByDefault: true,
customTags: DiagnosticCustomTags.Unnecessary);
return (s_descriptorRemoveThisOrMe, severity);
}
public DiagnosticAnalyzerCategory GetAnalyzerCategory()
......
......@@ -92,8 +92,11 @@ private void AnalyzeSemanticModel(SemanticModelAnalysisContext context)
foreach (var symbol in candidateFields)
{
var diagnostic = Diagnostic.Create(
GetDescriptorWithSeverity(option.Notification.Value),
symbol.Locations[0]);
Descriptor,
symbol.Locations[0],
option.Notification.Value,
additionalLocations: null,
properties: null);
context.ReportDiagnostic(diagnostic);
}
......
......@@ -54,31 +54,30 @@ private void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context)
return;
}
var descriptor = GetDescriptorWithSeverity(option.Notification.Value);
Recurse(context, preferredOrder, descriptor, root);
Recurse(context, preferredOrder, option.Notification.Value, root);
}
protected abstract void Recurse(
SyntaxTreeAnalysisContext context,
Dictionary<int, int> preferredOrder,
DiagnosticDescriptor descriptor,
DiagnosticSeverity severity,
SyntaxNode root);
protected void CheckModifiers(
SyntaxTreeAnalysisContext context,
Dictionary<int, int> preferredOrder,
DiagnosticDescriptor descriptor,
DiagnosticSeverity severity,
SyntaxNode memberDeclaration)
{
var modifiers = _syntaxFacts.GetModifiers(memberDeclaration);
if (!IsOrdered(preferredOrder, modifiers))
{
if (descriptor.DefaultSeverity == DiagnosticSeverity.Hidden)
if (severity == DiagnosticSeverity.Hidden)
{
// If the severity is hidden, put the marker on all the modifiers so that the
// user can bring up the fix anywhere in the modifier list.
context.ReportDiagnostic(
Diagnostic.Create(descriptor, context.Tree.GetLocation(
Diagnostic.Create(Descriptor, context.Tree.GetLocation(
TextSpan.FromBounds(modifiers.First().SpanStart, modifiers.Last().Span.End))));
}
else
......@@ -86,7 +85,7 @@ private void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context)
// If the Severity is not hidden, then just put the user visible portion on the
// first token. That way we don't
context.ReportDiagnostic(
Diagnostic.Create(descriptor, modifiers.First().GetLocation()));
Diagnostic.Create(Descriptor, modifiers.First().GetLocation(), severity, additionalLocations: null, properties: null));
}
}
}
......
......@@ -46,7 +46,7 @@ private void AnalyzeOperation(OperationAnalysisContext context)
.Add(PopulateSwitchHelpers.MissingDefaultCase, missingDefaultCase.ToString());
var diagnostic = Diagnostic.Create(
HiddenDescriptor,
Descriptor,
switchBlock.GetFirstToken().GetLocation(),
properties: properties,
additionalLocations: new[] { switchBlock.GetLocation() });
......
......@@ -116,8 +116,11 @@ private void AnalyzeOperation(OperationAnalysisContext context)
if (severity != DiagnosticSeverity.Hidden)
{
context.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
simpleName.GetLocation()));
Descriptor,
simpleName.GetLocation(),
severity,
additionalLocations: null,
properties: null));
}
}
}
......
......@@ -110,8 +110,11 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
var additionalLocations = ImmutableArray.Create(parenthesizedExpression.GetLocation());
context.ReportDiagnostic(Diagnostic.Create(
CreateUnnecessaryDescriptor(severity),
parenthesizedExpression.GetFirstToken().GetLocation(), additionalLocations));
UnnecessaryWithSuggestionDescriptor,
parenthesizedExpression.GetFirstToken().GetLocation(),
severity,
additionalLocations,
properties: null));
context.ReportDiagnostic(Diagnostic.Create(
UnnecessaryWithoutSuggestionDescriptor,
......
......@@ -317,34 +317,22 @@ private void Process(AnalysisResult result, SemanticModelAnalysisContext context
// Place the appropriate marker on the field depending on the user option.
var diagnostic1 = Diagnostic.Create(
GetFieldDescriptor(option), nodeToFade.GetLocation(),
additionalLocations: additionalLocations);
UnnecessaryWithSuggestionDescriptor,
nodeToFade.GetLocation(),
option.Notification.Value,
additionalLocations: additionalLocations,
properties: null);
// Also, place a hidden marker on the property. If they bring up a lightbulb
// there, they'll be able to see that they can convert it to an auto-prop.
var diagnostic2 = Diagnostic.Create(
HiddenDescriptor, propertyDeclaration.GetLocation(),
Descriptor, propertyDeclaration.GetLocation(),
additionalLocations: additionalLocations);
context.ReportDiagnostic(diagnostic1);
context.ReportDiagnostic(diagnostic2);
}
private DiagnosticDescriptor GetFieldDescriptor(CodeStyleOption<bool> styleOption)
{
if (styleOption.Value)
{
switch (styleOption.Notification.Value)
{
case DiagnosticSeverity.Error: return ErrorDescriptor;
case DiagnosticSeverity.Warning: return WarningDescriptor;
case DiagnosticSeverity.Info: return InfoDescriptor;
}
}
return UnnecessaryWithSuggestionDescriptor;
}
protected virtual bool IsEligibleHeuristic(
IFieldSymbol field, TPropertyDeclaration propertyDeclaration,
Compilation compilation, CancellationToken cancellationToken)
......
......@@ -130,9 +130,11 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
whenPartToCheck.GetLocation());
context.ReportDiagnostic(Diagnostic.Create(
this.GetDescriptorWithSeverity(option.Notification.Value),
Descriptor,
conditionalExpression.GetLocation(),
locations));
option.Notification.Value,
locations,
properties: null));
}
}
}
......@@ -129,9 +129,11 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context)
whenPartToKeep.GetLocation());
context.ReportDiagnostic(Diagnostic.Create(
this.GetDescriptorWithSeverity(option.Notification.Value),
Descriptor,
conditionalExpression.GetLocation(),
locations));
option.Notification.Value,
locations,
properties: null));
}
}
}
......@@ -112,9 +112,11 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context, INamedTypeSymbol ien
var severity = option.Notification.Value;
context.ReportDiagnostic(Diagnostic.Create(
CreateDescriptorWithSeverity(severity),
Descriptor,
objectCreationExpression.GetLocation(),
additionalLocations: locations));
severity,
additionalLocations: locations,
properties: null));
FadeOutCode(context, optionSet, matches.Value, locations);
}
......
......@@ -69,9 +69,11 @@ private void AnalyzeOperation(OperationAnalysisContext context)
var additionalLocations = ImmutableArray.Create(ifStatement.GetLocation());
context.ReportDiagnostic(Diagnostic.Create(
this.CreateDescriptorWithSeverity(option.Notification.Value),
Descriptor,
ifStatement.GetFirstToken().GetLocation(),
additionalLocations));
option.Notification.Value,
additionalLocations,
properties: null));
}
}
}
......@@ -63,8 +63,10 @@ private void AnalyzeOperation(OperationAnalysisContext context)
var properties = ImmutableDictionary<string, string>.Empty.Add(
nameof(ElementName), namedField.Name);
context.ReportDiagnostic(Diagnostic.Create(
GetDescriptorWithSeverity(severity),
Descriptor,
nameNode.GetLocation(),
severity,
additionalLocations: null,
properties));
}
}
......
......@@ -144,7 +144,8 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context, IMethodSymbol refe
var severity = option.Notification.Value;
context.ReportDiagnostic(
Diagnostic.Create(
GetDescriptorWithSeverity(severity), nameNode.GetLocation(),
Descriptor, nameNode.GetLocation(),
severity,
additionalLocations, properties));
}
......
......@@ -179,8 +179,9 @@ private void AnalyzeSyntax(SyntaxNodeAnalysisContext context, INamedTypeSymbol e
}
context.ReportDiagnostic(Diagnostic.Create(
this.GetDescriptorWithSeverity(option.Notification.Value),
Descriptor,
conditionalExpression.GetLocation(),
option.Notification.Value,
locations,
properties));
}
......
......@@ -89,9 +89,11 @@ private void AnalyzeNode(SyntaxNodeAnalysisContext context)
var severity = option.Notification.Value;
context.ReportDiagnostic(Diagnostic.Create(
CreateDescriptorWithSeverity(severity),
Descriptor,
objectCreationExpression.GetLocation(),
additionalLocations: locations));
severity,
additionalLocations: locations,
properties: null));
FadeOutCode(context, optionSet, matches.Value, locations);
}
......
......@@ -146,10 +146,8 @@ private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol
throwOperation.Exception.Syntax.GetLocation(),
assignmentExpression.Value.Syntax.GetLocation());
var descriptor = GetDescriptorWithSeverity(option.Notification.Value);
context.ReportDiagnostic(
Diagnostic.Create(descriptor, throwStatementSyntax.GetLocation(), additionalLocations: allLocations));
Diagnostic.Create(Descriptor, throwStatementSyntax.GetLocation(), option.Notification.Value, additionalLocations: allLocations, properties: null));
// Fade out the rest of the if that surrounds the 'throw' exception.
......
......@@ -83,9 +83,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.AddAccessibilityModifiers
' Have an issue to flag, either add or remove. Report issue to user.
Dim additionalLocations = ImmutableArray.Create(member.GetLocation())
context.ReportDiagnostic(Diagnostic.Create(
CreateDescriptorWithSeverity([option].Notification.Value),
Descriptor,
name.GetLocation(),
additionalLocations:=additionalLocations))
[option].Notification.Value,
additionalLocations:=additionalLocations,
properties:=Nothing))
End Sub
Private Function MatchesDefaultAccessibility(accessibility As Accessibility, member As StatementSyntax) As Boolean
......
......@@ -19,7 +19,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.OrderModifiers
Protected Overrides Sub Recurse(
context As SyntaxTreeAnalysisContext,
preferredOrder As Dictionary(Of Integer, Integer),
descriptor As DiagnosticDescriptor,
severity As DiagnosticSeverity,
root As SyntaxNode)
For Each child In root.ChildNodesAndTokens()
......@@ -27,10 +27,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.OrderModifiers
Dim declarationStatement = TryCast(child.AsNode(), DeclarationStatementSyntax)
If declarationStatement IsNot Nothing Then
If ShouldCheck(declarationStatement) Then
CheckModifiers(context, preferredOrder, descriptor, declarationStatement)
CheckModifiers(context, preferredOrder, severity, declarationStatement)
End If
Recurse(context, preferredOrder, descriptor, declarationStatement)
Recurse(context, preferredOrder, severity, declarationStatement)
End If
End If
Next
......
......@@ -48,9 +48,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseInferredMemberName
' Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CodeStyleOptions.PreferInferredTupleNames, context.Compilation.Language).Notification.Value),
nameColonEquals.GetLocation()))
Diagnostic.Create(
Descriptor,
nameColonEquals.GetLocation(),
optionSet.GetOption(CodeStyleOptions.PreferInferredTupleNames, context.Compilation.Language).Notification.Value,
additionalLocations:=Nothing,
properties:=Nothing))
' Also fade out the part of the name-colon-equals syntax
Dim fadeSpan = TextSpan.FromBounds(nameColonEquals.Name.SpanStart, nameColonEquals.ColonEqualsToken.Span.End)
......@@ -76,9 +79,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseInferredMemberName
' Create a normal diagnostic
context.ReportDiagnostic(
Diagnostic.Create(GetDescriptorWithSeverity(
optionSet.GetOption(CodeStyleOptions.PreferInferredAnonymousTypeMemberNames, context.Compilation.Language).Notification.Value),
syntaxTree.GetLocation(fadeSpan)))
Diagnostic.Create(
Descriptor,
syntaxTree.GetLocation(fadeSpan),
optionSet.GetOption(CodeStyleOptions.PreferInferredAnonymousTypeMemberNames, context.Compilation.Language).Notification.Value,
additionalLocations:=Nothing,
properties:=Nothing))
' Also fade out the part of the name-equals syntax
context.ReportDiagnostic(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册