Skip to content

feat: preserve change object refresh modifier#363

Merged
ako merged 2 commits intomendixlabs:mainfrom
hjotha:submit/change-object-refresh-modifier
Apr 30, 2026
Merged

feat: preserve change object refresh modifier#363
ako merged 2 commits intomendixlabs:mainfrom
hjotha:submit/change-object-refresh-modifier

Conversation

@hjotha
Copy link
Copy Markdown
Contributor

@hjotha hjotha commented Apr 27, 2026

Summary

Adds explicit MDL syntax for preserving ChangeObjectAction.RefreshInClient.

Changes

  • Accepts change $Object refresh; and change $Object (...) refresh;.
  • Carries the refresh flag through the AST and builder.
  • Emits refresh when describing change-object actions with RefreshInClient=true.
  • Adds proposal docs, a doctype fixture, quick-reference entry, and skill guidance.

Validation

  • go test ./mdl/visitor -run TestChangeObjectParsesRefresh
  • go test ./mdl/executor -run 'Test(FormatAction_ChangeObject.*Refresh|ChangeObjectBuilderWritesRefreshInClient)'
  • ./bin/mxcli check mdl-examples/doctype-tests/change_refresh_modifier.test.mdl
  • make build
  • make lint-go
  • make test

Closes #345
Part of #332

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.
@hjotha hjotha force-pushed the submit/change-object-refresh-modifier branch from 4b12de0 to c1d6a85 Compare April 30, 2026 08:10
@github-actions
Copy link
Copy Markdown

AI Code Review

What Looks Good

The PR implements the change object refresh modifier feature comprehensively and correctly:

  1. Full-stack consistency: All required layers are properly updated:

    • Grammar: MDLParser.g4 updated with REFRESH? option
    • AST: ChangeObjectStmt now includes RefreshInClient bool field
    • Executor: Builder logic updated to handle the flag, formatting functions updated to emit refresh keyword
    • Tests: Added doctest fixture (change_refresh_modifier.test.mdl) and unit tests for builder and formatter
    • Documentation: Updated quick reference, skills documentation, and added proposal document
  2. MDL syntax compliance:

    • Follows standard patterns using existing change verb
    • Reads as clear English: change $Customer refresh;
    • Uses proper qualified names for variables ($Customer)
    • Consistent with existing property format patterns
    • refresh is a clear, non-overloading modifier keyword
    • Diff-friendly implementation (one-line addition for the feature)
  3. Test coverage:

    • Added doctrtest fixture demonstrating both forms
    • Added unit tests for builder serialization and formatter output
    • PR mentions running relevant validation tests
  4. Documentation:

    • Comprehensive proposal document explaining motivation and semantics
    • Updated quick reference with new syntax
    • Added examples to microflow skills documentation

Recommendation

The 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 ako added this to the v0.8.0 milestone Apr 30, 2026
Copy link
Copy Markdown
Collaborator

@ako ako left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • REFRESH is already a keyword token — no new lexer rules needed.
  • Grammar placement (REFRESH? after the optional member list) is unambiguous and consistent with COMMIT/ROLLBACK.
  • Visitor one-liner stmt.RefreshInClient = changeCtx.REFRESH() != nil is correct.
  • Builder correctly ORs the explicit flag with the auto-refresh-on-empty condition.
  • Both member and no-member formatter paths emit refresh correctly.
  • Existing TestEmptyChangeObjectRefreshesInClient and TestFormatAction_ChangeObject_NoChanges tests are unaffected (both use RefreshInClient = false).

@ako ako merged commit 78c42dc into mendixlabs:main Apr 30, 2026
1 of 2 checks passed
hjotha pushed a commit to hjotha/mxcli that referenced this pull request May 2, 2026
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>
hjotha pushed a commit to hjotha/mxcli that referenced this pull request May 2, 2026
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>
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.

Preserve refresh-in-client on change-object actions with member assignments

3 participants