<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using HellBrick.Json.Common;

namespace HellBrick.Json.Serialization.Providers
{
	internal class CollectionSerializerBuilderProvider : ISerializerBuilderProvider
	{
		public ISerializerBuilder<T> TryCreateBuilder<T>()
		{
			EnumerableTypeInfo enumerableTypeInfo = EnumerableTypeInfo.TryCreate( typeof( T ) );
			if ( enumerableTypeInfo == null )
				return null;

			Type builderType = typeof( CollectionSerializerBuilder<,> ).MakeGenericType( enumerableTypeInfo.CollectionType, enumerableTypeInfo.ItemType );
			ISerializerBuilder<T> builder = Activator.CreateInstance( builderType, new object[] { enumerableTypeInfo } ) as ISerializerBuilder<T>;
			return builder;
		}

		private class CollectionSerializerBuilder<TCollection, TItem> : ISerializerBuilder<TCollection>
		{
			private readonly EnumerableTypeInfo _enumerableTypeInfo;

			public CollectionSerializerBuilder( EnumerableTypeInfo enumerableTypeInfo )
			{
				_enumerableTypeInfo = enumerableTypeInfo;
			}

			public Expression BuildSerializationExpression( Expression value, Expression writer )
			{
				LocalVariables locals = new LocalVariables( _enumerableTypeInfo );
				return Expression.Block( locals.Variables, EnumerateSerializerExpressions( value, writer, locals ) );
			}

			private IEnumerable<Expression> EnumerateSerializerExpressions( Expression value, Expression writer, LocalVariables locals )
			{
				yield return Expression.Call( writer, JsonWriterMembers.WriteStartArray );
				yield return Expression.Assign( locals.Enumerator, Expression.Call( value, _enumerableTypeInfo.GetEnumeratorMethod ) );<commit_msg>Added support for serializing null collections<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using HellBrick.Json.Common;

namespace HellBrick.Json.Serialization.Providers
{
	internal class CollectionSerializerBuilderProvider : ISerializerBuilderProvider
	{
		public ISerializerBuilder<T> TryCreateBuilder<T>()
		{
			EnumerableTypeInfo enumerableTypeInfo = EnumerableTypeInfo.TryCreate( typeof( T ) );
			if ( enumerableTypeInfo == null )
				return null;

			Type builderType = typeof( CollectionSerializerBuilder<,> ).MakeGenericType( enumerableTypeInfo.CollectionType, enumerableTypeInfo.ItemType );
			ISerializerBuilder<T> builder = Activator.CreateInstance( builderType, new object[] { enumerableTypeInfo } ) as ISerializerBuilder<T>;
			return builder;
		}

		private class CollectionSerializerBuilder<TCollection, TItem> : ReferenceTypeSerializerBuilder<TCollection>
		{
			private readonly EnumerableTypeInfo _enumerableTypeInfo;

			public CollectionSerializerBuilder( EnumerableTypeInfo enumerableTypeInfo )
			{
				_enumerableTypeInfo = enumerableTypeInfo;
			}

			protected override Expression SerializeNonNullValue( Expression value, Expression writer )
			{
				LocalVariables locals = new LocalVariables( _enumerableTypeInfo );
				return Expression.Block( locals.Variables, EnumerateSerializerExpressions( value, writer, locals ) );
			}

			private IEnumerable<Expression> EnumerateSerializerExpressions( Expression value, Expression writer, LocalVariables locals )
			{
				yield return Expression.Call( writer, JsonWriterMembers.WriteStartArray );
				yield return Expression.Assign( locals.Enumerator, Expression.Call( value, _enumerableTypeInfo.GetEnumeratorMethod ) );
{'fraction_non_alphanumeric': 0.07399103139013453, 'fraction_numerical': 0.0, 'mean_word_length': 6.039447731755424, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5938822', 'n_tokens_mistral': 984, 'n_tokens_neox': 904, 'n_words': 218}