/// <summary> /// Generates syntax to invoke a method on a grain. /// </summary> /// <param name="grainType"> /// The grain type. /// </param> /// <param name="grain"> /// The grain instance expression. /// </param> /// <param name="method"> /// The method. /// </param> /// <param name="arguments"> /// The arguments expression. /// </param> /// <returns> /// Syntax to invoke a method on a grain. /// </returns> private static StatementSyntax[] GenerateInvokeForMethod( Type grainType, IdentifierNameSyntax grain, MethodInfo method, ExpressionSyntax arguments) { var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain)); // Construct expressions to retrieve each of the method's parameters. var parameters = new List <ExpressionSyntax>(); var methodParameters = method.GetParameters().ToList(); for (var i = 0; i < methodParameters.Count; i++) { var parameter = methodParameters[i]; var parameterType = parameter.ParameterType.GetTypeSyntax(); var indexArg = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i))); var arg = SF.CastExpression( parameterType, SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg)); parameters.Add(arg); } // Invoke the method. var grainMethodCall = SF.InvocationExpression(castGrain.Member(method.Name)) .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray()); if (method.ReturnType == typeof(void)) { var completed = (Expression <Func <Task <object> > >)(() => TaskUtility.Completed()); return(new StatementSyntax[] { SF.ExpressionStatement(grainMethodCall), SF.ReturnStatement(completed.Invoke()) }); } //// Generate a Task wrapper for a query method //if (GrainInterfaceUtils.IsQueryType(method.ReturnType)) //{ // var TaskFromResult = SF.InvocationExpression( // SF.MemberAccessExpression( // SyntaxKind.SimpleMemberAccessExpression, // SF.IdentifierName("global::System.Threading.Tasks.Task"), // SF.IdentifierName("FromResult")), // SF.ArgumentList(SF.SeparatedList(new[] { SF.Argument(grainMethodCall) }))); // return new StatementSyntax[] //{ // SF.ReturnStatement(SF.InvocationExpression(TaskFromResult.Member((Task _) => _.Box()))) //}; //} // The invoke method expects a Task<object>, so we need to upcast the returned value. // For methods which do not return a value, the Box extension method returns a meaningless value. return(new StatementSyntax[] { SF.ReturnStatement(SF.InvocationExpression(grainMethodCall.Member((Task _) => _.Box()))) }); }
private BlockSyntax GeneratedSerializerForBlock(GeneratedSerializerRW writeOp) { var elementAccess = SF.ElementAccessExpression( Basics.SimpleMemberAccess(Basics.WriteInputInVariableIdentifierName, SF.IdentifierName(MemberDecl.DeclSymbol.Name)), SF.BracketedArgumentList().AddArguments(SF.Argument(ForIndexId))); return(SF.Block(writeOp.GenerateWrite(ClassSymbol, MemberDecl, elementAccess))); }
private MemberDeclarationSyntax ExplicitInterfaceMember() { var decoratedValueTypeSyntax = ValueTypeSyntax; if (Symbol.ReturnsByRef) { decoratedValueTypeSyntax = F.RefType(decoratedValueTypeSyntax); } else if (Symbol.ReturnsByRefReadonly) { decoratedValueTypeSyntax = F.RefType(decoratedValueTypeSyntax).WithReadOnlyKeyword(F.Token(SyntaxKind.ReadOnlyKeyword)); } var mockedIndexer = F.IndexerDeclaration(decoratedValueTypeSyntax) .WithParameterList(KeyType.BuildParameterList()) .WithExplicitInterfaceSpecifier(F.ExplicitInterfaceSpecifier(TypesForSymbols.ParseName(InterfaceSymbol))); var arguments = KeyType.BuildArgumentList(); if (Symbol.IsReadOnly) { ExpressionSyntax elementAccess = F.ElementAccessExpression(F.IdentifierName(MemberMockName)) .WithExpressionsAsArgumentList(arguments); if (Symbol.ReturnsByRef || Symbol.ReturnsByRefReadonly) { elementAccess = TypesForSymbols.WrapByRef(elementAccess, ValueTypeSyntax); } mockedIndexer = mockedIndexer.WithExpressionBody(F.ArrowExpressionClause(elementAccess)) .WithSemicolonToken(F.Token(SyntaxKind.SemicolonToken)); } else { if (!Symbol.IsWriteOnly) { mockedIndexer = mockedIndexer.AddAccessorListAccessors(F.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithExpressionBody(F.ArrowExpressionClause(F.ElementAccessExpression(F.IdentifierName(MemberMockName)) .WithExpressionsAsArgumentList(arguments))) .WithSemicolonToken(F.Token(SyntaxKind.SemicolonToken)) ); } if (!Symbol.IsReadOnly) { mockedIndexer = mockedIndexer.AddAccessorListAccessors(F.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithExpressionBody(F.ArrowExpressionClause( F.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, F.ElementAccessExpression(F.IdentifierName(MemberMockName)).WithExpressionsAsArgumentList(arguments), F.IdentifierName("value")))) .WithSemicolonToken(F.Token(SyntaxKind.SemicolonToken))); } } return(mockedIndexer); }
/// <summary> /// Generates syntax to invoke a method on a grain. /// </summary> /// <param name="grainType"> /// The grain type. /// </param> /// <param name="grain"> /// The grain instance expression. /// </param> /// <param name="method"> /// The method. /// </param> /// <param name="arguments"> /// The arguments expression. /// </param> /// <returns> /// Syntax to invoke a method on a grain. /// </returns> private static StatementSyntax[] GenerateInvokeForMethod( Type grainType, IdentifierNameSyntax grain, MethodInfo method, ExpressionSyntax arguments) { var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain)); // Construct expressions to retrieve each of the method's parameters. var parameters = new List <ExpressionSyntax>(); var methodParameters = method.GetParameters().ToList(); for (var i = 0; i < methodParameters.Count; i++) { var parameter = methodParameters[i]; var parameterType = parameter.ParameterType.GetTypeSyntax(); var indexArg = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i))); var arg = SF.CastExpression( parameterType, SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg)); parameters.Add(arg); } // Invoke the method. var grainMethodCall = SF.InvocationExpression(castGrain.Member(method.Name)) .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray()); // For void methods, invoke the method and return a completed task. if (method.ReturnType == typeof(void)) { var completed = (Expression <Func <Task <object> > >)(() => TaskUtility.Completed()); return(new StatementSyntax[] { SF.ExpressionStatement(grainMethodCall), SF.ReturnStatement(completed.Invoke()) }); } // For methods which return the expected type, Task<object>, simply return that. if (method.ReturnType == typeof(Task <object>)) { return(new StatementSyntax[] { SF.ReturnStatement(grainMethodCall) }); } // The invoke method expects a Task<object>, so we need to upcast the returned value. // For methods which do not return a value, the Box extension method returns a meaningless value. return(new StatementSyntax[] { SF.ReturnStatement(SF.InvocationExpression(grainMethodCall.Member((Task _) => _.Box()))) }); }
/// <summary> /// Generates syntax to invoke a method on a grain. /// </summary> /// <param name="grainType"> /// The grain type. /// </param> /// <param name="grain"> /// The grain instance expression. /// </param> /// <param name="method"> /// The method. /// </param> /// <param name="arguments"> /// The arguments expression. /// </param> /// <returns> /// Syntax to invoke a method on a grain. /// </returns> private static StatementSyntax[] GenerateInvokeForMethod( Type grainType, IdentifierNameSyntax grain, MethodInfo method, ExpressionSyntax arguments) { var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain)); // Construct expressions to retrieve each of the method's parameters. var parameters = new List <ExpressionSyntax>(); var methodParameters = method.GetParameters().ToList(); for (var i = 0; i < methodParameters.Count; i++) { var parameter = methodParameters[i]; var parameterType = parameter.ParameterType.GetTypeSyntax(); var indexArg = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i))); var arg = SF.CastExpression( parameterType, SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg)); parameters.Add(arg); } // If the method is a generic method definition, use the generic method invoker field to invoke the method. if (method.IsGenericMethodDefinition) { var invokerFieldName = GetGenericMethodInvokerFieldName(method); var invokerCall = SF.InvocationExpression( SF.IdentifierName(invokerFieldName) .Member((GenericMethodInvoker invoker) => invoker.Invoke(null, null))) .AddArgumentListArguments(SF.Argument(grain), SF.Argument(arguments)); return(new StatementSyntax[] { SF.ReturnStatement(SF.AwaitExpression(invokerCall)) }); } // Invoke the method. var grainMethodCall = SF.InvocationExpression(castGrain.Member(method.Name)) .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray()); // For void methods, invoke the method and return null. if (method.ReturnType == typeof(void)) { return(new StatementSyntax[] { SF.ExpressionStatement(grainMethodCall), SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression)) }); } // For methods which return non-generic Task, await the method and return null. if (method.ReturnType == typeof(Task)) { return(new StatementSyntax[] { SF.ExpressionStatement(SF.AwaitExpression(grainMethodCall)), SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression)) }); } if (method.ReturnType.IsGenericType && method.ReturnType.GetGenericTypeDefinition().FullName == "System.Threading.Tasks.ValueTask`1") { var convertToTaskResult = SF.IdentifierName("AsTask"); // Converting ValueTask method result to Task since "Invoke" method should return Task. // Temporary solution. Need to change when Orleans will be using ValueTask instead of Task. grainMethodCall = SF.InvocationExpression( SF.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, SF.ExpressionStatement(grainMethodCall).Expression, convertToTaskResult)); } return(new StatementSyntax[] { SF.ReturnStatement(SF.AwaitExpression(grainMethodCall)) }); }
/// <summary> /// Generates syntax to invoke a method on a grain. /// </summary> /// <param name="grainType"> /// The grain type. /// </param> /// <param name="grain"> /// The grain instance expression. /// </param> /// <param name="method"> /// The method. /// </param> /// <param name="arguments"> /// The arguments expression. /// </param> /// <returns> /// Syntax to invoke a method on a grain. /// </returns> private static StatementSyntax[] GenerateInvokeForMethod( Type grainType, IdentifierNameSyntax grain, MethodInfo method, ExpressionSyntax arguments) { var castGrain = SF.ParenthesizedExpression(SF.CastExpression(grainType.GetTypeSyntax(), grain)); // Construct expressions to retrieve each of the method's parameters. var parameters = new List <ExpressionSyntax>(); var methodParameters = method.GetParameters().ToList(); for (var i = 0; i < methodParameters.Count; i++) { var parameter = methodParameters[i]; var parameterType = parameter.ParameterType.GetTypeSyntax(); var indexArg = SF.Argument(SF.LiteralExpression(SyntaxKind.NumericLiteralExpression, SF.Literal(i))); var arg = SF.CastExpression( parameterType, SF.ElementAccessExpression(arguments).AddArgumentListArguments(indexArg)); parameters.Add(arg); } // If the method is a generic method definition, use the generic method invoker field to invoke the method. if (method.IsGenericMethodDefinition) { var invokerFieldName = GetGenericMethodInvokerFieldName(method); var invokerCall = SF.InvocationExpression( SF.IdentifierName(invokerFieldName) .Member((GenericMethodInvoker invoker) => invoker.Invoke(null, null))) .AddArgumentListArguments(SF.Argument(grain), SF.Argument(arguments)); return(new StatementSyntax[] { SF.ReturnStatement(SF.AwaitExpression(invokerCall)) }); } // Invoke the method. var grainMethodCall = SF.InvocationExpression(castGrain.Member(method.Name)) .AddArgumentListArguments(parameters.Select(SF.Argument).ToArray()); // For void methods, invoke the method and return null. if (method.ReturnType == typeof(void)) { return(new StatementSyntax[] { SF.ExpressionStatement(grainMethodCall), SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression)) }); } // For methods which return non-generic Task, await the method and return null. if (method.ReturnType == typeof(Task)) { return(new StatementSyntax[] { SF.ExpressionStatement(SF.AwaitExpression(grainMethodCall)), SF.ReturnStatement(SF.LiteralExpression(SyntaxKind.NullLiteralExpression)) }); } return(new StatementSyntax[] { SF.ReturnStatement(SF.AwaitExpression(grainMethodCall)) }); }