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

using Microsoft.CodeAnalysis.Diagnostics;
4

5
namespace Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers
6
{
7
    public abstract partial class DiagnosticAnalyzerCorrectnessAnalyzer : DiagnosticAnalyzer
8
    {
9
        internal static readonly string DiagnosticAnalyzerTypeFullName = typeof(DiagnosticAnalyzer).FullName;
10
        internal static readonly string DiagnosticAnalyzerAttributeFullName = typeof(DiagnosticAnalyzerAttribute).FullName;
11 12
        internal static readonly string DiagnosticFullName = typeof(Diagnostic).FullName;
        internal static readonly string DiagnosticDescriptorFullName = typeof(DiagnosticDescriptor).FullName;
13
        internal static readonly string LocalizableStringFullName = typeof(LocalizableString).FullName;
14 15 16 17 18 19 20 21 22 23 24 25 26 27

        internal static readonly string AnalysisContextFullName = typeof(AnalysisContext).FullName;
        internal static readonly string CompilationStartAnalysisContextFullName = typeof(CompilationStartAnalysisContext).FullName;
        internal static readonly string CompilationEndAnalysisContextFullName = typeof(CompilationEndAnalysisContext).FullName;
        internal static readonly string SemanticModelAnalysisContextFullName = typeof(SemanticModelAnalysisContext).FullName;
        internal static readonly string SymbolAnalysisContextFullName = typeof(SymbolAnalysisContext).FullName;
        internal static readonly string SyntaxNodeAnalysisContextFullName = typeof(SyntaxNodeAnalysisContext).FullName;
        internal static readonly string SyntaxTreeAnalysisContextFullName = typeof(SyntaxTreeAnalysisContext).FullName;
        internal static readonly string CodeBlockStartAnalysisContextFullName = typeof(CodeBlockStartAnalysisContext<>).FullName;
        internal static readonly string CodeBlockEndAnalysisContextFullName = typeof(CodeBlockEndAnalysisContext).FullName;
        internal static readonly string SymbolKindFullName = typeof(SymbolKind).FullName;

        internal static readonly string RegisterSyntaxNodeActionName = nameof(AnalysisContext.RegisterSyntaxNodeAction);
        internal static readonly string RegisterSymbolActionName = nameof(AnalysisContext.RegisterSymbolAction);
28 29
        internal static readonly string RegisterCodeBlockStartActionName = nameof(AnalysisContext.RegisterCodeBlockStartAction);
        internal static readonly string RegisterCodeBlockEndActionName = nameof(AnalysisContext.RegisterCodeBlockEndAction);
30
        internal static readonly string RegisterCompilationStartActionName = nameof(AnalysisContext.RegisterCompilationStartAction);
31 32 33
        internal static readonly string RegisterCompilationEndActionName = nameof(CompilationStartAnalysisContext.RegisterCompilationEndAction);
        internal static readonly string ReportDiagnosticName = nameof(CompilationEndAnalysisContext.ReportDiagnostic);
        internal static readonly string SupportedDiagnosticsName = nameof(DiagnosticAnalyzer.SupportedDiagnostics);
34
        internal static readonly string TLanguageKindEnumName = @"TLanguageKindEnum";
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

        public override void Initialize(AnalysisContext context)
        {
            context.RegisterCompilationStartAction(compilationContext =>
            {
                var diagnosticAnalyzer = compilationContext.Compilation.GetTypeByMetadataName(DiagnosticAnalyzerTypeFullName);
                var diagnosticAnalyzerAttribute = compilationContext.Compilation.GetTypeByMetadataName(DiagnosticAnalyzerAttributeFullName);

                if (diagnosticAnalyzer == null || diagnosticAnalyzerAttribute == null)
                {
                    // We don't need to check assemblies unless they're referencing Microsoft.CodeAnalysis which defines DiagnosticAnalyzer.
                    return;
                }

                var analyzer = GetCompilationAnalyzer(compilationContext.Compilation, diagnosticAnalyzer, diagnosticAnalyzerAttribute);
                if (analyzer == null)
                {
                    return;
                }

                compilationContext.RegisterSymbolAction(c => analyzer.AnalyzeSymbol(c), SymbolKind.NamedType);
            });
        }

        protected abstract CompilationAnalyzer GetCompilationAnalyzer(Compilation compilation, INamedTypeSymbol diagnosticAnalyzer, INamedTypeSymbol diagnosticAnalyzerAttribute);
    }
}