Ich habe folgende Beispielklassen:Transforming Kette fließend Ausdrücke mit Roslyn
// Sample fluent style class
namespace Fluent
{
public class FluentSample
{
private readonly IList<string> _options;
public FluentSample()
{
_options = new List<string>();
}
public static FluentSample Build()
{
return new FluentSample();
}
public FluentSample WithOption(string option)
{
_options.Add(option);
return this;
}
}
}
// Sample class that uses the one above
public class FooSample
{
public void Build()
{
FluentSample.Build()
.WithOption("uppercase")
.WithOption("trim")
.WithOption("concat");
}
}
Nehmen wir an, ich den Code zu transformieren möchten, dass die FluentSample
-Klasse verwendet und ersetzen FluentSample.Build()
mit Fluent.FluentSample.Build().WithOption("addnewline")
. Um das zu tun, muss ich sicherstellen, dass es wirklich diese Klasse aufruft (und nicht eine andere mit dem gleichen Namen), was eine gewisse Symbolbindung erfordert.
Aus der Syntax Visualizer Fenster habe ich, dass es im Grunde ein InvocationExpressionSyntax
Knoten gefunden, so dass ich zwingende VisitInvocationExpression
von CSharpSyntaxRewriter
:
public class Rewritter : CSharpSyntaxRewriter
{
private readonly SemanticModel SemanticModel;
public Rewritter(SemanticModel semanticModel)
{
SemanticModel = semanticModel;
}
public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
{
var symbol = SemanticModel.GetSymbolInfo(node).Symbol;
}
}
die Symbole erhalte ich jedoch die vielen WithOption
Anrufe . Die Syntaxanalyse zeigt, dass es eine Kette von Ausdrücken enthält, die nur zu mehr und mehr WithOption
s führt. Wie kann ich überprüfen, ob dies wirklich ein Aufruf an Fluent.FluentSample
ist und die Transformation anwenden?
Der ursprüngliche Code ist fast genau so, so dass die Aussagen immer in fließendem Stil sein werden.
Wo genau ist „am Ende des Aufrufs“? Denken Sie daran, dass Leute 'var x = new FluentSample() schreiben können; x.WithOption ("a"); (x.WithOption ("b")). MitOption (c); '. Es wäre viel einfacher, wenn Sie sagen würden: "Wie kann ich überprüfen, ob es sich wirklich um einen Aufruf von' Fluent.FluentSample.Build() 'handelt und ersetzen Sie es durch' Fluent.FluentSample.Build(). MitOption ("addnewline") ' –
Sie haben Recht, ich habe nicht darüber nachgedacht, es so zu formulieren. Außerdem wird der Code immer in fließendem Stil sein, keine Notwendigkeit, Randfälle abzudecken. Ich habe die Frage bearbeitet, um sie weiter zu klären. –