/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Core/CodeAnalysisTest/Diagnostics/AnalysisContextInfoTests.cs
121 строка
6 KB
Jan Jones
Consolidate exception stack trace reporting from analyzers (#70031)
26 сен 2023, 13:38
Не верифицирован
26 сен 2023, 13:38
6d20799
Код
Авторство
О чём код?
// 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.Generic; using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; using Microsoft.CodeAnalysis.Text; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.UnitTests.Diagnostics { public class AnalysisContextInfoTests { [Fact] public void InitializeTest() { var code = @"class C { void M() { return; } }"; var parseOptions = new CSharpParseOptions(kind: SourceCodeKind.Regular, documentationMode: DocumentationMode.None) .WithFeatures(new[] { new KeyValuePair<string, string>("IOperation", "true") }); var compilation = CreateCompilation(code, parseOptions: parseOptions); var options = new AnalyzerOptions(new[] { new TestAdditionalText() }.ToImmutableArray<AdditionalText>()); Verify(compilation, options, nameof(AnalysisContext.RegisterCodeBlockAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterCodeBlockStartAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterCompilationAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterCompilationStartAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterOperationAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterOperationBlockAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterSemanticModelAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterSymbolAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterSyntaxNodeAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterSyntaxTreeAction)); Verify(compilation, options, nameof(AnalysisContext.RegisterAdditionalFileAction)); } private static void Verify(Compilation compilation, AnalyzerOptions options, string context) { var analyzer = new Analyzer(s => context == s); var diagnostics = compilation.GetAnalyzerDiagnostics(new DiagnosticAnalyzer[] { analyzer }, options); Assert.Equal(1, diagnostics.Length); Assert.True(diagnostics[0].ToString().IndexOf(analyzer.Info.GetContext()) >= 0); } private class Analyzer : DiagnosticAnalyzer { public const string Id = "exception"; private static readonly DiagnosticDescriptor s_rule = GetRule(Id); private readonly Func<string, bool> _throwPredicate; private AnalysisContextInfo _info; public Analyzer(Func<string, bool> throwPredicate) { _throwPredicate = throwPredicate; } public AnalysisContextInfo Info => _info; public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(s_rule); public override void Initialize(AnalysisContext c) { c.RegisterCodeBlockAction(b => ThrowIfMatch(nameof(c.RegisterCodeBlockAction), new AnalysisContextInfo(b.SemanticModel.Compilation, b.OwningSymbol, b.CodeBlock))); c.RegisterCodeBlockStartAction<SyntaxKind>(b => ThrowIfMatch(nameof(c.RegisterCodeBlockStartAction), new AnalysisContextInfo(b.SemanticModel.Compilation, b.OwningSymbol, b.CodeBlock))); c.RegisterCompilationAction(b => ThrowIfMatch(nameof(c.RegisterCompilationAction), new AnalysisContextInfo(b.Compilation))); c.RegisterCompilationStartAction(b => ThrowIfMatch(nameof(c.RegisterCompilationStartAction), new AnalysisContextInfo(b.Compilation))); c.RegisterOperationAction(b => ThrowIfMatch(nameof(c.RegisterOperationAction), new AnalysisContextInfo(b.Compilation, b.Operation)), OperationKind.Return); c.RegisterOperationBlockAction(b => ThrowIfMatch(nameof(c.RegisterOperationBlockAction), new AnalysisContextInfo(b.Compilation, b.OwningSymbol))); c.RegisterSemanticModelAction(b => ThrowIfMatch(nameof(c.RegisterSemanticModelAction), new AnalysisContextInfo(b.SemanticModel))); c.RegisterSymbolAction(b => ThrowIfMatch(nameof(c.RegisterSymbolAction), new AnalysisContextInfo(b.Compilation, b.Symbol)), SymbolKind.NamedType); c.RegisterSyntaxNodeAction(b => ThrowIfMatch(nameof(c.RegisterSyntaxNodeAction), new AnalysisContextInfo(b.SemanticModel.Compilation, b.Node)), SyntaxKind.ReturnStatement); c.RegisterSyntaxTreeAction(b => ThrowIfMatch(nameof(c.RegisterSyntaxTreeAction), new AnalysisContextInfo(b.Compilation, new SourceOrAdditionalFile(b.Tree)))); c.RegisterAdditionalFileAction(b => ThrowIfMatch(nameof(c.RegisterAdditionalFileAction), new AnalysisContextInfo(b.Compilation, new SourceOrAdditionalFile(b.AdditionalFile)))); } private void ThrowIfMatch(string context, AnalysisContextInfo info) { if (!_throwPredicate(context)) { return; } _info = info; throw new Exception("exception"); } } private static DiagnosticDescriptor GetRule(string id) { return new DiagnosticDescriptor( id, id, "{0}", "Test", DiagnosticSeverity.Warning, isEnabledByDefault: true); } private static Compilation CreateCompilation(string source, CSharpParseOptions parseOptions = null) { string fileName = "Test.cs"; string projectName = "TestProject"; var syntaxTree = CSharpSyntaxTree.ParseText(source, path: fileName, options: parseOptions); return CSharpCompilation.Create( projectName, syntaxTrees: new[] { syntaxTree }, references: new[] { TestBase.MscorlibRef }); } } }