Skip to content

docs(examples): GObject.registerClass static-block ordering trap + Form A docstring#410

Merged
JumpLink merged 3 commits into
mainfrom
feat/gobject-static-block-ordering-example
May 22, 2026
Merged

docs(examples): GObject.registerClass static-block ordering trap + Form A docstring#410
JumpLink merged 3 commits into
mainfrom
feat/gobject-static-block-ordering-example

Conversation

@JumpLink
Copy link
Copy Markdown
Collaborator

Why

Companion to the new Patterns → GObject classes page on the website (gjsify/gjsify#247) — gives readers a runnable side-by-side demo of:

  • the static-block ordering trap behind GNOME/gjs#704
  • the two correct shapes (fields-first vs metadata-inline)
  • the static override $gtype: GObject.GType<Foo> declaration that narrows the statically-inherited $gtype from the base class (per Philip Chimento's matrix thread)

What lands

examples/gobject-static-block-ordering/ (new)

Three classes side-by-side, all exercised at runtime with assertions:

Class Pattern Outcome
BrokenFoo static { registerClass } first, static [interfaces] after throws Could not find definition of virtual function init at class registration on GJS 1.86+ — wrapped in try/catch so the rest of the demo runs
WorkingFoo static [interfaces] first, static { registerClass } last init() runs the vfunc body
InlineFoo metadata passed inline to registerClass({ Implements: [...] }, Foo) init() runs the vfunc body — no ordering question (preferred Form A)

Regression guard: if BrokenFoo ever stops throwing (upstream gjs fix), the script exits 1 — we'll know to update the pattern guidance.

examples/gobject-param-spec/main.ts (augmented)

Adds the static override $gtype: GObject.GType<ExampleObject> declaration and an explanatory docstring block above the class explaining why this is Form A and how it sidesteps the ordering trap. No behavioural change — runtime output unchanged.

Test plan

  • gjsify run check clean in both example dirs
  • gjsify run start in gobject-static-block-ordering prints all three ✓ lines and exits 0
  • gjsify run start in gobject-param-spec still emits the full ParamSpec demo
  • After gjsify/gjsify#247 merges + deploys, the https://gjsify.github.io/gjsify/patterns/gobject-classes/ links in both READMEs and main.ts headers resolve

JumpLink added 3 commits May 22, 2026 09:24
…rm A docstring

Adds a new `examples/gobject-static-block-ordering/` directory that
reproduces the bug behind GNOME/gjs#704 side-by-side with two
correct shapes, and runs all three with assertions:

  BrokenFoo:   static { registerClass } first, static [interfaces] after
               → throws "Could not find definition of virtual function
                 init" at class registration (current GJS) or first
                 vfunc invocation (older GJS). Wrapped in try/catch so
                 the rest of the demo runs; absence of the throw fails
                 the script (regression guard against upstream fixes).
  WorkingFoo:  static [interfaces] first, static { registerClass } last
               → init() runs the vfunc body.
  InlineFoo:   metadata passed inline to registerClass({ Implements:
               [...] }, Foo). No static [GObject.*] = … fields, so the
               ordering question doesn't arise. This is the form the
               website's patterns/gobject-classes page recommends.

All three classes also use `static override $gtype: GObject.GType<Foo>`
to narrow the statically-inherited `$gtype` from the base class.
Without that, `GObject.type_is_a(x, Foo)` returns `x is Object`,
not `x is Foo`.

The companion `examples/gobject-param-spec/` gets a docstring block
explaining why it follows Form A + the `static override $gtype`
declaration so it matches the recommended shape end-to-end.

Both examples link to https://gjsify.github.io/gjsify/patterns/gobject-classes/
for the full pattern reference (PR opening shortly on the website
repo — landing this on a slight lead means the README links resolve
the moment the website PR merges).
…tes)

Picks up the registerClass-overload regeneration from
gjsify/types@ebca4fe6 — the template fix from #406 only takes
effect when types-dev is rebuilt with it, and the previous
submodule pointer (2d1385ec) predated that. The build-validate
job on this PR was red because of exactly that disconnect:
`examples/gobject-register-class-inference/main.ts` exercises the
inference path that becomes reachable only when the Standard
overloads are absent.

After this bump:
  $ cd examples/gobject-register-class-inference && yarn run check
  Done in 0.84s.
@JumpLink JumpLink merged commit 5629a26 into main May 22, 2026
7 checks passed
@JumpLink JumpLink deleted the feat/gobject-static-block-ordering-example branch May 22, 2026 08:55
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.

1 participant