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();
}
}
}