Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a list of all fields with a specified attribute?

I am trying to find fields with a specified attribute. I tried to modify the FirstQuickFix example, because I thought, it could be a good starting point. But if I run the code, nothing happens. Any ideas what my major-problem is?

My understanding, after reading the Project Overview and the walkthrough-documents, is that I am able to request the attributes for a token, that I found in the syntax-tree. The syntax-tree is an exact tree-representation of the source-code. The connection of declaration of a field and its attributes is accessible via semantic. Or is my understanding totally wrong?

[ExportCodeIssueProvider("FirstQuickFix_", LanguageNames.CSharp)]
class CodeIssueProvider : ICodeIssueProvider
{
    public IEnumerable<CodeIssue> GetIssues
      (IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken)
    {
        var tokens = from nodeOrToken in node.ChildNodesAndTokens()
                     where nodeOrToken.HasAnnotations(Type.GetType("myAttribute"))
                     select nodeOrToken.AsToken();

        foreach (var token in tokens)
        {
            var issueDescription = string.Format("found!!!");
            yield return new CodeIssue(CodeIssueKind.Info, token.Span, issueDescription);
        }
    }
}

Edit:

what I want to achieve, is to find ie. all fields with the attribute myAttribute:

namespace ConsoleApplication
{
    class Program
    {
        [myAttribute]
        string myField = "test";

        public void testing()
        {
            Console.WriteLine(myField);
        }
    }
}
like image 562
Anton Avatar asked Mar 14 '13 08:03

Anton


1 Answers

To do this, you can use LINQ to get all AttributeSyntax nodes with the specified name and then use Parent (twice) to get the node representing the field:

var fields = root.DescendantNodes()
                 .OfType<AttributeSyntax>()
                 .Where(a => a.Name.ToString() == "myAttribute")
                 .Select(a => a.Parent.Parent)
                 .Cast<FieldDeclarationSyntax>();

This is the most primitive version and works only on the syntactic level, so it won't work right if you have an attribute with the same name in another namespace, use the full name of the attribute (including namespace) or if you use using to refer to the attribute type using an alias.

If you want to support that, you will need to get the semantic model and then get the symbol representing the type of the attribute.

like image 107
svick Avatar answered Oct 30 '22 17:10

svick