2016-06-02 3 views
1

Я создаю CodeFixProvider для анализатора, который обнаруживает, что пользовательский атрибут отсутствует в объявлении метода. В основном пользовательский атрибут, который должен быть добавлен к методу выглядитRoslyn CodeFixProvider добавить атрибут к методу

[CustomAttribute(param1: false, param2: new int[]{1,2,3})] 

это то, что у меня до сих пор:

public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { 
     var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); 

     var diagnostic = context.Diagnostics.First(); 
     var diagnosticSpan = diagnostic.Location.SourceSpan; 
     var declaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType<MethodDeclarationSyntax>().First(); 

     context.RegisterCodeFix(
      CodeAction.Create(
       title: title, 
       createChangedSolution: c => this.AddCustomAttribute(context.Document, declaration, c), 
       equivalenceKey: title), 
      diagnostic); 
    } 

    private async Task<Solution> AddCustomAttribute(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) { 
     // I suspect I need to do something like methodDeclaration.AddAttributeLists(new AttributeListSyntax[] { 
     // but not sure how to use it exactly 

     throw new NotImplementedException(); 
    } 

ответ

5

Помните, Roslyn синтаксических деревьев неизменны. Вам нужно что-то вроде:

private async Task<Solution> AddCustomAttribute(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) 
{ 
    var root = await document.GetSyntaxRootAsync(cancellationToken); 
    var attributes = methodDeclaration.AttributeLists.Add(
     SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList<AttributeSyntax>(
      SyntaxFactory.Attribute(SyntaxFactory.IdentifierName("CustomAttribute")) 
      // .WithArgumentList(...) 
     )).NormalizeWhitespace()); 

    return document.WithSyntaxRoot(
     root.ReplaceNode(
      methodDeclaration, 
      methodDeclaration.WithAttributeLists(attributes) 
     )).Project.Solution; 
} 

Чтобы получить полный SyntaxFactory код для конструктора атрибута .WithArgumentList() бросить его в Roslyn Quoter.

+0

Это сработало, однако вы могли бы указать мне хороший ресурс по этому вопросу? – AlexanderM

Смежные вопросы