Reputation: 301
I have this working code that will load a .cs file into the Roslyn SyntaxTree class, create a new PropertyDeclarationSyntax, insert it into the class, and re-write the .cs file. I'm doing this as a learning experience as well as some potential future ideas. I found that there doesn't really seem to be a full Roslyn API documentation anywhere and I'm unsure if I am doing this efficiently. My main concern is where I call 'root.ToFullString()' - whilst it works, is this the right way to do it?
using System.IO;
using System.Linq;
using Roslyn.Compilers;
using Roslyn.Compilers.CSharp;
class RoslynWrite
{
public RoslynWrite()
{
const string csFile = "MyClass.cs";
// Parse .cs file using Roslyn SyntaxTree
var syntaxTree = SyntaxTree.ParseFile(csFile);
var root = syntaxTree.GetRoot();
// Get the first class from the syntax tree
var myClass = root.DescendantNodes().OfType<ClassDeclarationSyntax>().First();
// Create a new property : 'public bool MyProperty { get; set; }'
var myProperty = Syntax.PropertyDeclaration(Syntax.ParseTypeName("bool"), "MyProperty")
.WithModifiers(Syntax.Token(SyntaxKind.PublicKeyword))
.WithAccessorList(
Syntax.AccessorList(Syntax.List(
Syntax.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
.WithSemicolonToken(Syntax.Token(SyntaxKind.SemicolonToken)),
Syntax.AccessorDeclaration(SyntaxKind.SetAccessorDeclaration)
.WithSemicolonToken(Syntax.Token(SyntaxKind.SemicolonToken)))));
// Add the new property to the class
var updatedClass = myClass.AddMembers(myProperty);
// Update the SyntaxTree and normalize whitespace
var updatedRoot = root.ReplaceNode(myClass, updatedClass).NormalizeWhitespace();
// Is this the way to write the syntax tree? ToFullString?
File.WriteAllText(csFile, updatedRoot.ToFullString());
}
}
Upvotes: 16
Views: 6627
Reputation: 11615
Answered on the Roslyn CTP forum in this post:
That approach is generally fine, though if you are worried about allocating a string for the text of the entire file, you should probably use IText.Write(TextWriter) instead of ToFullString().
Keep in mind that it's possible to generate trees that will not round-trip through the parser. For example, if you generated something that violates precedence rules, the SyntaxTree construction APIs won't catch that.
Upvotes: 3