How to specialize a node of concept X to concept Y where Y extends X Follow
Hi,
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!
Cheers,
LaAck
Please sign in to leave a 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;
....
}
}
}
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.
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!
Yes, you are correct. "replace with initialized" should be used, sorry for the omission.
Vaclav