示例#1
0
        MethodDeclarationSyntax RewriteMethod(MethodDeclarationSyntax inMethodSyntax, SemanticModel semanticModel)
        {
            var inMethodSymbol = semanticModel.GetDeclaredSymbol(inMethodSyntax);

            //Log.LogMessage("Method {0}: {1}", inMethodInfo.Symbol.Name, inMethodInfo.Symbol.);

            var outMethodName = inMethodSyntax.Identifier.Text + "Async";

            _log.Debug("  Rewriting method {0} to {1}", inMethodSymbol.Name, outMethodName);

            // Visit all method invocations inside the method, rewrite them to async if needed
            var rewriter = new MethodInvocationRewriter(_log, semanticModel, _excludedTypes);
            var outMethod = (MethodDeclarationSyntax)rewriter.Visit(inMethodSyntax);

            // Method signature
            outMethod = outMethod
                .WithIdentifier(SyntaxFactory.Identifier(outMethodName))
                .WithAttributeLists(new SyntaxList<AttributeListSyntax>())
                .WithModifiers(inMethodSyntax.Modifiers
                  .Add(SyntaxFactory.Token(SyntaxKind.AsyncKeyword))
                  //.Remove(SyntaxFactory.Token(SyntaxKind.OverrideKeyword))
                  //.Remove(SyntaxFactory.Token(SyntaxKind.NewKeyword))
                );

            // Transform return type adding Task<>
            var returnType = inMethodSyntax.ReturnType.ToString();
            outMethod = outMethod.WithReturnType(SyntaxFactory.ParseTypeName(
                returnType == "void" ? "Task" : $"Task<{returnType}>")
            );

            // Remove the override and new attributes. Seems like the clean .Remove above doesn't work...
            for (var i = 0; i < outMethod.Modifiers.Count;)
            {
                var text = outMethod.Modifiers[i].Text;
                if (text == "override" || text == "new") {
                    outMethod = outMethod.WithModifiers(outMethod.Modifiers.RemoveAt(i));
                    continue;
                }
                i++;
            }

            var attr = inMethodSymbol.GetAttributes().Single(a => a.AttributeClass.Name == "RewriteAsyncAttribute");

            if (attr.ConstructorArguments.Length > 0 && (bool) attr.ConstructorArguments[0].Value)
            {
                outMethod = outMethod.AddModifiers(SyntaxFactory.Token(SyntaxKind.OverrideKeyword));
            }

            return outMethod;
        }
示例#2
0
        MethodDeclarationSyntax RewriteMethod(MethodDeclarationSyntax inMethodSyntax, SemanticModel semanticModel, ITypeSymbol cancellationTokenSymbol)
        {
            var inMethodSymbol = semanticModel.GetDeclaredSymbol(inMethodSyntax);
            // ASYNC_TODO: Find all references

            //Log.LogMessage("Method {0}: {1}", inMethodInfo.Symbol.Name, inMethodInfo.Symbol.);

            var outMethodName = inMethodSyntax.Identifier.Text + "Async";

            _log.Debug("  Rewriting method {0} to {1}", inMethodSymbol.Name, outMethodName);

            // Visit all method invocations inside the method, rewrite them to async if needed
            var rewriter  = new MethodInvocationRewriter(_log, semanticModel, excludedTypesSet, cancellationTokenSymbol, GenerateConfigureAwait);
            var outMethod = (MethodDeclarationSyntax)rewriter.Visit(inMethodSyntax);

            // Method signature
            outMethod = outMethod
                        .WithIdentifier(SyntaxFactory.Identifier(outMethodName))
                        .WithAttributeLists(new SyntaxList <AttributeListSyntax>());

            if (inMethodSyntax.FirstAncestorOrSelf <TypeDeclarationSyntax>().Kind() == SyntaxKind.InterfaceDeclaration)
            {
                outMethod = outMethod
                            .WithModifiers(inMethodSyntax.Modifiers);
            }
            else
            {
                outMethod = outMethod
                            .WithModifiers(inMethodSyntax.Modifiers
                                           .Add(SyntaxFactory.Token(SyntaxKind.AsyncKeyword)));
            }
            //.Remove(SyntaxFactory.Token(SyntaxKind.OverrideKeyword))
            //.Remove(SyntaxFactory.Token(SyntaxKind.NewKeyword))

            // Insert the cancellation token into the parameter list at the right place
            outMethod = outMethod
                        .WithParameterList(SyntaxFactory.ParameterList(inMethodSyntax.ParameterList.Parameters.Insert(
                                                                           inMethodSyntax.ParameterList.Parameters.TakeWhile(p => p.Default == null && !p.Modifiers.Any(m => m.IsKind(SyntaxKind.ParamsKeyword))).Count(),
                                                                           SyntaxFactory.Parameter(
                                                                               SyntaxFactory.List <AttributeListSyntax>(),
                                                                               SyntaxFactory.TokenList(),
                                                                               SyntaxFactory.ParseTypeName("CancellationToken"),
                                                                               SyntaxFactory.Identifier("cancellationToken"),
                                                                               null
                                                                               ))));

            // Transform return type adding Task<>
            var returnType = inMethodSyntax.ReturnType.ToString();

            outMethod = outMethod.WithReturnType(SyntaxFactory.ParseTypeName(
                                                     returnType == "void" ? "Task" : $"Task<{returnType}>")
                                                 );

            // Remove the override and new attributes. Seems like the clean .Remove above doesn't work...
            for (var i = 0; i < outMethod.Modifiers.Count;)
            {
                var text = outMethod.Modifiers[i].Text;
                if (text == "override" || text == "new")
                {
                    outMethod = outMethod.WithModifiers(outMethod.Modifiers.RemoveAt(i));
                    continue;
                }
                i++;
            }

            var attr = inMethodSymbol.GetAttributes().Single(a => a.AttributeClass.Name == "RewriteAsyncAttribute");

            if (attr.ConstructorArguments.Length > 0 && (bool)attr.ConstructorArguments[0].Value)
            {
                outMethod = outMethod.AddModifiers(SyntaxFactory.Token(SyntaxKind.OverrideKeyword));
            }

            return(outMethod);
        }
示例#3
0
        MethodDeclarationSyntax RewriteMethodAsyncWithCancellationToken(MethodDeclarationSyntax inMethodSyntax, SemanticModel semanticModel)
        {
            var inMethodSymbol = semanticModel.GetDeclaredSymbol(inMethodSyntax);

            //Log.LogMessage("Method {0}: {1}", inMethodInfo.Symbol.Name, inMethodInfo.Symbol.);

            var outMethodName = inMethodSyntax.Identifier.Text + "Async";

            _log.Info("  Rewriting method {0} to {1}", inMethodSymbol.Name, outMethodName);

            // Visit all method invocations inside the method, rewrite them to async if needed
            var rewriter  = new MethodInvocationRewriter(_log, semanticModel, _excludedTypes, _cancellationTokenSymbol);
            var outMethod = (MethodDeclarationSyntax)rewriter.Visit(inMethodSyntax);

            // Method signature
            outMethod = outMethod
                        .WithIdentifier(SyntaxFactory.Identifier(outMethodName))
                        .WithAttributeLists(new SyntaxList <AttributeListSyntax>())
                        .WithModifiers(inMethodSyntax.Modifiers
                                       .Add(SyntaxFactory.Token(SyntaxKind.AsyncKeyword))
                        //.Remove(SyntaxFactory.Token(SyntaxKind.OverrideKeyword))
                        //.Remove(SyntaxFactory.Token(SyntaxKind.NewKeyword))
                                       )
                        // Insert the cancellation token into the parameter list at the right place
                        .WithParameterList(SyntaxFactory.ParameterList(inMethodSyntax.ParameterList.Parameters.Insert(
                                                                           inMethodSyntax.ParameterList.Parameters.TakeWhile(p => p.Default == null && !p.Modifiers.Any(m => m.IsKind(SyntaxKind.ParamsKeyword))).Count(),
                                                                           SyntaxFactory.Parameter(
                                                                               SyntaxFactory.List <AttributeListSyntax>(),
                                                                               SyntaxFactory.TokenList(),
                                                                               SyntaxFactory.ParseTypeName("CancellationToken"),
                                                                               SyntaxFactory.Identifier("cancellationToken"),
                                                                               null
                                                                               ))));

            // Transform return type adding Task<>
            var returnType = inMethodSyntax.ReturnType.ToString();

            outMethod = outMethod.WithReturnType(SyntaxFactory.ParseTypeName(
                                                     returnType == "void" ? "Task" : $"Task<{returnType}>")
                                                 );

            var parentContainsAsyncMethod            = GetAllMembers(inMethodSymbol.ReceiverType.BaseType).Any(c => c.Name == outMethodName);
            var parentContainsMethodWithRewriteAsync = GetAllMembers(inMethodSymbol.ReceiverType.BaseType)
                                                       .Where(c => c.Name == inMethodSyntax.Identifier.Text)
                                                       .Any(m => m.GetAttributes().Any(a => a.AttributeClass.Name.Contains("RewriteAsync")));

            // Remove the override and new attributes. Seems like the clean .Remove above doesn't work...
            if (!(parentContainsAsyncMethod || parentContainsMethodWithRewriteAsync))
            {
                for (var i = 0; i < outMethod.Modifiers.Count;)
                {
                    var text = outMethod.Modifiers[i].Text;
                    if (text == "override" || text == "new")
                    {
                        outMethod = outMethod.WithModifiers(outMethod.Modifiers.RemoveAt(i));
                        continue;
                    }
                    i++;
                }
            }

            var attr = inMethodSymbol.GetAttributes().Single(a => a.AttributeClass.Name.EndsWith("RewriteAsyncAttribute"));

            if (attr.ConstructorArguments.Length > 0 && (bool)attr.ConstructorArguments[0].Value)
            {
                for (var i = 0; i < outMethod.Modifiers.Count;)
                {
                    var text = outMethod.Modifiers[i].Text;

                    if (text == "public" || text == "private" || text == "protected")
                    {
                        outMethod = outMethod.WithModifiers(outMethod.Modifiers.RemoveAt(i));
                        continue;
                    }

                    i++;
                }

                outMethod = outMethod.WithModifiers(outMethod.Modifiers.Insert(0, SyntaxFactory.Token(SyntaxKind.PublicKeyword)));
            }

            return(outMethod);
        }