< Summary

Information
Class: Hertzole.ScriptableValues.Generator.SymbolExtensions
Assembly: Hertzole.ScriptableValues.Generator
File(s): Generator/Hertzole.ScriptableValues.Generator/Extensions/SymbolExtensions.cs
Tag: 52_28197466029
Line coverage
53%
Covered lines: 28
Uncovered lines: 24
Coverable lines: 52
Total lines: 137
Line coverage: 53.8%
Branch coverage
52%
Covered branches: 18
Total branches: 34
Branch coverage: 52.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

Generator/Hertzole.ScriptableValues.Generator/Extensions/SymbolExtensions.cs

#LineLine coverage
 1using System;
 2using System.Collections.Immutable;
 3using Microsoft.CodeAnalysis;
 4
 5namespace Hertzole.ScriptableValues.Generator;
 6
 7internal static class SymbolExtensions
 8{
 9    public static bool StringEquals(this ISymbol symbol, string value)
 10    {
 20011        return string.Equals(symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat), value, StringComparison.O
 12    }
 13
 14    public static bool StringEquals(this ISymbol symbol, ISymbol other)
 15    {
 016        return StringEquals(symbol, other.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat));
 17    }
 18
 19    public static string GetFullyQualifiedMetadataName(this ITypeSymbol symbol)
 20    {
 2521        using ArrayBuilder<char> builder = new ArrayBuilder<char>();
 22
 2523        symbol.AppendFullyQualifiedMetadataName(in builder);
 24
 2525        return builder.ToString();
 2526    }
 27
 28    private static void AppendFullyQualifiedMetadataName(this ITypeSymbol symbol, in ArrayBuilder<char> builder)
 29    {
 2530        BuildFrom(symbol, in builder);
 2531        return;
 32
 33        static void BuildFrom(ISymbol symbol, in ArrayBuilder<char> builder)
 34        {
 35            switch (symbol)
 36            {
 37                // Namespaces that are nested also append a leading '.'
 38                case INamespaceSymbol { ContainingNamespace.IsGlobalNamespace: false }:
 1239                    BuildFrom(symbol.ContainingNamespace, in builder);
 1240                    builder.Add('.');
 1241                    builder.AddRange(symbol.MetadataName.AsSpan());
 1242                    break;
 43
 44                // Other namespaces (ie. the one right before global) skip the leading '.'
 45                case INamespaceSymbol { IsGlobalNamespace: false }:
 1246                    builder.AddRange(symbol.MetadataName.AsSpan());
 1247                    break;
 48
 49                // Types with no namespace just have their metadata name directly written
 50                case ITypeSymbol { ContainingSymbol: INamespaceSymbol { IsGlobalNamespace: true } }:
 1351                    builder.AddRange(symbol.MetadataName.AsSpan());
 1352                    break;
 53
 54                // Types with a containing non-global namespace also append a leading '.'
 55                case ITypeSymbol { ContainingSymbol: INamespaceSymbol namespaceSymbol }:
 1256                    BuildFrom(namespaceSymbol, in builder);
 1257                    builder.Add('.');
 1258                    builder.AddRange(symbol.MetadataName.AsSpan());
 1259                    break;
 60
 61                // Nested types append a leading '+'
 62                case ITypeSymbol { ContainingSymbol: ITypeSymbol typeSymbol }:
 063                    BuildFrom(typeSymbol, in builder);
 064                    builder.Add('+');
 065                    builder.AddRange(symbol.MetadataName.AsSpan());
 66                    break;
 67            }
 068        }
 69    }
 70
 71    public static bool HasAttribute(this ISymbol symbol, string fullyQualifiedAttributeName)
 72    {
 6273        ImmutableArray<AttributeData> attributes = symbol.GetAttributes();
 6274        if (attributes.IsDefaultOrEmpty)
 75        {
 076            return false;
 77        }
 78
 39679        for (int i = 0; i < attributes.Length; i++)
 80        {
 16181            AttributeData attribute = attributes.ItemRef(i);
 82
 16183            if (attribute.AttributeClass == null)
 84            {
 085                return false;
 86            }
 87
 16188            string name = attribute.AttributeClass.ToDisplayString(NullableFlowState.NotNull, SymbolDisplayFormat.FullyQ
 16189            if (string.Equals(name, fullyQualifiedAttributeName, StringComparison.Ordinal))
 90            {
 2591                return true;
 92            }
 93        }
 94
 3795        return false;
 96    }
 97
 98    public static bool TryGetCallbackAttribute(this ISymbol symbol, out CallbackType callbackType)
 99    {
 100        string name;
 0101        if (symbol is ITypeSymbol typeSymbol)
 102        {
 0103            name = typeSymbol.ToDisplayString(NullableFlowState.NotNull, SymbolDisplayFormat.FullyQualifiedFormat);
 104        }
 105        else
 106        {
 0107            name = symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
 108        }
 109
 0110        if (name.Equals(Types.GLOBAL_GENERATE_VALUE_CALLBACK_ATTRIBUTE, StringComparison.Ordinal))
 111        {
 0112            callbackType = CallbackType.Value;
 0113            return true;
 114        }
 115
 0116        if (name.Equals(Types.GLOBAL_GENERATE_EVENT_CALLBACK_ATTRIBUTE, StringComparison.Ordinal))
 117        {
 0118            callbackType = CallbackType.Event;
 0119            return true;
 120        }
 121
 0122        if (name.Equals(Types.GLOBAL_GENERATE_POOL_CALLBACK_ATTRIBUTE, StringComparison.Ordinal))
 123        {
 0124            callbackType = CallbackType.Pool;
 0125            return true;
 126        }
 127
 0128        if (name.Equals(Types.GLOBAL_GENERATE_COLLECTION_CALLBACK_ATTRIBUTE, StringComparison.Ordinal))
 129        {
 0130            callbackType = CallbackType.Collection;
 0131            return true;
 132        }
 133
 0134        callbackType = (CallbackType) byte.MaxValue;
 0135        return false;
 136    }
 137}