CSharpTypeStyleDiagnosticAnalyzerBase.cs 3.7 KB
Newer Older
1 2
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

3 4
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.CSharp.CodeStyle;
5
using Microsoft.CodeAnalysis.CSharp.Extensions;
6
using Microsoft.CodeAnalysis.CSharp.Utilities;
7 8 9
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Text;

B
Balaji Krishnan 已提交
10
namespace Microsoft.CodeAnalysis.CSharp.Diagnostics.TypeStyle
11
{
12
    internal abstract partial class CSharpTypeStyleDiagnosticAnalyzerBase :
13
        AbstractCodeStyleDiagnosticAnalyzer
14
    {
15 16
        protected abstract CSharpTypeStyleHelper Helper { get; }

17 18 19
        protected CSharpTypeStyleDiagnosticAnalyzerBase(
            string diagnosticId, LocalizableString title, LocalizableString message)
            : base(diagnosticId, title, message)
20 21 22
        {
        }

23
        public override DiagnosticAnalyzerCategory GetAnalyzerCategory() => DiagnosticAnalyzerCategory.SemanticSpanAnalysis;
24

25
        public override bool OpenFileOnly(Workspace workspace)
26 27 28 29 30 31 32 33 34
        {
            var forIntrinsicTypesOption = workspace.Options.GetOption(CSharpCodeStyleOptions.UseImplicitTypeForIntrinsicTypes).Notification;
            var whereApparentOption = workspace.Options.GetOption(CSharpCodeStyleOptions.UseImplicitTypeWhereApparent).Notification;
            var wherePossibleOption = workspace.Options.GetOption(CSharpCodeStyleOptions.UseImplicitTypeWherePossible).Notification;

            return !(forIntrinsicTypesOption == NotificationOption.Warning || forIntrinsicTypesOption == NotificationOption.Error ||
                     whereApparentOption == NotificationOption.Warning || whereApparentOption == NotificationOption.Error ||
                     wherePossibleOption == NotificationOption.Warning || wherePossibleOption == NotificationOption.Error);
        }
35

36 37
        protected override void InitializeWorker(AnalysisContext context)
            => context.RegisterSyntaxNodeAction(
V
Victor Zaytsev 已提交
38
                HandleVariableDeclaration, SyntaxKind.VariableDeclaration, SyntaxKind.ForEachStatement, SyntaxKind.DeclarationExpression);
39 40 41 42

        private void HandleVariableDeclaration(SyntaxNodeAnalysisContext context)
        {
            var declarationStatement = context.Node;
J
Jonathon Marolf 已提交
43 44
            var options = context.Options;
            var syntaxTree = context.Node.SyntaxTree;
45
            var cancellationToken = context.CancellationToken;
J
Jonathon Marolf 已提交
46 47 48 49 50
            var optionSet = options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();
            if (optionSet == null)
            {
                return;
            }
51

52 53 54
            var semanticModel = context.SemanticModel;
            var declaredType = Helper.FindAnalyzableType(declarationStatement, semanticModel, cancellationToken);
            if (declaredType == null)
55
            {
56
                return;
57
            }
58

59 60
            var typeStyle = Helper.AnalyzeTypeName(
                declaredType, semanticModel, optionSet, cancellationToken);
61
            if (!typeStyle.IsStylePreferred || !typeStyle.CanConvert())
62
            {
63
                return;
64 65
            }

66
            // The severity preference is not Hidden, as indicated by IsStylePreferred.
67
            var descriptor = Descriptor;
68
            context.ReportDiagnostic(CreateDiagnostic(descriptor, declarationStatement, declaredType.StripRefIfNeeded().Span, typeStyle.Severity));
69
        }
70

71
        private Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, SyntaxNode declaration, TextSpan diagnosticSpan, ReportDiagnostic severity) 
72
            => DiagnosticHelper.Create(descriptor, declaration.SyntaxTree.GetLocation(diagnosticSpan), severity, additionalLocations: null, properties: null);
73
    }
S
Sam Harwell 已提交
74
}