How to make caching a model built from a PsiElement

 

Task:

I have created model classes from a PsiElement. For example: Model - JPA Entity, PsiElement - PsiClass. The model has (cross)reference to other the JPA Entity, for instance, attribute type and entity parent.

Questions:

1. How best to make invalidate the model cache? Use com.intellij.openapi.vfs.VirtualFileListener as in the com.intellij.psi.impl.file.impl.PsiVFSListener?
2. Or better not to cache model and every time to rebuild the model. I have many references to the model. Will this not cause performance problems?

I know about com.intellij.persistence.util.PersistenceCommonUtil#getPersistenceRoles(com.intellij.psi.PsiClass) and com.intellij.persistence.model.PersistentObject , but:
1. I am development plugin for ‘Community’ version.

2. I want to know the common approach. Also, I have other model classes created from XmlFile, XmlTag, and other PsiElement.

Sorry for my English. Сan I ask questions in Russian?

0
Avatar
Permanently deleted user

PsiElements are UserDataHolders; you can attach random data -- like your model -- to them.  The nice thing is that the user data is garbage collected when the PsiElement is.  Therefore, if the element becomes invalid (e.g. it no longer exists on a reparse), then the associated data is also removed.  That's your cache clearing.  To use the API is simple:

 

public string MY_MODEL_KEY = "MyModelKey";  // << ----  Any globally unique string is usable here.

public MyModel getModel(PsiElement elem) {

  MyModel model = elem.getUserData(MY_MODEL_KEY);

  if (null == model) {

    model = new MyModel(...);

    elem.putUserData(MY_MODEL_KEY, model);

  }

  return model;

}

 

0

I'd suggest to use CachedValuesManager (which also stores CachedValue in the user data), then you're also sure the model is invalidated in time (if you use PsiModificationTracker.MODIFICATION_COUNT as a cached value dependency).

0

Thanks, Eric Bishton! It's really nice that the PsiElement validates its UserData.

0

Thanks, Peter Gromov! It looks like what I was looking for.

 

0

请先登录再写评论。