1
0

chore: initial commit

Signed-off-by: Alan Brault <alan.brault@visus.io>
This commit is contained in:
2025-07-21 13:43:39 -04:00
commit fb4bf1aaee
37 changed files with 2645 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
// This file is ported and adapted from CommunityToolkit.Mvvm (CommunityToolkit/dotnet)
namespace MapperSourceGen.SourceGenerator.Model;
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using static Microsoft.CodeAnalysis.SymbolDisplayTypeQualificationStyle;
/// <summary>
/// Represents information about a type hierarchy in a source code file.
/// </summary>
internal sealed partial class HierarchyInfo : IEquatable<HierarchyInfo>
{
/// <summary>
/// Initializes a new instance of the <see cref="HierarchyInfo" /> class.
/// </summary>
/// <param name="fileNameHint">The filename hint for the type (including namespace) without extension.</param>
/// <param name="namespace">The containing namespace for the type.</param>
/// <param name="hierarchy">The current hierarchy for the type.</param>
/// <exception cref="ArgumentException"><paramref name="fileNameHint" /> is <c>null</c> or empty.</exception>
private HierarchyInfo(string fileNameHint, string @namespace, ImmutableArray<TypeInfo> hierarchy)
{
if ( string.IsNullOrWhiteSpace(fileNameHint) )
{
throw new ArgumentException($"'{nameof(fileNameHint)}' cannot be null or empty.", nameof(fileNameHint));
}
FileNameHint = fileNameHint;
Hierarchy = hierarchy;
Namespace = @namespace;
}
/// <summary>
/// Gets the file name hint (including full namespace) for the type hierarchy.
/// </summary>
public string FileNameHint { get; }
/// <summary>
/// Gets a collection of <see cref="TypeInfo" /> representing the hierarchy of types.
/// </summary>
public ImmutableArray<TypeInfo> Hierarchy { get; }
/// <summary>
/// Gets the namespace of the type hierarchy.
/// </summary>
public string Namespace { get; }
public static HierarchyInfo From(INamedTypeSymbol typeSymbol)
{
if ( typeSymbol is null )
{
throw new ArgumentNullException(nameof(typeSymbol));
}
LinkedList<TypeInfo> hierarchy = [];
for ( INamedTypeSymbol? parent = typeSymbol;
parent is not null;
parent = parent.ContainingType )
{
hierarchy.AddLast(new TypeInfo(parent.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
parent.TypeKind,
parent.DeclaredAccessibility,
parent.IsRecord,
parent.IsSealed));
}
return new HierarchyInfo(typeSymbol.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: NameAndContainingTypesAndNamespaces)),
typeSymbol.ContainingNamespace.ToDisplayString(new SymbolDisplayFormat(typeQualificationStyle: NameAndContainingTypesAndNamespaces)),
[..hierarchy]);
}
public static bool operator ==(HierarchyInfo? left, HierarchyInfo? right)
{
return Equals(left, right);
}
public static bool operator !=(HierarchyInfo? left, HierarchyInfo? right)
{
return !Equals(left, right);
}
/// <inheritdoc />
public bool Equals(HierarchyInfo? other)
{
if ( other is null )
{
return false;
}
if ( ReferenceEquals(this, other) )
{
return true;
}
return string.Equals(FileNameHint, other.FileNameHint, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Namespace, other.Namespace, StringComparison.OrdinalIgnoreCase);
}
/// <inheritdoc />
public override bool Equals(object? obj)
{
return ReferenceEquals(this, obj) || ( obj is HierarchyInfo other && Equals(other) );
}
/// <inheritdoc />
public override int GetHashCode()
{
unchecked
{
return ( StringComparer.OrdinalIgnoreCase.GetHashCode(FileNameHint) * 397 )
^ StringComparer.OrdinalIgnoreCase.GetHashCode(Namespace);
}
}
}