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 stringwith value "Add new concept to store.".
- 
Add another static final class variables of type stringwith value "Do not use!".
- 
Add the constructor to the class which assigns the wordStoreto 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 thepatternby using light quotation (ctrl+space + "<light quotation>").
 Then adding the new word to the list of thewordStore, and finally assigning the reference of our parameterNounWordRefto the newly created word.
- 
Create a transformation menu for the NounWordRefnode.
- 
Add a completion section. 
- 
The default reference menu for the originalWordreference 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 wordStoreroot 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 textsection return thepatternvariable.
 Thepatternvariable is what the user has written in the editor.
- 
In the can executesection set conditions for the execution of the action.
 Use the helper method to check if thepatternvariable is empty or if the word exists in thewordStore.
- 
In the executemethod call theaddNewNounhelper method and pass thepatternandnodevariables to it.
- 
Give the action a description text- use the constant we defined earlier in the helper method. In this case theADD_NEW_NOUNstring.
 
- 
- 
Add a second action with the following items: - 
In the textsection return thepatternvariable.
 Because otherwise the code won’t compile.
- 
In the can executesection use the helper methodcheckWordExiststo 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 executesection 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.