Reputation: 10375
I'm trying to add an attribute and a using statement in my code fix, but it's happening as two iterations, and thus fails to work properly. I don't understand enough about Roslyn yet to know why I'm getting a second iteration.
This is my code fix:
private static async Task<Document> AddRequiredAttributeAsync(Document document, PropertyDeclarationSyntax property, CancellationToken cancellationToken) {
var attribute = SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("Required"));
var attributeList = SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(attribute));
var updated = property.AddAttributeLists(attributeList);
var editor = await DocumentEditor
.CreateAsync(document, cancellationToken)
.ConfigureAwait(false);
editor.ReplaceNode(property, updated);
const string @ns = "System.ComponentModel.DataAnnotations";
var root = (CompilationUnitSyntax)editor.OriginalRoot;
if (root.Usings.Any(x => x.Name?.ToString() == @ns) is false) {
var usingDirective = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(@ns));
var newRoot = root.AddUsings(usingDirective);
editor.ReplaceNode(root, newRoot);
}
return editor.GetChangedDocument();
}
In my test, for the fixed code, it fails saying it got two iterations if I use the following:
var fixedCode = """
using System.ComponentModel.DataAnnotations;
[Table("foo")]
class SomeClass {
[Required]
public int Age { get; set; }
}
""";
Interestingly, if I move the {
on the class definition to the next line, then it does not fail with a second iteration, but the match then fails because the fixed code expects the {
to be on the same line as the class
.
Upvotes: 0
Views: 18