Constraint causes problem


I have a Concept A that extends Expression and has a reference on Concept B.

A is just a "connector" to B so that I can build a bool expression out of different Bs  :   B1 => B2 && B3 .

My ultimate goal is recalculate the expression every time a reference is changed. I know I could use a listener, but I dont want to.

What I did is use the setHandler of the Contraints Aspect on Concept A. The problem are the contents of the 3 parameters of the setHandler.

referenceNode  :   gives me a copy of the original that is not in the tree, but will be in the tree when i check after the setHandler. The ref is alredy pointing to the new ref. How I know it is not in the tree , i checked the NodeID before and after and also calling "referenceNode.parent" in the setHandler gives me NULL

oldRef : gives me NULL

newRef : gives me the newRef


When I build a Concept A that does NOT EXTEND  Expression and  has a ref to Concept B, the setHandler in the Constraint gives me the original node and everything is fine.

So my assumption is that some sidetransform or something that I inherite from Expression does create a copy before the setHanlder is called.

I seached for something like this in the baseLanguage but wasnt sucessfull.

Anyone has an idea where the problem is ?


Thx in advance.



I think the first behavior you described may be the way MPS handles "smart references" which are concepts that only have a reference to another concept. Instead of offering a single menu item for "A", MPS offers all possible reference targets (all Bs) and wraps them in an instance of A automatically. I can't explain why the second behavior is different though - maybe you are trying it out in a different editor.


Thx for the quick answer. It seems you have pointed me to the right solution. The "extend expression" seems to have not really been the problem. I will try to not use a smart reference at this place. That does mean I have to provide the scope for my reference myself, right?


I think you would have to provide a correct scope in both cases if the default one doesn't suit you. Or am I missing something?


With the smartreference , I was presented with all Bs to select from. If I change it from a smartReference to a [0..1] to avoid that the smart ref creates a copy in the constraint, I dont get anything presented to me when I push cmd+space. So I assume I have to provide a scope in the constraint and find the possible ref targets myself. The thing is they dont show when I press cmd+space.

I did this as scope  in the constraint :

Scope :

(exists, referenceNode, contextNode, containingLink, linkTarget, operationContext, enclosingNode, model, position, contextRole)->Scope {
  new ListScope(referenceNode.ancestor<concept = ProductLineConfig>.descendants<concept = Feature>) {
    public string getName(node<> child) {
      ((node<INamedConcept>) child).name;


Please sign in to leave a comment.