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.


Comment actions Permalink

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.

Comment actions Permalink

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?

Comment actions Permalink

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?

Comment actions Permalink

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.