Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
-- ============================================================================
-- Bug #306: Annotations emitted before unsupported-activity comments
-- ============================================================================
--
-- Symptom (before fix):
-- Activities whose BSON type isn't yet implemented in mxcli's describer
-- render as `-- unsupported: <Type>` comments. Before the fix, the
-- describer still prefixed these comment lines with `@position`,
-- `@anchor`, etc. The grammar only accepts annotations as prefixes of
-- real microflow statements (not comments), so the resulting MDL failed
-- to re-parse with errors like:
-- line N:0 mismatched input '@' expecting {...}
--
-- After fix:
-- When a formatted statement begins with `--`, `emitObjectAnnotations`
-- is skipped — only the comment is emitted. Annotations on SUPPORTED
-- activities continue to be emitted as before.
--
-- Reproducibility note:
-- The unsupported-activity branch can only be triggered by an .mpr
-- containing a BSON activity type that mxcli does not yet describe
-- (typical examples are very new or rarely-used activity types). Pure
-- MDL cannot create such an activity. The Go-side regression
-- `TestTraverseFlow_UnsupportedActivitySkipsAnnotations` covers that
-- path directly.
--
-- This script provides a POSITIVE CONTROL: a microflow whose every
-- activity carries position / caption / anchor annotations. Its describe
-- output must (a) parse with `mxcli check`, and (b) round-trip cleanly,
-- confirming the annotation-emission codepath still works for the
-- common case.
--
-- Usage:
-- mxcli exec mdl-examples/bug-tests/306-describer-annotations-before-unsupported-comment.mdl -p app.mpr
-- mxcli -p app.mpr -c "describe microflow BugTest306.MF_AnnotatedFlow"
-- The output must re-execute cleanly against the same project.
-- ============================================================================

create module BugTest306;

create microflow BugTest306.MF_AnnotatedFlow (
$input: string
)
returns string as $result
begin
declare $result string = empty;

@caption 'log entry'
log info node 'BugTest306' 'flow started';

@caption 'guard'
if $input != empty then
@caption 'happy path'
set $result = 'value: ' + $input;
else
set $result = 'no value';
end if;

return $result;
end;
/
12 changes: 12 additions & 0 deletions mdl/executor/cmd_microflows_show_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,18 @@ func emitActivityStatement(
return
}

// When the activity is unsupported by the describer (e.g. CallWebServiceAction,
// CastAction, InheritanceSplit placeholder) we fall back to emitting just an
// MDL line comment. Decorating that comment with @position/@anchor/@annotation
// leaves the annotations orphaned — the grammar only accepts `annotation*`
// as a prefix of a real microflowStatement, so line comments preceded by
// annotations cause "no viable alternative at input '@position...end'" during
// exec. Emit the comment on its own instead.
if strings.HasPrefix(strings.TrimSpace(stmt), "--") {
*lines = append(*lines, indentStr+stmt)
return
}

// Emit @ annotations before the statement
emitObjectAnnotations(obj, lines, indentStr, annotationsByTarget, flowsByOrigin, flowsByDest)

Expand Down
43 changes: 43 additions & 0 deletions mdl/executor/cmd_microflows_traverse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,49 @@ func TestTraverseFlow_IfElse(t *testing.T) {
}
}

// TestTraverseFlow_UnsupportedActivitySkipsAnnotations verifies that when the
// describer falls back to a `-- Unsupported action type: ...` placeholder, it
// does NOT also emit @position / @anchor before the comment. Annotations are
// only valid as a prefix of real MDL statements; orphaning them above a pure
// line comment triggers `no viable alternative at input '@position...end'`
// during `exec`.
func TestTraverseFlow_UnsupportedActivitySkipsAnnotations(t *testing.T) {
e := newTestExecutor()

activityMap := map[model.ID]microflows.MicroflowObject{
mkID("start"): &microflows.StartEvent{BaseMicroflowObject: mkObj("start")},
mkID("soap"): &microflows.ActionActivity{
BaseActivity: microflows.BaseActivity{BaseMicroflowObject: mkObj("soap")},
Action: &microflows.UnknownAction{TypeName: "Microflows$CallWebServiceAction"},
},
mkID("end"): &microflows.EndEvent{BaseMicroflowObject: mkObj("end")},
}

flowsByOrigin := map[model.ID][]*microflows.SequenceFlow{
mkID("start"): {mkFlow("start", "soap")},
mkID("soap"): {mkFlow("soap", "end")},
}

var lines []string
visited := make(map[model.ID]bool)
e.traverseFlow(mkID("start"), activityMap, flowsByOrigin, nil, visited, nil, nil, &lines, 0, nil, 0, nil)

for _, line := range lines {
if contains(line, "@position") {
t.Errorf("expected no @position prefix before unsupported-action comment, got: %v", lines)
}
}
found := false
for _, line := range lines {
if contains(line, "Unsupported action type") {
found = true
}
}
if !found {
t.Errorf("expected unsupported-action comment, got: %v", lines)
}
}

// =============================================================================
// collectErrorHandlerStatements
// =============================================================================
Expand Down