<commit_before>#region Credits

// This work is based on LinFu.DynamicProxy framework (c) <NAME> who has donated it to NHibernate project.
// The license is the same of NHibernate license (LGPL Version 2.1, February 1999).
// The source was then modified to be the default DynamicProxy of NHibernate project.

#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;

namespace NHibernate.Proxy.DynamicProxy
{
	public sealed class ProxyFactory
	{
		private static readonly ConstructorInfo baseConstructor = typeof(object).GetConstructor(new System.Type[0]);
		private static readonly MethodInfo getTypeFromHandle = typeof(System.Type).GetMethod("GetTypeFromHandle");

		private static readonly MethodInfo getValue = typeof (SerializationInfo).GetMethod("GetValue", BindingFlags.Public | BindingFlags.Instance, null,
																																											 new[] { typeof(string), typeof(System.Type) }, null);

		private static readonly MethodInfo setType = typeof(SerializationInfo).GetMethod("SetType", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(System.Type) }, null);

		private static readonly MethodInfo addValue = typeof (SerializationInfo).GetMethod("AddValue", BindingFlags.Public | BindingFlags.Instance, null,
		                                                                                   new[] {typeof (string), typeof (object)}, null);

		public ProxyFactory()
			: this(new DefaultyProxyMethodBuilder()) {}

		public ProxyFactory(IProxyMethodBuilder proxyMethodBuilder)
		{
			if (proxyMethodBuilder == null)
			{
				throw new ArgumentNullException("proxyMethodBuilder");
			}
			ProxyMethodBuilder = proxyMethodBuilder;
			Cache = new ProxyCache();
		}

		public IProxyCache Cache { get; private set; }

		public IProxyMethodBuilder ProxyMethodBuilder { get; private set; }

		public object CreateProxy(System.Type instanceType, IInterceptor interceptor, params System.Type[] baseInterfaces)
		{
			System.Type proxyType = CreateProxyType(instanceType, baseInterfaces);
			object result = Activator.CreateInstance(proxyType);
			var proxy = (IProxy) result;
			proxy.Interceptor = interceptor;

			return result;
		}

		public System.Type CreateProxyType(System.Type baseType, params System.Type[] interfaces)
		{
			System.Type[] baseInterfaces = ReferenceEquals(null, interfaces) ? new System.Type[0] : interfaces.Where(t => t != null).ToArray();
			// Reuse the previous results, if possible
			if (Cache.Contains(baseType, baseInterfaces))
			{
				return Cache.GetProxyType(baseType, baseInterfaces);
			}

			System.Type result = CreateUncachedProxyType(baseType, baseInterfaces);

			// Cache the proxy type
			if (result != null && Cache != null)
			{
				Cache.StoreProxyType(result, baseType, baseInterfaces);
			}

			return result;
		}

		private System.Type CreateUncachedProxyType(System.Type baseType, System.Type[] baseInterfaces)
		{
			AppDomain currentDomain = AppDomain.CurrentDomain;
			string typeName = string.Format("{0}Proxy", baseType.Name);
			string assemblyName = string.Format("{0}Assembly", typeName);
			string moduleName = string.Format("{0}Module", typeName);

			var name = new AssemblyName(assemblyName);
#if DEBUG
			AssemblyBuilderAccess access = AssemblyBuilderAccess.RunAndSave;
#else
      AssemblyBuilderAccess access = AssemblyBuilderAccess.Run;
#endif
			AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name, access);

#if DEBUG
			ModuleBuilder moduleBuilder =
				assemblyBuilder.DefineDynamicModule(moduleName, string.Format("{0}.mod", moduleName), true);
#else
       ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName);
#endif

			TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class |
			                                TypeAttributes.Public | TypeAttributes.BeforeFieldInit;

			var interfaces = new HashSet<System.Type>();
			interfaces.Merge(baseInterfaces);

			// Use the proxy dummy as the base type 
			// since we're not inheriting from any class type
			System.Type parentType = baseType;
			if (baseType.IsInterface)
			{
				parentType = typeof (ProxyDummy);
				interfaces.Add(baseType);
			}

			// Add any inherited interfaces
			System.Type[] computedInterfaces = interfaces.ToArray();
			foreach (System.Type interfaceType in computedInterfaces)
			{
				interfaces.Merge(GetInterfaces(interfaceType));
			}

			// Add the ISerializable interface so that it can be implemented
			interfaces.Add(typeof (ISerializable));

			TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray());

			ConstructorBuilder defaultConstructor = DefineConstructor(typeBuilder);

			// Implement IProxy
			var implementor = new ProxyImplementor();
			implementor.ImplementProxy(typeBuilder);

			FieldInfo interceptorField = implementor.InterceptorField;
			
			// Provide a custom implementation of ISerializable
			// instead of redirecting it back to the interceptor
			foreach (MethodInfo method in GetProxiableMethods(baseType, interfaces).Where(method => method.DeclaringType != typeof(ISerializable)))
			{
				ProxyMethodBuilder.CreateProxiedMethod(interceptorField, method, typeBuilder);
			}

			// Make the proxy serializable
			AddSerializationSupport(baseType, baseInterfaces, typeBuilder, interceptorField, defaultConstructor);
			System.Type proxyType = typeBuilder.CreateType();

#if DEBUG_PROXY_OUTPUT
     assemblyBuilder.Save("generatedAssembly.dll");
#endif
			return proxyType;
		}

		private IEnumerable<System.Type> GetInterfaces(System.Type currentType)
		{
			return GetAllInterfaces(currentType);
		}

		private IEnumerable<System.Type> GetAllInterfaces(System.Type currentType)
		{
			System.Type[] interfaces = currentType.GetInterfaces();

			foreach (System.Type current in interfaces)
			{
				yield return current;
				foreach (System.Type @interface in GetAllInterfaces(current))
				{
					yield return @interface;
				}
			}
		}

		private IEnumerable<MethodInfo> GetProxiableMethods(System.Type type, IEnumerable<System.Type> interfaces)
		{
			const BindingFlags candidateMethodsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
			return 
				type.GetMethods(candidateMethodsBindingFlags)
					.Where(method => IsProxiable(method))
					.Concat(interfaces.SelectMany(interfaceType => interfaceType.GetMethods())).Distinct();
		}

		private bool IsProxiable(MethodInfo method)
		{
			return (((method.IsPublic || method.IsFamily || method.IsAssembly || method.IsFamilyOrAssembly)
			         && (method.IsVirtual || method.IsAbstract))
			        && (method.DeclaringType != typeof(MarshalByRefObject)))
			       && (method.DeclaringType != typeof(object) || !"finalize".Equals(method.Name.ToLowerInvariant()));
		}

		private static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder)
		{
			const MethodAttributes constructorAttributes = MethodAttributes.Public |
			                                               MethodAttributes.HideBySig | MethodAttributes.SpecialName |
			                                               MethodAttributes.RTSpecialName;<commit_msg>Fix NH-2607 even if cannot be recreated using the obj as mapped entity (the DynProxyTypeValidator already prevent the case exposed).<commit_after>#region Credits

// This work is based on LinFu.DynamicProxy framework (c) <NAME> who has donated it to NHibernate project.
// The license is the same of NHibernate license (LGPL Version 2.1, February 1999).
// The source was then modified to be the default DynamicProxy of NHibernate project.

#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.Serialization;

namespace NHibernate.Proxy.DynamicProxy
{
	public sealed class ProxyFactory
	{
		private static readonly ConstructorInfo baseConstructor = typeof(object).GetConstructor(new System.Type[0]);
		private static readonly MethodInfo getTypeFromHandle = typeof(System.Type).GetMethod("GetTypeFromHandle");

		private static readonly MethodInfo getValue = typeof (SerializationInfo).GetMethod("GetValue", BindingFlags.Public | BindingFlags.Instance, null,
																																											 new[] { typeof(string), typeof(System.Type) }, null);

		private static readonly MethodInfo setType = typeof(SerializationInfo).GetMethod("SetType", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(System.Type) }, null);

		private static readonly MethodInfo addValue = typeof (SerializationInfo).GetMethod("AddValue", BindingFlags.Public | BindingFlags.Instance, null,
		                                                                                   new[] {typeof (string), typeof (object)}, null);

		public ProxyFactory()
			: this(new DefaultyProxyMethodBuilder()) {}

		public ProxyFactory(IProxyMethodBuilder proxyMethodBuilder)
		{
			if (proxyMethodBuilder == null)
			{
				throw new ArgumentNullException("proxyMethodBuilder");
			}
			ProxyMethodBuilder = proxyMethodBuilder;
			Cache = new ProxyCache();
		}

		public IProxyCache Cache { get; private set; }

		public IProxyMethodBuilder ProxyMethodBuilder { get; private set; }

		public object CreateProxy(System.Type instanceType, IInterceptor interceptor, params System.Type[] baseInterfaces)
		{
			System.Type proxyType = CreateProxyType(instanceType, baseInterfaces);
			object result = Activator.CreateInstance(proxyType);
			var proxy = (IProxy) result;
			proxy.Interceptor = interceptor;

			return result;
		}

		public System.Type CreateProxyType(System.Type baseType, params System.Type[] interfaces)
		{
			System.Type[] baseInterfaces = ReferenceEquals(null, interfaces) ? new System.Type[0] : interfaces.Where(t => t != null).ToArray();
			// Reuse the previous results, if possible
			if (Cache.Contains(baseType, baseInterfaces))
			{
				return Cache.GetProxyType(baseType, baseInterfaces);
			}

			System.Type result = CreateUncachedProxyType(baseType, baseInterfaces);

			// Cache the proxy type
			if (result != null && Cache != null)
			{
				Cache.StoreProxyType(result, baseType, baseInterfaces);
			}

			return result;
		}

		private System.Type CreateUncachedProxyType(System.Type baseType, System.Type[] baseInterfaces)
		{
			AppDomain currentDomain = AppDomain.CurrentDomain;
			string typeName = string.Format("{0}Proxy", baseType.Name);
			string assemblyName = string.Format("{0}Assembly", typeName);
			string moduleName = string.Format("{0}Module", typeName);

			var name = new AssemblyName(assemblyName);
#if DEBUG
			AssemblyBuilderAccess access = AssemblyBuilderAccess.RunAndSave;
#else
      AssemblyBuilderAccess access = AssemblyBuilderAccess.Run;
#endif
			AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(name, access);

#if DEBUG
			ModuleBuilder moduleBuilder =
				assemblyBuilder.DefineDynamicModule(moduleName, string.Format("{0}.mod", moduleName), true);
#else
       ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moduleName);
#endif

			TypeAttributes typeAttributes = TypeAttributes.AutoClass | TypeAttributes.Class |
			                                TypeAttributes.Public | TypeAttributes.BeforeFieldInit;

			var interfaces = new HashSet<System.Type>();
			interfaces.Merge(baseInterfaces);

			// Use the proxy dummy as the base type 
			// since we're not inheriting from any class type
			System.Type parentType = baseType;
			if (baseType.IsInterface)
			{
				parentType = typeof (ProxyDummy);
				interfaces.Add(baseType);
			}

			// Add any inherited interfaces
			System.Type[] computedInterfaces = interfaces.ToArray();
			foreach (System.Type interfaceType in computedInterfaces)
			{
				interfaces.Merge(GetInterfaces(interfaceType));
			}

			// Add the ISerializable interface so that it can be implemented
			interfaces.Add(typeof (ISerializable));

			TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName, typeAttributes, parentType, interfaces.ToArray());

			ConstructorBuilder defaultConstructor = DefineConstructor(typeBuilder);

			// Implement IProxy
			var implementor = new ProxyImplementor();
			implementor.ImplementProxy(typeBuilder);

			FieldInfo interceptorField = implementor.InterceptorField;
			
			// Provide a custom implementation of ISerializable
			// instead of redirecting it back to the interceptor
			foreach (MethodInfo method in GetProxiableMethods(baseType, interfaces).Where(method => method.DeclaringType != typeof(ISerializable)))
			{
				ProxyMethodBuilder.CreateProxiedMethod(interceptorField, method, typeBuilder);
			}

			// Make the proxy serializable
			AddSerializationSupport(baseType, baseInterfaces, typeBuilder, interceptorField, defaultConstructor);
			System.Type proxyType = typeBuilder.CreateType();

#if DEBUG_PROXY_OUTPUT
     assemblyBuilder.Save("generatedAssembly.dll");
#endif
			return proxyType;
		}

		private IEnumerable<System.Type> GetInterfaces(System.Type currentType)
		{
			return GetAllInterfaces(currentType);
		}

		private IEnumerable<System.Type> GetAllInterfaces(System.Type currentType)
		{
			System.Type[] interfaces = currentType.GetInterfaces();

			foreach (System.Type current in interfaces)
			{
				yield return current;
				foreach (System.Type @interface in GetAllInterfaces(current))
				{
					yield return @interface;
				}
			}
		}

		private IEnumerable<MethodInfo> GetProxiableMethods(System.Type type, IEnumerable<System.Type> interfaces)
		{
			const BindingFlags candidateMethodsBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
			return 
				type.GetMethods(candidateMethodsBindingFlags)
					.Where(method => IsProxiable(method))
					.Concat(interfaces.SelectMany(interfaceType => interfaceType.GetMethods())).Distinct();
		}

		private bool IsProxiable(MethodInfo method)
		{
			return (
				((method.IsPublic || method.IsFamily || method.IsAssembly || method.IsFamilyOrAssembly) && (method.IsVirtual || method.IsAbstract))
				&& !method.IsFinal
			  && (method.DeclaringType != typeof (MarshalByRefObject)))
			  && (method.DeclaringType != typeof (object) || !"finalize".Equals(method.Name.ToLowerInvariant())
				);
		}

		private static ConstructorBuilder DefineConstructor(TypeBuilder typeBuilder)
		{
			const MethodAttributes constructorAttributes = MethodAttributes.Public |
			                                               MethodAttributes.HideBySig | MethodAttributes.SpecialName |
			                                               MethodAttributes.RTSpecialName;
{'fraction_non_alphanumeric': 0.0916695001700102, 'fraction_numerical': 0.0019041142468548113, 'mean_word_length': 4.057083906464924, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2361554', 'n_tokens_mistral': 4383, 'n_tokens_neox': 3741, 'n_words': 958}