Пример #1
0
        /// <summary>
        /// Generates invoker methods.
        /// </summary>
        /// <param name="grainType">The grain type.</param>
        /// <param name="onEncounteredType">
        /// The callback which is invoked when a type is encountered.
        /// </param>
        /// <returns>Invoker methods for the provided grain type.</returns>
        private static MemberDeclarationSyntax[] GenerateInvokeMethods(Type grainType, Action <Type> onEncounteredType)
        {
            var baseReference = SF.BaseExpression();
            var methods       = GrainInterfaceUtils.GetMethods(grainType);
            var members       = new List <MemberDeclarationSyntax>();

            foreach (var method in methods)
            {
                onEncounteredType(method.ReturnType);
                var methodId         = GrainInterfaceUtils.ComputeMethodId(method);
                var methodIdArgument =
                    SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                // Construct a new object array from all method arguments.
                var parameters = method.GetParameters();
                var body       = new List <StatementSyntax>();
                foreach (var parameter in parameters)
                {
                    onEncounteredType(parameter.ParameterType);
                    if (typeof(IGrainObserver).IsAssignableFrom(parameter.ParameterType))
                    {
                        body.Add(
                            SF.ExpressionStatement(
                                CheckGrainObserverParamInternalExpression.Invoke()
                                .AddArgumentListArguments(SF.Argument(parameter.Name.ToIdentifierName()))));
                    }
                }

                // Get the parameters argument value.
                ExpressionSyntax args;
                if (parameters.Length == 0)
                {
                    args = SF.LiteralExpression(SyntaxKind.NullLiteralExpression);
                }
                else
                {
                    args =
                        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                        .WithInitializer(
                            SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                            .AddExpressions(parameters.Select(GetParameterForInvocation).ToArray()));
                }

                var options = GetInvokeOptions(method);

                // Construct the invocation call.
                if (method.ReturnType == typeof(void))
                {
                    var invocation = SF.InvocationExpression(baseReference.Member("InvokeOneWayMethod"))
                                     .AddArgumentListArguments(methodIdArgument)
                                     .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ExpressionStatement(invocation));
                }
                //else if (GrainInterfaceUtils.IsReactiveComputationType(method.ReturnType))
                //{
                //    var resultTypeArgument =
                //        SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(methodId)));

                //    var returnType = method.ReturnType.GenericTypeArguments[0];
                //                        args =
                //        SF.ArrayCreationExpression(typeof(object).GetArrayTypeSyntax())
                //            .WithInitializer(
                //                SF.InitializerExpression(SyntaxKind.ArrayInitializerExpression)
                //                    .AddExpressions(parameters.Select(GetParameterForInvocation).ToArray()));
                //    var invocation =
                //        SF.InvocationExpression(baseReference.Member("CreateReactiveComputation", returnType.GenericTypeArguments[0]))
                //            .AddArgumentListArguments(methodIdArgument)
                //            .AddArgumentListArguments(SF.Argument(args));
                //    if (options != null)
                //    {
                //        invocation = invocation.AddArgumentListArguments(options);
                //    }

                //    body.Add(SF.ReturnStatement(invocation));
                //}
                //else if (grainType is IReactiveGrain)
                //{
                //    var returnType = (method.ReturnType == typeof(Task))
                //     ? typeof(object)
                //     : method.ReturnType.GenericTypeArguments[0];
                //    var invocation =
                //        SF.InvocationExpression(baseReference.Member("InvokeMethodAsync", returnType))
                //            .AddArgumentListArguments(methodIdArgument)
                //            .AddArgumentListArguments(SF.Argument(args));

                //    if (options != null)
                //    {
                //        invocation = invocation.AddArgumentListArguments(options);
                //    }

                //    body.Add(SF.ReturnStatement(invocation));
                //}
                else if (GrainInterfaceUtils.IsTaskType(method.ReturnType))
                {
                    var returnType = (method.ReturnType == typeof(Task))
                     ? typeof(object)
                     : method.ReturnType.GenericTypeArguments[0];
                    var invocation =
                        SF.InvocationExpression(baseReference.Member("InvokeMethodAsync", returnType))
                        .AddArgumentListArguments(methodIdArgument)
                        .AddArgumentListArguments(SF.Argument(args));

                    if (options != null)
                    {
                        invocation = invocation.AddArgumentListArguments(options);
                    }

                    body.Add(SF.ReturnStatement(invocation));
                }

                members.Add(method.GetDeclarationSyntax().AddBodyStatements(body.ToArray()));
            }


            return(members.ToArray());
        }