// 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. // This file is ported and adapted from ComputeSharp (Sergio0694/ComputeSharp), // more info in ThirdPartyNotices.txt in the root of the project. using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using CommunityToolkit.Mvvm.SourceGenerators.Extensions; using CommunityToolkit.Mvvm.SourceGenerators.Helpers; using Microsoft.CodeAnalysis; using static Microsoft.CodeAnalysis.SymbolDisplayTypeQualificationStyle; namespace CommunityToolkit.Mvvm.SourceGenerators.Models; /// /// A model describing the hierarchy info for a specific type. /// /// The filename hint for the current type. /// The metadata name for the current type. /// Gets the namespace for the current type. /// Gets the sequence of type definitions containing the current type. internal sealed partial record HierarchyInfo(string FilenameHint, string MetadataName, string Namespace, ImmutableArray Hierarchy) { /// /// Creates a new instance from a given . /// /// The input instance to gather info for. /// A instance describing . public static HierarchyInfo From(INamedTypeSymbol typeSymbol) { ImmutableArray.Builder hierarchy = ImmutableArray.CreateBuilder(); for (INamedTypeSymbol? parent = typeSymbol; parent is not null; parent = parent.ContainingType) { hierarchy.Add(new TypeInfo( parent.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat), parent.TypeKind, parent.IsRecord)); } return new( typeSymbol.GetFullMetadataNameForFileName(), typeSymbol.MetadataName, typeSymbol.ContainingNamespace.ToDisplayString(new(typeQualificationStyle: NameAndContainingTypesAndNamespaces)), hierarchy.ToImmutable()); } /// /// An implementation for . /// public sealed class Comparer : Comparer { /// protected override void AddToHashCode(ref HashCode hashCode, HierarchyInfo obj) { hashCode.Add(obj.FilenameHint); hashCode.Add(obj.MetadataName); hashCode.Add(obj.Namespace); hashCode.AddRange(obj.Hierarchy); } /// protected override bool AreEqual(HierarchyInfo x, HierarchyInfo y) { return x.FilenameHint == y.FilenameHint && x.MetadataName == y.MetadataName && x.Namespace == y.Namespace && x.Hierarchy.SequenceEqual(y.Hierarchy); } } }