Constraints

Skip to end of metadata
Go to start of metadata

The Structure Language may sometimes be insufficient to express advanced constraints on the language structure. The Constraints aspect gives you a way to define such additional constraints.

Can be child/parent/ancestor/root

These are the first knobs to turn when defining constraints for a concept. They determine whether instances of this concept can be hooked as children (parents, ancestors) nodes of other nodes or root nodes in models.You specify them as boolean closures to invoke each time when evaluating allowed possition for a node in the AST.

can be child

Return false if an instance of the concept is not allowed to be a child of specific nodes.

parameter description
operationContext IOperationContext
scope current context (IScope)
parentNode the parent node we are checking
childConcept concept of the child node (can be a subconcept of this concept)
link LinkDeclaration of the child node (child role can be taken from there)

can be parent

Return false if an instance of concept is not allowed to be a parent of specific concept node (in a given role).

parameter description
operationContext IOperationContext
scope context (IScope)
node the parent node we are checking (instance of this concept)
childConcept the concept of the child node we are checking
link LinkDeclaration of the child node

can be ancestor

Return false if an instance of the concept is not allowed to be an ancestor of specific nodes.

parameter description
operationContext IOperationContext
scope context (IScope)
node the ancestor node we are checking (instance of this concept)
childConcept the concept of the descendant node

can be root

This constraint is available only for rootable concepts (instance can be root is true in the concept structure description). Return false if instance of concept cannot be a root in the given model.

parameter description
operationContext IOperationContext
scope context (IScope)
model model of the root

Property constraints

Technically speaking, "pure" concept properties are not properties in its original meaning, but only public fields. Property constraints allow you to make them real properties. Using these constraints, the behavior of concept's properties can be customized. Each propertz constraint is applied to a single specified property.

property - the property to which this constraint is applied.

get - this method is executed to get property value every time property is accessed.

parameter description
node node to get property from
scope context (IScope)

set - this method is executed to set property value on every write. The property value is guaranteed to be valid.

parameter description
node node to set property
propertyValue new property value
scope context (IScope)

is valid - this method should determine whether the value of the property is valid. This method is executed every time before changing the value, and if it returns false, the set() method is not executed.

parameter description
node node to check property
propertyValue value to be checked
scope context (IScope)

Referent constraints

Constraints of this type help to add behavior to concept's links and make them look more properties-like.

referent set handler - if specified, this method is executed on every set of this link.

parameter description
referenceNode node that contains link.
oldReferentNode old value of the reference.
newReferentNode new value of the reference.
scope context: IScope interface to object that shows you models, languages and devkits you can see from the code.


search scope - defines the set of nodes to which this link can point. The method can return either a sequence<node<>> or ISearchScope.

parameter description
model the model that contains the node with the link. This is included for convenience, since both referenceNode and enclosingNode keep the model too.
scope IScope interface that shows models, languages and devkits you can see from the code.
referenceNode the node that contains the actual link. It can be null when a new node is being created for a concept with smart reference. In this situation smart reference is used to determine what type of node to create in the context of enclosingNode, so the search scope method is called with a null referenceNode.
enclosingNode parent of the node that contains the actual link, null for root nodes. Both referenceNode and enclosingNode cannot be null at the same time.
linkTarget the concept that this link can refer to. Usually it is a concept of the reference, so it is known statically. If we specialize reference in subconcept and do not define search scope for specialized reference, then linkTarget parameter can be used to determine what reference specialization is required.

If search scope is not set for the reference then default scope from the referenced concept is used. If the default search scope is also not set then "global" scope is used: all instances of referent concept from all imported models.


validator (since 1.5) - Each reference is checked against it's search scope and if, after changes in the model, a reference ends up pointing out of the search scope, MPS marks such a reference with an error message. Sometimes it is not efficient to build the whole search scope just to check if the reference is in scope. The search scope can be big or it may be much easier to check if the given node is in scope than to calculate what nodes are in scope. You can create quick reference check procedure here to speed up reference validation in such situations.

parameter description
model
scope
referenceNode
enclosingNode
linkTarget
context of reference usage, the same meaning as in the search scope method. The main difference: referenceNode cannot be null here because validator is not used during node creation.
checkedNode the node to be validated (referenceNode has a reference to checkedNode of type linkTarget)

It is possible to create validation routine only if you have created a list of nodes in the corresponding search scope. If ISearchScope is returned from search scope method, then isInScope(SNode) method of ISearchScope interface will be used for validation, you should override this method with your validation routine.
It is not possible to define validation routine without defining search scope.


presentation - here you specify how the reference will look like in the editor and in the completion list. Sometimes it is convenient to show reference differently depending on context. For example, in Java all references to an instance field f should be shown as this.f, if the field is being shadowed by the local variable declaration with the same name. By default, if no presentation is set, the name of the reference node will be used as its presentation (provided it is an INamedConcept).

parameter description
model
scope
referenceNode
enclosingNode
linkTarget
the context of reference usage, the same meaning as in the search scope function.
parameterNode the node to be presented (referenceNode has a reference to parameterNode of type linkTarget)
visible true - presentation of existing node, false - for new node (to be created after selection in completion menu)
smartReference true - node is presented in the smart reference
inEditor true - presentation for editor, false - for completion menu
ISearchScope

Low level interface that can be implemented to support search scope. We recommend to subclass AbstractSearchScope (implements ISearchScope) abstract class instead of direct implementation of ISearchScope interface. The only abstract method in AbstractSearchScope class is
@NotNull List<SNode> getNodes(Condition<SNode> condition) - return list of nodes in the current search scope satisfying condition, similar to [search scope] but with the additional condition.
Other useful methods to override:
boolean isInScope(SNode node) - the same function as in [validator] method.
IReferenceInfoResolver getReferenceInfoResolver(SNode, AbstractConceptDeclaration);

resolve info - TODO

Default scope

Suppose we have a link pointing to an instance of concept C and we have no search scope defined for this link in referent constraints. When you edit this link, all instances of concept C from all imported models are visible by default. If you want to restrict set of visible instances for all links to concept C you can set default scope for the concept. As in referent constraint you can set search scope, validator and presentation methods. All the parameters are the same.

Previous Next

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Feb 14, 2009

    How do you change the default scope?

    I have created 2 sandboxes in the solution, and the second solution's generated field declaration start numbering where the first one left off.

    First sandbox has

    inputField0

    inputField1

    and the second sandbox has:

    inputField2

    what I was expecting was

    inputField0

    1. May 13, 2009

      If I hear you aright, you are talking about Calculator tutorial and generated field declarations - this has nothing in common with scopes.

      Scopes are used mainly while editing source code; generated field declarations just have unique names. For now, unique names are produced by generation in "per-session" manner. So, If you generate the models together (in one generation session), names will be unique throughout all models generated in this session.

  2. Sep 30, 2011

    Anonymous

    Testing.

Add Comment