Skip to content

Commit 25a4252

Browse files
authored
Merge pull request #263 from hjotha/submit/microflow-nested-caption-preservation
fix: preserve decision/loop captions across nested control flow
2 parents 67263fa + 94bded8 commit 25a4252

4 files changed

Lines changed: 407 additions & 2 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
-- ============================================================================
2+
-- Bug #263: Preserve decision/loop captions across nested control flow
3+
-- ============================================================================
4+
--
5+
-- Symptom (before fix):
6+
-- `@caption` on an outer IF/LOOP/WHILE was being overwritten by the inner
7+
-- IF/LOOP's caption because `pendingAnnotations` was shared mutable state
8+
-- across recursive addStatement calls. Annotations attached to the outer
9+
-- split ended up bound to the inner split, and the outer split inherited
10+
-- whatever caption the inner statement carried.
11+
--
12+
-- After fix:
13+
-- addIfStatement / addLoopStatement / addWhileStatement snapshot + clear
14+
-- `pendingAnnotations` before recursing, then re-apply to their own activity
15+
-- after it's created. The WHILE case also gained explicit handling in
16+
-- mergeStatementAnnotations (previously fell through to `default: nil`).
17+
--
18+
-- Usage:
19+
-- mxcli exec mdl-examples/bug-tests/263-nested-caption-preservation.mdl -p app.mpr
20+
-- Open in Studio Pro — each split/loop displays its own caption, not
21+
-- inherited from a nested statement.
22+
-- ============================================================================
23+
24+
create module BugTest263;
25+
26+
create microflow BugTest263.MF_NestedCaptions (
27+
$S: string
28+
)
29+
returns boolean as $ok
30+
begin
31+
declare $ok boolean = false;
32+
33+
@caption 'String not empty?'
34+
if $S != empty then
35+
@caption 'Right format?'
36+
if isMatch($S, 'x') then
37+
return true;
38+
else
39+
return false;
40+
end if;
41+
else
42+
return false;
43+
end if;
44+
end;
45+
/

mdl/executor/cmd_microflows_builder_annotations.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ func getStatementAnnotations(stmt ast.MicroflowStatement) *ast.ActivityAnnotatio
3737
return s.Annotations
3838
case *ast.LoopStmt:
3939
return s.Annotations
40+
case *ast.WhileStmt:
41+
return s.Annotations
4042
case *ast.LogStmt:
4143
return s.Annotations
4244
case *ast.CallMicroflowStmt:
@@ -116,8 +118,8 @@ func (fb *flowBuilder) applyAnnotations(activityID model.ID, ann *ast.ActivityAn
116118
continue
117119
}
118120

119-
// @caption, @color, and @excluded — only applicable to ActionActivity
120-
if activity, ok := obj.(*microflows.ActionActivity); ok {
121+
switch activity := obj.(type) {
122+
case *microflows.ActionActivity:
121123
if ann.Caption != "" {
122124
activity.Caption = ann.Caption
123125
activity.AutoGenerateCaption = false
@@ -128,6 +130,22 @@ func (fb *flowBuilder) applyAnnotations(activityID model.ID, ann *ast.ActivityAn
128130
if ann.Excluded {
129131
activity.Disabled = true
130132
}
133+
case *microflows.ExclusiveSplit:
134+
// Splits carry a human-readable Caption (e.g. "Right format?")
135+
// independent of the expression/rule being evaluated.
136+
if ann.Caption != "" {
137+
activity.Caption = ann.Caption
138+
}
139+
case *microflows.InheritanceSplit:
140+
if ann.Caption != "" {
141+
activity.Caption = ann.Caption
142+
}
143+
case *microflows.LoopedActivity:
144+
// LOOP / WHILE activities can carry a caption just like
145+
// splits and action activities.
146+
if ann.Caption != "" {
147+
activity.Caption = ann.Caption
148+
}
131149
}
132150

133151
break

0 commit comments

Comments
 (0)