SModel language Modification operations
The most commonly used change operation in SModel is the act of changing a feature. In order to set a value of a property, or assign a child or reference node of 0..1 or 1 cardinality, you can use straight assignment (with =) or the set operation. In order to add a child to 0..n or 1..n children collection, you can either use the.add operation from the collection language or call add next-sibling/add prev-sibling operations on a node<> passing another node as a parameter.
For example,
classDef.name = "NewClassName";
classDef.name.set( "NewClassName");
myNode.condition = trueConstant;
node<InstanceMethodDeclaration> method = classDef.member.add new initialized(InstanceMethodDeclaration);
When setting a target to a reference link, there is no need to access a target node. Having a pointer to the target is enough. This is possible with the set ptr operation, which is applicable to reference link access expressions.
node.instanceMethodDeclaration.set ptr(Object->equals)
Similarly, to check that a node is a specific one, there is the "is" operation available.
node.parent.is(Object->equals);
There are several ways to create a new node:
new operation: new node<Concept>()
new instance operation on a model: model.newInstance()
new instance operation on a concept: concept.newInstance()
add new(Concept) and set new(Concept) operations applied to feature expressions
replace with new(Concept) operation
new root node(Concept) operation applied to a model. In this case the concept should be rootable
new next-sibling<Concept>/new prev-sibling<Concept> operations adding new sibling to an existing node
tip
Note that the jetbrains.mps.lang.actions language adds the possibility to initialize the newly created nodes using the rules specified in NodeFactories. Upon importing the jetbrains.mps.lang.actions language you are able to call:
new initialized node<Concept>()
model.new initialized node(Concept)
node.new initialized next/previous sibling(Concept)
add new initialized(Concept)
set new initialized(Concept)
replace with new initialized(Concept)
replace with initialized next/previous-sibling(Concept)
To preserve the tree shape of the model, a node can only have at most one parent. As soon as you add a node as a child to a parent node, the node is detached automatically from any previous parent node that it may have had. Creating copies of nodes, including their sub-trees, may thus come handy. To create a copy of an existing node, you can use the copy operation. E.g., node<> yourNode = myNode.copy
To replace a node in the AST with an instance of another node, you can use the 'replace with' operation. If you want to replace and create at the same time, there is a shortcut operation 'replace with new(Concept)', which takes a concept as a parameter.
If you want to delete a node from the model, you can use the detach operation. You can still add the detached node to the model later.
Properties can be assigned values directly using the assignment operation. The remove() operation on a property will delete its value from the model.
tip
To access and delete values of properties that have been deleted from the meta-model (aka language definition), you can no longer use smodel. The downcast operator (/) will resolve the underlying java object that you can then manipulate through the Java API.
Iterable<SProperty> properties = foo/.getProperties(); for(SProperty p : properties) { SAbstractConcept owner = p.getOwner(); if (!owner.getProperties().contains(p)) { foo/.setProperty(p, null); } } });
Thanks for your feedback!