The following snippet replaces all Attributes called "PreviousAttribute" by an Attribute called "ReplacementAttribute" for an entire solution. The sample manually uses a SyntaxRewriter to exchange the attributes.
/// <summary>
/// The CSharpSyntaxRewriter allows to rewrite the Syntax of a node
/// </summary>
public class AttributeStatementChanger : CSharpSyntaxRewriter
{
/// Visited for all AttributeListSyntax nodes
/// The method replaces all PreviousAttribute attributes annotating a method by ReplacementAttribute attributes
public override SyntaxNode VisitAttributeList(AttributeListSyntax node)
{
// If the parent is a MethodDeclaration (= the attribute annotes a method)
if (node.Parent is MethodDeclarationSyntax &&
// and if the attribute name is PreviousAttribute
node.Attributes.Any(
currentAttribute => currentAttribute.Name.GetText().ToString() == "PreviousAttribute"))
{
// Return an alternate node that is injected instead of the current node
return SyntaxFactory.AttributeList(
SyntaxFactory.SingletonSeparatedList(
SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("ReplacementAttribute"),
SyntaxFactory.AttributeArgumentList(
SyntaxFactory.SeparatedList(new[]
{
SyntaxFactory.AttributeArgument(
SyntaxFactory.LiteralExpression(
SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(@"Sample"))
)
})))));
}
// Otherwise the node is left untouched
return base.VisitAttributeList(node);
}
}
/// The method calling the Syntax Rewriter
private static async Task<bool> ModifySolutionUsingSyntaxRewriter(string solutionPath)
{
using (var workspace = MSBuildWorkspace.Create())
{
// Selects a Solution File
var solution = await workspace.OpenSolutionAsync(solutionPath);
// Iterates through every project
foreach (var project in solution.Projects)
{
// Iterates through every file
foreach (var document in project.Documents)
{
// Selects the syntax tree
var syntaxTree = await document.GetSyntaxTreeAsync();
var root = syntaxTree.GetRoot();
// Generates the syntax rewriter
var rewriter = new AttributeStatementChanger();
root = rewriter.Visit(root);
// Exchanges the document in the solution by the newly generated document
solution = solution.WithDocumentSyntaxRoot(document.Id, root);
}
}
// applies the changes to the solution
var result = workspace.TryApplyChanges(solution);
return result;
}
}
The above example can be tested for the following class:
public class Program
{
[PreviousAttribute()]
static void Main(string[] args)
{
}
}