Finding the Class Declarations in an ICSharpFile

Hi, I'm struggling to make sense of the hierarchy of documents whilst writing my plugin. I'm writing a custom macro for a live template that will pull out the description from a classes Summary XML documentation (in bold):

    /// <summary>
    /// Retrieves the summary text from a types documentation
    /// </summary>

I have the following code already to obtain a reference to the file that called the macro:

     IPsiSourceFile psiSourceFile = context.SessionContext.Document.GetPsiSourceFile(context.SessionContext.Solution);
     var psiLanguageType = MacroUtil.GetLanguageType(context);
     var file = psiSourceFile.GetPsiFile(psiLanguageType);


I have the reference to the file - how to I pull out the first class declaration (or all the class declarations) from the document? The file object here gives me the ability to read the namespaces - but not anything further.

I'm using Resharper 6 - andmust admit I am finding it heavy going without XML documentation of many of the objects and no document modal documentation that I could find. :(

Any help is appreciated.

5 comments
Comment actions Permalink
You want to find the nodes that implement IClass - these are the class declaration nodes. The best way to discover the structure of the PSI of a file is to start ReSharper in "internal" mode. This involves starting devenv.exe with the /ReSharper.Internal command line switch: devenv.exe /ReSharper.Internal. Once this is set, ReSharper has a new "Internal" menu that offers a whole heap of extra functions, one of which (ReSharper -> Internal -> Windows -> PSI Browser) displays a view of the PSI tree of the current file.
0
Comment actions Permalink

Thankyou for the reply Matt. Could you point me in the direction of where any of this is documented please?

Would you also be kind enough to post some demo code that I would use to navigate an ICSharpFile to find node of a certain type? It's not without trying that I've tried to find this kind of information.

0
Comment actions Permalink
Sadly, because the PSI trees are so extensive, and different for each file type (there is a different PSI tree for C#, JS, CSS, ASPX, Razor, XML, etc. They're different syntaxes, so get a different tree), there isn't any documentation for the structure of the PSI trees. Investigating code files interactively with the PSI browser is really the best way to discover this.As for processing, you want to use an extension method on ITreeNode (an interface indicating the nodes in the PSI tree) called ProcessDescendants. This takes in an instance of IRecursiveElementProcessor (that you implement), and it walks the tree for you, calling your methods: InteriorShouldBeProcessed to see if you want to walk *into* the tree, and ProcessBeforeInterior and ProcessAfterInterior which are called before and after walking deeper into the tree. An example of this can be seen in the SDK examples - check out the CyclomaticComplexity sample. This has a "daemon stage process" that is called on a background thread. This process gets the current file, creates a new, custom IRecursiveElementProcessor and passes it to ProcessDescendants on the file.Matt
0
Comment actions Permalink
I have a similar question - how do I find all the IMethodDeclaration objects within an IClassDeclaration (I have the IClassDeclaration object in hand)?
0
Comment actions Permalink
IClassDeclaration inherits from IClassLikeDeclaration, which has a MethodDeclarations property. There's also a MethodDeclarationsEnumerable property. MethodDeclarations is a snapshot, so if you keep a hold of that property, the contents don't change if methods are added or removed. MethodDeclarationsEnumerable re-evaluates the contents of the class each time it's enumerated, so you can keep a hold of the value.
0

Please sign in to leave a comment.