feat: preserve change object refresh modifier#363
Conversation
Mendix change-object actions can have RefreshInClient=true even when they also change members, but MDL had no syntax for that flag. Describing and rebuilding such an action therefore rewrote the flag to false. The grammar now accepts an optional `refresh` modifier on change-object statements, the AST carries that flag, the formatter emits it for refreshed change actions, and the builder writes it back to ChangeObjectAction.RefreshInClient. Tests cover parser, formatter, and builder behavior with and without member assignments. The branch also adds a draft proposal, doctype fixture, quick-reference entry, and skill guidance; `mxcli check` on the fixture plus make build, make lint-go, and make test pass locally.
4b12de0 to
c1d6a85
Compare
AI Code ReviewWhat Looks GoodThe PR implements the change object refresh modifier feature comprehensively and correctly:
RecommendationThe PR is ready for approval. It correctly implements the feature following all architectural guidelines, includes proper tests and documentation, and maintains consistency with existing MDL patterns. No changes are needed. Approve Automated review via OpenRouter (Nemotron Super 120B) — workflow source |
ako
left a comment
There was a problem hiding this comment.
Review — feat: preserve change object refresh modifier
Overview
Clean, minimal PR. The grammar change is one token (REFRESH?) consistent with the existing COMMIT ... REFRESH? and ROLLBACK ... REFRESH? pattern. The full-stack pipeline (grammar → visitor → AST → builder → formatter) is complete, test coverage is good, and the s.RefreshInClient || len(s.Changes) == 0 expression in the builder correctly preserves the existing auto-refresh-on-empty logic.
Info: describe output changes for existing empty-change actions (intentional, but undocumented)
Before this PR, describe on an MPR whose empty ChangeObjectAction had RefreshInClient = true in BSON emitted change $Customer; (no refresh — the formatter didn't know about the flag). After this PR it emits change $Customer refresh;.
Both forms exec to identical BSON, so the roundtrip is stable. But any user who previously saved described MDL scripts will see the output diverge. This is intentional (making the implicit flag explicit) but the PR summary doesn't mention it. Worth a one-line note in the PR description so users aren't surprised by diff noise on describe output for existing projects.
Minor: CE0032 reference dropped from the builder comment
The original comment included:
// The CE0032 message mentions only items/commit, but mx check accepts
// RefreshInClient=true as the third valid escape.
The new comment omits the CE0032 reference. That error code is exactly what a developer would search for when wondering why empty changes force RefreshInClient = true. Worth keeping.
Minor: .test.mdl suffix — fourth PR in this batch with this CI gap
change_refresh_modifier.test.mdl won't be picked up by TestMxCheck_DoctypeScripts. Same issue flagged in PRs #334, #336, and #362. Rename to .mdl.
Positive
REFRESHis already a keyword token — no new lexer rules needed.- Grammar placement (
REFRESH?after the optional member list) is unambiguous and consistent withCOMMIT/ROLLBACK. - Visitor one-liner
stmt.RefreshInClient = changeCtx.REFRESH() != nilis correct. - Builder correctly ORs the explicit flag with the auto-refresh-on-empty condition.
- Both member and no-member formatter paths emit
refreshcorrectly. - Existing
TestEmptyChangeObjectRefreshesInClientandTestFormatAction_ChangeObject_NoChangestests are unaffected (both useRefreshInClient = false).
Batches the remaining polish items ako flagged in PRs that already merged: - PR mendixlabs#357 (Java return-type inference): remove the dead `case javaactions.ListType:` value form, replace the exprToString→strip→lookup string-mangling with a direct `*ast.VariableExpr` type assertion, and add the missing unit test for `*javaactions.EntityType` return registration. - PR mendixlabs#363 (change refresh modifier): restore the CE0032 reference in the `addChangeObjectAction` comment so developers searching for the Studio Pro error code find the inference logic. - PR mendixlabs#364 (enum split): collapse the dual `return true` branches of `isTerminalStmt`'s EnumSplitStmt arm into one and expand the comment documenting the intentional divergence from `bodyReturns`. - PR mendixlabs#364 minor: add a doc comment on `hasExplicitFalseBranchAnchor` explaining the Top→Bottom heuristic, and add TestHasExplicitFalseBranchAnchor covering nil, default, and single-sided cases. Validation: make build, make test, make lint-go. Related: mendixlabs#463 (walkStatements refactor), mendixlabs#468 (TitleOverride nil). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Batches the remaining polish items ako flagged in PRs that already merged: - PR mendixlabs#357 (Java return-type inference): remove the dead `case javaactions.ListType:` value form, replace the exprToString→strip→lookup string-mangling with a direct `*ast.VariableExpr` type assertion, and add the missing unit test for `*javaactions.EntityType` return registration. - PR mendixlabs#363 (change refresh modifier): restore the CE0032 reference in the `addChangeObjectAction` comment so developers searching for the Studio Pro error code find the inference logic. - PR mendixlabs#364 (enum split): collapse the dual `return true` branches of `isTerminalStmt`'s EnumSplitStmt arm into one and expand the comment documenting the intentional divergence from `bodyReturns`. - PR mendixlabs#364 minor: add a doc comment on `hasExplicitFalseBranchAnchor` explaining the Top→Bottom heuristic, and add TestHasExplicitFalseBranchAnchor covering nil, default, and single-sided cases. Validation: make build, make test, make lint-go. Related: mendixlabs#463 (walkStatements refactor), mendixlabs#468 (TitleOverride nil). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Adds explicit MDL syntax for preserving
ChangeObjectAction.RefreshInClient.Changes
change $Object refresh;andchange $Object (...) refresh;.refreshwhen describing change-object actions withRefreshInClient=true.Validation
go test ./mdl/visitor -run TestChangeObjectParsesRefreshgo test ./mdl/executor -run 'Test(FormatAction_ChangeObject.*Refresh|ChangeObjectBuilderWritesRefreshInClient)'./bin/mxcli check mdl-examples/doctype-tests/change_refresh_modifier.test.mdlmake buildmake lint-gomake testCloses #345
Part of #332