Skip to content

Commit 9a0d45c

Browse files
hjothamendixclaude
andcommitted
fix: always emit merge for continuing inheritance split branches
addStructuredInheritanceSplit took a no-merge shortcut when exactly one non-split branch continued and the rest terminated — it wired the parent's next statement directly to that branch's tail. Two failure modes followed: 1. Re-describe emitted the parent continuation inside the case body (the post-split statement was visually buried inside the first case). 2. Studio Pro raised CE0079 ("condition value should be configured for an outgoing flow") on terminating branches because their cases had no merge to converge on. With this change any surviving branch causes a merge to be emitted, so the parent always resumes after the split. Test: new TestInheritanceSplitAlwaysEmitsMergeWhenBranchContinues asserts that a one-case + terminating-else split still creates the ExclusiveMerge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f9f3758 commit 9a0d45c

2 files changed

Lines changed: 64 additions & 3 deletions

File tree

mdl/executor/cmd_microflows_builder_actions.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,10 +563,15 @@ func (fb *flowBuilder) addStructuredInheritanceSplit(s *ast.InheritanceSplitStmt
563563
fb.endsWithReturn = savedEndsWithReturn
564564
if allBranchesReturn {
565565
fb.endsWithReturn = true
566-
} else if len(branchTails) == 1 && !branchTails[0].fromSplit {
567-
fb.nextConnectionPoint = branchTails[0].id
568-
fb.nextFlowCase = branchTails[0].caseValue
569566
} else if len(branchTails) > 0 {
567+
// Always emit an ExclusiveMerge when at least one branch continues.
568+
// Previous code skipped the merge when exactly one non-split branch
569+
// continued and wired the parent's next statement directly to that
570+
// branch's tail — but re-describe then buried the parent continuation
571+
// inside the case body, and Studio Pro rejected the terminating
572+
// branches' outgoing flows with CE0079 ("condition value should be
573+
// configured for an outgoing flow") because they had no merge to
574+
// converge on.
570575
merge := &microflows.ExclusiveMerge{
571576
BaseMicroflowObject: microflows.BaseMicroflowObject{
572577
BaseElement: model.BaseElement{ID: model.ID(types.GenerateID())},
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
package executor
4+
5+
import (
6+
"testing"
7+
8+
"github.com/mendixlabs/mxcli/mdl/ast"
9+
"github.com/mendixlabs/mxcli/sdk/microflows"
10+
)
11+
12+
// TestInheritanceSplitAlwaysEmitsMergeWhenBranchContinues guards against a
13+
// describe/exec roundtrip regression where `addStructuredInheritanceSplit`
14+
// used to take a "no-merge shortcut" when exactly one non-split branch
15+
// continued: it wired the parent's next statement directly to the
16+
// continuing case's tail. Two things broke:
17+
//
18+
// 1. Re-describe emitted the parent's continuation inside the case body
19+
// (visually burying statements in the wrong scope).
20+
// 2. Studio Pro raised CE0079 ("condition value should be configured for
21+
// an outgoing flow") on terminating branches because their cases had
22+
// no merge to converge on.
23+
func TestInheritanceSplitAlwaysEmitsMergeWhenBranchContinues(t *testing.T) {
24+
fb := &flowBuilder{
25+
spacing: HorizontalSpacing,
26+
measurer: &layoutMeasurer{},
27+
}
28+
29+
// An InheritanceSplit with one continuing case (`CastedA`) and a
30+
// terminating else that returns. Before the fix this took the no-merge
31+
// shortcut because branchTails == 1 && !fromSplit.
32+
fb.addStructuredInheritanceSplit(&ast.InheritanceSplitStmt{
33+
Variable: "obj",
34+
Cases: []ast.InheritanceSplitCase{
35+
{
36+
Entity: ast.QualifiedName{Module: "M", Name: "CastedA"},
37+
Body: []ast.MicroflowStatement{
38+
&ast.LogStmt{Level: ast.LogInfo, Message: &ast.LiteralExpr{Kind: ast.LiteralString, Value: "continue"}},
39+
},
40+
},
41+
},
42+
ElseBody: []ast.MicroflowStatement{
43+
&ast.ReturnStmt{},
44+
},
45+
})
46+
47+
var merge *microflows.ExclusiveMerge
48+
for _, obj := range fb.objects {
49+
if m, ok := obj.(*microflows.ExclusiveMerge); ok {
50+
merge = m
51+
}
52+
}
53+
if merge == nil {
54+
t.Fatal("expected ExclusiveMerge to be created when one branch continues — no-merge shortcut regression")
55+
}
56+
}

0 commit comments

Comments
 (0)