<commit_before>﻿using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

namespace Ploeh.SemanticComparison
{
    internal static class ProxyGenerator
    {
        private const string assemblyName = "SemanticComparisonGeneratedAssembly";

        internal static TSource OverrideEquals<TSource>(TSource value, IEqualityComparer comparer)
        {
            TypeBuilder builder = BuildType<TSource>(BuildModule(BuildAssembly(assemblyName)));
            FieldBuilder equals = BuildFieldComparer(builder);

            BuildConstructors<TSource>(builder, equals);
            BuildMethodEquals(builder, BuildFieldEqualsHasBeenCalled(builder), equals);

            var proxy = (TSource)Activator.CreateInstance(
                builder.CreateType(),
                new object[] { comparer });
            CopyProperties(source: value, destination: proxy);
            return proxy;
        }

        private static AssemblyBuilder BuildAssembly(string name)
        {
            var an = new AssemblyName(name);
            an.Version = Assembly.GetExecutingAssembly().GetName().Version;
            return AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
        }

        private static ModuleBuilder BuildModule(AssemblyBuilder ab)
        {
            return ab.DefineDynamicModule(assemblyName, assemblyName + ".dll");
        }

        private static TypeBuilder BuildType<TSource>(ModuleBuilder mb)
        {
            TypeBuilder type = mb.DefineType(
                typeof(TSource).Name + "Proxy" + Guid.NewGuid().ToString().Replace("-", ""),
                TypeAttributes.Public,
                typeof(TSource));
            return type;
        }

        private static FieldBuilder BuildFieldEqualsHasBeenCalled(TypeBuilder type)<commit_msg>Internal improvements related to Likeness's Proxy.<commit_after>﻿using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;

namespace Ploeh.SemanticComparison
{
    internal static class ProxyGenerator
    {
        private const string assemblyName = "SemanticComparisonGeneratedAssembly";

        internal static TSource OverrideEquals<TSource>(TSource value, IEqualityComparer comparer)
        {
            TypeBuilder builder = ProxyGenerator.BuildType<TSource>(BuildModule(BuildAssembly(assemblyName)));
            FieldBuilder equals = ProxyGenerator.BuildFieldComparer(builder);

            ProxyGenerator.BuildConstructors<TSource>(builder, equals);
            ProxyGenerator.BuildMethodEquals(builder, BuildFieldEqualsHasBeenCalled(builder), equals);

            var proxy = (TSource)Activator.CreateInstance(
                builder.CreateType(),
                new object[] { comparer });
            ProxyGenerator.CopyProperties(source: value, destination: proxy);
            return proxy;
        }

        private static AssemblyBuilder BuildAssembly(string name)
        {
            var an = new AssemblyName(name);
            an.Version = Assembly.GetExecutingAssembly().GetName().Version;
            return AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
        }

        private static ModuleBuilder BuildModule(AssemblyBuilder ab)
        {
            return ab.DefineDynamicModule(assemblyName, assemblyName + ".dll");
        }

        private static TypeBuilder BuildType<TSource>(ModuleBuilder mb)
        {
            TypeBuilder type = mb.DefineType(
                typeof(TSource).Name + "Proxy" + Guid.NewGuid().ToString().Replace("-", ""),
                TypeAttributes.Public,
                typeof(TSource));
            return type;
        }

        private static FieldBuilder BuildFieldEqualsHasBeenCalled(TypeBuilder type)
{'fraction_non_alphanumeric': 0.08293838862559241, 'fraction_numerical': 0.0, 'mean_word_length': 2.7391732283464565, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, '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': '1200496', 'n_tokens_mistral': 899, 'n_tokens_neox': 866, 'n_words': 190}