Mehrere Änderungen gleichzeitig an einem SyntaxTree vornehmen

8

Ich möchte mehrere Modifikationen gleichzeitig an einem Roslyn-Syntaxbaum vornehmen, und zwar überall im selben Codebereich

%Vor%

jedoch ist nur die erste Modifikation erfolgreich. Es scheint, dass die erste Änderung alle Knoten um sie herum ändert, sodass die RemoveNodes -Methode nicht mehr toRemove in der resultierenden Struktur findet. Ich möchte wirklich nicht die Arbeit wiederholen, um toRemove in der neuen Struktur neu zu berechnen, und einen einzigen SyntaxRewriter zu verwenden, um all die Arbeit auszuführen (das Überschreiben der DefaultVisit -Methode) ist lächerlich langsam.

Wie kann ich tun, was ich will?

    
thecoop 17.11.2012, 21:56
quelle

1 Antwort

5

Bevor ich ein paar Alternativen anführe, ist Ihr Kommentar, dass ein SyntaxRewriter "lächerlich langsam" ist, etwas überraschend. Wenn du "langsam" sagst, meinst du "es ist viel Code zum schreiben" oder "macht es furchtbar"? Dies ist die schnellste (Ausführungszeit) Möglichkeit, mehrere Ersetzungen durchzuführen, und sowohl ReplaceNodes als auch RemoveNode verwenden intern einen Rewriter. Stellen Sie bei Leistungsproblemen sicher, dass Sie beim Implementieren von DefaultVisit nur untergeordnete Typen besuchen, wenn sich die Knoten, die Sie interessieren, unter dem Knoten befinden, für den sie aufgerufen werden. Der einfache Trick besteht darin, die Spannen zu vergleichen und sicherzustellen, dass die Spanne des Knotenpunktes die Knoten schneidet, die Sie bearbeiten.

Wie auch immer, SyntaxAnnotations bieten eine nützliche Möglichkeit, Knoten in Bäumen nach einer Änderung zu lokalisieren. Sie können einfach eine Instanz des Typs erstellen und sie mit der Erweiterungsmethode WithAdditionalAnnotations an einen Knoten anfügen. Sie können den Knoten erneut mit der GetAnnotatedNodesOrTokens-Methode suchen.

Eine Möglichkeit, Ihr Problem anzugehen, besteht darin, Ihre toRemove zu kommentieren und dann, wenn Sie ReplaceNodes aufrufen, zwei Ersetzungen im selben Aufruf auszuführen - einen, um den oldNode auszuführen - & gt; newNode Ersatz und dann einen toRemove - & gt; toRemoveWithAnnotation Ersatz. Suchen Sie dann den annotierten Knoten in der resultierenden Struktur und rufen Sie RemoveNode auf.

Wenn Sie wissen, dass oldNode und toRemove keine Vorfahren voneinander sind (d. h. sie sind in nicht verwandten Teilen der Struktur), wäre eine andere Option, die Reihenfolge umzukehren. Greifen Sie den übergeordneten Knoten (nennen Sie es oldNodeParent) von toRemove und rufen Sie RemoveNode auf, was bedeutet, dass Sie einen aktualisierten übergeordneten Knoten erhalten (nennen Sie ihn oldNodeParentRewritten). Rufen Sie dann ReplaceNodes auf, die zwei Ersetzungen ausführen: oldNode - & gt; newNode und oldNodeParent - & gt; oldNodeParentRewritten. Keine Anmerkungen erforderlich.

    
Jason Malinowski 18.11.2012 00:49
quelle

Tags und Links