How to specialize a node of concept X to concept Y where Y extends X


I'm currently trying to write an intention that converts a node of a concept (let's call it X) to a node of a different concept (let's call it Y and let Y be an extension of concept X). 

As far as I understand, conversion should be possible since Y has at least all properties etc. that X has. However, I've tried to simply cast the node with the colon operator ...

node<Y> replacement = node:Y;
node.replace with(replacement);

If I do so, the workbench throws a "NodeCastException: Can't cast node: ...". Though this was somehow expected (referring to the Java world), I wonder how to get this conversion running. Of course, I could simply copy all the things to a freshly created node of concept Y but this is ugly.

Thanks in advance for your hints!


Comment actions Permalink
Official comment

The ":" cast operator merely expands the type information about the node, it does not create a new node while copying the properties from the old node. So your code "node:Y" is supposed to fail.

You have to create a new node, perhaps as:

node<Y> n = node.replace with new (Y)

To avoid copying the properties from "node" to your new node, use NodeFactories in the actions model:

node factories XandY_conversions

node concept: Y
description : <none>
set-up : (newNode, sampleNode, enclosingNode, model)->void {
    ifInstanceOf (sampleNode is X nodeX) {
        newNode.property1 = nodeX.property1;

Comment actions Permalink

Thank you very much for the fast reply. Ok, the issue with the cast operator I understand completely and I also expected something like that.

However, I'm a bit surprised that I have to copy all properties and child nodes programmatically to the new node. But if this is the current "clean way", I will do it like you suggested.  

Comment actions Permalink

I've implemented the node factory now but it seemed not to be used. Replacing the old node with a new instance of concept Y leads to an "empty" node of concept Y, i.e. no properties and no child nodes are copied. According to the documentation I have to use "replace with new initialized" instead of "replace with" (MPS 2019.3). After I changed it to "replace with new initialized" everything works now. Thank's a lot! 

Comment actions Permalink

Yes, you are correct. "replace with initialized" should be used, sorry for the omission.




Please sign in to leave a comment.