static string GetTypeNameCore(TypeReference type, IEnumerator <bool?> nullabilityMap, bool nullable, bool disableNested)
        {
            if (type.IsGenericParameter)
            {
                return(type.Name);
            }

            if (type is ArrayType array)
            {
                if (nullable)
                {
                    return(CSharpTypeKeyword.Get(GetTypeName(array.ElementType, nullabilityMap, NullableMode.Default, disableNested)) + "[]");
                }
                else
                {
                    return(GetTypeName(array.ElementType, nullabilityMap, NullableMode.Default, disableNested) + "[]");
                }
            }

            if (type is PointerType pointer)
            {
                return(CSharpTypeKeyword.Get(GetTypeName(pointer.ElementType, nullabilityMap, NullableMode.Default, disableNested)) + "*");
            }

            if (!type.IsNested || disableNested)
            {
                var name = type is RequiredModifierType modType ? modType.ElementType.Name : type.Name;
                return((!string.IsNullOrEmpty(type.Namespace) ? (type.Namespace + ".") : "") + name);
            }

            return(GetTypeName(type.DeclaringType, null, NullableMode.Default, false) + "." + GetTypeName(type, null, NullableMode.Default, true));
        }
        static string GetTypeName(TypeReference type, IEnumerator <bool?> nullabilityMap, NullableMode mode, bool disableNested)
        {
            bool nullable = mode != NullableMode.Disable && (mode == NullableMode.Force || HasAnyReferenceType(type) && IsNullable());

            var typeName = GetTypeNameCore(type, nullabilityMap, nullable, disableNested);

            if (nullable && typeName != "System.Void")
            {
                typeName = CSharpTypeKeyword.Get(typeName) + "?";
            }

            return(typeName);

            bool IsNullable()
            {
                if (nullabilityMap == null)
                {
                    return(false);
                }

                if (!nullabilityMap.MoveNext())
                {
                    throw new InvalidOperationException("Not enough nullability information");
                }
                return(nullabilityMap.Current == true);
            }
        }