/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Test/Utilities/CSharp/NullableAttributesVisitor.cs
129 строк
5 KB
Cyrus Najmabadi
Add additional information when we throw an 'unreachable' exception
30 сен 2022, 22:11
30 сен 2022, 22:11
b5f9141
Код
Авторство
О чём код?
// 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. using System.Collections.Immutable; using System.Text; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Test.Utilities { /// <summary> /// Returns a string with all symbols containing nullable attributes. /// </summary> internal sealed class NullableAttributesVisitor : TestAttributesVisitor { internal static string GetString(PEModuleSymbol module) { var builder = new StringBuilder(); var visitor = new NullableAttributesVisitor(module, builder); visitor.Visit(module); return builder.ToString(); } private readonly PEModuleSymbol _module; private CSharpAttributeData? _nullableContext; private NullableAttributesVisitor(PEModuleSymbol module, StringBuilder builder) : base(builder) { _module = module; } public override void VisitNamedType(NamedTypeSymbol type) { var previousContext = _nullableContext; _nullableContext = GetNullableContextAttribute(type.GetAttributes()) ?? _nullableContext; base.VisitNamedType(type); _nullableContext = previousContext; } public override void VisitMethod(MethodSymbol method) { var previousContext = _nullableContext; _nullableContext = GetNullableContextAttribute(method.GetAttributes()) ?? _nullableContext; base.VisitMethod(method); _nullableContext = previousContext; } protected override SymbolDisplayFormat DisplayFormat => SymbolDisplayFormat.TestFormatWithConstraints. WithMemberOptions( SymbolDisplayMemberOptions.IncludeParameters | SymbolDisplayMemberOptions.IncludeType | SymbolDisplayMemberOptions.IncludeRef | SymbolDisplayMemberOptions.IncludeExplicitInterface); protected override void ReportSymbol(Symbol symbol) { var nullableContextAttribute = GetNullableContextAttribute(symbol.GetAttributes()); var nullableAttribute = GetNullableAttribute((symbol is MethodSymbol method) ? method.GetReturnTypeAttributes() : symbol.GetAttributes()); if (nullableContextAttribute == null && nullableAttribute == null) { if (_nullableContext == null) { // No explicit attributes on this symbol or above. return; } // No explicit attributes on this symbol. Check if nullability metadata was dropped. if (!_module.ShouldDecodeNullableAttributes(GetAccessSymbol(symbol))) { return; } } ReportContainingSymbols(symbol); _builder.Append(GetIndentString(symbol)); if (nullableContextAttribute != null) { _builder.Append($"{ReportAttribute(nullableContextAttribute)} "); } if (nullableAttribute != null) { _builder.Append($"{ReportAttribute(nullableAttribute)} "); } _builder.AppendLine(symbol.ToDisplayString(DisplayFormat)); _reported.Add(symbol); } private static Symbol GetAccessSymbol(Symbol symbol) { while (true) { switch (symbol.Kind) { case SymbolKind.Parameter: case SymbolKind.TypeParameter: symbol = symbol.ContainingSymbol; break; default: return symbol; } } } private static CSharpAttributeData? GetNullableContextAttribute(ImmutableArray<CSharpAttributeData> attributes) => GetAttribute(attributes, "System.Runtime.CompilerServices", "NullableContextAttribute"); private static CSharpAttributeData? GetNullableAttribute(ImmutableArray<CSharpAttributeData> attributes) => GetAttribute(attributes, "System.Runtime.CompilerServices", "NullableAttribute"); protected override bool TypeRequiresAttribute(TypeSymbol? type) { throw ExceptionUtilities.Unreachable(); } protected override CSharpAttributeData GetTargetAttribute(ImmutableArray<CSharpAttributeData> attributes) { throw ExceptionUtilities.Unreachable(); } } }