< Summary

Information
Class: Elsa.Extensions.TypeExtensions
Assembly: Elsa.Expressions
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Expressions/Extensions/TypeExtensions.cs
Line coverage
46%
Covered lines: 19
Uncovered lines: 22
Coverable lines: 41
Total lines: 103
Line coverage: 46.3%
Branch coverage
25%
Covered branches: 10
Total branches: 40
Branch coverage: 25%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
GetDefaultValue(...)0%620%
GetEnumerableElementType(...)0%2040%
FindIEnumerable(...)0%600240%
GetFriendlyTypeName(...)100%1010100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Expressions/Extensions/TypeExtensions.cs

#LineLine coverage
 1using System.Diagnostics.CodeAnalysis;
 2using System.Text;
 3using Elsa.Expressions.Models;
 4
 5// ReSharper disable once CheckNamespace
 6namespace Elsa.Extensions;
 7
 8/// <summary>
 9/// Adds extension methods to <see cref="Type"/>.
 10/// </summary>
 11public static class TypeExtensions
 12{
 13    /// <summary>
 14    /// Returns the default value for the specified type.
 15    /// </summary>
 016    public static object? GetDefaultValue(this Type type) => type.IsClass ? null : Activator.CreateInstance(type);
 17
 18    /// <summary>
 19    /// Returns the element type of the specified type representing an array or generic enumerable.
 20    /// </summary>
 21    public static Type GetEnumerableElementType(this Type type)
 22    {
 023        if (type.IsArray)
 024            return type.GetElementType()!;
 25
 026        var elementType = FindIEnumerable(type);
 027        return elementType == null ? type : elementType.GetGenericArguments()[0];
 28    }
 29
 30    /// <summary>
 31    /// Searches for the first implemented IEnumerable interface in the given type hierarchy, and returns the generic ty
 32    /// </summary>
 33    /// <param name="sequenceType">The type to search for the IEnumerable interface.</param>
 34    /// <returns>The generic type argument of the first implemented IEnumerable interface found in the type hierarchy, o
 35    [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
 36    private static Type? FindIEnumerable([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.Interfaces)] Type? s
 37    {
 038        if (sequenceType == null || sequenceType == typeof(string))
 039            return null;
 40
 041        if (sequenceType.IsArray)
 042            return typeof(IEnumerable<>).MakeGenericType(sequenceType.GetElementType()!);
 43
 044        if (sequenceType.IsGenericType)
 45        {
 046            foreach (var arg in sequenceType.GetGenericArguments())
 47            {
 048                var enumerable = typeof(IEnumerable<>).MakeGenericType(arg);
 049                if (enumerable.IsAssignableFrom(sequenceType))
 050                    return enumerable;
 51            }
 52        }
 53
 054        var interfaces = sequenceType.GetInterfaces();
 55
 056        if (interfaces is { Length: > 0 })
 57        {
 058            foreach (var interfaceType in interfaces)
 59            {
 060                var enumerable = FindIEnumerable(interfaceType);
 061                if (enumerable != null) return enumerable;
 62            }
 63        }
 064        if (sequenceType.BaseType != null && sequenceType.BaseType != typeof(object))
 065            return FindIEnumerable(sequenceType.BaseType);
 66
 067        return null;
 68    }
 69
 70    /// <summary>
 71    /// Gets a friendly type name for the specified type.
 72    /// </summary>
 73    public static string GetFriendlyTypeName(this Type type, Brackets brackets)
 74    {
 1975        if (type.IsArray)
 76        {
 577            var elementTypeName = GetFriendlyTypeName(type.GetElementType()!, brackets);
 578            var rank = type.GetArrayRank();
 579            var commas = rank > 1 ? new string(',', rank - 1) : string.Empty;
 580            return elementTypeName + "[" + commas + "]";
 81        }
 82
 1483        if (!type.IsGenericType)
 984            return type.FullName!;
 85
 586        var sb = new StringBuilder();
 587        sb.Append(type.Namespace);
 588        sb.Append('.');
 589        sb.Append(type.Name[..type.Name.IndexOf('`')]);
 590        sb.Append(brackets.Open);
 591        var genericArgs = type.GetGenericArguments();
 2292        for (var i = 0; i < genericArgs.Length; i++)
 93        {
 694            if (i > 0)
 195                sb.Append(", ");
 696            sb.Append(GetFriendlyTypeName(genericArgs[i], brackets));
 97        }
 98
 599        sb.Append(brackets.Close);
 5100        return sb.ToString();
 101    }
 102
 103}