Estoy tratando de aprender Roslyn construyendo una aplicación existente pero simple desde cero, que parece ser una forma productiva de aprender esto. De todos modos, tengo el siguiente código:Agregar Propiedad auto-implementada a la clase usando Roslyn
var root = (CompilationUnitSyntax)document.GetSyntaxRoot();
// Add the namespace
var namespaceAnnotation = new SyntaxAnnotation();
root = root.WithMembers(
Syntax.NamespaceDeclaration(
Syntax.ParseName("ACO"))
.NormalizeWhitespace()
.WithAdditionalAnnotations(namespaceAnnotation));
document = document.UpdateSyntaxRoot(root);
// Add a class to the newly created namespace, and update the document
var namespaceNode = (NamespaceDeclarationSyntax)root
.GetAnnotatedNodesAndTokens(namespaceAnnotation)
.Single()
.AsNode();
var classAnnotation = new SyntaxAnnotation();
var baseTypeName = Syntax.ParseTypeName("System.Windows.Forms.Form");
SyntaxTokenList syntaxTokenList = new SyntaxTokenList()
{
Syntax.Token(SyntaxKind.PublicKeyword)
};
var newNamespaceNode = namespaceNode
.WithMembers(
Syntax.List<MemberDeclarationSyntax>(
Syntax.ClassDeclaration("MainForm")
.WithAdditionalAnnotations(classAnnotation)
.AddBaseListTypes(baseTypeName)
.WithModifiers(Syntax.Token(SyntaxKind.PublicKeyword))));
root = root.ReplaceNode(namespaceNode, newNamespaceNode).NormalizeWhitespace();
document = document.UpdateSyntaxRoot(root);
var attributes = Syntax.List(Syntax.AttributeDeclaration(Syntax.SeparatedList(Syntax.Attribute(Syntax.ParseName("STAThread")))));
// Find the class just created, add a method to it and update the document
var classNode = (ClassDeclarationSyntax)root
.GetAnnotatedNodesAndTokens(classAnnotation)
.Single()
.AsNode();
var syntaxList = Syntax.List<MemberDeclarationSyntax>(
Syntax.MethodDeclaration(
Syntax.ParseTypeName("void"), "Main")
.WithModifiers(Syntax.TokenList(Syntax.Token(SyntaxKind.PublicKeyword)))
.WithAttributes(attributes)
.WithBody(
Syntax.Block()));
syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));
var newClassNode = classNode
.WithMembers(syntaxList);
root = root.ReplaceNode(classNode, newClassNode).NormalizeWhitespace();
document = document.UpdateSyntaxRoot(root);
Que emite el siguiente código en el IDocument.
namespace ACO
{
public class MainForm : System.Windows.Forms.Form
{
[STAThread]
public void Main()
{
}
}
}
A pesar de que debe ser de la misma familia (nótese que trataron de añadir la propiedad Timer)
namespace ACO
{
public class MainForm : System.Windows.Forms.Form
{
public System.Windows.Forms.Timer Ticker {get; set;}
[STAThread]
public void Main()
{
}
}
}
Además, parece que el código que estoy escribiendo para un proceso tan simple parece excesivo. Además de mi pregunta principal, ¿pueden las personas ofrecer sugerencias sobre cómo puedo hacer esto de una manera más elegante? Tal vez un enlace a un blog, o fragmentos de código o algo así?
Resulta que tenía que cambiar esta línea:
syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));
Para esta línea:
syntaxList = syntaxList.Add(Syntax.PropertyDeclaration(Syntax.ParseTypeName("System.Windows.Forms.Timer"), "Ticker"));
Sin embargo, ahora consigo esta salida:
namespace ACO
{
public class MainForm : System.Windows.Forms.Form
{
[STAThread]
public void Main()
{
}
System.Windows.Forms.Timer Ticker
{
}
}
}
Ahora no obtengo el "get; set;" texto dentro de la propiedad. ¿Alguien sabe lo que me estoy perdiendo?
El recordatorio de la inmutabilidad me llevó a darse cuenta de lo que estaba haciendo mal, que he publicado a continuación. Haré una pregunta por separado sobre cómo realmente construir mi Árbol de sintaxis particular de abajo arriba. – Beaker
Aquí está el enlace a mi nueva pregunta sobre cómo construir mi Árbol de sintaxis desde cero como sugirió. http://stackoverflow.com/questions/11351977/roslyn-ctp-building-a-syntaxtree-from-the-ground-up – Beaker
En esa otra pregunta suya he agregado un enlace a una herramienta llamada Quoter que puede ayudar en la generación automática de las llamadas API de sintaxis de Roslyn para cualquier programa: http://blogs.msdn.com/b/kirillosenkov/archive/2012/07/22/roslyn-code-quoter-tool-generating-syntax-tree-api- calls-for-any-c-program.aspx –