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)))); }
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)))); }
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)))); }
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)))); }