PsiTreeChangeListener - ChildRemoved is not working properly

Answered

In ChildRemoved, removed child is returned by event.getChild(). but it was not giving me the correct psiElement that i removed. if any declared statement is below to that removed psiElement then even.getChild().getText() was giving me that  declared statement not the removed Statement. if any declared statement is not there then only it is giving me the correct removed child. how to resolve this problem.

10 comments
Comment actions Permalink

How did you remove the child, with which code?

What do you use this event listener for?

0
Comment actions Permalink

i used this event listener in my plugin to listen the changes of psiElements in the project. selected the text and then removed it.

0
Comment actions Permalink

Reparse produces all kinds of PSI events, not all of them intuitive. I wouldn't rely on them. Which code do you want to put into the PSI listener, what do you want to achieve with it?

0
Comment actions Permalink

I am having a list of elements with me and whenever, they become invalid (user interaction or otherwise) I want to update my list.

This listener is working for all other cases except for drag n drop and the removal cases. Right now DND is not my top priority but the removal is a very common use case.

0
Comment actions Permalink

First, keeping a large list of PSI elements (from different files) is likely to consume a lot of memory.

Second, PSI exists only inside a read/write action. The fact that the PsiElement objects survive between read actions, is an implementation detail, and you shouldn't rely on that. PSI can be invalidated due to very different reasons and you won't always get specific events about those. For example, changing Project Structure settings often results in such global invalidation.

For both issues, I'd recommend using smart pointers instead (SmartPointerManager#createSmartPsiElementPointer).

0
Comment actions Permalink

Actually in my use case, the element will definitely be invalidated due to user changes and not by reparsing file or any other intellij actions. So using the smart pointer actually doesnt work in my case.

0
Comment actions Permalink

I don't understand why using smart pointers don't work, have you tried them? I don't understand what you mean by user changes. If it's text editing, then it's exactly reparse that changes the PSI.

0
Comment actions Permalink

Sorry I couldn't explain the use case correctly before. I will try once again:

Of course using the smart pointer will help me to definitely tell that the element is invalidated, but I wouldn't know if when it is invalidated.Thats where my listener comes in.

The listener I am having should tell me whenever an element is invalidated, for all these invalidated elements I will see if I am having them in my list (the list is very small at max 10-12 elements). So if one of these elements is invalidated, I dont need to update it with the new version of the element but remove the corresponding file from my another list.

0
Comment actions Permalink

Then I'd still recommend to use smart pointers, and after anything changes (e.g. in MergingUpdateQueue update queued inside a PSI change listener; I wouldn't do that inside PSI listener directly since it's slow) check if they all can still be retrieved. If not, then some PSI just got really invalidated, and you can handle that.

0
Comment actions Permalink

Thanks Peter.

0

Please sign in to leave a comment.