using System; using Microsoft.CodeAnalysis.CSharp; namespace Vellum.Generator { /// /// Describes a saved field or auto-property as plain data, which an incremental generator step can compare between /// runs. /// public sealed class MemberShape : IEquatable { /// /// Holds the member's name, which is the key it's saved under. /// public readonly string Key; /// /// Holds the member's type, spelled so generated code names it from anywhere. /// public readonly string TypeName; /// /// Holds whether C# lets code in the type assign the member outside a constructor. A readonly field and a /// property with no setter, or only an init setter, don't. /// public readonly bool AssignsDirectly; public MemberShape(string key, string typeName) : this(key, typeName, assignsDirectly: true) { } public MemberShape(string key, string typeName, bool assignsDirectly) { Key = key; TypeName = typeName; AssignsDirectly = assignsDirectly; } /// /// Returns the member read through , with an @ if its name is a keyword. /// public string On(string instance) { if (SyntaxFacts.GetKeywordKind(Key) != SyntaxKind.None) { return instance + ".@" + Key; } return instance + "." + Key; } public bool Equals(MemberShape other) { return other != null && Key == other.Key && TypeName == other.TypeName && AssignsDirectly == other.AssignsDirectly; } public override bool Equals(object obj) { return Equals(obj as MemberShape); } public override int GetHashCode() { return Key.GetHashCode() * 31 + TypeName.GetHashCode(); } } }