using System; namespace Vellum.Generator { /// /// Records one call inside a generic method that hands the method's type parameters on, as plain data an /// incremental generator step can compare between runs. /// /// /// If the callee saves one of its type arguments, then the caller saves whatever type that argument is built /// from, and so is a saving method too. /// public sealed class SaveEdge : IEquatable { /// /// Holds the documentation IDs the caller can be registered under, with the caller's own first. /// public readonly EquatableArray CallerIds; /// /// Holds how many of the leading are the caller's own. /// public readonly int OwnCallerCount; /// /// Holds, for each of the that isn't the caller's own, the number each type parameter /// of the caller's type has among the interface's, or a negative number for one that isn't one of them. /// /// /// An interface numbers its own type parameters, so a template that uses the holding type's parameters /// is renumbered by this to be registered under it. There is an entry for every caller ID, and those of the /// caller's own are empty. /// public readonly EquatableArray> CallerClassMaps; /// /// Holds the documentation IDs the callee's registration could be under. /// public readonly EquatableArray CalleeIds; /// /// Holds, for each of the , what the type parameters of the type holding that callee /// stand for here, in terms of the caller's type parameters. /// /// /// A base class or interface is seen through its own type arguments, which a class can order differently, so /// each callee has its own. A type that uses a parameter of the caller but can't be spelled is /// . /// public readonly EquatableArray> CalleeClassArguments; /// /// Holds what the callee was handed for each of its type arguments, in terms of the caller's type /// parameters. A type that uses one of them but can't be spelled is . /// Null is a type that uses none and can't be spelled, which no registration needs. /// /// /// A callee that has no type parameters is handed the types its Type arguments name, in order. /// public readonly EquatableArray Arguments; /// /// Makes an edge whose caller IDs are all the caller's own. /// public SaveEdge(EquatableArray callerIds, EquatableArray calleeIds, EquatableArray arguments) : this(callerIds, callerIds.Items.Length, calleeIds, arguments) { } /// /// Makes an edge whose callers take no renumbering and whose callees' types have no type parameters. /// public SaveEdge(EquatableArray callerIds, int ownCallerCount, EquatableArray calleeIds, EquatableArray arguments) : this(callerIds, ownCallerCount, default, calleeIds, default, arguments) { } public SaveEdge(EquatableArray callerIds, int ownCallerCount, EquatableArray> callerClassMaps, EquatableArray calleeIds, EquatableArray> calleeClassArguments, EquatableArray arguments) { CallerIds = callerIds; OwnCallerCount = ownCallerCount; CallerClassMaps = callerClassMaps; CalleeIds = calleeIds; CalleeClassArguments = calleeClassArguments; Arguments = arguments; } public bool Equals(SaveEdge other) { return other != null && CallerIds.Equals(other.CallerIds) && OwnCallerCount == other.OwnCallerCount && CallerClassMaps.Equals(other.CallerClassMaps) && CalleeIds.Equals(other.CalleeIds) && CalleeClassArguments.Equals(other.CalleeClassArguments) && Arguments.Equals(other.Arguments); } public override bool Equals(object obj) { return Equals(obj as SaveEdge); } public override int GetHashCode() { int returnMe = (CallerIds.GetHashCode() * 31 + OwnCallerCount) * 31 + CalleeIds.GetHashCode(); return (returnMe * 31 + CalleeClassArguments.GetHashCode()) * 31 + Arguments.GetHashCode(); } } }