< Summary

Line coverage
59%
Covered lines: 51
Uncovered lines: 35
Coverable lines: 86
Total lines: 238
Line coverage: 59.3%
Branch coverage
38%
Covered branches: 10
Total branches: 26
Branch coverage: 38.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)0%220%
.ctor(...)25%44100%
AppendFullName(...)50%8883.33%
ToAssemblyName()0%440%
Parse(...)0%220%
TryParse(...)100%44100%
ExtractAssemblyNameFlags(...)100%11100%
ExtractAssemblyContentType(...)100%11100%
ExtractProcessorArchitecture(...)100%110%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/AssemblyNameInfo.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.Diagnostics.CodeAnalysis;
 6using System.Text;
 7
 8#if !SYSTEM_PRIVATE_CORELIB
 9using System.Collections.Immutable;
 10using System.Linq;
 11#endif
 12
 13namespace System.Reflection.Metadata
 14{
 15    /// <summary>
 16    /// Describes an assembly.
 17    /// </summary>
 18    /// <remarks>
 19    /// It's a more lightweight, immutable version of <seealso cref="AssemblyName"/> that does not pre-allocate <seealso
 20    /// </remarks>
 21    [DebuggerDisplay("{FullName}")]
 22#if SYSTEM_REFLECTION_METADATA
 23    public
 24#else
 25    internal
 26#endif
 27    sealed class AssemblyNameInfo
 28    {
 29        internal readonly AssemblyNameFlags _flags;
 30        private string? _fullName;
 31
 32#if !SYSTEM_PRIVATE_CORELIB
 33        /// <summary>
 34        /// Initializes a new instance of the AssemblyNameInfo class.
 35        /// </summary>
 36        /// <param name="name">The simple name of the assembly.</param>
 37        /// <param name="version">The version of the assembly.</param>
 38        /// <param name="cultureName">The name of the culture associated with the assembly.</param>
 39        /// <param name="flags">The attributes of the assembly.</param>
 40        /// <param name="publicKeyOrToken">The public key or its token. Set <paramref name="flags"/> to <seealso cref="A
 41        /// <exception cref="ArgumentNullException"><paramref name="name"/> is null.</exception>
 042        public AssemblyNameInfo(string name, Version? version = null, string? cultureName = null, AssemblyNameFlags flag
 043        {
 044            Name = name ?? throw new ArgumentNullException(nameof(name));
 045            Version = version;
 046            CultureName = cultureName;
 047            _flags = flags;
 048            PublicKeyOrToken = publicKeyOrToken;
 049        }
 50#endif
 51
 715652        internal AssemblyNameInfo(AssemblyNameParser.AssemblyNameParts parts)
 715653        {
 715654            Name = parts._name;
 715655            Version = parts._version;
 715656            CultureName = parts._cultureName;
 715657            _flags = parts._flags;
 58#if SYSTEM_PRIVATE_CORELIB
 59            PublicKeyOrToken = parts._publicKeyOrToken;
 60#else
 715661            PublicKeyOrToken = parts._publicKeyOrToken is null ? default : parts._publicKeyOrToken.Length == 0
 715662                ? ImmutableArray<byte>.Empty
 715663#if NET
 715664                : Runtime.InteropServices.ImmutableCollectionsMarshal.AsImmutableArray(parts._publicKeyOrToken);
 65#else
 66                : ImmutableArray.Create(parts._publicKeyOrToken);
 67#endif
 68#endif
 715669        }
 70
 71        /// <summary>
 72        /// Gets the simple name of the assembly.
 73        /// </summary>
 1392874        public string Name { get; }
 75
 76        /// <summary>
 77        /// Gets the version of the assembly.
 78        /// </summary>
 1392879        public Version? Version { get; }
 80
 81        /// <summary>
 82        /// Gets the name of the culture associated with the assembly.
 83        /// </summary>
 84        /// <remarks>
 85        /// Do not create a <see cref="System.Globalization.CultureInfo"/> instance from this string unless
 86        /// you know the string has originated from a trustworthy source.
 87        /// </remarks>
 1392888        public string? CultureName { get; }
 89
 90        /// <summary>
 91        /// Gets the attributes of the assembly.
 92        /// </summary>
 1005693        public AssemblyNameFlags Flags => _flags;
 94
 95        /// <summary>
 96        /// Gets the public key or the public key token of the assembly.
 97        /// </summary>
 98        /// <remarks>Check <seealso cref="Flags"/> for <seealso cref="AssemblyNameFlags.PublicKey"/> flag to see whether
 99#if SYSTEM_PRIVATE_CORELIB
 100        public byte[]? PublicKeyOrToken { get; }
 101#else
 10056102        public ImmutableArray<byte> PublicKeyOrToken { get; }
 103#endif
 104
 105        /// <summary>
 106        /// Gets the full name of the assembly, also known as the display name.
 107        /// </summary>
 108        /// <remarks>In contrary to <seealso cref="AssemblyName.FullName"/> it does not validate public key token neithe
 109        public string FullName
 110        {
 111            get
 3872112            {
 3872113                if (_fullName is null)
 3872114                {
 3872115                    ValueStringBuilder vsb = new(stackalloc char[256]);
 3872116                    AppendFullName(ref vsb);
 3872117                    _fullName = vsb.ToString();
 3872118                }
 119
 3872120                return _fullName;
 3872121            }
 122        }
 123
 124        internal void AppendFullName(ref ValueStringBuilder vsb)
 10056125        {
 10056126            if (_fullName is not null)
 0127            {
 0128                vsb.Append(_fullName);
 0129            }
 130            else
 10056131            {
 10056132                bool isPublicKey = (Flags & AssemblyNameFlags.PublicKey) != 0;
 133
 10056134                byte[]? publicKeyOrToken =
 10056135#if SYSTEM_PRIVATE_CORELIB
 10056136                    PublicKeyOrToken;
 10056137#elif NET
 10056138                    !PublicKeyOrToken.IsDefault ? Runtime.InteropServices.ImmutableCollectionsMarshal.AsArray(PublicKeyO
 139#else
 140                    !PublicKeyOrToken.IsDefault ? PublicKeyOrToken.ToArray() : null;
 141#endif
 10056142                AssemblyNameFormatter.AppendDisplayName(ref vsb, Name, Version, CultureName,
 10056143                    pkt: isPublicKey ? null : publicKeyOrToken,
 10056144                    ExtractAssemblyNameFlags(_flags), ExtractAssemblyContentType(_flags),
 10056145                    pk: isPublicKey ? publicKeyOrToken : null);
 10056146            }
 10056147        }
 148
 149        /// <summary>
 150        /// Initializes a new instance of the <seealso cref="AssemblyName"/> class based on the stored information.
 151        /// </summary>
 152        /// <remarks>
 153        /// Do not create an <see cref="AssemblyName"/> instance with <see cref="CultureName"/> string unless
 154        /// you know the string has originated from a trustworthy source.
 155        /// </remarks>
 156        public AssemblyName ToAssemblyName()
 0157        {
 0158            AssemblyName assemblyName = new();
 0159            assemblyName.Name = Name;
 0160            assemblyName.CultureName = CultureName;
 0161            assemblyName.Version = Version;
 0162            assemblyName.Flags = Flags;
 0163            assemblyName.ContentType = ExtractAssemblyContentType(_flags);
 164#pragma warning disable SYSLIB0037 // Type or member is obsolete
 0165            assemblyName.ProcessorArchitecture = ExtractProcessorArchitecture(_flags);
 166#pragma warning restore SYSLIB0037 // Type or member is obsolete
 167
 168#if SYSTEM_PRIVATE_CORELIB
 169            if (PublicKeyOrToken is not null)
 170            {
 171                if ((Flags & AssemblyNameFlags.PublicKey) != 0)
 172                {
 173                    assemblyName.SetPublicKey(PublicKeyOrToken);
 174                }
 175                else
 176                {
 177                    assemblyName.SetPublicKeyToken(PublicKeyOrToken);
 178                }
 179            }
 180#else
 0181            if (!PublicKeyOrToken.IsDefault)
 0182            {
 183                // A copy of the array needs to be created, as AssemblyName allows for the mutation of provided array.
 0184                if ((Flags & AssemblyNameFlags.PublicKey) != 0)
 0185                {
 0186                    assemblyName.SetPublicKey(PublicKeyOrToken.ToArray());
 0187                }
 188                else
 0189                {
 0190                    assemblyName.SetPublicKeyToken(PublicKeyOrToken.ToArray());
 0191                }
 0192            }
 193#endif
 194
 0195            return assemblyName;
 0196        }
 197
 198        /// <summary>
 199        /// Parses a span of characters into a assembly name.
 200        /// </summary>
 201        /// <param name="assemblyName">A span containing the characters representing the assembly name to parse.</param>
 202        /// <returns>Parsed type name.</returns>
 203        /// <exception cref="ArgumentException">Provided assembly name was invalid.</exception>
 204        public static AssemblyNameInfo Parse(ReadOnlySpan<char> assemblyName)
 0205            => TryParse(assemblyName, out AssemblyNameInfo? result)
 0206                ? result
 0207                : throw new ArgumentException(SR.InvalidAssemblyName, nameof(assemblyName));
 208
 209        /// <summary>
 210        /// Tries to parse a span of characters into an assembly name.
 211        /// </summary>
 212        /// <param name="assemblyName">A span containing the characters representing the assembly name to parse.</param>
 213        /// <param name="result">Contains the result when parsing succeeds.</param>
 214        /// <returns>true if assembly name was converted successfully, otherwise, false.</returns>
 215        public static bool TryParse(ReadOnlySpan<char> assemblyName, [NotNullWhen(true)] out AssemblyNameInfo? result)
 11164216        {
 11164217            AssemblyNameParser.AssemblyNameParts parts = default;
 11164218            if (!assemblyName.IsEmpty && AssemblyNameParser.TryParse(assemblyName, ref parts))
 7156219            {
 7156220                result = new(parts);
 7156221                return true;
 222            }
 223
 4008224            result = null;
 4008225            return false;
 11164226        }
 227
 228        internal static AssemblyNameFlags ExtractAssemblyNameFlags(AssemblyNameFlags combinedFlags)
 10056229            => combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F);
 230
 231        internal static AssemblyContentType ExtractAssemblyContentType(AssemblyNameFlags flags)
 10056232            => (AssemblyContentType)((((int)flags) >> 9) & 0x7);
 233
 234        internal static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags)
 0235            => (ProcessorArchitecture)((((int)flags) >> 4) & 0x7);
 236    }
 237}
 238