Left Transfrom on Expressions
Hi Pros,
i m having some issues with left transformations. My Problem is very similar to the Situation we have with the SNodeTypeCastExpression
if we have something similar to node : DotExpression and i place the cursor straight before the n of node, typing &&
i get something like [ <exp> && node : DotExpression ] and not [ <exp> && node ] : DotExpression (the [ should denote the actual AST)
I have a concept called StatusOf with an editor like <exp> of <someStatusRef>. Now if the user types && left of the <exp> in the editor, it becomes
[<exp> && <exp>] of <someStatusRef> while it should become [<exp> && <exp> of <someStatusRef>]
Hope that i put the problem in some understandable form ...
Any ideas or recommendations?
Dan
Please sign in to leave a comment.
Hi Dan,
you can take inspiration from how BaseLanguage does this. Expressions have priorities and when performing a side transformation the priorities of the "inserted" binary expression is being compared with the priorities of the context expression as well as its parents (up to some level). This way the proper place in the AST is located and the transformation then applied in that place.
See PrecedenceUtil.processLeftTransform() and PrecedenceUtil.getTargetForLeftTransform().
Best,
Vaclav
Hi Vaclav,
thanks for comming back on my question. I just checked the PrecedenceUtil and the priorities coded there. However, i did not realize how i can hook in and declare priorities. Guess i need a prio under DEFAULT, so that the left transform is applied on the parent, and not on the actual exp.
My StatusOf concept mentioned in my initial post is an extension of the baselang expression concept. I did not find any methods i can overwrite in the behaviour aspect. Is there an example how to interfere?
Cheers,
Dan
Judging by the source code of PrecedenceUtil, your StatusOf concept has to extend BinaryOperation and override its `getPriority()` method to return a value from 2 to 11 so that it is handled by the switch in PrecedenceUtil.getPriority().
`&&` has a priority of 3 so anything higher than 3 will cause your StatusOf operator to bind tighter than `&&`, meaning that `a && b of c` will be parsed as `a && (b of c)`.
Hi Sergej,
thanks for comming back on this issue.
BinaryOperation comes with a leftExpression and a rightExpression. Both have cardinality of 1, thus, demanding 2 Expressions. The Editor will report an error if those expressions are not present.
I do not have a left and a right exp in the statusof. So i can not easily extend BinaryOperation. Is there no other solution to this issue. I even thought about providing an intention for the user to fix things after the left transform (as a last resort).
Cheers,
Dan
In this case your only option seems to be to ask Vaclav to make the priority mechanism extensible.
You could create an auto-applied quick fix, too.
You are talking about a type system quick fix, right? How can i auto-apply it?
(1) Define Typesystem Rule reporting the problem
(2) Link that rule to a quick-fix.
Guess Vaclav has to make the prio mechansim extensible. Side-transforms are quite important when working with expressions. And the priority is also key ...
Ok, found it. There is a apply immediately in the "intention to fix an error" ...
Indeed, as you and Sergej have already discovered, the mechanism of assigning precedence to expressions in BL is not extensible and so you cannot have precedence other than DEFAULT for your expression, unless you find it possible to extend any of the existing expressions.
I can think of introducing markup interfaces, such as IDotExpressionLikePrecedence or IUnaryExpressionLikePrecedence that when implemented would drive the precedence assignment. Would that be a viable solution?
Vaclav
Hi Vaclav,
i implemented an typesystem rule identifying the "incorrect" side transform and fixing it immediatelly. That works like charm. Amazing what one can do with MPS!!
Why not have a virtual method "getSideTransformPriority()" in the behaviour aspect of expression? Then one has not to know about markup interfaces, but specifying a prio is necessary when extending...
Dan
I'm happy to hear that you succeeded..
A number returning method would demand the user to know the numbers, so basically the private Precedence enum would become the part of the API. I find names like IDotExpressionLikePrecedence more telling.