This is a fairly rare use case but it comes up at times: how do you implement UI that behaves like a reference but without using a reference?
- you might want to refer to something that is not a node, such as a model or a module,
- you want to refer to a node in another model but without introducing a dependency on that model (creating a “weak” reference).
In these cases you cannot use built-in references but you can still create something that comes pretty close, what I would call a pseudoreference.
There are four main “ingredients” to a reference:
- Structure: a concept that keeps information about the target of the pseudoreference. It can be a model or node reference, serialized to a string.
- Completion menu: showing all the available targets for the user to choose.
- Navigation: jumping to the target on
- Checking for broken references (i.e. when the target is gone).
With pseudoreferences we can make most of these work, though some things might work differently from the normal references.
There are several implementations of pseudoreferences in MPS and I will use them as examples rather than building a separate sample.
The first example is a model reference represented by
ModelIdentity interface concept and
implementing it (MPS
ModelPointer defines a few properties and children to contain the information about the target model. It defines a
named substitute menu (
that simply returns all available models. The concept is designed to be reusable so the menu isn’t engaged by default
(in case you want to reuse the
ModelPointer concept in your language but have the user choose from a different set of
Unfortunately, the MPS editor language doesn’t provide any means to set up navigation to a model on Ctrl+Click, so navigating to the target model is not supported.
Broken model references are not highlighted in any way, probably left for the reusing language to implement.
“Reflection” node references
jetbrains.mps.lang.migration language implements a “dynamic” node reference concept, named
This concept contains properties to store the ID of the target node and its model. The editor looks up the node if it
exists and shows its presentation. If the target node exists, the editor enables navigation to it via
The concept does not mark missing targets as an error (as it is not an error in this case). Rather, it highlights them with a yellow background: