using System; using System.Collections.Immutable; using Upsilon.BoundTypes; namespace Upsilon.BaseTypes { public class TypeContainer { public Type Type { get; protected set; } public virtual string UserData { get; } protected TypeContainer(Type t) { if (t == Type.UserData) { throw new Exception( "Instantiating a userdata type without specifying type. Use constructor with string instead."); } Type = t; } public TypeContainer(string userData) { if (string.IsNullOrEmpty(userData)) { throw new Exception("Userdata name was null or empty. Not setting this properly will lead to issues later on."); } Type = Type.UserData; UserData = userData; } public TypeContainer(Type type, string userData) { if (string.IsNullOrEmpty(userData)) { throw new Exception("Userdata name was null or empty. Not setting this properly will lead to issues later on."); } Type = type; UserData = userData; } public static implicit operator TypeContainer (Type type) { return new TypeContainer(type); } public static implicit operator Type(TypeContainer t) { return t.Type; } protected bool Equals(TypeContainer other) { return Type == other.Type; } public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj is Type t) { return t == Type; } if (obj.GetType() != this.GetType()) return false; return Equals((TypeContainer) obj); } public override int GetHashCode() { return (int) Type; } public static bool operator == (TypeContainer a, object b) { return Equals(a, b); } public static bool operator != (TypeContainer a, object b) { return !Equals(a, b); } public override string ToString() { return Type == Type.UserData ? UserData : Type.ToString(); } } public class UndefinedUserDataTypeContainer : TypeContainer { private System.Type RealType { get; set; } public UndefinedUserDataTypeContainer(System.Type realType) : base(realType.Name) { if (realType == null) throw new Exception("Type can't be null"); RealType = realType; } public UndefinedUserDataTypeContainer(Type t, System.Type realType) : base(t, realType.Name) { if (realType == null) throw new Exception("Type can't be null"); RealType = realType; } private string _userData; public override string UserData { get { var s = _userData; if (s != null) { return s; } _userData = BoundTypeHandler.GetTypeName(RealType); if (_userData != null) { RealType = null; } return _userData; } } } public class CompositeTypeContainer : TypeContainer { public ImmutableArray Types { get; } public CompositeTypeContainer(ImmutableArray types) : base(Type.Table) { Types = types; } public override string ToString() { return $"{Type.ToString()} ({string.Join(", ", Types)})"; } } }