/// <summary> /// Resolves enum type information. /// </summary> /// <param name="type"> /// The type to resolve. /// </param> /// <returns> /// An <see cref="EnumResolution" /> with information about the type. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the type is not an enum type. /// </exception> public override TypeResolution Resolve(Type type) { if (!type.IsEnum) { throw new UnsupportedTypeException(type); } var name = new IdentifierResolution(type.Name); var @namespace = string.IsNullOrEmpty(type.Namespace) ? null : new IdentifierResolution(type.Namespace); var isFlagEnum = GetAttribute <FlagsAttribute>(type) != null; var symbols = type.GetFields(BindingFlags.Public | BindingFlags.Static) .Select(f => ( MemberInfo: f as MemberInfo, Name: new IdentifierResolution(f.Name), Value: Enum.Parse(type, f.Name) )) .OrderBy(f => f.Value) .ThenBy(f => f.Name.Value) .Select(f => new SymbolResolution(f.MemberInfo, f.Name, f.Value)) .ToList(); return(new EnumResolution(type, type.GetEnumUnderlyingType(), name, @namespace, isFlagEnum, symbols)); }
/// <summary> /// Resolves class, interface, or struct type information. /// </summary> /// <param name="type"> /// The type to resolve. /// </param> /// <returns> /// A <see cref="RecordResolution" /> with information about the type. /// </returns> /// <exception cref="UnsupportedTypeException"> /// Thrown when the type is an array type or a primitive type. /// </exception> public override TypeResolution Resolve(Type type) { if (type.IsArray || type.IsPrimitive) { throw new UnsupportedTypeException(type); } var name = new IdentifierResolution(type.Name); var @namespace = string.IsNullOrEmpty(type.Namespace) ? null : new IdentifierResolution(type.Namespace); var fields = GetMembers(type, MemberVisibility) .Select(m => ( m.MemberInfo, m.Type, Name: new IdentifierResolution(m.MemberInfo.Name) )) .OrderBy(m => m.Name.Value) .Select(m => new FieldResolution(m.MemberInfo, m.Type, m.Name)) .ToList(); var constructors = GetConstructors(type, MemberVisibility) .Select(c => new ConstructorResolution( c.ConstructorInfo, c.Parameters.Select(p => new ParameterResolution(p, p.ParameterType, new IdentifierResolution(p.Name))).ToList() )).ToList(); return(new RecordResolution(type, name, @namespace, fields, constructors)); }
/// <summary> /// Resolves class, interface, or struct type information. /// </summary> /// <param name="type"> /// The type to resolve. /// </param> /// <returns> /// A <see cref="RecordResolution" /> with information about the type. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the type is an array type or a primitive type. /// </exception> public override TypeResolution Resolve(Type type) { if (!IsMatch(type)) { throw new ArgumentException("The object resolver can only be applied to non-array, non-primitive types.", nameof(type)); } var name = new IdentifierResolution(type.Name); var @namespace = string.IsNullOrEmpty(type.Namespace) ? null : new IdentifierResolution(type.Namespace); var fields = GetMembers(type, MemberVisibility) .Select(m => ( m.MemberInfo, m.Type, Name: new IdentifierResolution(m.MemberInfo.Name) )) .OrderBy(m => m.Name.Value) .Select(m => new FieldResolution(m.MemberInfo, m.Type, m.Name)) .ToList(); return(new RecordResolution(type, name, @namespace, fields)); }
/// <summary> /// Resolves enum type information. /// </summary> /// <param name="type"> /// The type to resolve. /// </param> /// <returns> /// An <see cref="EnumResolution" /> with information about the type. /// </returns> /// <exception cref="ArgumentException"> /// Thrown when the type is not an enum type. /// </exception> public override TypeResolution Resolve(Type type) { if (!IsMatch(type)) { throw new ArgumentException("The enum case can only be applied to enum types.", nameof(type)); } var name = new IdentifierResolution(type.Name); var @namespace = string.IsNullOrEmpty(type.Namespace) ? null : new IdentifierResolution(type.Namespace); var isFlagEnum = GetAttribute <FlagsAttribute>(type) != null; var symbols = type.GetFields(BindingFlags.Public | BindingFlags.Static) .Select(f => ( MemberInfo: f as MemberInfo, Name: new IdentifierResolution(f.Name), Value: Enum.Parse(type, f.Name) )) .OrderBy(f => f.Value) .ThenBy(f => f.Name.Value) .Select(f => new SymbolResolution(f.MemberInfo, f.Name, f.Value)) .ToList(); return(new EnumResolution(type, name, @namespace, isFlagEnum, symbols)); }
/// <summary> /// Whether the resolved name matches another resolved name. /// </summary> /// <param name="other"> /// The resolved name to compare. /// </param> public virtual bool IsMatch(IdentifierResolution other) { return(IsMatch(other.Value)); }
/// <summary> /// Creates a new record type resolution. /// </summary> /// <param name="type"> /// The record type. /// </param> /// <param name="name"> /// The record type name. /// </param> /// <param name="namespace"> /// The record type namespace. /// </param> /// <param name="fields"> /// The record fields. If no fields collection is supplied, <see cref="Fields" /> will be /// empty. /// </param> /// <param name="constructors"> /// The constructors for the underlying type. /// </param> /// <param name="isNullable"> /// Whether the record type can have a null value. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown when the record type or the name is null. /// </exception> public RecordResolution(Type type, IdentifierResolution name, IdentifierResolution @namespace = null, ICollection <FieldResolution> fields = null, ICollection <ConstructorResolution> constructors = null, bool isNullable = false) : base(type, name, @namespace, isNullable) { Fields = fields ?? new FieldResolution[0]; Constructors = constructors ?? new ConstructorResolution[0]; }
/// <summary> /// Creates a new enum type resolution. /// </summary> /// <param name="type"> /// The enum type. /// </param> /// <param name="underlyingType"> /// The enum’s underlying integral type. /// </param> /// <param name="name"> /// The enum type name. /// </param> /// <param name="namespace"> /// The enum type namespace. /// </param> /// <param name="isFlagEnum"> /// Whether the enum is a bit flag enum. /// </param> /// <param name="symbols"> /// The enum symbols. If no symbol collection is supplied, <see cref="Symbols" /> will be /// empty. /// </param> /// <param name="isNullable"> /// Whether the enum type can have a null value. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown when the enum type or the name is null. /// </exception> public EnumResolution(Type type, Type underlyingType, IdentifierResolution name, IdentifierResolution @namespace = null, bool isFlagEnum = false, ICollection <SymbolResolution> symbols = null, bool isNullable = false) : base(type, name, @namespace, isNullable) { IsFlagEnum = isFlagEnum; Symbols = symbols ?? new SymbolResolution[0]; UnderlyingType = underlyingType; }
/// <summary> /// Creates a new named type resolution. /// </summary> /// <param name="type"> /// The named type. /// </param> /// <param name="name"> /// The type name. /// </param> /// <param name="namespace"> /// The type namespace. /// </param> /// <param name="isNullable"> /// Whether the named type can have a null value. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown when the named type or the name is null. /// </exception> public NamedTypeResolution(Type type, IdentifierResolution name, IdentifierResolution @namespace = null, bool isNullable = false) : base(type, isNullable) { Name = name; Namespace = @namespace; }
/// <summary> /// Creates a new symbol resolution. /// </summary> /// <param name="member"> /// The resolved static field reflection info. /// </param> /// <param name="name"> /// The symbol name. /// </param> /// <param name="value"> /// The raw symbol value. /// </param> public SymbolResolution(MemberInfo member, IdentifierResolution name, object value) { Member = member; Name = name; Value = value; }
/// <summary> /// Creates a new field resolution. /// </summary> /// <param name="member"> /// The resolved member reflection info. /// </param> /// <param name="type"> /// The field or property type. /// </param> /// <param name="name"> /// The field or property name. /// </param> /// <exception cref="ArgumentNullException"> /// Thrown when reflection info, type, or name is null. /// </exception> public FieldResolution(MemberInfo member, Type type, IdentifierResolution name) { Member = member; Name = name; Type = type; }
/// <summary> /// Creates a new record type resolution. /// </summary> /// <param name="type"> /// The record type. /// </param> /// <param name="name"> /// The record type name. /// </param> /// <param name="namespace"> /// The record type namespace. /// </param> /// <param name="fields"> /// The record fields. If no fields collection is supplied, <see cref="Fields" /> will be /// empty. /// </param> /// <param name="constructors"> /// The constructors for the underlying type. /// </param> /// <param name="isNullable"> /// Whether the record type can have a null value. /// </param> public RecordResolution(Type type, IdentifierResolution name, IdentifierResolution? @namespace = null, ICollection <FieldResolution>?fields = null, ICollection <ConstructorResolution>?constructors = null, bool isNullable = false) : base(type, name, @namespace, isNullable) { Fields = fields ?? new List <FieldResolution>(); Constructors = constructors ?? new List <ConstructorResolution>(); }
/// <summary> /// Creates a new parameter resolution. /// </summary> /// <param name="parameter"> /// The resolved parameter reflection info. /// </param> /// <param name="type"> /// The parameter type. /// </param> /// <param name="name"> /// The parameter name. /// </param> public ParameterResolution(ParameterInfo parameter, Type type, IdentifierResolution name) { Parameter = parameter; Name = name; Type = type; }