Automatic editor node type inference for string literal/string expression
(Apologies if this is an easy one, and also please let me know if there's a better way to do what I'm trying to do.)
I'm building a DSL in which one of my concepts (call it MyFunction) has a child that must either be a string literal or a concept that ultimately resolves to a string. I've set up a simple concept hierarchy like this:
AbstractStringExpression
-- StringLiteralExpression (has property "value" of type string)
-- AFunctionThatReturnsString
-- AnotherFunctionThatReturnsString
And I've got the aforementioned original concept, MyFunction, has a child called value of type AbstractStringExpression (cardinality 1).
What I'm having trouble accomplishing is this: when the user is entering the "value" child of MyFunction, I'd like to have the editor infer that the value the user is entering is a string literal, either by the user starting out by typing double-quotes, or once the text the user enters clearly doesn't match the alias of any concept that descends from AbstractStringExpression, and subsequently automatically substitute a StringLiteralExpression node for the initially null AbstractStringExpression node.
I see that the "expressions" sample that ships with MPS does this for the initializer in variable declarations; the initial node is of concept Expression, but once you type a non-zero number it is automatically substituted to IntegerConstant, and if you subsequently enter a decimal, it is again substituted to FlatConstant. So I know that theoretically this type of inference and node substitution based on the user's input is possible, but I just can't seem to figure out how it is done.
Any input you can give me would be greatly appreciated.
Thanks,
Scott
I'm building a DSL in which one of my concepts (call it MyFunction) has a child that must either be a string literal or a concept that ultimately resolves to a string. I've set up a simple concept hierarchy like this:
AbstractStringExpression
-- StringLiteralExpression (has property "value" of type string)
-- AFunctionThatReturnsString
-- AnotherFunctionThatReturnsString
And I've got the aforementioned original concept, MyFunction, has a child called value of type AbstractStringExpression (cardinality 1).
What I'm having trouble accomplishing is this: when the user is entering the "value" child of MyFunction, I'd like to have the editor infer that the value the user is entering is a string literal, either by the user starting out by typing double-quotes, or once the text the user enters clearly doesn't match the alias of any concept that descends from AbstractStringExpression, and subsequently automatically substitute a StringLiteralExpression node for the initially null AbstractStringExpression node.
I see that the "expressions" sample that ships with MPS does this for the initializer in variable declarations; the initial node is of concept Expression, but once you type a non-zero number it is automatically substituted to IntegerConstant, and if you subsequently enter a decimal, it is again substituted to FlatConstant. So I know that theoretically this type of inference and node substitution based on the user's input is possible, but I just can't seem to figure out how it is done.
Any input you can give me would be greatly appreciated.
Thanks,
Scott
Please sign in to leave a comment.
I suggest that you create a node substitution action as follows:
node substitute actions <no name> substituted node: AbstractStringExpression // <no description> condition : <none> common initializer : <no common variables> .................................... <no supplemental initializer> actions : remove defaults ---------- add custom items (output concept: StringLiteralExpression) simple item can substitute <default> matching text " description text <default> icon node <default> type <default> create child node (pattern, parentNode, currentTargetNode, childConcept, model, operationContext)->node<StringLiteralExpression> { currentTargetNode.replace with new initialized(StringLiteralExpression); } selection handler <default> ---------- add custom items (output concept: StringLiteralExpression) simple item can substitute (pattern, strictly, parentNode, currentTargetNode, childConcept, model, operationContext)->boolean { pattern.isNotEmpty && pattern :ne: "afunc" && pattern :ne: "\""; } matching text <default> description text <default> icon node <default> type <default> create child node (pattern, parentNode, currentTargetNode, childConcept, model, operationContext)->node<StringLiteralExpression> { node<StringLiteralExpression> newNode = currentTargetNode.replace with new initialized(StringLiteralExpression); newNode.value = pattern; newNode; } selection handler <default> ---------- add custom items (output concept: AFunctionThatReturnsString) simple item can substitute <default> matching text afunc description text <default> icon node <default> type <default> create child node (pattern, parentNode, currentTargetNode, childConcept, model, operationContext)->node<AFunctionThatReturnsString> { currentTargetNode.replace with new initialized(AFunctionThatReturnsString); } selection handler <default>