Skip to content

Commit edafafb

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 c50ff9f commit edafafb

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
@@ -557,10 +557,15 @@ func (fb *flowBuilder) addStructuredInheritanceSplit(s *ast.InheritanceSplitStmt
557557
fb.endsWithReturn = savedEndsWithReturn
558558
if allBranchesReturn {
559559
fb.endsWithReturn = true
560-
} else if len(branchTails) == 1 && !branchTails[0].fromSplit {
561-
fb.nextConnectionPoint = branchTails[0].id
562-
fb.nextFlowCase = branchTails[0].caseValue
563560
} else if len(branchTails) > 0 {
561+
// Always emit an ExclusiveMerge when at least one branch continues.
562+
// Previous code skipped the merge when exactly one non-split branch
563+
// continued and wired the parent's next statement directly to that
564+
// branch's tail — but re-describe then buried the parent continuation
565+
// inside the case body, and Studio Pro rejected the terminating
566+
// branches' outgoing flows with CE0079 ("condition value should be
567+
// configured for an outgoing flow") because they had no merge to
568+
// converge on.
564569
merge := &microflows.ExclusiveMerge{
565570
BaseMicroflowObject: microflows.BaseMicroflowObject{
566571
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)