Repository navigation
Commit f3a2fa7
authored
feat(java): make entity and extractor generators ejectable (#425)
* feat(java): the entity and extractor generators are ejectable
"Everything should be ejectable." An audit of the stock generators in all five
ports found eight that could not be ejected; this is the Java part, `entity`
(JavaObjectCodeGenerator) and `extractor` (ExtractorCodeGenerator). Every Java
generator can now be ejected except `template` (ADR-0034 Amendment 6).
Why they could not be ejected
- entity compiled only inside its writers' package: it called two protected
naming steps on a writer it does not extend, and named its siblings by bare
name. The package line is the one thing eject rewrites, so a copy did not
compile (39 errors).
- extractor was not a generator. It was a step entity ran, so no <generator>
entry could name an owned copy and the drift check had nothing to run.
What the owned copy carries, and what stays in the package
- The owned entity is JavaObjectCodeGenerator.java alone: flavor selection, the
writer factory (createWriter), the ObjectClassBindingProvider source, its
META-INF/services registration, and whether the extractors are written there.
- The class body stays in codegen-base's flavor writers (JavaCodeWriter,
PojoAwareCodeWriter, ValueObjectCodeWriter), now named as supported surface:
subclass one, override a protected step, return it from createWriter. They
are not copied because every generated class's header names the writer class
that wrote it, so a copied writer would change every generated file, and
because a change to the class body is one overridden step.
- JavaCodeWriter gains javaPackageOf(mo) and javaClassNameOf(mo), public views
of the naming steps. The steps stay protected: widening them would break
every subclass that overrides one as protected.
- The owned extractor holds all of its emit.
extractor as a generator of its own
- ExtractorCodeGenerator implements Generator and takes the naming args entity
takes. entity still writes the extractors when no separate extractor is in
the run, so a pom that wires only entity emits byte for byte what it did.
- When one is in <generators>, the Maven plugin sets emitExtractors=false on
the others (EmitsObjectExtractors, derived where useNames is), so each file
has one emitter. An explicit value in the pom wins.
Eject
- codegen-base ships the two reference sources. The registry gives both an
eject path, and extractor a wiring note the eject report prints, since a pom
may have no <generator> entry for it to change.
- Behaviour change: `-Dnames=entity` and `-Dnames=extractor` are now ejectable
on both JVM ports, so with no port implied by the project's dependencies the
goal asks for -Dport, as it does for `names`. It used to resolve to Kotlin.
Proof
- EjectedBaseGeneratorsCompileTest: both copies compile package-renamed against
the module's public API.
- EntityExtractorEjectRoundTripTest: ejects both through the mojo, compiles
them, and holds the unchanged copies to the packaged generators' output over
the persistence corpus in every flavor; an edit to each copy shows in its
output; -Dlist marks the copies identical or DIFFERS; mvn metaobjects:verify
runs the owned copies and reports what they no longer produce.
- StandaloneExtractorGeneratorTest, EmitExtractorsDerivationTest and a second
compile-gate selection hold the split between the two generators.
The model tier's class header still carries a wall-clock "Generated On:" line,
so the entity comparisons leave that one line out and the drift proof re-runs
a pass that crossed a second. Both go once that line is removed.
Docs: ADR-0034 Amendment 6, own-your-codegen, the Java port page and README
matrix, the codegen skill's Java reference (with regenerated agent-context
goldens), the module README and the CHANGELOG.
* fix(java): the standalone extractor needs entity's filters; say so and test it
Pre-gate review found that nothing told an adopter the separate extractor
generator has to select the same objects as entity. Each <generator> merges its
own <filters>, so an extractor wired without entity's filters writes a
<Name>Extractor for an object entity wrote no class for, which does not compile.
- The eject wiring note, ExtractorCodeGenerator's javadoc, own-your-codegen, the
Java port page, the codegen skill's Java reference (goldens regenerated) and
the CHANGELOG now name <filters> beside the naming args.
- StandaloneExtractorGeneratorTest holds that the two generators, given the same
filters, select the same objects.
- EjectRuntimeRoundTripTest runs every ejectable Java generator off the registry;
entity is one now, so its shared args carry entity's required type and flavor.
That test also holds that neither generator's output imports a codegen helper,
so ejecting them copies no runtime.
* refactor(java): simplify pass on the ejectable entity and extractor change
- The eject mojo reads each wiring note from the resolved entries when it
prints, instead of collecting them in a second list during the copy loop.
- EjectedBaseGeneratorsCompileTest compiles through JavaCompileTestSupport, the
module's shared compile helper, which also dumps the sources on failure.
- EmitExtractorsDerivationTest reuses UseNamesDerivationTest's recording
generator instead of carrying a copy of it.
- A literal "false" and an imported StringWriter; no output changes.
* no-mistakes(review): eject entity writers, deterministic headers, single extractor emitter
Assisted-by: no-mistakes:claude:claude-opus-5-5
* no-mistakes(review): move changelog to 1.1.0, drop naming views and overloads
Assisted-by: no-mistakes:claude:claude-opus-5-5
* no-mistakes(review): document one extractor entry per entity entry
Assisted-by: no-mistakes:claude:claude-opus-5-51 parent 0d8b09a commit f3a2fa7
30 files changed
Lines changed: 1833 additions & 138 deletions
File tree
- agent-context/skills/metaobjects-codegen/references
- docs
- features
- ports
- fixtures/agent-context-conformance
- java-kotlin-react-tanstack/expected/.claude/skills/metaobjects-codegen/references
- java-react/expected/.claude/skills/metaobjects-codegen/references
- server/java
- codegen-base
- src
- main/java/com/metaobjects/generator
- direct/object
- javacode
- test/java/com/metaobjects/generator/direct/object
- codegen-spring
- src
- main/java/com/metaobjects/generator
- test/java/com/metaobjects/generator
- spring
- maven-plugin/src
- main/java/com/metaobjects/mojo
- test/java/com/metaobjects/mojo
- spec/decisions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
74 | 107 | | |
75 | 108 | | |
76 | 109 | | |
| |||
456 | 489 | | |
457 | 490 | | |
458 | 491 | | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
459 | 510 | | |
460 | 511 | | |
461 | 512 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
159 | 159 | | |
160 | 160 | | |
161 | 161 | | |
162 | | - | |
| 162 | + | |
163 | 163 | | |
164 | 164 | | |
165 | 165 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
159 | 159 | | |
160 | 160 | | |
161 | 161 | | |
162 | | - | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
163 | 177 | | |
164 | 178 | | |
165 | 179 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
520 | 520 | | |
521 | 521 | | |
522 | 522 | | |
523 | | - | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
524 | 526 | | |
525 | 527 | | |
526 | 528 | | |
| |||
538 | 540 | | |
539 | 541 | | |
540 | 542 | | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
| 547 | + | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
| 554 | + | |
| 555 | + | |
| 556 | + | |
| 557 | + | |
| 558 | + | |
| 559 | + | |
| 560 | + | |
| 561 | + | |
| 562 | + | |
| 563 | + | |
| 564 | + | |
| 565 | + | |
| 566 | + | |
| 567 | + | |
| 568 | + | |
| 569 | + | |
| 570 | + | |
| 571 | + | |
| 572 | + | |
| 573 | + | |
| 574 | + | |
| 575 | + | |
| 576 | + | |
| 577 | + | |
| 578 | + | |
| 579 | + | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
541 | 606 | | |
542 | 607 | | |
543 | 608 | | |
| |||
610 | 675 | | |
611 | 676 | | |
612 | 677 | | |
613 | | - | |
614 | | - | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
615 | 682 | | |
616 | 683 | | |
617 | | - | |
618 | | - | |
619 | | - | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
620 | 688 | | |
621 | 689 | | |
622 | 690 | | |
| |||
0 commit comments