How to monitor type system?

Hi!

I want to monitor the type system, i.e. Psi structure, from my ReSharper 8.2 plugin and react to certain events (new class/class removed, new property/property removed). But I can't seem to find the right trail to follow.

I can read the types, find specific methods and change their code etc. but I still have no clue where to register for some kind of meaningful "change events". It would really need to be "robust", i.e. I can't afford to get "out of sync" with the type system by missing out on an added or removed type(-member).

Any hint would be greatly appreciated! :)

Best regards,
Robert.

2 comments
Comment actions Permalink

You have two options, really. If you want to monitor the file being edited, and display highlights and warnings, you should implement a daemon stage process. This will get called as changes are made to the file, but is only called when the file is visible, and doesn't really maintain any state other than highlights and warnings. On the other hand, you can implement ICache, which is used to maintain a cache of all the files in the solution. It is initially called for each file in the solution when the solution is first opened. It can process the file or ignore it, depending on the requirements of the cache (e.g. only process C# files, but ignore JS files). It then serialises the cache to disk, and this cache is loaded on subsequent solution opens. Whenever a file changes, it is removed from the cache, and re-processed. The cache can then be used from other parts of your plugin, e.g. a cache could keep track of assembly level attributes (which can be in any file), and a daemon stage process could refer to this cache in order to display appropriate highlights (e.g. ReSharper has a cache that tracks InternalsVisibleTo, and uses this cache to decide if types are available for use). ICache isn't documented, yet, unfortunately. Here's an introductory page, and here's a boilerplate abstract class that provides a skeleton implementation of ICache.

Which method you choose really depends on why you need to monitor for changes.

Matt

0
Comment actions Permalink

Hi Matt,

thank you very much for your reply! I hadn't considered implementing my own cache, but it sounds worth a try. Is really the whole file reprocessed each time something changes in it? That way it seems hard to me to detect renames and similar.

Currently I try to track PSI changes by listening to IPsiServices.Files.AfterPsiChanged.

To modify the sources seems a challenge because it has to be done on a certain thread, and there seems to be no way to get hold of its JetDispatcher other than a) having some of your code being execute on that thread and b) storing the reference to the JetDispatcher in that code, so other threads can use it.

It seems that the documentation for ReSharper 9 is planned to be more detailed (like http://jetbrains.github.io/resharper-devguide/Architecture/PSI.html). That would be very much appreciated.

My goal is to have my plugin support Aspect Oriented Programming through code generation (I don't like code injection because it produces "invisible code" which is a major source of confusion).

Best regards,
Robert.

0

Please sign in to leave a comment.