fix: honor user-defined UpdateProps on receiver components (#116)
* fix(tuigen): honor user-defined UpdateProps on receiver components
The generator emitted UpdateProps unconditionally for method templs, so a
receiver type with a handwritten UpdateProps failed to compile with a
duplicate-method error. Skip the generated wrapper when the user declares
their own, matching the existing BindApp/UnbindApp detection, and always
emit an unexported updatePropsFields helper that overrides can delegate to,
mirroring bindAppFields.
Fixes #114
* fix(tuigen): assert PropsUpdater even when UpdateProps is user-defined
Review finding: with the wrapper suppressed, a user UpdateProps with the
wrong signature would compile and silently stop prop refresh on cached
components. Emitting the compile-time assertion unconditionally turns that
into a loud interface error.
* fix(tuigen): detect unnamed receivers and reject generated-name collisions
The hasUserMethod regex required a named receiver, so a legal unnamed
declaration like func (*row) UpdateProps(...) escaped detection and still
produced the duplicate-method error for all three lifecycle methods.
Declarations that collide with generated code (a templ sharing a name with
a Go function, duplicate templs, a handwritten Render next to a method
templ, a user type named <Name>View) previously surfaced as raw Go
redeclared errors inside the generated file; the analyzer now rejects them
with errors pointing at the .gsx source.
Also documents the generated lifecycle methods, the override rule, and the
reserved helper names in the interfaces reference.
* fix(tuigen): detect user lifecycle methods across sibling files of the package
User-method detection and collision checks previously scanned only the
.gsx file being processed, so an UpdateProps/BindApp/UnbindApp declared in
a plain .go file of the same package still produced a duplicate-method
error. A new PackageContext collects sibling declarations (go/parser for
.go files, the tuigen parser for .gsx files) and feeds both the generator
and the analyzer. Generated files, by _gsx.go suffix or generated-code
header, are excluded so the generator never treats its own output as user
code, and _test.go files are excluded so a test-only method cannot
suppress a method production builds need.
tui generate and tui check build the context from the file's directory.
The LSP builds it per document, using open editor buffers for sibling .gsx
files so unsaved edits are seen, and disk for the rest.
* fix(tuigen): reject reserved generated helper names on templ receiver types
updatePropsFields, bindAppFields, and unbindAppFields are emitted
unconditionally on templ receiver types, so a user method with one of
those names collided with generated code as a raw redeclared error in the
generated file. The analyzer now rejects the reserved names up front, in
the .gsx file or a sibling file, matching the other generated-name
collision checks. Suppressing the helper instead was rejected: the
generated wrapper delegates to it, so a coincidentally named user method
would silently become the lifecycle delegation target.
Joel Holsteen · 6d · 0592ab2 · parent df4ed47 · 32 files +1514 -0