private static MemberDeclarationSyntax GenerateResultProperty( LibraryTypes libraryTypes, ResultFieldDescription resultField) { var getter = AccessorDeclaration(SyntaxKind.GetAccessorDeclaration) .WithExpressionBody( ArrowExpressionClause( CastExpression( libraryTypes.Object.ToTypeSyntax(), ThisExpression().Member(resultField.FieldName)))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); var setter = AccessorDeclaration(SyntaxKind.SetAccessorDeclaration) .WithExpressionBody( ArrowExpressionClause( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, ThisExpression().Member(resultField.FieldName), CastExpression(resultField.FieldType.ToTypeSyntax(), IdentifierName("value"))))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); return(PropertyDeclaration(libraryTypes.Object.ToTypeSyntax(), "Result") .WithAccessorList( AccessorList() .AddAccessors( getter, setter)) .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword)))); }
private static MemberDeclarationSyntax GenerateGetResultProperty( LibraryTypes libraryTypes, ResultFieldDescription resultField) { var type = IdentifierName("TResult"); var typeToken = Identifier("TResult"); ExpressionSyntax body; if (resultField != null) { body = CastExpression( type, CastExpression(libraryTypes.Object.ToTypeSyntax(), ThisExpression().Member(resultField.FieldName))); } else { body = ThrowExpression( ObjectCreationExpression(libraryTypes.InvalidOperationException.ToTypeSyntax()) .WithArgumentList( ArgumentList( SingletonSeparatedList( Argument("Method does not have a return value.".GetLiteralExpression()))))); } return(MethodDeclaration(type, "GetResult") .WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter(typeToken)))) .WithParameterList(ParameterList()) .WithExpressionBody(ArrowExpressionClause(body)) .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword))) .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))); }
private static MemberDeclarationSyntax GenerateInvokeMethod( LibraryTypes libraryTypes, MethodDescription method, List <FieldDescription> fields, TargetFieldDescription target, ResultFieldDescription result) { var body = new List <StatementSyntax>(); var resultTask = IdentifierName("resultTask"); // C# var resultTask = this.target.{Method}({params}); var args = SeparatedList( fields.OfType <MethodParameterFieldDescription>() .OrderBy(p => p.ParameterOrdinal) .Select(p => Argument(ThisExpression().Member(p.FieldName)))); ExpressionSyntax methodCall; if (method.Method.TypeParameters.Length > 0) { methodCall = MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, ThisExpression().Member(target.FieldName), GenericName( Identifier(method.Method.Name), TypeArgumentList( SeparatedList <TypeSyntax>( method.Method.TypeParameters.Select(p => IdentifierName(p.Name)))))); } else { methodCall = ThisExpression().Member(target.FieldName).Member(method.Method.Name); } body.Add( LocalDeclarationStatement( VariableDeclaration( ParseTypeName("var"), SingletonSeparatedList( VariableDeclarator(resultTask.Identifier) .WithInitializer( EqualsValueClause( InvocationExpression( methodCall, ArgumentList(args)))))))); // C#: if (resultTask.IsCompleted) // Even if it failed. // C#: { // C#: this.result = resultTask.GetAwaiter().GetResult(); // C#: return default; // default(ValueTask) is a successfully completed ValueTask. // C#: } var synchronousCompletionBody = new List <StatementSyntax>(); if (result != null) { synchronousCompletionBody.Add( ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, ThisExpression().Member(result.FieldName), InvocationExpression( InvocationExpression(resultTask.Member("GetAwaiter")).Member("GetResult"))))); } synchronousCompletionBody.Add(ReturnStatement(DefaultExpression(libraryTypes.ValueTask.ToTypeSyntax()))); body.Add(IfStatement(resultTask.Member("IsCompleted"), Block(synchronousCompletionBody))); // C#: async ValueTask InvokeAsync(ValueTask<int> asyncValue) // C#: { // C#: this.result = await asyncValue.ConfigureAwait(false); // C#: } var invokeAsyncParam = IdentifierName("asyncTask"); var invokeAsyncBody = new List <StatementSyntax>(); var awaitExpression = AwaitExpression( InvocationExpression( invokeAsyncParam.Member("ConfigureAwait"), ArgumentList( SingletonSeparatedList(Argument(LiteralExpression(SyntaxKind.FalseLiteralExpression)))))); if (result != null) { invokeAsyncBody.Add( ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, ThisExpression().Member(result.FieldName), awaitExpression))); } else { invokeAsyncBody.Add(ExpressionStatement(AwaitExpression(invokeAsyncParam))); } var invokeAsync = LocalFunctionStatement(libraryTypes.ValueTask.ToTypeSyntax(), "InvokeAsync") .WithModifiers(TokenList(Token(SyntaxKind.AsyncKeyword))) .WithParameterList( ParameterList( SingletonSeparatedList( Parameter(invokeAsyncParam.Identifier).WithType(method.Method.ReturnType.ToTypeSyntax())))) .WithBody(Block(invokeAsyncBody)); // C#: return InvokeAsync(resultTask); body.Add( ReturnStatement( InvocationExpression( IdentifierName("InvokeAsync"), ArgumentList(SingletonSeparatedList(Argument(resultTask)))))); body.Add(invokeAsync); return(MethodDeclaration(libraryTypes.ValueTask.ToTypeSyntax(), "Invoke") .WithParameterList(ParameterList()) .WithBody(Block(body)) .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword)))); }