Ho scritto un CSharpSyntaxRewriter
che sto usando per rimuovere gli attributi dai metodi, ma sto cercando di mantenere qualsiasi cosa prima dell'attributo (fino al metodo precedente) quando rimuovo tutti gli attributi da un metodo.Come rimuovere tutto l'attributo membro ma lasciare una riga vuota?
Ciò funziona perfettamente per i metodi con più di un attributo, ma non per uno solo.
Ecco un Repro minima:
void Main()
{
var code = @"namespace P
{
class Program
{
public void NoAttributes() { }
//???
[TestCategory(""Atomic"")]
public void OneAtt1() { }
[TestCategory(""Atomic"")]
public void OneAtt2() { }
[TestMethod, TestCategory(""Atomic"")]
public void TwoAtts() { }
}
}";
var tree = CSharpSyntaxTree.ParseText(code);
var rewriter = new AttributeRemoverRewriter();
var rewrittenRoot = rewriter.Visit(tree.GetRoot());
Console.WriteLine(rewrittenRoot.GetText().ToString());
}
public class AttributeRemoverRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitAttributeList(AttributeListSyntax attributeList)
{
var nodesToRemove =
attributeList
.Attributes
.Where(att => (att.Name as IdentifierNameSyntax).Identifier.Text.StartsWith("TestCategory"))
.ToArray();
if (nodesToRemove.Length == attributeList.Attributes.Count)
{
//Remove the entire attribute
return
attributeList
.RemoveNode(attributeList, SyntaxRemoveOptions.KeepNoTrivia);
}
else
{
//Remove just the matching ones recursively
foreach (var node in nodesToRemove)
return
VisitAttributeList(attributeList.RemoveNode(node, SyntaxRemoveOptions.KeepNoTrivia));
}
return
base.VisitAttributeList(attributeList);
}
}
versione completa è qui sul mio gist (prima che qualcuno fa notare tutte le altre questioni).
risultato atteso è:
namespace P
{
class Program
{
public void NoAttributes() { }
//???
public void OneAtt1() { }
public void OneAtt2() { }
[TestMethod]
public void TwoAtts() { }
}
}
uscita Attuale è:
namespace P
{
class Program
{
public void NoAttributes() { }
public void OneAtt1() { }
public void OneAtt2() { }
[TestMethod]
public void TwoAtts() { }
}
}
tutte le idee su quello che devo fare per mantenere gli spazi (o anche commenti !!)?
Ho combinato con ogni combinazione di Trivia
a cui riesco a pensare. La modifica dei risultati SyntaxRemoveOptions
in NullReferenceException
s all'interno della base di codici di Roslyn e l'utilizzo dei metodi di estensione *Trivia
comporta che gli attributi non siano stati rimossi più: solo spazi bianchi.
Queste eccezioni sembrano bug per me. Li ho appena riprodotti localmente e non penso che la modifica di 'SyntaxRemoveOptions' dovrebbe causare eccezioni. Dovresti creare un problema su: https://github.com/dotnet/roslyn/issues – JoshVarty