Resolve reference to built-in methods of custom language

Hello everyone,

I am currently writing a plugin to support a custom language. This custom language contains quite a few built-in functions.
Of course, I want to be able to resolve these built-in-functions when they are used in code.

Since I don't have the implementation of the built-in methods (or library methods), my idea is to create an own file (or multiple files) which contains nothing but the function headers.


Let's say, there is a function called "length" which returns the size of a parameter (e.g. list or string).

My file would therefore simply contain something like following:

 * Returns the length of the parameter (either list or string)
 * @param list_or_string either list or string parameter
 * @return length
function length(list_or_string) {
   // no implementation available

When a function reference is resolved, a hidden file (similar to resolving JDK functions) should be shown in read-only mode which shows the implementation (or rather function headers).

My motivation behind delivering such a hidden file is:

  • Opening such a hidden file is a great source of documentation because the user can browse other built-in functions
  • Having a PsiReference to a real PsiElement makes life much easier in the documentation provider because creating documentation / quick navigation info from doc comments applies to built-in methods the same way as it applies to own custom functions.

How would I best go on about this?
In the documentation, I have found a reference to synthetic libraries ( It sounds somewhat correct, but I am not sure if this is a viable implementation for my goal:

  1. Declare my own AdditionalLibraryRootsProvider which returns a collection of a single synthetic library
  2. The synthetic library returns a collection of virtual files
  3. I have to create my own virtual files from a source which I would keep in my plugins resources

Following questions remain:

  • Is it correct that the library source is automatically indexed? If not, how can I create the PSI / Stub tree for the source?
  • If I create VirtualFile instances from within the plugin code. How often are these created? I would assume that this needs to happen inside of the additional roots provider or in some sort of a singleton?

Am I on the correct path or is there some other way entirely?

Looking forward for some viable input - thanks in advance!


1 comment

Hello, did you solve it? I'm running into the same problem, can anyone answer?


Please sign in to leave a comment.