< Summary

Line coverage
87%
Covered lines: 75
Uncovered lines: 11
Coverable lines: 86
Total lines: 238
Line coverage: 87.2%
Branch coverage
80%
Covered branches: 21
Total branches: 26
Branch coverage: 80.7%
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(...)100%44100%
AppendFullName(...)87.5%8883.33%
ToAssemblyName()100%44100%
Parse(...)100%22100%
TryParse(...)75%44100%
ExtractAssemblyNameFlags(...)100%11100%
ExtractAssemblyContentType(...)100%11100%
ExtractProcessorArchitecture(...)100%11100%

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
 494052        internal AssemblyNameInfo(AssemblyNameParser.AssemblyNameParts parts)
 494053        {
 494054            Name = parts._name;
 494055            Version = parts._version;
 494056            CultureName = parts._cultureName;
 494057            _flags = parts._flags;
 58#if SYSTEM_PRIVATE_CORELIB
 59            PublicKeyOrToken = parts._publicKeyOrToken;
 60#else
 494061            PublicKeyOrToken = parts._publicKeyOrToken is null ? default : parts._publicKeyOrToken.Length == 0
 494062                ? ImmutableArray<byte>.Empty
 494063#if NET
 494064                : Runtime.InteropServices.ImmutableCollectionsMarshal.AsImmutableArray(parts._publicKeyOrToken);
 65#else
 66                : ImmutableArray.Create(parts._publicKeyOrToken);
 67#endif
 68#endif
 494069        }
 70
 71        /// <summary>
 72        /// Gets the simple name of the assembly.
 73        /// </summary>
 4415074        public string Name { get; }
 75
 76        /// <summary>
 77        /// Gets the version of the assembly.
 78        /// </summary>
 4415079        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>
 4662088        public string? CultureName { get; }
 89
 90        /// <summary>
 91        /// Gets the attributes of the assembly.
 92        /// </summary>
 4620693        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
 46950102        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
 4940112            {
 4940113                if (_fullName is null)
 4940114                {
 4940115                    ValueStringBuilder vsb = new(stackalloc char[256]);
 4940116                    AppendFullName(ref vsb);
 4940117                    _fullName = vsb.ToString();
 4940118                }
 119
 4940120                return _fullName;
 4940121            }
 122        }
 123
 124        internal void AppendFullName(ref ValueStringBuilder vsb)
 4940125        {
 4940126            if (_fullName is not null)
 0127            {
 0128                vsb.Append(_fullName);
 0129            }
 130            else
 4940131            {
 4940132                bool isPublicKey = (Flags & AssemblyNameFlags.PublicKey) != 0;
 133
 4940134                byte[]? publicKeyOrToken =
 4940135#if SYSTEM_PRIVATE_CORELIB
 4940136                    PublicKeyOrToken;
 4940137#elif NET
 4940138                    !PublicKeyOrToken.IsDefault ? Runtime.InteropServices.ImmutableCollectionsMarshal.AsArray(PublicKeyO
 139#else
 140                    !PublicKeyOrToken.IsDefault ? PublicKeyOrToken.ToArray() : null;
 141#endif
 4940142                AssemblyNameFormatter.AppendDisplayName(ref vsb, Name, Version, CultureName,
 4940143                    pkt: isPublicKey ? null : publicKeyOrToken,
 4940144                    ExtractAssemblyNameFlags(_flags), ExtractAssemblyContentType(_flags),
 4940145                    pk: isPublicKey ? publicKeyOrToken : null);
 4940146            }
 4940147        }
 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()
 31800157        {
 31800158            AssemblyName assemblyName = new();
 31800159            assemblyName.Name = Name;
 31800160            assemblyName.CultureName = CultureName;
 31800161            assemblyName.Version = Version;
 31800162            assemblyName.Flags = Flags;
 31800163            assemblyName.ContentType = ExtractAssemblyContentType(_flags);
 164#pragma warning disable SYSLIB0037 // Type or member is obsolete
 31800165            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
 31800181            if (!PublicKeyOrToken.IsDefault)
 4526182            {
 183                // A copy of the array needs to be created, as AssemblyName allows for the mutation of provided array.
 4526184                if ((Flags & AssemblyNameFlags.PublicKey) != 0)
 4058185                {
 4058186                    assemblyName.SetPublicKey(PublicKeyOrToken.ToArray());
 4058187                }
 188                else
 468189                {
 468190                    assemblyName.SetPublicKeyToken(PublicKeyOrToken.ToArray());
 468191                }
 4526192            }
 193#endif
 194
 31800195            return assemblyName;
 31800196        }
 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)
 4204205            => TryParse(assemblyName, out AssemblyNameInfo? result)
 4204206                ? result
 4204207                : 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)
 8408216        {
 8408217            AssemblyNameParser.AssemblyNameParts parts = default;
 8408218            if (!assemblyName.IsEmpty && AssemblyNameParser.TryParse(assemblyName, ref parts))
 4940219            {
 4940220                result = new(parts);
 4940221                return true;
 222            }
 223
 3468224            result = null;
 3468225            return false;
 8408226        }
 227
 228        internal static AssemblyNameFlags ExtractAssemblyNameFlags(AssemblyNameFlags combinedFlags)
 4940229            => combinedFlags & unchecked((AssemblyNameFlags)0xFFFFF10F);
 230
 231        internal static AssemblyContentType ExtractAssemblyContentType(AssemblyNameFlags flags)
 36740232            => (AssemblyContentType)((((int)flags) >> 9) & 0x7);
 233
 234        internal static ProcessorArchitecture ExtractProcessorArchitecture(AssemblyNameFlags flags)
 31800235            => (ProcessorArchitecture)((((int)flags) >> 4) & 0x7);
 236    }
 237}
 238