Skip to content

1.17.0 — zero emitter defects

Choose a tag to compare

@freitasjca freitasjca released this 11 Sep 11:25
· 38 commits to main since this release

Delphi-nghttp2 1.17.0

Four generator fixes, all of the same family: a proto field or enum value whose
Pascal spelling collides with something the generated code itself relies on.
Every one of them changes generated identifiers, which is what makes this a
minor rather than a patch — downstream sees different code even though nothing
breaks.

The shadowing family, now closed on all three declaration kinds

A generated class is not a closed world: its own property names sit in scope
inside its own method bodies, its enum values sit at unit scope, and an
inherited method can be hidden by a published property. Four defects, four
different blast radii:

what shadows what reach
FIX-SHADOW-2 (11a8cd5) a field named high shadows the intrinsic inside its own class's methods
SHADOW-2b (0c05091) a field named free hides inherited TObject.Free other classes holding one as a field
SHADOW-3 (0c05091) an enum value SYSTEM shadows the System unit every qualified RTL call in the unit
UNIT-SHADOW-1 (new) a field named system shadows the System unit every System.Length/High/SetLength in its class

SHADOW-3 and UNIT-SHADOW-1 are the same collision reached from the two
directions a Pascal identifier can arrive from. 11a8cd5 qualified emitted
intrinsics as System.High / System.Length / System.SetLength on the
grounds that a qualified reference cannot be shadowed — and then both halves of
this release were the discovery that it can be, once by an enum value and once
by a property.

google.cloud.dataplex.v1 declares string system = 11 (EntryType) and
string system = 2 (EntrySource); both classes also carry map fields, so both
emitted System.Length(Flabels) and got Error: Illegal qualifier. Those
three schemas — approval_workflow, catalog, data_products — were the only
DID NOT COMPILE cases left in the corpus.

system now renames to sys, following the existing string -> str
abbreviation. Unconditionally, and that distinction matters: the FIELDWORD-1
cases (length, high) only collide when a class happens to emit that
intrinsic, but System. is emitted for every repeated and map accessor, so
there is no per-message narrowing to be had.

FIX-IDENT-1 now bounds generated TYPE names (6429a64)

The identifier-length guard covered enum values only; long generated type
names could still be emitted unbounded. Now both.

Corpus

compile-check.sh --all, all 7,301 googleapis schemas:

COMPILED emitter defects FPC crashes refused
1.16.0 7,216 7 57 21
1.17.0 7,230 0 50 21

No schema in the corpus is now rejected because of Pascal we emitted. The
remaining 71 are 21 deliberate refusals (Group B scalars, Api/DescriptorProto,
and the bigquery enum declaring both minimal and MINIMAL) and 50 on which
FPC itself falls over.

The shape of the result is worth as much as the number: UNIT-SHADOW-1 moved
the defect column by exactly 3 and left crashes and refusals untouched at
50/21. A fix that also moved those would have needed explaining.

corpus-check.sh (parse + emit) — run for this release, not carried
forward: ACCEPT 7,287 · REFUSE known 14 · REFUSE UNKNOWN 0 · ERROR 0,
unchanged from 1.16.0. That it did not move is the useful part: all four
fixes rename emitted identifiers, so none of them should change whether a
schema is accepted, and the flat result is what confirms nothing regressed
underneath the compile improvement.

Its refusal bucket (14) and compile-check.sh's (21) count different things
and do not reconcile by arithmetic. Quote each with the tool that produced it.

The compiler crashed column counts FPC falling over, not our output being
rejected. Internal error 2015071503 remains unattributed (noted against
oracledatabase in 0c05091, and it also hits analytics/admin); an earlier
theory this session that it was the >=127-character identifier limit was
measured and disproved — the longest identifier in a crashing unit is 75
characters, and a same-file type reference never takes the unit prefix that
would have made it longer.

Upgrading

Regenerate. A proto field named system or free, or an enum value SYSTEM,
now emits under a different Pascal spelling, so hand-written code referring to
the old name needs the new one. Nothing else moves.