on
Adding smart references using transformation menus
This post will follow a user friendly way of creating nodes, adding them to a location of our choice and referring to them from a smart reference, from the transformation menu of a smart reference.
Rationale
Having references is helpful in a lot of ways. Instead of creating and storing data every time you need it you can store it in one place and access it later from various locations and manipulate it. This saves memory and computing time since we will mostly pass on addresses instead of the entire values of a variable. Smart references are as transparent as they can - you can see all nodes you can refer to through the completion menu as if you are adding a node of the concept.
An issue pops up when you actually want to add a new entry to the list of referred items. Then you would have to manually go to the list and add the entry yourself which may be harder than expected if the project is large.
Overview
You can find the example project we will see here at F1res GitHub page. |
The idea of the sample project is to have a store for words and one or many thesauri that can define synonyms or if the language is extended in the future - different types of dictionaries.
We have a language called Dictionary
that can store nouns into WordStores
and refer to them in Thesaurus
root nodes.
NounWord
implements the INamedConcept
interface.
Its reference concept NounWordRef
has an originalWord
reference of cardinality [1] to a NounWord
concept.
The WordStore
contains NounWords
and the Thesaurus
contains Definitions
that have a reference to the noun word it’s going to assign synonyms to and a list of noun word references for the synonyms.
The Thesaurus
also contains a reference to the wordStore
it’s going to get words from.
With this setup if we wanted to add new words we have to go to the WordStore
and add them manually.
Then we have to go back to the Thesaurus
and use them.
We can ease this process by adding the possibility to directly add entries to the wordStore
from the completion menu of the smart reference.
We are going to use the transformation menu for this solution.
We will add a Transformation Menu to the NounWordRef
concept.
In this transformation menu we will create a completion section that has two actions, because if it has only one the autocomplete will execute it immediately and fill our wordStore
with nonsense comprised of every letter of a word until we have finished.
A transformation menu allows us to transform the current node in whatever direction we want. With it we can manipulate the node in several ways - completion, context assistant, side transform. We can overwrite the default or define additional entries to these sections. |
The completion section extends the code completion tool (ctrl+space). It allows for a fluid access to various menus of sub/super-concepts or user defined actions without interrupting the flow of writing code. |
In these actions we create a new noun node, add it to the wordStore
and set our nodes reference to it.
Transformation menu checklist
First we will create a runtime solution with a helper method that will hold the logic of the transformation menu. It is generally better to hold more complex logic in separate helper classes.
-
Create a language runtime solution.
-
Add a model for the editor of the language with the following dependencies and used languages.
-
Create a helper class.
-
Add one class variable that is of type
node<wordStore>
. -
Add one static final class variables of type
string
with value "Add new concept to store.". -
Add another static final class variables of type
string
with value "Do not use!". -
Add the constructor to the class which assigns the
wordStore
to an externalwordStore
. -
Add one method that checks if a string, given in the parameters, is empty or if a noun that matches it exists.
-
Add one method that creates a new noun, from a string parameter, adds it to the word store and assigns it to a
NounWordRef
, also from a parameter.
We do that by creating a new word and assigning it’s name to be thepattern
by using light quotation (ctrl+space + "<light quotation>").
Then adding the new word to the list of thewordStore
, and finally assigning the reference of our parameterNounWordRef
to the newly created word.
-
Create a transformation menu for the
NounWordRef
node. -
Add a completion section.
-
The default reference menu for the
originalWord
reference has to be included so the existing words will still be listed in the menu as possible reference targets. -
Create a group, because we want to use variables. In this group do the following:
-
In the variables section add one variable that points to the
wordStore
root node so we can add new nodes to it. -
In the variables section add another variable that is the helper class.
It will assist with the logic of the transformation menu. -
Add one action with the following items:
-
In the
text
section return thepattern
variable.
Thepattern
variable is what the user has written in the editor. -
In the
can execute
section set conditions for the execution of the action.
Use the helper method to check if thepattern
variable is empty or if the word exists in thewordStore
. -
In the
execute
method call theaddNewNoun
helper method and pass thepattern
andnode
variables to it. -
Give the action a
description text
- use the constant we defined earlier in the helper method. In this case theADD_NEW_NOUN
string.
-
-
Add a second action with the following items:
-
In the
text
section return thepattern
variable.
Because otherwise the code won’t compile. -
In the
can execute
section use the helper methodcheckWordExists
to set a condition for the execution of the action.
This is done to avoid having this item show up when it shouldn’t. -
Leave the
execute
section empty so we do not confuse the user. -
Add a
description text
- use the other constant we defined earlier in the helper method - theDO_NOT_USE_ITEM
.
-
-
We could emphasize more that the second action is not important by adding a completion styling to our transformation menu that sets the strikeout flag to an item of the menu. This is completely visual and is not necessary for the example to work. |
About Atanas Marchev
I am a Junior Model Driven Engineer at F1RE. I started my journey with F1RE in December 2021. I’ve worked with many aspects of programming and this way of development seems very interesting. Just the thought alone of the way one has to extract basic concepts out of complex ideas and structures seems challenging enough to make your head spin.
You can contact me at atanas@f1re.io.