Example #1
0
        private static MemberDeclarationSyntax GenerateSetTargetMethod(
            LibraryTypes libraryTypes,
            IInvokableInterfaceDescription interfaceDescription,
            TargetFieldDescription targetField)
        {
            var type            = IdentifierName("TTargetHolder");
            var typeToken       = Identifier("TTargetHolder");
            var holderParameter = Identifier("holder");
            var holder          = IdentifierName("holder");

            var getTarget = InvocationExpression(
                MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    holder,
                    GenericName(interfaceDescription.IsExtension ? "GetExtension" : "GetTarget")
                    .WithTypeArgumentList(
                        TypeArgumentList(
                            SingletonSeparatedList(interfaceDescription.InterfaceType.ToTypeSyntax())))))
                            .WithArgumentList(ArgumentList());

            var body =
                AssignmentExpression(
                    SyntaxKind.SimpleAssignmentExpression,
                    ThisExpression().Member(targetField.FieldName),
                    getTarget);

            return(MethodDeclaration(libraryTypes.Void.ToTypeSyntax(), "SetTarget")
                   .WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter(typeToken))))
                   .WithParameterList(ParameterList(SingletonSeparatedList(Parameter(holderParameter).WithType(type))))
                   .WithExpressionBody(ArrowExpressionClause(body))
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword))));
        }
Example #2
0
        private static MemberDeclarationSyntax GenerateGetTargetMethod(
            TargetFieldDescription targetField)
        {
            var type      = IdentifierName("TTarget");
            var typeToken = Identifier("TTarget");

            var body = CastExpression(type, ThisExpression().Member(targetField.FieldName));

            return(MethodDeclaration(type, "GetTarget")
                   .WithTypeParameterList(TypeParameterList(SingletonSeparatedList(TypeParameter(typeToken))))
                   .WithParameterList(ParameterList())
                   .WithExpressionBody(ArrowExpressionClause(body))
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.OverrideKeyword))));
        }
Example #3
0
        private static MemberDeclarationSyntax GenerateInvokeInnerMethod(
            LibraryTypes libraryTypes,
            MethodDescription method,
            List <FieldDescription> fields,
            TargetFieldDescription target)
        {
            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);
            }

            return(MethodDeclaration(method.Method.ReturnType.ToTypeSyntax(), "InvokeInner")
                   .WithParameterList(ParameterList())
                   .WithExpressionBody(ArrowExpressionClause(InvocationExpression(methodCall, ArgumentList(args))))
                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken))
                   .WithModifiers(TokenList(Token(SyntaxKind.ProtectedKeyword), Token(SyntaxKind.OverrideKeyword))));
        }
Example #4
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))));
        }