Find a specific ITreeNode in a sub tree

As I didn't something in  the R# API, I implemented it myself:

    private IEnumerable<ITreeNode> FindAllNodes (ITreeNode startNode, Func<ITreeNode, TreeNodeActionType> predicate)
    {
      var currentNode = startNode;

      while (true)
      {
        currentNode = currentNode.FindNextNode (predicate);

        if (currentNode == null)
          yield break;

        yield return currentNode;
      }
    }


Does this functionality already exist in the R# API? If not, is my implementation OK in view of performance? Does it terminate with any given startNode?

2 comments
Comment actions Permalink

I don't think there's anything quite so generic. But ReSharper does provide a number of navigation methods, most of them defined in TreeNodeExtensions. This returns an enumerable of siblings, or children, or descendants and so on. You can then use standard LINQ queries on these enumerables, and use more methods from TreeNodeExtensions to do further processing, kind of like how XLinq works.

0
Comment actions Permalink

Missed the second part of your question. Performance should be fine - it's simply walking object references and calling a predicate, so performance will really just depend on what you do in the predicate. However, it's a recursive function, so care should be taken walking large trees.

It should be noted that this doesn't look in the sub-tree, exactly. It will walk all sibling nodes of the first node. When it runs out of siblings it will get the parent and walk all of the siblings of the parent, recursively. This means it will walk to the end of the file from the starting node, but it doesn't visit every node along the way. It misses out all descendant nodes. E.g. if you start with a method declaration node, you'll visit all sibling method declarations (and potentially property declarations, fields, etc), but you won't see method bodies. Then you'll move up to the class declaration node, and walk all of its siblings, so you'll see any other class declarations, but not see the class members. Then you'll move up the namespace, walk any other namespaces defined, but won't see inside those namespaces. Frankly, it's an odd way to walk a tree.

As for terminating with any given startNode, it actually ignores the startNode - it assumes you've already processed the current node and want to get the next one.

0

Please sign in to leave a comment.