/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Test/Core/Diagnostics/TestDiagnosticAnalyzer.cs
123 строки
5 KB
Tomas Matousek
Move
23 окт 2020, 21:06
23 окт 2020, 21:06
d49cd2b
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Collections.Immutable; using System.Linq; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis.Diagnostics; namespace Microsoft.CodeAnalysis.Test.Utilities { public abstract class TestDiagnosticAnalyzer<TLanguageKindEnum> : DiagnosticAnalyzer where TLanguageKindEnum : struct { protected static readonly ImmutableArray<SymbolKind> AllSymbolKinds = GetAllEnumValues<SymbolKind>(); protected static readonly ImmutableArray<TLanguageKindEnum> AllSyntaxKinds = GetAllEnumValues<TLanguageKindEnum>(); protected static readonly ImmutableArray<string> AllAnalyzerMemberNames = new string[] { "AnalyzeCodeBlock", "AnalyzeCompilation", "AnalyzeNode", "AnalyzeSemanticModel", "AnalyzeSymbol", "AnalyzeSyntaxTree", "AnalyzeAdditionalFile", "Initialize", "SupportedDiagnostics" }.ToImmutableArray(); protected static readonly DiagnosticDescriptor DefaultDiagnostic = #pragma warning disable RS1029 // Do not use reserved diagnostic IDs. new DiagnosticDescriptor("CA7777", "CA7777_AnalyzerTestDiagnostic", "I'm here for test purposes", "Test", DiagnosticSeverity.Warning, isEnabledByDefault: true); #pragma warning restore RS1029 // Do not use reserved diagnostic IDs. private static ImmutableArray<T> GetAllEnumValues<T>() { return ImmutableArray.CreateRange(Enum.GetValues(typeof(T)).Cast<T>()); } protected abstract void OnAbstractMember(string abstractMemberName, SyntaxNode node = null, ISymbol symbol = null, [CallerMemberName] string callerName = null); protected virtual void OnOptions(AnalyzerOptions options, [CallerMemberName] string callerName = null) { } #region Implementation public override void Initialize(AnalysisContext context) { OnAbstractMember("Initialize"); context.RegisterCodeBlockStartAction<TLanguageKindEnum>(new NestedCodeBlockAnalyzer(this).Initialize); context.RegisterCompilationAction(this.AnalyzeCompilation); context.RegisterSemanticModelAction(this.AnalyzeSemanticModel); context.RegisterCodeBlockAction(this.AnalyzeCodeBlock); context.RegisterSymbolAction(this.AnalyzeSymbol, AllSymbolKinds.ToArray()); context.RegisterSyntaxTreeAction(this.AnalyzeSyntaxTree); context.RegisterAdditionalFileAction(this.AnalyzeAdditionalFile); context.RegisterSyntaxNodeAction<TLanguageKindEnum>(this.AnalyzeNode, AllSyntaxKinds.ToArray()); } private void AnalyzeCodeBlock(CodeBlockAnalysisContext context) { OnAbstractMember("CodeBlock", context.CodeBlock, context.OwningSymbol); OnOptions(context.Options); } private void AnalyzeCompilation(CompilationAnalysisContext context) { OnAbstractMember("Compilation"); OnOptions(context.Options); } private void AnalyzeSemanticModel(SemanticModelAnalysisContext context) { OnAbstractMember("SemanticModel"); OnOptions(context.Options); } public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { OnAbstractMember("SupportedDiagnostics"); return ImmutableArray.Create(DefaultDiagnostic); } } private void AnalyzeSymbol(SymbolAnalysisContext context) { OnAbstractMember("Symbol", symbol: context.Symbol); OnOptions(context.Options); } private void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context) { OnAbstractMember("SyntaxTree"); OnOptions(context.Options); } private void AnalyzeAdditionalFile(AdditionalFileAnalysisContext context) { OnAbstractMember("AdditionalFile"); OnOptions(context.Options); } private void AnalyzeNode(SyntaxNodeAnalysisContext context) { OnAbstractMember("SyntaxNode", context.Node); OnOptions(context.Options); } private class NestedCodeBlockAnalyzer { private readonly TestDiagnosticAnalyzer<TLanguageKindEnum> _container; public NestedCodeBlockAnalyzer(TestDiagnosticAnalyzer<TLanguageKindEnum> container) { _container = container; } public void Initialize(CodeBlockStartAnalysisContext<TLanguageKindEnum> context) { _container.OnAbstractMember("CodeBlockStart", context.CodeBlock, context.OwningSymbol); context.RegisterCodeBlockEndAction(_container.AnalyzeCodeBlock); context.RegisterSyntaxNodeAction(_container.AnalyzeNode, TestDiagnosticAnalyzer<TLanguageKindEnum>.AllSyntaxKinds.ToArray()); } } #endregion } }