private ReactMethodImpl MakeReturningMethod(ReflectionMethodInfo methodInfo, Type returnType, ParameterInfo[] parameters) { // It is like the MakeCallbackMethod but callback is not passed as a parameter. // Input parameters for generated lambda ParameterExpression moduleParameter = Expression.Parameter(typeof(object), "module"); ParameterExpression inputReaderParameter = Expression.Parameter(typeof(IJSValueReader), "inputReader"); ParameterExpression outputWriterParameter = Expression.Parameter(typeof(IJSValueWriter), "outputWriter"); ParameterExpression resolveParameter = Expression.Parameter(typeof(MethodResultCallback), "resolve"); ParameterExpression rejectParameter = Expression.Parameter(typeof(MethodResultCallback), "reject"); // Input variables to read from inputReader ParameterExpression[] inputVariables = new ParameterExpression[parameters.Length]; for (int i = 0; i < parameters.Length; ++i) { inputVariables[i] = Expression.Variable(parameters[i].ParameterType, parameters[i].Name); } // The result variable to store method call result var resultVariable = Expression.Variable(returnType); // Statements of the generated lambda List <Expression> statements = new List <Expression>(); // Generate code to read input variables from the inputReader var callReadNext = Expression.Call(inputReaderParameter, typeof(IJSValueReader).GetMethod("ReadNext")); statements.Add(callReadNext); foreach (ParameterExpression variable in inputVariables) { statements.Add(callReadNext); statements.Add(Expression.Call(null, JSValueReader.GetReadValueMethod(variable.Type), inputReaderParameter, variable)); } // Generate code to call the method statements.Add(Expression.Assign(resultVariable, Expression.Call( Expression.Convert(moduleParameter, methodInfo.DeclaringType), methodInfo, inputVariables))); // Generate code to write result to outputWriter statements.Add(Expression.Call(outputWriterParameter, typeof(IJSValueWriter).GetMethod("WriteArrayBegin"))); statements.Add(Expression.Call(null, JSValueWriter.GetWriteValueMethod(resultVariable.Type), outputWriterParameter, resultVariable)); statements.Add(Expression.Call(outputWriterParameter, typeof(IJSValueWriter).GetMethod("WriteArrayEnd"))); // Generate code to call resolve callback statements.Add(Expression.Invoke(resolveParameter, outputWriterParameter)); // Generate the lambda to return var lambda = Expression.Lambda <ReactMethodImpl>( Expression.Block(inputVariables.Append(resultVariable), statements), moduleParameter, inputReaderParameter, outputWriterParameter, resolveParameter, rejectParameter); // Compile and return the lambda return(lambda.Compile()); }