AOP with Roslyn–part 2

I want to transform code by injecting some simple code, like “Console.WriteLine(“method”)

So this code:

 

using System;
namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
              var dt=DateTime.Now;
        }
     }
}

 

should be modified to this code:

 

using System;

namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" + "\"Program_Main_6\"" + @");//this is automatically added
            var dt = DateTime.Now;
        }
    }
}

 
How I do the code: I derive from CSharpSyntaxRewriter and override the VisitMethodDeclaration  . I will construct a new node with the Console.WriteLine statement inserted

 

public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
        {


            if (node.Body == null || node.Body.Statements.Count == 0)
                return base.VisitMethodDeclaration(node);
            var parent = node.Parent as ClassDeclarationSyntax;
            if (parent == null)
                return base.VisitMethodDeclaration(node);

            var nameMethod = node.Identifier.Text;
            var nameClass = parent.Identifier.Text;
            Console.WriteLine(nameMethod);
            node = (MethodDeclarationSyntax)base.VisitMethodDeclaration(node);
            var lineStart = node.GetLocation().GetLineSpan().StartLinePosition;
            string nameVariable = $"{nameClass}_{nameMethod}_{lineStart.Line}";
            var cmd = SyntaxFactory.ParseStatement($"Console.WriteLine(\"{nameVariable}\");//this is automatically added");

            var blockWithNewStatements = new SyntaxList<StatementSyntax>();
            
            for (int i = node.Body.Statements.Count - 1; i >= 0; i--)
            {
                var st = node.Body.Statements[i];
                blockWithNewStatements = blockWithNewStatements.Insert(0, st);
            }

            blockWithNewStatements = blockWithNewStatements.Insert(0, cmd);

            var newBlock = SyntaxFactory.Block(blockWithNewStatements);

            var newMethod = SyntaxFactory.MethodDeclaration
                (node.AttributeLists, node.Modifiers, node.ReturnType,
                node.ExplicitInterfaceSpecifier, node.Identifier, node.TypeParameterList,
                node.ParameterList, node.ConstraintClauses,
                newBlock,
                node.ExpressionBody, node.SemicolonToken);


            var newNode = node.ReplaceNode(node, newMethod);

            return base.VisitMethodDeclaration(newNode);
        }

 

As test, I have created a TestMethodRewriterSimple that verifies that.

        [TestMethod]
        public void TestMethodRewriterSimple()
        {

            var rc = new RewriteCode();
            rc.Code = @"
using System;
namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
              var dt=DateTime.Now;
        }
     }
}";
            var result= rc.RewriteCodeMethod();
            var newCode = @"
using System;

namespace Test1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(" + "\"Program_Main_6\"" + @");//this is automatically added
            var dt = DateTime.Now;
        }
    }
}";
            Assert.AreEqual(newCode.Replace(Environment.NewLine,""), newCode.Replace(Environment.NewLine, ""));
        }
    }

You can find the code on https://github.com/ignatandrei/AOP_With_Roslyn