<commit_before>﻿//
// NProxy is a library for the .NET framework to create lightweight dynamic proxies.
// Copyright © 2012 <NAME>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NProxy.Core.Internal.Reflection;
using NProxy.Core.Internal.Common;

namespace NProxy.Core.Interceptors
{
    /// <summary>
    /// Represents an interceptor invocation handler.
    /// </summary>
    internal sealed class InterceptorInvocationHandler : IInvocationHandler
    {
        /// <summary>
        /// The default interceptors.
        /// </summary>
        private readonly IInterceptor[] _defaultInterceptors;

        /// <summary>
        /// The interceptors.
        /// </summary>
        private readonly Dictionary<long, IInterceptor[]> _interceptors;

        /// <summary>
        /// Initializes a new instance of the <see cref="InterceptorInvocationHandler"/> class.
        /// </summary>
        /// <param name="defaultInterceptors">The default interceptor.</param>
        public InterceptorInvocationHandler(IInterceptor[] defaultInterceptors)
        {
            if (defaultInterceptors == null)
                throw new ArgumentNullException("defaultInterceptors");

            _defaultInterceptors = defaultInterceptors;

            _interceptors = new Dictionary<long, IInterceptor[]>();
        }

        /// <summary>
        /// Applies all interceptors for the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="inherit">A value indicating whether to search the type's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        public void ApplyInterceptors(Type type, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            if (interceptors == null)
                throw new ArgumentNullException("interceptors");

            // Apply type interception behaviors.
            var typeInterceptors = ApplyInterceptionBehaviors(type, inherit, interceptors);

            // Apply event interception behaviors.
            var eventVisitor = Visitor.Create<EventInfo>(e => ApplyInterceptors(e, inherit, typeInterceptors));

            type.VisitEvents(eventVisitor);

            // Apply property interception behaviors.
            var propertyVisitor = Visitor.Create<PropertyInfo>(p => ApplyInterceptors(p, inherit, typeInterceptors));

            type.VisitProperties(propertyVisitor);

            // Apply method interception behaviors.
            var methodVisitor = Visitor.Create<MethodInfo>(m => ApplyInterceptors(m, inherit, typeInterceptors));

            type.VisitMethods(methodVisitor);
        }

        /// <summary>
        /// Applies all interceptors for the specified event.
        /// </summary>
        /// <param name="eventInfo">The event information.</param>
        /// <param name="inherit">A value indicating whether to search the event's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void ApplyInterceptors(EventInfo eventInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var eventInterceptors = ApplyInterceptionBehaviors(eventInfo, inherit, interceptors);

            foreach (var methodInfo in eventInfo.GetAccessorMethods())
            {
                ApplyInterceptors(methodInfo, inherit, eventInterceptors);
            }
        }

        /// <summary>
        /// Applies all interceptors for the specified property.
        /// </summary>
        /// <param name="propertyInfo">The property information.</param>
        /// <param name="inherit">A value indicating whether to search the property's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void ApplyInterceptors(PropertyInfo propertyInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var propertyInterceptors = ApplyInterceptionBehaviors(propertyInfo, inherit, interceptors);

            foreach (var methodInfo in propertyInfo.GetAccessorMethods())
            {
                ApplyInterceptors(methodInfo, inherit, propertyInterceptors);
            }
        }

        /// <summary>
        /// Applies all interceptors for the specified method.
        /// </summary>
        /// <param name="methodInfo">The method information.</param>
        /// <param name="inherit">A value indicating whether to search the method's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void ApplyInterceptors(MethodInfo methodInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var methodInterceptors = ApplyInterceptionBehaviors(methodInfo, inherit, interceptors);

            SetInterceptors(methodInfo, methodInterceptors);
        }

        /// <summary>
        /// Applies the interception behaviors for the specified member.
        /// </summary>
        /// <param name="memberInfo">The member information.</param>
        /// <param name="inherit">A value indicating whether to search the member's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        /// <returns>The member interceptors.</returns>
        private static IList<IInterceptor> ApplyInterceptionBehaviors(MemberInfo memberInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var interceptionBehaviors = memberInfo.GetCustomAttributes<IInterceptionBehavior>(inherit);
            var memberInterceptors = new List<IInterceptor>(interceptors);

            foreach (var interceptionBehavior in interceptionBehaviors)
            {
                interceptionBehavior.Validate(memberInfo);
                interceptionBehavior.Apply(memberInfo, memberInterceptors);
            }

            return memberInterceptors;
        }

        /// <summary>
        /// Sets the interceptors for the specified method.
        /// </summary>
        /// <param name="methodInfo">The method information.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void SetInterceptors(MethodInfo methodInfo, IList<IInterceptor> interceptors)
        {
            if (interceptors.Count == 0)
                return;

            var methodToken = methodInfo.GetToken();

            _interceptors.Add(methodToken, interceptors.Concat(_defaultInterceptors).ToArray());
        }

        /// <summary>
        /// Returns all interceptors for the specified member.
        /// </summary>
        /// <param name="memberInfo">The member information.</param>
        /// <returns>The interceptors.</returns>
        private IInterceptor[] GetInterceptors(MemberInfo memberInfo)
        {
            var methodToken = memberInfo.GetToken();
            IInterceptor[] interceptors;
<commit_msg>Minor changes.<commit_after>﻿//
// NProxy is a library for the .NET framework to create lightweight dynamic proxies.
// Copyright © 2012 <NAME>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NProxy.Core.Internal.Reflection;
using NProxy.Core.Internal.Common;

namespace NProxy.Core.Interceptors
{
    /// <summary>
    /// Represents an interceptor invocation handler.
    /// </summary>
    internal sealed class InterceptorInvocationHandler : IInvocationHandler
    {
        /// <summary>
        /// The default interceptors.
        /// </summary>
        private readonly IInterceptor[] _defaultInterceptors;

        /// <summary>
        /// The interceptors.
        /// </summary>
        private readonly Dictionary<long, IInterceptor[]> _interceptors;

        /// <summary>
        /// Initializes a new instance of the <see cref="InterceptorInvocationHandler"/> class.
        /// </summary>
        /// <param name="defaultInterceptors">The default interceptor.</param>
        public InterceptorInvocationHandler(IInterceptor[] defaultInterceptors)
        {
            if (defaultInterceptors == null)
                throw new ArgumentNullException("defaultInterceptors");

            _defaultInterceptors = defaultInterceptors;

            _interceptors = new Dictionary<long, IInterceptor[]>();
        }

        /// <summary>
        /// Applies all interceptors for the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="inherit">A value indicating whether to search the type's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        public void ApplyInterceptors(Type type, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            if (type == null)
                throw new ArgumentNullException("type");

            if (interceptors == null)
                throw new ArgumentNullException("interceptors");

            // Apply type interception behaviors.
            var typeInterceptors = ApplyInterceptionBehaviors(type, inherit, interceptors);

            // Apply event interception behaviors.
            var eventVisitor = Visitor.Create<EventInfo>(e => ApplyInterceptors(e, inherit, typeInterceptors));

            type.VisitEvents(eventVisitor);

            // Apply property interception behaviors.
            var propertyVisitor = Visitor.Create<PropertyInfo>(p => ApplyInterceptors(p, inherit, typeInterceptors));

            type.VisitProperties(propertyVisitor);

            // Apply method interception behaviors.
            var methodVisitor = Visitor.Create<MethodInfo>(m => ApplyInterceptors(m, inherit, typeInterceptors));

            type.VisitMethods(methodVisitor);
        }

        /// <summary>
        /// Applies all interceptors for the specified event.
        /// </summary>
        /// <param name="eventInfo">The event information.</param>
        /// <param name="inherit">A value indicating whether to search the event's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void ApplyInterceptors(EventInfo eventInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var eventInterceptors = ApplyInterceptionBehaviors(eventInfo, inherit, interceptors);

            foreach (var methodInfo in eventInfo.GetAccessorMethods())
            {
                ApplyInterceptors(methodInfo, inherit, eventInterceptors);
            }
        }

        /// <summary>
        /// Applies all interceptors for the specified property.
        /// </summary>
        /// <param name="propertyInfo">The property information.</param>
        /// <param name="inherit">A value indicating whether to search the property's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void ApplyInterceptors(PropertyInfo propertyInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var propertyInterceptors = ApplyInterceptionBehaviors(propertyInfo, inherit, interceptors);

            foreach (var methodInfo in propertyInfo.GetAccessorMethods())
            {
                ApplyInterceptors(methodInfo, inherit, propertyInterceptors);
            }
        }

        /// <summary>
        /// Applies all interceptors for the specified method.
        /// </summary>
        /// <param name="methodInfo">The method information.</param>
        /// <param name="inherit">A value indicating whether to search the method's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void ApplyInterceptors(MethodInfo methodInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var methodInterceptors = ApplyInterceptionBehaviors(methodInfo, inherit, interceptors);

            SetInterceptors(methodInfo, methodInterceptors);
        }

        /// <summary>
        /// Applies the interception behaviors for the specified member.
        /// </summary>
        /// <param name="memberInfo">The member information.</param>
        /// <param name="inherit">A value indicating whether to search the member's inheritance chain to find interception behaviors.</param>
        /// <param name="interceptors">The interceptors.</param>
        /// <returns>The member interceptors.</returns>
        private static IList<IInterceptor> ApplyInterceptionBehaviors(MemberInfo memberInfo, bool inherit, IEnumerable<IInterceptor> interceptors)
        {
            var interceptionBehaviors = memberInfo.GetCustomAttributes<IInterceptionBehavior>(inherit);
            var memberInterceptors = new List<IInterceptor>(interceptors);

            foreach (var interceptionBehavior in interceptionBehaviors)
            {
                interceptionBehavior.Validate(memberInfo);
                interceptionBehavior.Apply(memberInfo, memberInterceptors);
            }

            return memberInterceptors;
        }

        /// <summary>
        /// Sets the interceptors for the specified method.
        /// </summary>
        /// <param name="methodInfo">The method information.</param>
        /// <param name="interceptors">The interceptors.</param>
        private void SetInterceptors(MethodInfo methodInfo, ICollection<IInterceptor> interceptors)
        {
            if (interceptors.Count == 0)
                return;

            var methodToken = methodInfo.GetToken();

            _interceptors.Add(methodToken, interceptors.Concat(_defaultInterceptors).ToArray());
        }

        /// <summary>
        /// Returns all interceptors for the specified member.
        /// </summary>
        /// <param name="memberInfo">The member information.</param>
        /// <returns>The interceptors.</returns>
        private IInterceptor[] GetInterceptors(MemberInfo memberInfo)
        {
            var methodToken = memberInfo.GetToken();
            IInterceptor[] interceptors;

{'fraction_non_alphanumeric': 0.10041388092964024, 'fraction_numerical': 0.0007640878701050621, 'mean_word_length': 2.5461729510047415, 'pattern_counts': {'":': 0, '<': 165, '<?xml version=': 0, '>': 171, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '3316426', 'n_tokens_mistral': 3809, 'n_tokens_neox': 3548, 'n_words': 1105}