| File: MetadataReader\MetadataTypeName.Key.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Diagnostics; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis { internal partial struct MetadataTypeName { /// <summary> /// A digest of MetadataTypeName's fully qualified name which can be used as the key in a dictionary /// </summary> public readonly struct Key : IEquatable<Key> { // PERF: We can work with either a fully qualified name (a single string) or // a 'split' name (namespace and type). If typeName is null, then a FQN is // stored in namespaceOrFullyQualifiedName private readonly string _namespaceOrFullyQualifiedName; private readonly string _typeName; private readonly byte _useCLSCompliantNameArityEncoding; // Using byte instead of bool for denser packing and smaller structure size private readonly short _forcedArity; internal Key(in MetadataTypeName mdTypeName) { if (mdTypeName.IsNull) { _namespaceOrFullyQualifiedName = null; _typeName = null; _useCLSCompliantNameArityEncoding = 0; _forcedArity = 0; } else { if (mdTypeName._fullName != null) { _namespaceOrFullyQualifiedName = mdTypeName._fullName; _typeName = null; } else { Debug.Assert(mdTypeName._namespaceName != null); Debug.Assert(mdTypeName._typeName != null); _namespaceOrFullyQualifiedName = mdTypeName._namespaceName; _typeName = mdTypeName._typeName; } _useCLSCompliantNameArityEncoding = mdTypeName.UseCLSCompliantNameArityEncoding ? (byte)1 : (byte)0; _forcedArity = mdTypeName._forcedArity; } } private bool HasFullyQualifiedName { get { return _typeName == null; } } public bool Equals(Key other) { return _useCLSCompliantNameArityEncoding == other._useCLSCompliantNameArityEncoding && _forcedArity == other._forcedArity && EqualNames(ref other); } private bool EqualNames(ref Key other) { if (_typeName == other._typeName) { return _namespaceOrFullyQualifiedName == other._namespaceOrFullyQualifiedName; } if (this.HasFullyQualifiedName) { return MetadataHelpers.SplitNameEqualsFullyQualifiedName(other._namespaceOrFullyQualifiedName, other._typeName, _namespaceOrFullyQualifiedName); } if (other.HasFullyQualifiedName) { return MetadataHelpers.SplitNameEqualsFullyQualifiedName(_namespaceOrFullyQualifiedName, _typeName, other._namespaceOrFullyQualifiedName); } return false; } public override bool Equals(object obj) { return obj is Key && this.Equals((Key)obj); } public override int GetHashCode() { return Hash.Combine(GetHashCodeName(), Hash.Combine(_useCLSCompliantNameArityEncoding != 0, _forcedArity)); } private int GetHashCodeName() { int hashCode = Hash.GetFNVHashCode(_namespaceOrFullyQualifiedName); if (!this.HasFullyQualifiedName) { hashCode = Hash.CombineFNVHash(hashCode, MetadataHelpers.DotDelimiter); hashCode = Hash.CombineFNVHash(hashCode, _typeName); } return hashCode; } } public readonly Key ToKey() { return new Key(in this); } } }