How to restrict types to use without breaking parent node

Hello,

i am starting to learn MPS and i am having troubles with restricting types to use. i would like to use custom types; some inherits from Float, String, some others like Array not. I did manage to filter out all types i dont want from the completion menu by following this thread:

https://mps-support.jetbrains.com/hc/en-us/community/posts/205828509-How-to-constraint-a-subset-of-baselanguages-types-and-expression

So I have end up with an Interface concept used to add the type needed and a constraint in that interface which check againts all the types I want to show. When I am in editor and in context where should go a type, everything is as expected, i only get types specified in conditions.

The problem resides in that for example declaring a function to have a return type makes the contraint fail for any other child, for example a body of type StatetementList. 

Can anyone point me in the right direction with this problem? Is there a better solution for addressing this types restrictions?

Thanks in advance,

David

6 comments

I suspect your constraint code does not take into account the kind (role) of a child. Could it be it?

Vaclav

 

1

Hi Vaclav,

thanks for answering. I am not sure actually, sorry. What does that means: "does not take into account the kind (role) of a child"?

The code I have in the Interface is: 

Then I use that in Function concept constraint like:

With the last two extra OR conditions i manage to remove the error (Node can not be parent of node) because I am also checking for every child of function, this is Param and Statements. Now the question that arise is:

Do I need to write all those checkings for every concept that I consider "Typed"? Is there a better way for this?

I also read this other thread: https://mps-support.jetbrains.com/hc/en-us/community/posts/205828169-Using-constraints-defined-on-super-concept

And also tried to use type rules, but with types rules i am still lacking of knowledge so not sure where to go in that direction.

 

thanks in advance.

David

1

Hi David,

instead of checking for Statement and Param in your "can be parent", you should perhaps test the "link" and only worry about the type concept if the child is supposed to be in the "type" role, not "body" or "parameter".

Vaclav

 

0

Hi Vaclav,

thanks for the hints! While it helped me to find in docs interesting funtionality like `childNode.hasRole(ITyped : type)` i am afraid I don't know how to use it properly, if it is the right way and i am not able still to follow you :(

i have make some trial and error since it is difficult for me to check what comes in `link` parameter of my "can be parent", I have check `getRoleName()` method but it seems it is deprecated so i would prefer not to use it in any case.

One things i am assuming it is "must" by now is:

I need to make the check `node.isBuiltInType(childConcept)` in any case, if not i dont get type list filtered. Is this assumption correct?

Then I have tried to play with conditions like `link.isValid() && childNode.hasRole(ITyped : type)` and variations of its but still get the error "Node X can not be parent of node Y".

This did not work either:

```

if (childNode.hasRole(ITyped : type)) {
    return node.isBuiltInType(childConcept);
}


return true;

```

I have tried to use also `link.getTargetConcept()` but once i have the SModel instance i dont know what to do with it.

 

What am i missing here?

 

Thanks again for your time.

David

0

I guess this should do the trick:

if (link/ITyped : type/ :eq: link) { 
    return node.isBuiltInType(childConcept); 
}

return true;

0

Your are right!!

i tried the link query also but comparing with names as string. Never came up with idea of compare with :eq: operator against the link parameter :-)

I need to read more about this one and roles.

like always, solution is simpler that you expect.

Thanks you very much Vaclav for taking time to guide and provide me with the solution.

David

0

Please sign in to leave a comment.