ID |
|
|---|---|
Status |
Backlog |
Bucket |
Backlog |
Priority |
3 |
Theme |
model-cleanup |
Created |
2026-06-18 |
Updated |
2026-07-28 |
Generated argument extraction is unreadable nested-ternary one-liners
Every generated @condition argument is inlined as a nested ternary directly in the WHERE
chain, e.g. env.getArgument("filter") instanceof Map<?, ?> map1 ? (String) map1.get("brukerId") : null,
repeated once per argument across a single .and(...) term. A method with several condition args
renders as one dense, hard-to-read, hard-to-breakpoint expression (flagged by a consumer as "an
eyesore" that "violates our principle of readable and debuggable code"). R330 made the surrounding
.and(...) chains and the FK-target EXISTS multi-line, but did not touch the per-argument
extraction, which is cross-cutting: it lives in ArgCallEmitter.buildArgExtraction and feeds every
WHERE-emitting site (the QueryConditions shim plus the inline / lookup / split fetcher emitters).
The fix likely extracts each argument into an explicitly-typed named local (never var;
GeneratedSourcesLintTest.emittedSourcesDoNotUseVar bans it in emitted code) before the call, or
routes through a small generated helper, so the call site reads as
Conditions.method(table, brukerId) and each extraction is independently debuggable. Scope:
emitter-only, generated output changes shape but not behaviour; pipeline tests must not assert on
generated method bodies, so coverage stays at the compile/execution tier.
Narrowed for the condition family (2026-07-28, R552 pickup)
R552 (condition-command) absorbs this item’s fix for @condition argument extraction: the glue
body’s one-local-per-argument convention delivers the named-locals shape by construction (R552
slice 1 for the root family, slice 2 for every inline call site), so the ternary chains stop
appearing at condition call sites entirely. Everything below in the expanded scope stays here:
the mutation insert-value ternaries, the polymorphic discriminator expression, and the
$fields-mapper deep-path extraction with its inputs/*.fromMap reuse finding are not condition
content and remain this item’s. Do not delete this item when R552 closes.
Expanded scope (2026-07-24 audit)
A full audit of the graphitron-sakila-example generated tree found the same
expression-over-statement pattern beyond @condition extraction; this item now covers all of it
(same emitter family, same fix shape: hoist to explicitly-typed named locals per path segment,
named after the GraphQL argument or column):
-
Deep input-path extraction in fetchers and
$fieldsmappers: nestedinstanceof Map/Listternary chains up to ~600 characters on one line (QueryFetchers.filmsByNestedListPath, the two ~330-char.where(...)arguments inoccupantsByFilter,types/Store.$fieldsGrouped). Some sites re-check the sameinstanceoftwice or testin != nullafterin.get(...)was already dereferenced; the locals-first rewrite removes the redundancy. Note the emitter already generates typedinputs/*.fromMapclasses for many of these shapes and then ignores them, re-digging raw maps at the use site; reusing the input classes where one exists deletes the pattern outright. -
Insert-value ternaries:
in.containsKey("x") ? DSL.val(...) : DSL.defaultValue(...)emitted once per column per mutation (39 occurrences inMutationFetchers). A named local per column, or a tiny emittedvalOrDefault(in, "x", FIELD)helper, restores the column list’s readability. -
The polymorphic discriminator expression
DSL.field(table.getQualifiedName().append(DSL.name("content_type")), Object.class)is rebuilt inline up to four times within a single method (29 occurrences across the root fetcher classes); bind it once to a named local per method.
R521 (generated-output-hygiene-sweep) tracks the complementary naming/dedup/hygiene findings
from the same audit and explicitly excludes statement-form defects in favour of this item.
R85 (helper-emission-non-fetcher-hosts) reshapes the same method: it fixes the
ContextArg arm of ArgCallEmitter.buildArgExtraction that fails to emit the
graphitronContext helper on non-fetcher hosts, while this item extracts the
per-argument extraction into named locals or a helper for readability. Whichever
lands first changes the other’s diff; sequence knowingly (distinct deliverables,
not a merge).