private MethodBuilder GenerateMethod(TypeBuilder typeBuilder)
        {
            var methodBuilder = typeBuilder.DefineMethod(
                _methodMetadata.Name,
                _methodMetadata.MethodAttributes,
                CallingConventions.Standard,
                _methodMetadata.ReturnType,
                _methodMetadata.ParameterTypes);

            var parameters = _methodMetadata.Method.GetParameters();
            var parameterCount = parameters.Length;

            var parameterBuilders = new ParameterBuilder[parameterCount];

            for (var i = 0; i < parameterCount; i++)
            {
                parameterBuilders[i] = methodBuilder.DefineParameter(i + 1, ParameterAttributes.None, parameters[i].Name);
            }

            var il = methodBuilder.GetILGenerator();

            var args = new IExpressionEmitter[parameterCount];

            for (var i = 0; i < parameterCount; i++)
            {
                args[i] = new LoadArgumentExpression(parameterBuilders[i]);
            }

            il.Emit(OpCodes.Ldarg_0);

            if (_methodMetadata.ReturnType == typeof(void))
            {
                new CallMethodStatement(_methodMetadata.TargetMethod, args).Emit(il);

                il.Emit(OpCodes.Ldnull);

                new ReturnStatement().Emit(il);
            }
            else
            {
                new ReturnStatement(
                    new CallMethodExpression(_methodMetadata.TargetMethod, args)
                ).Emit(il);
            }

            return methodBuilder;
        }
 public CastOrUnboxExpression(Type targetType, IExpressionEmitter valueExpression)
 {
     _targetType = targetType;
     _valueExpression = valueExpression;
 }
 public ReturnStatement(IExpressionEmitter valueExpression)
 {
     _valueExpression = valueExpression;
 }
 public StoreLocalStatement(LocalBuilder local, IExpressionEmitter valueExpression)
 {
     _local = local;
     _valueExpression = valueExpression;
 }
 public StoreFieldStatement(FieldBuilder field, IExpressionEmitter valueEmitter)
 {
     _field = field;
     _valueEmitter = valueEmitter;
 }
 public CallMethodStatement(MethodInfo method, IExpressionEmitter[] arguments)
 {
     _method = method;
     _arguments = arguments;
 }