| File: Parsing\TypeSymbolExtensions.cs | Web Access |
| Project: src\src\Generators\Microsoft.Gen.Logging\Microsoft.Gen.Logging.csproj (Microsoft.Gen.Logging) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.Gen.Shared; namespace Microsoft.Gen.Logging.Parsing; internal static class TypeSymbolExtensions { internal static bool IsEnumerable(this ITypeSymbol sym, SymbolHolder symbols) => (sym.ImplementsInterface(symbols.EnumerableSymbol) || SymbolEqualityComparer.Default.Equals(sym, symbols.EnumerableSymbol)) && sym.SpecialType != SpecialType.System_String; internal static bool ImplementsIConvertible(this ITypeSymbol sym, SymbolHolder symbols) { sym = sym.GetPossiblyNullWrappedType(); foreach (var member in sym.GetMembers("ToString")) { if (member is IMethodSymbol ts) { if (ts.DeclaredAccessibility == Accessibility.Public) { if (ts.Arity == 0 && ts.Parameters.Length == 1 && SymbolEqualityComparer.Default.Equals(ts.Parameters[0].Type, symbols.FormatProviderSymbol)) { return true; } } } } return false; } internal static bool ImplementsIFormattable(this ITypeSymbol sym, SymbolHolder symbols) { sym = sym.GetPossiblyNullWrappedType(); foreach (var member in sym.GetMembers("ToString")) { if (member is IMethodSymbol ts) { if (ts.DeclaredAccessibility == Accessibility.Public) { if (ts.Arity == 0 && ts.Parameters.Length == 2 && ts.Parameters[0].Type.SpecialType == SpecialType.System_String && SymbolEqualityComparer.Default.Equals(ts.Parameters[1].Type, symbols.FormatProviderSymbol)) { return true; } } } } return false; } internal static bool ImplementsISpanFormattable(this ITypeSymbol sym, SymbolHolder symbols) { sym = sym.GetPossiblyNullWrappedType(); return symbols.SpanFormattableSymbol != null && (sym.ImplementsInterface(symbols.SpanFormattableSymbol) || SymbolEqualityComparer.Default.Equals(sym, symbols.SpanFormattableSymbol)); } internal static bool IsSpecialType(this ITypeSymbol typeSymbol, SymbolHolder symbols) => typeSymbol.SpecialType != SpecialType.None || typeSymbol.OriginalDefinition.SpecialType != SpecialType.None || #pragma warning disable RS1024 symbols.IgnorePropertiesSymbols.Contains(typeSymbol); #pragma warning restore RS1024 internal static bool HasCustomToString(this ITypeSymbol type) { ITypeSymbol? current = type; while (current != null && current.SpecialType != SpecialType.System_Object) { if (current.GetMembers("ToString").Where(m => m.Kind == SymbolKind.Method && m.DeclaredAccessibility == Accessibility.Public).Cast<IMethodSymbol>().Any(m => m.Parameters.Length == 0)) { return true; } current = current.BaseType; } return false; } internal static ITypeSymbol GetPossiblyNullWrappedType(this ITypeSymbol sym) { if (sym is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.IsGenericType && namedTypeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T) { return namedTypeSymbol.TypeArguments[0]; } return sym; } }