< Summary

Information
Class: AmbientServices.Utilities.AssemblyUtilities
Assembly: AmbientServices
File(s): /home/runner/work/AmbientServices/AmbientServices/AmbientServices/Utilities/AssemblyUtilities.cs
Tag: 332_35464845198
Line coverage
100%
Covered lines: 5
Uncovered lines: 0
Coverable lines: 5
Total lines: 44
Line coverage: 100%
Branch coverage
70%
Covered branches: 7
Total branches: 10
Branch coverage: 70%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
TypesFromException(...)100%22100%
GetCallingCodeSourceFolder(...)62.5%88100%

File(s)

/home/runner/work/AmbientServices/AmbientServices/AmbientServices/Utilities/AssemblyUtilities.cs

#LineLine coverage
 1using AmbientServices.Extensions;
 2using System;
 3using System.IO;
 4using System.Linq;
 5using System.Reflection;
 6
 7namespace AmbientServices.Utilities;
 8
 9/// <summary>
 10/// A static class with extension functions for <see cref="System.Reflection.Assembly"/>.
 11/// </summary>
 12/// <remarks>
 13/// <pitch>Reflection salvage and source-location helpers: recover the loadable types carried by a <see cref="Reflection
 14/// <pledge><see cref="GetCallingCodeSourceFolder"/> depends on debug (PDB) file information being available for the cal
 15/// </remarks>
 16public static class AssemblyUtilities
 17{
 18    /// <summary>
 19    /// Gets the loadable types from the <see cref="ReflectionTypeLoadException"/>.
 20    /// </summary>
 21    /// <param name="ex">The <see cref="ReflectionTypeLoadException"/> that was thrown.</param>
 22    /// <returns>The list of types that *are* loadable, as obtained from the exception.</returns>
 23    internal static Type[] TypesFromException(ReflectionTypeLoadException ex)
 24    {
 25#if NET5_0_OR_GREATER
 226        ArgumentNullException.ThrowIfNull(ex);
 27#else
 28        if (ex is null) throw new ArgumentNullException(nameof(ex));
 29#endif
 230        return ex.Types.Where(t => t != null).ToArray()!; // the where condition filters out null values!
 31    }
 32    /// <summary>
 33    /// Gets the folder where the calling source code's project is located so that it can be stripped from stack trace d
 34    /// </summary>
 35    /// <param name="subfolders">The number of subfolders to remove from the path because the calling source is in a pro
 36    /// <param name="skipFrames">The number of stack frames to skip to get to the "calling code".</param>
 37    /// <returns>The calling code's project's root folder path, if it could be determined, or null if it could not.</ret
 38    public static string? GetCallingCodeSourceFolder(int subfolders = 0, int skipFrames = 0)
 39    {
 240        string? foldername = Path.GetDirectoryName(new System.Diagnostics.StackFrame(skipFrames + 1, true).GetFileName()
 241        while (foldername != null && subfolders-- > 0 && (foldername.Contains(Path.DirectorySeparatorChar, StringCompari
 242        return foldername;
 43    }
 44}