generated/runtime/Helpers/TypeDetails.cs

/*---------------------------------------------------------------------------------------------
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
 
namespace Commvault.Powershell.Runtime.Json
{
     
     
 
    internal class TypeDetails
    {
        private readonly Type info;
 
        internal TypeDetails(Type info)
        {
            this.info = info ?? throw new ArgumentNullException(nameof(info));
        }
 
        internal Type NonNullType { get; set; }
 
        internal object DefaultValue { get; set; }
 
        internal bool IsNullable { get; set; }
 
        internal bool IsList { get; set; }
 
        internal bool IsStringLike { get; set; }
 
        internal bool IsEnum => info.IsEnum;
 
        internal bool IsArray => info.IsArray;
 
        internal bool IsValueType => info.IsValueType;
 
        internal Type ElementType { get; set; }
 
        internal IJsonConverter JsonConverter { get; set; }
 
        #region Creation
 
        private static readonly ConcurrentDictionary<Type, TypeDetails> cache = new ConcurrentDictionary<Type, TypeDetails>();
 
        internal static TypeDetails Get<T>() => Get(typeof(T));
 
        internal static TypeDetails Get(Type type) => cache.GetOrAdd(type, Create);
 
        private static TypeDetails Create(Type type)
        {
            var isGenericList = !type.IsPrimitive && type.ImplementsOpenGenericInterface(typeof(IList<>));
            var isList = !type.IsPrimitive && (isGenericList || typeof(IList).IsAssignableFrom(type));
 
            var isNullable = type.IsNullable();
 
            Type elementType;
 
            if (type.IsArray)
            {
                elementType = type.GetElementType();
            }
            else if (isGenericList)
            {
                var iList = type.GetOpenGenericInterface(typeof(IList<>));
 
                elementType = iList.GetGenericArguments()[0];
            }
            else
            {
                elementType = null;
            }
 
            var nonNullType = isNullable ? type.GetGenericArguments()[0] : type;
 
            var isStringLike = false;
 
            IJsonConverter converter;
 
            var jsonConverterAttribute = type.GetCustomAttribute<JsonConverterAttribute>();
 
            if (jsonConverterAttribute != null)
            {
                converter = jsonConverterAttribute.Converter;
            }
            else if (nonNullType.IsEnum)
            {
                converter = new EnumConverter(nonNullType);
            }
            else if (JsonConverterFactory.Instances.TryGetValue(nonNullType, out converter))
            {
            }
            else if (StringLikeHelper.IsStringLike(nonNullType))
            {
                isStringLike = true;
 
                converter = new StringLikeConverter(nonNullType);
            }
 
            return new TypeDetails(nonNullType) {
                NonNullType = nonNullType,
                DefaultValue = type.IsValueType ? Activator.CreateInstance(type) : null,
                IsNullable = isNullable,
                IsList = isList,
                IsStringLike = isStringLike,
                ElementType = elementType,
                JsonConverter = converter
            };
        }
 
        #endregion
    }
}