提交 4222a5c8 编写于 作者: C CyrusNajmabadi

Make more diagnostic analyzers into code style analyzers.

上级 765dbf3f
// 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 Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.Diagnostics.AddBraces
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
internal sealed class CSharpAddBracesDiagnosticAnalyzer : DiagnosticAnalyzer, IBuiltInAnalyzer
internal sealed class CSharpAddBracesDiagnosticAnalyzer :
AbstractCodeStyleDiagnosticAnalyzer, IBuiltInAnalyzer
{
private static readonly LocalizableString s_localizableTitle =
new LocalizableResourceString(nameof(FeaturesResources.Add_braces), FeaturesResources.ResourceManager,
......@@ -17,14 +19,11 @@ internal sealed class CSharpAddBracesDiagnosticAnalyzer : DiagnosticAnalyzer, IB
new LocalizableResourceString(nameof(WorkspacesResources.Add_braces_to_0_statement), WorkspacesResources.ResourceManager,
typeof(WorkspacesResources));
private static readonly DiagnosticDescriptor s_descriptor = new DiagnosticDescriptor(IDEDiagnosticIds.AddBracesDiagnosticId,
s_localizableTitle,
s_localizableMessage,
DiagnosticCategory.Style,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(s_descriptor);
public CSharpAddBracesDiagnosticAnalyzer()
: base(IDEDiagnosticIds.AddBracesDiagnosticId,
s_localizableTitle, s_localizableMessage)
{
}
public bool OpenFileOnly(Workspace workspace) => false;
......@@ -39,7 +38,8 @@ internal sealed class CSharpAddBracesDiagnosticAnalyzer : DiagnosticAnalyzer, IB
SyntaxKind.UsingStatement,
SyntaxKind.LockStatement);
public override void Initialize(AnalysisContext context)
protected override void InitializeWorker(AnalysisContext context)
=> context.RegisterSyntaxNodeAction(AnalyzeNode, s_syntaxKindsOfInterest);
public DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticSpanAnalysis;
......@@ -53,7 +53,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var ifStatement = (IfStatementSyntax)node;
if (AnalyzeIfStatement(ifStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
ifStatement.IfKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.IfKeyword)));
}
}
......@@ -63,7 +63,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var elseClause = (ElseClauseSyntax)node;
if (AnalyzeElseClause(elseClause))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
elseClause.ElseKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ElseKeyword)));
}
}
......@@ -73,7 +73,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var forStatement = (ForStatementSyntax)node;
if (AnalyzeForStatement(forStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
forStatement.ForKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ForKeyword)));
}
}
......@@ -83,7 +83,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var forEachStatement = (CommonForEachStatementSyntax)node;
if (AnalyzeForEachStatement(forEachStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
forEachStatement.ForEachKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.ForEachKeyword)));
}
}
......@@ -93,7 +93,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var whileStatement = (WhileStatementSyntax)node;
if (AnalyzeWhileStatement(whileStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
whileStatement.WhileKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.WhileKeyword)));
}
}
......@@ -103,7 +103,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var doStatement = (DoStatementSyntax)node;
if (AnalyzeDoStatement(doStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
doStatement.DoKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.DoKeyword)));
}
}
......@@ -113,7 +113,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var usingStatement = (UsingStatementSyntax)context.Node;
if (AnalyzeUsingStatement(usingStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
usingStatement.UsingKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.UsingKeyword)));
}
}
......@@ -123,7 +123,7 @@ public void AnalyzeNode(SyntaxNodeAnalysisContext context)
var lockStatement = (LockStatementSyntax)context.Node;
if (AnalyzeLockStatement(lockStatement))
{
context.ReportDiagnostic(Diagnostic.Create(s_descriptor,
context.ReportDiagnostic(Diagnostic.Create(HiddenDescriptor,
lockStatement.LockKeyword.GetLocation(), SyntaxFacts.GetText(SyntaxKind.LockKeyword)));
}
}
......
......@@ -9,6 +9,11 @@ internal abstract class AbstractCodeStyleDiagnosticAnalyzer : DiagnosticAnalyzer
{
protected readonly string DescriptorId;
/// <summary>
/// Diagnostic descriptor that for analysis results that we don't want any treatment for.
/// </summary>
protected readonly DiagnosticDescriptor HiddenDescriptor;
/// <summary>
/// Diagnostic descriptor for code you want to fade out *and* want to have a smart-tag
/// appear for. This is the common descriptor for code that is being faded out
......@@ -39,7 +44,7 @@ internal abstract class AbstractCodeStyleDiagnosticAnalyzer : DiagnosticAnalyzer
_localizableTitle = title;
_localizableMessage = message ?? title;
var primaryDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Hidden);
HiddenDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Hidden);
UnnecessaryWithSuggestionDescriptor = CreateDescriptorWithId(
descriptorId, _localizableTitle, _localizableMessage,
......@@ -51,7 +56,7 @@ internal abstract class AbstractCodeStyleDiagnosticAnalyzer : DiagnosticAnalyzer
DiagnosticSeverity.Hidden, DiagnosticCustomTags.Unnecessary);
SupportedDiagnostics = ImmutableArray.Create(
primaryDescriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor);
HiddenDescriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor);
}
public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
......
......@@ -40,6 +40,8 @@ internal static class IDEDiagnosticIds
public const string UseNullPropagationDiagnosticId = "IDE0030";
public const string UseAutoPropertyDiagnosticId = "IDE0031";
// Analyzer error Ids
public const string AnalyzerChangedId = "IDE1001";
public const string AnalyzerDependencyConflictId = "IDE1002";
......
......@@ -4,6 +4,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Reflection;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Semantics;
using Microsoft.CodeAnalysis.Shared.Extensions;
......@@ -11,26 +12,25 @@
namespace Microsoft.CodeAnalysis.PopulateSwitch
{
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
internal sealed class PopulateSwitchDiagnosticAnalyzer : DiagnosticAnalyzer, IBuiltInAnalyzer
internal sealed class PopulateSwitchDiagnosticAnalyzer :
AbstractCodeStyleDiagnosticAnalyzer, IBuiltInAnalyzer
{
private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(FeaturesResources.Add_missing_cases), FeaturesResources.ResourceManager, typeof(FeaturesResources));
private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(WorkspacesResources.Populate_switch), WorkspacesResources.ResourceManager, typeof(WorkspacesResources));
private static readonly DiagnosticDescriptor s_descriptor = new DiagnosticDescriptor(IDEDiagnosticIds.PopulateSwitchDiagnosticId,
s_localizableTitle,
s_localizableMessage,
DiagnosticCategory.Style,
DiagnosticSeverity.Hidden,
isEnabledByDefault: true);
public PopulateSwitchDiagnosticAnalyzer()
: base(IDEDiagnosticIds.PopulateSwitchDiagnosticId,
s_localizableTitle, s_localizableMessage)
{
}
#region Interface methods
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(s_descriptor);
public bool OpenFileOnly(Workspace workspace) => false;
private static MethodInfo s_registerMethod = typeof(AnalysisContext).GetTypeInfo().GetDeclaredMethod("RegisterOperationActionImmutableArrayInternal");
public override void Initialize(AnalysisContext context)
protected override void InitializeWorker(AnalysisContext context)
=> s_registerMethod.Invoke(context, new object[]
{
new Action<OperationAnalysisContext>(AnalyzeOperation),
......@@ -54,7 +54,7 @@ private void AnalyzeOperation(OperationAnalysisContext context)
.Add(PopulateSwitchHelpers.MissingDefaultCase, missingDefaultCase.ToString());
var diagnostic = Diagnostic.Create(
s_descriptor, switchBlock.GetLocation(), properties: properties);
HiddenDescriptor, switchBlock.GetLocation(), properties: properties);
context.ReportDiagnostic(diagnostic);
}
}
......
......@@ -4,29 +4,34 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Microsoft.CodeAnalysis.UseAutoProperty
{
internal abstract class AbstractUseAutoPropertyAnalyzer<TPropertyDeclaration, TFieldDeclaration, TVariableDeclarator, TExpression> : DiagnosticAnalyzer
internal abstract class AbstractUseAutoPropertyAnalyzer<TPropertyDeclaration, TFieldDeclaration, TVariableDeclarator, TExpression> :
AbstractCodeStyleDiagnosticAnalyzer
where TPropertyDeclaration : SyntaxNode
where TFieldDeclaration : SyntaxNode
where TVariableDeclarator : SyntaxNode
where TExpression : SyntaxNode
{
public const string UseAutoProperty = nameof(UseAutoProperty);
public const string UseAutoPropertyFadedToken = nameof(UseAutoPropertyFadedToken);
private static readonly LocalizableString s_title =
new LocalizableResourceString(nameof(FeaturesResources.Use_auto_property), FeaturesResources.ResourceManager, typeof(FeaturesResources));
private readonly static DiagnosticDescriptor s_descriptor = new DiagnosticDescriptor(
UseAutoProperty, FeaturesResources.Use_auto_property, FeaturesResources.Use_auto_property,
"Language", DiagnosticSeverity.Hidden, isEnabledByDefault: true);
protected AbstractUseAutoPropertyAnalyzer()
: base(IDEDiagnosticIds.UseAutoPropertyDiagnosticId, s_title, s_title)
{
}
private readonly static DiagnosticDescriptor s_fadedTokenDescriptor = new DiagnosticDescriptor(
UseAutoPropertyFadedToken, FeaturesResources.Use_auto_property, FeaturesResources.Use_auto_property,
"Language", DiagnosticSeverity.Hidden, isEnabledByDefault: true,
customTags: new[] { WellKnownDiagnosticTags.Unnecessary });
//private readonly static DiagnosticDescriptor s_descriptor = new DiagnosticDescriptor(
// UseAutoProperty, FeaturesResources.Use_auto_property, FeaturesResources.Use_auto_property,
// "Language", DiagnosticSeverity.Hidden, isEnabledByDefault: true);
public sealed override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(s_descriptor, s_fadedTokenDescriptor);
//private readonly static DiagnosticDescriptor s_fadedTokenDescriptor = new DiagnosticDescriptor(
// UseAutoPropertyFadedToken, FeaturesResources.Use_auto_property, FeaturesResources.Use_auto_property,
// "Language", DiagnosticSeverity.Hidden, isEnabledByDefault: true,
// customTags: new[] { WellKnownDiagnosticTags.Unnecessary });
protected abstract void RegisterIneligibleFieldsAction(CompilationStartAnalysisContext context, ConcurrentBag<IFieldSymbol> ineligibleFields);
protected abstract bool SupportsReadOnlyProperties(Compilation compilation);
......@@ -36,7 +41,7 @@ internal abstract class AbstractUseAutoPropertyAnalyzer<TPropertyDeclaration, TF
protected abstract TExpression GetSetterExpression(IMethodSymbol setMethod, SemanticModel semanticModel, CancellationToken cancellationToken);
protected abstract SyntaxNode GetNodeToFade(TFieldDeclaration fieldDeclaration, TVariableDeclarator variableDeclarator);
public sealed override void Initialize(AnalysisContext context)
protected sealed override void InitializeWorker(AnalysisContext context)
=> context.RegisterCompilationStartAction(csac =>
{
var analysisResults = new ConcurrentBag<AnalysisResult>();
......@@ -251,7 +256,7 @@ private void Process(AnalysisResult result, CompilationAnalysisContext compilati
var properties = ImmutableDictionary<string, string>.Empty.Add(nameof(result.SymbolEquivalenceKey), result.SymbolEquivalenceKey);
// Fade out the field/variable we are going to remove.
var diagnostic1 = Diagnostic.Create(s_fadedTokenDescriptor, nodeToFade.GetLocation());
var diagnostic1 = Diagnostic.Create(UnnecessaryWithSuggestionDescriptor, nodeToFade.GetLocation());
compilationContext.ReportDiagnostic(diagnostic1);
// Now add diagnostics to both the field and the property saying we can convert it to
......@@ -259,10 +264,10 @@ private void Process(AnalysisResult result, CompilationAnalysisContext compilati
// them when performing the code fix.
IEnumerable<Location> additionalLocations = new Location[] { propertyDeclaration.GetLocation(), variableDeclarator.GetLocation() };
var diagnostic2 = Diagnostic.Create(s_descriptor, propertyDeclaration.GetLocation(), additionalLocations, properties);
var diagnostic2 = Diagnostic.Create(HiddenDescriptor, propertyDeclaration.GetLocation(), additionalLocations, properties);
compilationContext.ReportDiagnostic(diagnostic2);
var diagnostic3 = Diagnostic.Create(s_descriptor, nodeToFade.GetLocation(), additionalLocations, properties);
var diagnostic3 = Diagnostic.Create(HiddenDescriptor, nodeToFade.GetLocation(), additionalLocations, properties);
compilationContext.ReportDiagnostic(diagnostic3);
}
......@@ -297,4 +302,4 @@ internal class AnalysisResult
}
}
}
}
}
\ No newline at end of file
......@@ -9,6 +9,7 @@
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Editing;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.Formatting;
......@@ -28,8 +29,8 @@ internal abstract class AbstractUseAutoPropertyCodeFixProvider<TPropertyDeclarat
{
protected static SyntaxAnnotation SpecializedFormattingAnnotation = new SyntaxAnnotation();
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(
AbstractUseAutoPropertyAnalyzer<TPropertyDeclaration, TFieldDeclaration, TVariableDeclarator, TExpression>.UseAutoProperty);
public sealed override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.UseAutoPropertyDiagnosticId);
public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册