@@ -211,28 +211,63 @@ func (e *Executor) traverseFlow(
211211
212212 trueFlow , falseFlow := findBranchFlows (flows )
213213
214+ // Guard pattern: true branch is a single EndEvent (RETURN),
215+ // but only when the false branch does NOT also end directly.
216+ // If both branches return, use normal IF/ELSE/END IF.
217+ isGuard := false
214218 if trueFlow != nil {
215- e .traverseFlowUntilMerge (trueFlow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
219+ if _ , isEnd := activityMap [trueFlow .DestinationID ].(* microflows.EndEvent ); isEnd {
220+ isGuard = true
221+ // Not a guard if both branches return directly
222+ if falseFlow != nil {
223+ if _ , falseIsEnd := activityMap [falseFlow .DestinationID ].(* microflows.EndEvent ); falseIsEnd {
224+ isGuard = false
225+ }
226+ }
227+ }
216228 }
217229
218- if falseFlow != nil {
219- * lines = append (* lines , indentStr + "ELSE" )
220- visitedFalseBranch := make (map [model.ID ]bool )
221- for id := range visited {
222- visitedFalseBranch [id ] = true
230+ if isGuard {
231+ e .traverseFlowUntilMerge (trueFlow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
232+ * lines = append (* lines , indentStr + "END IF;" )
233+ recordSourceMap (sourceMap , currentID , startLine , len (* lines )+ headerLineCount - 1 )
234+
235+ // Continue from the false branch (skip through merge if present)
236+ if falseFlow != nil {
237+ contID := falseFlow .DestinationID
238+ if _ , isMerge := activityMap [contID ].(* microflows.ExclusiveMerge ); isMerge {
239+ visited [contID ] = true
240+ for _ , flow := range flowsByOrigin [contID ] {
241+ contID = flow .DestinationID
242+ break
243+ }
244+ }
245+ e .traverseFlow (contID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent , sourceMap , headerLineCount , annotationsByTarget )
246+ }
247+ } else {
248+ if trueFlow != nil {
249+ e .traverseFlowUntilMerge (trueFlow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
223250 }
224- e .traverseFlowUntilMerge (falseFlow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visitedFalseBranch , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
225- }
226251
227- * lines = append (* lines , indentStr + "END IF;" )
228- recordSourceMap (sourceMap , currentID , startLine , len (* lines )+ headerLineCount - 1 )
252+ if falseFlow != nil {
253+ * lines = append (* lines , indentStr + "ELSE" )
254+ visitedFalseBranch := make (map [model.ID ]bool )
255+ for id := range visited {
256+ visitedFalseBranch [id ] = true
257+ }
258+ e .traverseFlowUntilMerge (falseFlow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visitedFalseBranch , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
259+ }
260+
261+ * lines = append (* lines , indentStr + "END IF;" )
262+ recordSourceMap (sourceMap , currentID , startLine , len (* lines )+ headerLineCount - 1 )
229263
230- // Continue after the merge point
231- if mergeID != "" {
232- visited [mergeID ] = true
233- nextFlows := flowsByOrigin [mergeID ]
234- for _ , flow := range nextFlows {
235- e .traverseFlow (flow .DestinationID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent , sourceMap , headerLineCount , annotationsByTarget )
264+ // Continue after the merge point
265+ if mergeID != "" {
266+ visited [mergeID ] = true
267+ nextFlows := flowsByOrigin [mergeID ]
268+ for _ , flow := range nextFlows {
269+ e .traverseFlow (flow .DestinationID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent , sourceMap , headerLineCount , annotationsByTarget )
270+ }
236271 }
237272 }
238273 return
@@ -324,28 +359,61 @@ func (e *Executor) traverseFlowUntilMerge(
324359
325360 trueFlow , falseFlow := findBranchFlows (flows )
326361
362+ // Guard pattern: true branch is a single EndEvent (RETURN),
363+ // but only when the false branch does NOT also end directly.
364+ isGuard := false
327365 if trueFlow != nil {
328- e .traverseFlowUntilMerge (trueFlow .DestinationID , nestedMergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
366+ if _ , isEnd := activityMap [trueFlow .DestinationID ].(* microflows.EndEvent ); isEnd {
367+ isGuard = true
368+ if falseFlow != nil {
369+ if _ , falseIsEnd := activityMap [falseFlow .DestinationID ].(* microflows.EndEvent ); falseIsEnd {
370+ isGuard = false
371+ }
372+ }
373+ }
329374 }
330375
331- if falseFlow != nil {
332- * lines = append (* lines , indentStr + "ELSE" )
333- visitedFalseBranch := make (map [model.ID ]bool )
334- for id := range visited {
335- visitedFalseBranch [id ] = true
376+ if isGuard {
377+ e .traverseFlowUntilMerge (trueFlow .DestinationID , nestedMergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
378+ * lines = append (* lines , indentStr + "END IF;" )
379+ recordSourceMap (sourceMap , currentID , startLine , len (* lines )+ headerLineCount - 1 )
380+
381+ // Continue from the false branch (skip through merge if present)
382+ if falseFlow != nil {
383+ contID := falseFlow .DestinationID
384+ if _ , isMerge := activityMap [contID ].(* microflows.ExclusiveMerge ); isMerge {
385+ visited [contID ] = true
386+ for _ , flow := range flowsByOrigin [contID ] {
387+ contID = flow .DestinationID
388+ break
389+ }
390+ }
391+ e .traverseFlowUntilMerge (contID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent , sourceMap , headerLineCount , annotationsByTarget )
392+ }
393+ } else {
394+ if trueFlow != nil {
395+ e .traverseFlowUntilMerge (trueFlow .DestinationID , nestedMergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
336396 }
337- e .traverseFlowUntilMerge (falseFlow .DestinationID , nestedMergeID , activityMap , flowsByOrigin , splitMergeMap , visitedFalseBranch , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
338- }
339397
340- * lines = append (* lines , indentStr + "END IF;" )
341- recordSourceMap (sourceMap , currentID , startLine , len (* lines )+ headerLineCount - 1 )
398+ if falseFlow != nil {
399+ * lines = append (* lines , indentStr + "ELSE" )
400+ visitedFalseBranch := make (map [model.ID ]bool )
401+ for id := range visited {
402+ visitedFalseBranch [id ] = true
403+ }
404+ e .traverseFlowUntilMerge (falseFlow .DestinationID , nestedMergeID , activityMap , flowsByOrigin , splitMergeMap , visitedFalseBranch , entityNames , microflowNames , lines , indent + 1 , sourceMap , headerLineCount , annotationsByTarget )
405+ }
406+
407+ * lines = append (* lines , indentStr + "END IF;" )
408+ recordSourceMap (sourceMap , currentID , startLine , len (* lines )+ headerLineCount - 1 )
342409
343- // Continue after nested merge
344- if nestedMergeID != "" && nestedMergeID != mergeID {
345- visited [nestedMergeID ] = true
346- nextFlows := flowsByOrigin [nestedMergeID ]
347- for _ , flow := range nextFlows {
348- e .traverseFlowUntilMerge (flow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent , sourceMap , headerLineCount , annotationsByTarget )
410+ // Continue after nested merge
411+ if nestedMergeID != "" && nestedMergeID != mergeID {
412+ visited [nestedMergeID ] = true
413+ nextFlows := flowsByOrigin [nestedMergeID ]
414+ for _ , flow := range nextFlows {
415+ e .traverseFlowUntilMerge (flow .DestinationID , mergeID , activityMap , flowsByOrigin , splitMergeMap , visited , entityNames , microflowNames , lines , indent , sourceMap , headerLineCount , annotationsByTarget )
416+ }
349417 }
350418 }
351419 return
0 commit comments