Skip to content

R4: one argument form (Param = expr) and with ({n} = …) text templates (#751) - #772

Merged
ako merged 7 commits into
mainfrom
feature/751-argument-binding
Sep 28, 2026
Merged

ako merged 7 commits into
mainfrom
feature/751-argument-binding

Conversation

@ako

@ako ako commented Sep 27, 2026

Copy link
Copy Markdown
Owner

Part of #751 (R4 in full; the R3 alter … set ( Key: value ) half is left for a follow-up — see below). Tracking: #714.

What changes

One argument form at every call site: Param = expression (no $, = not :):
call microflow/nanoflow/java action/javascript action/external action, web service operation, execute database query, send rest request … with (id = $X), show page M.P(Order = $O), page/button actions and microflow/nanoflow data sources (Action: microflow M.F(Order = $currentObject)), and workflow calls: call microflow M.F(Order = $WorkflowContext) as act1 comment '…' (bare expression, right after the callee).

One text-template form: with ({1} = e, …) for show message and validation feedback (already the form of log and REST templates).

Old spellings are registered deprecated aliases (both language versions warn, fmt --upgrade rewrites them, rewrites computed from the parse tree):

Code Old Canonical
MDL-DEPR006 $Param = e Param = e (quoted only when the name is not a valid parameterName)
MDL-DEPR007 Param: e (show page, page actions, data sources) Param = e
MDL-DEPR008 workflow with (Param = '<expr>') (Param = <expr>) after the callee
MDL-DEPR009 objects [a, b] / parameters [a, b] with ({1} = a, {2} = b)

describe emits the canonical forms everywhere (microflow show page, show message, validation feedback, send rest request, page actions incl. inferred show_page args, data sources, workflow calls). It now also emits a validation feedback's template arguments, which it silently dropped (describe → exec lost them; finding recorded).

Skills (make sync-skills), docs-site, MDL_QUICK_REFERENCE.md, mxcli syntax entries and CHANGELOG are migrated.

Design choices the ADRs did not settle

  • Workflow string argument → no meaning change. The new form is new syntax (a list after the callee), so nothing existing changes meaning; the old with (P = '<expr>') keeps its meaning (the string's content is the expression) and is an alias (MDL-DEPR008), not a gated change. The rewrite unquotes only when the content parses as an MDL expression and reads back as exactly the same stored text (visitor.BareExpression); otherwise it is left and reported (Result.Unrewritten). Writing both lists on one call is an error.
  • describe fallback for workflow arguments. A stored expression that does not read back as itself when bare (surrounding whitespace, text the MDL expression grammar can't parse) is described in the string form, which carries it byte for byte — describe must never alter a stored expression. This is the only place describe can emit a deprecated spelling, and only for such expressions.
  • send rest request keeps its with (…) clause; only the binding form changes ($id = e → id = e). Moving the list next to the operation is a bracket question (R2, R2: three brackets, three meanings — integration documents, navigation/menus, on error, while (3.4) #754), not R4.
  • with ({n} = …) on show message / validation feedback is stored by number; the numbers must be exactly 1..N (the model holds a positional list), otherwise a parse error.
  • Registry codes 006–009 were taken in order; parallel wave-2 PRs may collide on numbers and need a renumber at merge.

Not in this PR (follow-ups)

  • R3: alter <type> X set ( Key: value, … ) with exactly create's keys for page set, odata alter, settings, styling; removing optional colons (type reference, modify attribute A: T). Overlaps R6/R7/R9/R10: verbs, session commands, metadata placement, Studio Pro document names (3.5–3.6) #755 (alter settings runtime) and the existing MDL-DEPR101–103 alter-page aliases, so it is better as its own PR.
  • Snippet call params {$Asset: $var} and fragment args ($p: $Data) still use :/$ (not call sites in the R4 list; fragment args are mxcli macros).
  • mdl-examples/ scripts were not rewritten (the examples upgrade test covers them).

Test plan (what I ran)

  • make build, make lint (Go + TS) — pass.
  • go test ./mdl/visitor/ ./mdl/upgrade/ ./mdl/deprecation/ ./mdl/grammar/ ./mdl/executor/ ./mdl/linter/... ./cmd/mxcli/... — pass (incl. TestUpgrade_ExamplesKeepTheirStatements, TestRegistryExamplesRecordTheirCode, TestGrammarAliasesAreRegistered, TestLargeSkillsWereSplit).
  • go test -tags integration ./mdl/roundtrip/ (PedApp + TestApp, execute-both upgrade property, describe: end every statement with ';', never print '/' (#744) #745 terminator test) — pass; no allowlist entries added.
  • New tests: TestArgumentBindingAliases (17 call-site cases: each old form records its code, has a fix, and builds exactly the canonical statement), workflow bare-expression / no-rewrite / two-lists tests, template numbering, TestUpgrade_ArgumentBinding (golden rewrite keeping case/comments/layout, idempotent), TestUpgrade_WorkflowStringArgumentWithoutBareForm, TestDescribe_* (show message, validation feedback, send rest request, workflow incl. fallback — each output re-parses with no deprecation).
  • Revert checks: restoring the four describe emitters to main fails TestDescribe_* and the updated describe expectations (old output also records MDL-DEPR006/008/009); disabling the visitor's Exit* hooks fails TestArgumentBindingAliases, TestRegistryExamplesRecordTheirCode, TestUpgrade_ArgumentBinding, TestUpgrade_EveryRegistryExample and the workflow/template tests.
  • Studio Pro-authored project: on two copies of TestApp (Mendix 11.14.0) exec'd the same script in canonical and in old spellings (microflow call, show page, show message/validation feedback/log templates, button actions, workflow call microflow): describe of the results is identical, and mxcli docker check on the canonical copy reports 0 errors.

🤖 Generated with Claude Code

ako and others added 7 commits September 27, 2026 18:43
…vision (#768)

`/` shares a precedence level with `*`, `div` and `mod`, so `$a/X * $b/Y`
parsed as `(($a/X) * $b) / Y` and was stored as `$a/X * $b / Y` (and, in a
list filter, `$b / $currentObject/Y`). When a `/ Member` step cannot
attach to the whole left side, attach it to the last operand of the
preceding multiplicative expression. Mendix has no `/` division.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… ({n} = e)) (#751)

Every call site binds an argument as `Param = expression`: call
microflow/nanoflow/java/javascript/external action, web service, execute
database query, send rest request, show page, and page/button actions and
flow data sources. A workflow's call microflow / call workflow takes its
arguments right after the callee as bare expressions. show message and
validation feedback take `with ({1} = e)`.

The old spellings stay as registered deprecated aliases with fmt --upgrade
rewrites computed from the parse tree:
  MDL-DEPR006  $Param = e
  MDL-DEPR007  Param: e
  MDL-DEPR008  workflow `with (Param = '<expr>')` (same meaning: the
               string's content is the expression)
  MDL-DEPR009  objects [..] / parameters [..]

describe writes the canonical forms, and now also writes a validation
feedback's template arguments, which it dropped. A stored workflow
expression that does not read back as itself when bare keeps the string
form in describe.

Skills, docs-site, the quick reference and `mxcli syntax` are migrated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… phrases read as nouns (#751)

The E001 hint's Right example, the control-bar selection suggestion, the
microflow help text and the vega-charts skill pack still wrote an argument
as `$Param = e` / `Param: e`, the spellings MDL-DEPR006/007 now warn on.
The four new registry Structural texts were verb phrases, so check printed
"Rewrite the drop the `$` ...".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… workflow args after the callee)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant