<commit_before>using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Core;
using Castle.Core.Interceptor;

namespace AutofacContrib.AggregateService
{
    /// <summary>
    /// Interceptor that resolves types of properties and methods using a <see cref="IComponentContext"/>.
    /// </summary>
    public class ResolvingInterceptor : IInterceptor
    {
        private readonly IComponentContext _context;
        private readonly Dictionary<MethodInfo, Action<IInvocation>> _invocationMap;

        ///<summary>
        /// Initialize <see cref="ResolvingInterceptor"/> with an interface type and a component context.
        ///</summary>
        public ResolvingInterceptor(Type interfaceType, IComponentContext context)
        {
            _context = context;
            _invocationMap = SetupInvocationMap(interfaceType);
        }

        void IInterceptor.Intercept(IInvocation invocation)
        {
            var invocationHandler = _invocationMap[invocation.Method];
            invocationHandler(invocation);
        }

        private Dictionary<MethodInfo, Action<IInvocation>> SetupInvocationMap(Type interfaceType)
        {
            var methods = interfaceType.GetMethods();
            var methodMap = new Dictionary<MethodInfo, Action<IInvocation>>(methods.Length);
            foreach (var method in methods)
            {
                var returnType = method.ReturnType;

                if (returnType == typeof(void))
                {
                    // Any method with 'void' return type (includes property setters) should throw an exception
                    methodMap.Add(method, InvalidReturnTypeInvocation);
                }
                else if (GetProperty(method) != null)
                {
                    // All properties should be resolved at proxy instantiation 
                    var propertyValue = _context.Resolve(returnType);
                    methodMap.Add(method, invocation => invocation.ReturnValue = propertyValue);
                }
                else
                {
                    // For methods with parameters, cache parameter info for use at invocation time
                    var parameters = method.GetParameters()
                        .OrderBy(parameterInfo => parameterInfo.Position)
                        .Select(parameterInfo => new { parameterInfo.Position, parameterInfo.ParameterType })
                        .ToArray();

                    if (parameters.Length > 0)
                    {
                        methodMap.Add(method, invocation =>
                                                  {
                                                      var arguments = invocation.Arguments;
                                                      var typedParameters = parameters
                                                          .Select(info => (Parameter)new TypedParameter(info.ParameterType, arguments[info.Position]));

                                                      invocation.ReturnValue = _context.Resolve(returnType, typedParameters);
                                                  });
                    }
                    else
                    {
                        methodMap.Add(method, invocation => invocation.ReturnValue = _context.Resolve(returnType));
                    }
                }
            }

            return methodMap;
        }

        private static void InvalidReturnTypeInvocation(IInvocation invocation)
        {
            throw new InvalidOperationException("The method " + invocation.Method + " has invalid return type System.Void");
        }

        private static PropertyInfo GetProperty(MethodInfo method)
        {
            var takesArg = method.GetParameters().Length == 1;
            var hasReturn = method.ReturnType != typeof(void);
            if (takesArg == hasReturn) return null;
            // Ignore setters
            //if (takesArg)
            //{
            //    return method.DeclaringType.GetProperties()
            //        .Where(prop => prop.GetSetMethod() == method).FirstOrDefault();<commit_msg>ResolvingInterceptor uses generic invocation method for methods without parameters.<commit_after>using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Core;
using Castle.Core.Interceptor;

namespace AutofacContrib.AggregateService
{
    /// <summary>
    /// Interceptor that resolves types of properties and methods using a <see cref="IComponentContext"/>.
    /// </summary>
    public class ResolvingInterceptor : IInterceptor
    {
        private readonly IComponentContext _context;
        private readonly Dictionary<MethodInfo, Action<IInvocation>> _invocationMap;

        ///<summary>
        /// Initialize <see cref="ResolvingInterceptor"/> with an interface type and a component context.
        ///</summary>
        public ResolvingInterceptor(Type interfaceType, IComponentContext context)
        {
            _context = context;
            _invocationMap = SetupInvocationMap(interfaceType);
        }

        void IInterceptor.Intercept(IInvocation invocation)
        {
            var invocationHandler = _invocationMap[invocation.Method];
            invocationHandler(invocation);
        }

        private Dictionary<MethodInfo, Action<IInvocation>> SetupInvocationMap(Type interfaceType)
        {
            var methods = interfaceType.GetMethods();
            var methodMap = new Dictionary<MethodInfo, Action<IInvocation>>(methods.Length);
            foreach (var method in methods)
            {
                var returnType = method.ReturnType;

                if (returnType == typeof(void))
                {
                    // Any method with 'void' return type (includes property setters) should throw an exception
                    methodMap.Add(method, InvalidReturnTypeInvocation);
                }
                else if (GetProperty(method) != null)
                {
                    // All properties should be resolved at proxy instantiation 
                    var propertyValue = _context.Resolve(returnType);
                    methodMap.Add(method, invocation => invocation.ReturnValue = propertyValue);
                }
                else
                {
                    // For methods with parameters, cache parameter info for use at invocation time
                    var parameters = method.GetParameters()
                        .OrderBy(parameterInfo => parameterInfo.Position)
                        .Select(parameterInfo => new { parameterInfo.Position, parameterInfo.ParameterType })
                        .ToArray();

                    if (parameters.Length > 0)
                    {
                        methodMap.Add(method, invocation =>
                                                  {
                                                      var arguments = invocation.Arguments;
                                                      var typedParameters = parameters
                                                          .Select(info => (Parameter)new TypedParameter(info.ParameterType, arguments[info.Position]));

                                                      invocation.ReturnValue = _context.Resolve(returnType, typedParameters);
                                                  });
                    }
                    else
                    {
                        var methodWithoutParams = GetType()
                            .GetMethod("MethodWithoutParams", BindingFlags.Instance|BindingFlags.NonPublic)
                            .MakeGenericMethod(new[]{ returnType });

                        var methodWithoutParamsDelegate = (Action<IInvocation>)Delegate.CreateDelegate(typeof (Action<IInvocation>), this, methodWithoutParams);
                        methodMap.Add(method, methodWithoutParamsDelegate);
                    }
                }
            }

            return methodMap;
        }

        private void MethodWithoutParams<TReturnType>(IInvocation invocation)
        {
            invocation.ReturnValue = _context.Resolve<TReturnType>();
        }

        private static void InvalidReturnTypeInvocation(IInvocation invocation)
        {
            throw new InvalidOperationException("The method " + invocation.Method + " has invalid return type System.Void");
        }

        private static PropertyInfo GetProperty(MethodInfo method)
        {
            var takesArg = method.GetParameters().Length == 1;
            var hasReturn = method.ReturnType != typeof(void);
            if (takesArg == hasReturn) return null;
            // Ignore setters
            //if (takesArg)
            //{
            //    return method.DeclaringType.GetProperties()
            //        .Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
{'fraction_non_alphanumeric': 0.0766057091882248, 'fraction_numerical': 0.00044603033006244426, 'mean_word_length': 1.5684421534936999, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6079901', 'n_tokens_mistral': 1921, 'n_tokens_neox': 1827, 'n_words': 464}