Ich arbeite an einem kleinen Roslyn-Projekt, das das Ändern des Syntaxbaums und das Schreiben von Änderungen in die Datei enthält. Ich habe mit dem Standalone-Code-Analyzer begonnen und möchte es als Befehlszeilen-App erstellen. Ich bin jedoch auf eine Herausforderung gestoßen. Arbeiten mit: Find classes which derive from a specific base class with Roslyn teilweise, und vor allem mit: https://github.com/dotnet/roslyn/wiki/Getting-Started-C%23-Syntax-Analysis ich dieses kleine Projekt erstellt haben:Suche nach allen nicht vererbenden C# -Klassen mit Roslyn und Änderung der Vererbung vom Basisobjekt (javaähnlich)
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
throw new ArgumentException();
SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0]));
var root = (CompilationUnitSyntax) tree.GetRoot();
var classes = from ClassDeclarationSyntax in root.DescendantNodesAndSelf() select ClassDeclarationSyntax;
foreach (var c in classes)
{
if (/*Not inheriting*/)
{
/*Add inherition*/
}
}
/*Write changes to file*/
}
catch (Exception e)
{
Console.WriteLine("Fatal error ocured.");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
Als Kommentare in Code Staaten, muss ich prüfen, ob Klasse von etwas erbt oder nicht (und wählen zweite Option) dann ändern Parse-Baum und zuletzt schreibe es in Datei, für jetzt wäre ich froh zu wissen, wie man "nicht Vererbung" nur überprüfen, obwohl alle Richtungen für Schritt zwei und drei sind auch willkommen. Datei zu analysieren und Änderung wird durch Pfad als Programmparameter hier geliefert:
if (args.Length < 1)
throw new ArgumentException();
SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0]));
SOLUTION
Mit Unterstützung erhielt Antworten, die ich gekommen bin oben mit App arbeiten. Hier ist mein Code, vielleicht nicht perfekt, aber arbeiten
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
throw new ArgumentException();
SyntaxTree tree = CSharpSyntaxTree.ParseText(File.ReadAllText(args[0]));
var root = (CompilationUnitSyntax) tree.GetRoot();
IdentifierNameSyntax iname = SyntaxFactory.IdentifierName("Object");
BaseTypeSyntax bts = SyntaxFactory.SimpleBaseType(iname);
SeparatedSyntaxList<BaseTypeSyntax> ssl = new SeparatedSyntaxList<BaseTypeSyntax>();
ssl = ssl.Add(bts);
BaseListSyntax bls = SyntaxFactory.BaseList(ssl);
bool x = true;
while(x) //Way to handle all nodes due to impossibility to handle more than one in foreach
{
foreach (var c in root.DescendantNodesAndSelf())
{
x = false;
var classDeclaration = c as ClassDeclarationSyntax;
if (classDeclaration == null)
continue;
if (classDeclaration.BaseList != null) //Inherits
continue;
else //Not inherits
{
root = root.ReplaceNode(classDeclaration, classDeclaration.WithBaseList(bls));
x = true;
break;
}
}
}
if (args.Length > 1) //Write to given file
using (var sw = new StreamWriter(File.Open(args[1], FileMode.Open)))
{
root.WriteTo(sw);
}
else //Overwrite source
using (var sw = new StreamWriter(File.Open(args[0], FileMode.Open)))
{
root.WriteTo(sw);
}
}
catch (Exception e)
{
Console.WriteLine("Fatal error ocured.");
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
}
}
Ist es nicht nur simplier 'BaseList' zu' null' zu vergleichen? Von dem, was ich experimentiert habe, funktioniert es auch. –
@RobertGrzesiak Nun, ich weiß nicht, Beispiel, wenn der Vergleich zwischen 'BaseList' und' null' nicht funktionieren würde, aber ich habe keine Dokumentation gefunden, die erklärt, dass 'BaseList' nicht null sein kann, wenn Klasse Basisklasse oder hat implementiert Schnittstellen. Ich bin also nicht sicher, ob dieser Vergleich in allen Fällen funktionieren wird oder nicht. –
Sie haben völlig Recht 'BaseList' existiert nur, wenn die Klasse etwas erbt oder implementiert. Also 'BaseList! = Null' sollte gut funktionieren von dem, was ich verstehe. –