Skip to content

Allow Dart macros to generate a single package-relative library - #9

Merged
MelbourneDeveloper merged 6 commits into
mainfrom
typeDiagram
Sep 14, 2026
Merged

MelbourneDeveloper merged 6 commits into
mainfrom
typeDiagram

Conversation

@MelbourneDeveloper

Copy link
Copy Markdown
Collaborator

TLDR

Let Dart macros emit one ordinary library at a safe package-relative path, unblocking NAP's single-file Flutter SDK.

Details

  • Bare output names remain siblings of the seed; paths resolve against its nearest pubspec.
  • DMX owns emitted files and removes obsolete outputs for that seed. Reject traversal, absolute paths, collisions and human-owned destinations.
  • Share the output-root guard with typeDiagram; document the macro protocol.

How Do The Automated Tests Prove It Works?

  • New regression first failed with DMX7007, then proved lib/src/generated/models.dart is created with the correct ownership marker.
  • Stale-output regression proves a subsequent macro expansion removes its obsolete output; existing collision and human-file assertions remain.
  • Local CI components passed: Rust and Dart coverage, coverage floors, lint/format, duplicate-code gate, WASM smoke, golden corpus, storefront (196), SQLite (27), OpenAPI (21), website unit (13) and browser (24), and real VS Code editor (6).
  • The initial make ci stopped at WASM compilation; native-only helpers were corrected, then remaining gates resumed without repeating passed suites. Release native and website builds passed.

For AI

Fixes #7. The runtime wire shape is unchanged. This supports a real Dart DmxMacro returning DmxGeneratedFile, not a Python code-generation layer. Issue #8 separately tracks inline --insert-regions behavior.

…ases

A definition with nothing beside it used to generate nothing, and every project
that wanted model classes wrote and maintained its own Mustache. There is now
one model template, shipped in the binary, used wherever a diagram generates
model classes.

Every record and every union case comes out of it as an immutable value — ==,
hashCode, toString, copyWith — built by the same Rust that builds them for
@dmx('model'), so the annotated path and the diagram path cannot say different
things about the same type. JSON is never a member of a generated class: it
goes on an `extension <Name>Json`, and nested decodes name the extension. The
runtime import is prefixed, so a diagram that declares its own Result, Ok or Err
cannot hide the one the codec means.

Union cases are named the way typeDiagram's own emitters name them — the case's
own name — and take their union's name as a prefix only where Dart's single
namespace forces it: `Ok` belongs to two unions in the parity corpus, and
`String` is Dart's own. A case with neither name available is refused (DMX8010)
rather than generated as two classes under one name. That alignment is what
tdbin interop needs.

Also brings the duplication gate back under its budget. It was breached at
7.6% before this branch: the typeDiagram goldens join the generated-output list
already in .deslop.toml, the two typeDiagram suites share one Workspace fixture,
and several test bodies that differed only in their data are table-driven. The
budget ratchets 7.0 -> 6.8.
@MelbourneDeveloper
MelbourneDeveloper enabled auto-merge (squash) September 14, 2026 07:29
@MelbourneDeveloper
MelbourneDeveloper merged commit 85008cc into main Sep 14, 2026
7 checks passed
@MelbourneDeveloper
MelbourneDeveloper deleted the typeDiagram branch September 14, 2026 07:36
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.

Allow DmxGeneratedFile to target a declared output directory

1 participant