Wrong messages might be code generated
I experienced this in the Workflow concern in the following case:
WorkflowUtility
defines getCurrentExecutor
as follows:
Also, the methods SequenceNode.depositToken
and ControlFlowNode.depositToken
call it. These methods are defined as follows:
The result of the code generation, however, might look like this:
static WorkflowExecutor getCurrentExecutor() {
for (int i = 0; i < numberOfActivations; i++) {
this.workflowNode = toActivate.get(this.i);
if (i == numberOfActivations) {
currentExecutor.scheduleNextNode(this.workflowNode);
} else {
WorkflowUtility.spawnExecution(this.workflowNode, c);
}
}
}
As you can see, this is the part after the call to getCurrentExecutor
from ControlFlowNode.depositToken
.
Sometimes, the code is correctly generated as defined in the message view, but sometimes it is not.
Comments (10)
-
reporter -
reporter Tracking it further down:
getMessagesForOperation
usesgetMessageFragments
, which searches for all fragments after the receive event. In the above case, there is the message spawnExecution inside the CombinedFragment. It does find this fragment (erroneously) and hence that call is considered.If I am not mistaken, if there is nested behaviour, there is for certain a reply message (even for void methods). What is necessary is to make sure that this reply message exists. The
getMessageFragments
query actual finds so called separatorFragments (send event of reply message), however, in the case of no such fragment being found it uses all subsequent fragments on that lifeline. -
reporter References
#425: Ensures that no message fragments are returned if no separator fragment has been found.In case no separator fragment is found (reply message of the message or incoming message), no fragments should be returned. Therefore, the index will be set to 0.
→ <<cset ac3522d51d9e>>
-
reporter The above fix, however, does not prevent the following case:
This is mainly a problem of how it is implemented. For instance, the index of fragments on the lifeline is not considered. However, I suggest that the second condition of the following is removed. This would mean that nested behaviour always ends with a reply message (even for void operations), just like the message view itself always has a reply message.
let message : Message = f.oclAsType(MessageEnd).message in (message.messageSort = MessageSort::reply and f = message.sendEvent and m.signature = message.signature) or (message.messageSort <> MessageSort::reply and not message.selfMessage and f = message.receiveEvent)
-
reporter References
#390,#425: Adds test cases to determine whether reply was created or not.→ <<cset ab933d4e4d15>>
-
reporter References
#390,#425: Fixes CreationTestHelper when checking arguments of reply messages.→ <<cset 66de295b7482>>
-
reporter References
#425: Adds creation of reply message also for void operations.→ <<cset ee6d2ec11e85>>
-
reporter Since there are many message views with no reply messages for nested behaviour, I am leaving the second condition in the code generator to still support it.
-
reporter - changed status to resolved
Merged in Issues/fixes-mv-codegen (pull request #83)
-
reporter References
#425: Updates condition for fragment creation after the send event.Void operations also have a reply message if their message view is not defined.
→ <<cset 20485d1268d1>>
- Log in to comment
It seems that
getMessagesForOperation(op : Operation)
in *commonHelpers.mtl` finds two messages in this case. Since it is converted to a set, I think the order depends and hence produces different results.I have the feeling that this query is implemented in this way, because of nested behaviour.