How to implement a PsiTreeChangeListener to Track Changes in PsiClass, PsiMethod, and PsiField Elements
Answered
I need to implement a PsiTreeChangedListener to maintain an AST (Abstract Syntax Tree) that I've created. I need to be able to retrieve the elements whenever a PsiClass, PsiMethod, or PsiField is added, removed, or renamed.
Currently, I'm facing an issue with handling the renaming events for PsiClass, PsiMethod, and PsiField. For example, if there's a variable named int a in a class, and I rename it to int aaa, I don't receive an event indicating this change.
public class MyPsiTreeChangedListener implements PsiTreeChangeListener {
private final MyLogger log = MyLogger.getLogger(CjqPsiTreeChangedListener.class);
private Project project;
public MyPsiTreeChangedListener(Project project) {
System.out.println("Psi Tree Changed Listener init");
this.project = project;
}
private void dealWithElement(@NotNull PsiTreeChangeEvent event, String logInfo_PsiAction) {
PsiElement element = event.getChild();
if (element instanceof PsiClass) {
PsiClass psiClass = (PsiClass) element;
log.info(logInfo_PsiAction+": PsiMethod: " + psiClass.getName());
} else if (element instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) element;
log.info(logInfo_PsiAction+": PsiMethod: " + psiMethod.getName());
} else if (element instanceof PsiField) {
PsiField psiField = (PsiField) element;
log.info(logInfo_PsiAction+": PsiField: " + psiField.getName());
}
}
@Override
public void beforeChildAddition(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void beforeChildRemoval(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void beforeChildReplacement(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void beforeChildMovement(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void beforeChildrenChange(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void beforePropertyChange(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void childAdded(@NotNull PsiTreeChangeEvent event) {
dealWithElement(event, "childAdded:");
}
@Override
public void childRemoved(@NotNull PsiTreeChangeEvent event) {
dealWithElement(event,"childRemoved:");
}
@Override
public void childReplaced(@NotNull PsiTreeChangeEvent event) {
dealWithElement(event, "childReplaced:");
}
@Override
public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void childMoved(@NotNull PsiTreeChangeEvent event) {
}
@Override
public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
}
}
Please sign in to leave a comment.
Meanwhile, I would also like to inquire about the specific scenarios triggering 'propertyChanged' events.
Hi,
I tried to reproduce it, and it works.
I registered the listener, run a plugin, created a test class:
After renaming it to
aaa
, I get the result printed:childReplaced:: PsiField: a