Ejemplo n.º 1
0
        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());
        }
Ejemplo n.º 2
0
        private ReactMethodImpl MakeFireAndForgetMethod(ReflectionMethodInfo methodInfo, ParameterInfo[] parameters)
        {
            // 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 < inputVariables.Length; ++i)
            {
                inputVariables[i] = Expression.Variable(parameters[i].ParameterType, parameters[i].Name);
            }

            // 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.Call(
                               Expression.Convert(moduleParameter, methodInfo.DeclaringType),
                               methodInfo,
                               inputVariables));

            // Generate the lambda to return
            var lambda = Expression.Lambda <ReactMethodImpl>(
                Expression.Block(inputVariables, statements),
                moduleParameter, inputReaderParameter, outputWriterParameter, resolveParameter, rejectParameter);

            // Compile and return the lambda
            return(lambda.Compile());
        }
Ejemplo n.º 3
0
        private ReactMethodImpl MakeCallbackMethod(ReflectionMethodInfo methodInfo, ParameterInfo[] parameters)
        {
            // The last variable is a delegate

            // 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 - 1];
            for (int i = 0; i < inputVariables.Length; ++i)
            {
                inputVariables[i] = Expression.Variable(parameters[i].ParameterType, parameters[i].Name);
            }

            // Generate the resolve delegate
            var inputResolveParameter = parameters[parameters.Length - 1];
            var resolveMethodInfo     = inputResolveParameter.ParameterType.GetMethod("Invoke");

            ParameterInfo[] resolveMethodParameters = resolveMethodInfo.GetParameters();
            if (resolveMethodParameters.Length != 1)
            {
                throw new ArgumentException($"Resolve callback type must have one parameter. Method: {MethodName}, Parameter: {inputResolveParameter.Name}");
            }
            Type resolveParameterType = resolveMethodParameters[0].ParameterType;
            ParameterExpression resolveLambdaParameter = Expression.Parameter(resolveParameterType, "value");

            List <Expression> resolveStatements = new List <Expression>();

            resolveStatements.Add(Expression.Call(outputWriterParameter, typeof(IJSValueWriter).GetMethod("WriteArrayBegin")));
            resolveStatements.Add(Expression.Call(null, JSValueWriter.GetWriteValueMethod(resolveParameterType), outputWriterParameter, resolveLambdaParameter));
            resolveStatements.Add(Expression.Call(outputWriterParameter, typeof(IJSValueWriter).GetMethod("WriteArrayEnd")));
            resolveStatements.Add(Expression.Invoke(resolveParameter, outputWriterParameter));
            var resolveLambda = Expression.Lambda(inputResolveParameter.ParameterType, Expression.Block(resolveStatements), resolveLambdaParameter);

            // 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.Call(
                               Expression.Convert(moduleParameter, methodInfo.DeclaringType),
                               methodInfo,
                               (inputVariables as IEnumerable <Expression>).Append(resolveLambda)));

            // Generate the lambda to return
            var lambda = Expression.Lambda <ReactMethodImpl>(
                Expression.Block(inputVariables, statements),
                moduleParameter, inputReaderParameter, outputWriterParameter, resolveParameter, rejectParameter);

            // Compile and return the lambda
            return(lambda.Compile());
        }