예제 #1
0
        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))));
        }
예제 #2
0
        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)));
        }
예제 #3
0
        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))));
        }