< Summary

Information
Class: Hertzole.ScriptableValues.Generator.ScriptableValueHelper
Assembly: Hertzole.ScriptableValues.Generator
File(s): Generator/Hertzole.ScriptableValues.Generator/Helpers/ScriptableValueHelper.cs
Tag: 52_28197466029
Line coverage
32%
Covered lines: 22
Uncovered lines: 46
Coverable lines: 68
Total lines: 184
Line coverage: 32.3%
Branch coverage
39%
Covered branches: 18
Total branches: 46
Branch coverage: 39.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
TryGetScriptableType(...)33.33%6650%
TryGetScriptableTypeFromType(...)61.11%181835.29%
TryGetScriptableTypeFromAddressable(...)0%660%
IsSupportedType(...)0%10100%
DoesTypeSupportCallbacks(...)83.33%6675%

File(s)

Generator/Hertzole.ScriptableValues.Generator/Helpers/ScriptableValueHelper.cs

#LineLine coverage
 1using System;
 2using Microsoft.CodeAnalysis;
 3
 4namespace Hertzole.ScriptableValues.Generator;
 5
 6internal enum ScriptableType
 7{
 8    None = 0,
 9    Event = 1,
 10    GenericEvent = 2,
 11    Value = 3,
 12    Pool = 4,
 13    List = 5,
 14    Dictionary = 6
 15}
 16
 17internal static class ScriptableValueHelper
 18{
 19    public static bool TryGetScriptableType(in SemanticModel semanticModel,
 20        INamedTypeSymbol? type,
 21        out ScriptableType scriptableType,
 22        out ITypeSymbol? genericType)
 23    {
 2524        genericType = null;
 25
 2526        if (type != null)
 27        {
 2528            if (TryGetScriptableTypeFromType(in semanticModel, type, out scriptableType, out genericType))
 29            {
 2530                return true;
 31            }
 32
 033            if (TryGetScriptableTypeFromAddressable(in semanticModel, type, out scriptableType, out genericType))
 34            {
 035                return true;
 36            }
 37        }
 38
 039        scriptableType = ScriptableType.None;
 040        return false;
 41    }
 42
 43    private static bool TryGetScriptableTypeFromType(in SemanticModel semanticModel,
 44        INamedTypeSymbol type,
 45        out ScriptableType scriptableType,
 46        out ITypeSymbol? genericType)
 47    {
 5048        if (type.ConstructedFrom.StringEquals(Types.SCRIPTABLE_VALUE) ||
 5049            type.ConstructedFrom.StringEquals(Types.VALUE_REFERENCE))
 50        {
 2551            genericType = type.TypeArguments[0];
 2552            scriptableType = ScriptableType.Value;
 2553            return true;
 54        }
 55
 2556        if (type.ConstructedFrom.StringEquals(Types.SCRIPTABLE_EVENT))
 57        {
 058            genericType = null;
 059            scriptableType = ScriptableType.Event;
 060            return true;
 61        }
 62
 2563        if (type.ConstructedFrom.StringEquals(Types.GENERIC_SCRIPTABLE_EVENT))
 64        {
 065            genericType = type.TypeArguments[0];
 066            scriptableType = ScriptableType.GenericEvent;
 067            return true;
 68        }
 69
 2570        if (type.ConstructedFrom.StringEquals(Types.SCRIPTABLE_POOL))
 71        {
 072            genericType = type.TypeArguments[0];
 073            scriptableType = ScriptableType.Pool;
 074            return true;
 75        }
 76
 2577        if (type.ConstructedFrom.StringEquals(Types.SCRIPTABLE_LIST))
 78        {
 079            genericType = type.TypeArguments[0];
 080            scriptableType = ScriptableType.List;
 081            return true;
 82        }
 83
 2584        if (type.ConstructedFrom.StringEquals(Types.SCRIPTABLE_DICTIONARY))
 85        {
 86            // Get the key and value types from ScriptableDictionary<TKey, TValue>
 087            ITypeSymbol keyType = type.TypeArguments[0];
 088            ITypeSymbol valueType = type.TypeArguments[1];
 89
 90            // Get the KeyValuePair<,> generic type definition
 091            INamedTypeSymbol? keyValuePairType = semanticModel.Compilation.GetTypeByMetadataName("System.Collections.Gen
 92
 093            if (keyValuePairType != null)
 94            {
 95                // Construct the KeyValuePair<TKey, TValue> with the specific type arguments
 096                genericType = keyValuePairType.Construct(keyType, valueType);
 097                scriptableType = ScriptableType.Dictionary;
 098                return true;
 99            }
 100        }
 101
 25102        if (type.BaseType != null)
 103        {
 25104            return TryGetScriptableTypeFromType(in semanticModel, type.BaseType, out scriptableType, out genericType);
 105        }
 106
 0107        scriptableType = ScriptableType.None;
 0108        genericType = null;
 0109        return false;
 110    }
 111
 112    private static bool TryGetScriptableTypeFromAddressable(in SemanticModel semanticModel,
 113        INamedTypeSymbol type,
 114        out ScriptableType scriptableType,
 115        out ITypeSymbol? genericType)
 116    {
 117        while (true)
 118        {
 0119            if (type.ConstructedFrom.StringEquals(Types.ASSET_REFERENCE_T))
 120            {
 0121                if (type.TypeArguments[0] is not INamedTypeSymbol namedTypeSymbol)
 122                {
 0123                    scriptableType = ScriptableType.None;
 0124                    genericType = null;
 0125                    return false;
 126                }
 127
 0128                return TryGetScriptableTypeFromType(in semanticModel, namedTypeSymbol, out scriptableType, out genericTy
 129            }
 130
 0131            if (type.BaseType != null)
 132            {
 0133                type = type.BaseType;
 0134                continue;
 135            }
 136
 0137            scriptableType = ScriptableType.None;
 0138            genericType = null;
 0139            return false;
 140        }
 141    }
 142
 143    public static bool IsSupportedType(in CallbackType callbackType, in ScriptableType scriptableType)
 144    {
 0145        switch (callbackType)
 146        {
 147            case CallbackType.Value:
 0148                return scriptableType == ScriptableType.Value;
 149            case CallbackType.Event:
 0150                return scriptableType == ScriptableType.Event || scriptableType == ScriptableType.GenericEvent;
 151            case CallbackType.Collection:
 0152                return scriptableType == ScriptableType.List || scriptableType == ScriptableType.Dictionary;
 153            case CallbackType.Pool:
 0154                return scriptableType == ScriptableType.Pool;
 155            default:
 0156                throw new ArgumentOutOfRangeException();
 157        }
 158    }
 159
 160    public static bool DoesTypeSupportCallbacks(in ITypeSymbol symbol, out NotSupportedReason reason)
 161    {
 25162        if (symbol.IsValueType && symbol.IsReadOnly)
 163        {
 0164            reason = NotSupportedReason.ReadOnlyStruct;
 0165            return false;
 166        }
 167
 25168        if (symbol.IsStatic)
 169        {
 1170            reason = NotSupportedReason.StaticClass;
 1171            return false;
 172        }
 173
 24174        reason = NotSupportedReason.None;
 24175        return true;
 176    }
 177}
 178
 179public enum NotSupportedReason
 180{
 181    None = 0,
 182    ReadOnlyStruct = 1,
 183    StaticClass = 2
 184}