Skip to content

Upgrade: Additional Checks#8

Closed
tooolbox wants to merge 18 commits intotypelate:mainfrom
tooolbox:next-march
Closed

Upgrade: Additional Checks#8
tooolbox wants to merge 18 commits intotypelate:mainfrom
tooolbox:next-march

Conversation

@tooolbox
Copy link
Copy Markdown

@tooolbox tooolbox commented Mar 7, 2026

This PR represents a series of functionalities added to this tool to make it more capable at catching problems in Go templates. Here is the summary:

New CLI features

  • -w flag — Enables warnings for potential issues that aren't type errors. Four warning categories, each with a diagnostic code:

    • W001 — Non-static template name: ExecuteTemplate called with a variable instead of a string literal
    • W002 — Unused templates: Templates loaded via ParseFS/ParseFiles/ParseGlob that are never referenced by any ExecuteTemplate call or {{template}} action
    • W003 — Unguarded pointer dereference: Field access on a pointer type (e.g. .Title on *Page) without a {{with .}} or {{if .}} nil guard. Includes per-value tracking so guarding a specific field suppresses just that field's warning
    • W004 — Interface field access: Field access on interface{}/any that can't be verified at compile time
  • ParseFiles and ParseGlob support — The CLI can now trace templates initialized with template.ParseFiles(...) and template.ParseGlob(...), not just ParseFS

Library changes

  • WarningCategory type with Code() method for diagnostic codes
  • PackageWarningFunc callback receives the category, position, and message — library consumers can filter by category
  • WarningFunc on Global struct for internal warning emission during type-checking

Fixes & improvements

  • FuncMap resolution — Replaced types.Eval with typesInfo.TypeOf, fixing support for method values and package-level variables in FuncMaps
  • Diagnostic format — Output now follows Go ecosystem conventions (file:line:col: message (CODE)), matching tools like go vet and staticcheck. Errors use E001

Documentation

  • README updated with code/template examples for all warnings and errors

tooolbox and others added 18 commits March 6, 2026 16:09
Add WarningFunc to the check.Package API and a -w CLI flag that emits
warnings when ExecuteTemplate is called with a non-static template name.
Warnings are off by default to avoid noise in existing workflows.

Also add tests for ./... with deeply nested packages and document how
the CLI discovers templates (embed.FS requirement, supported patterns).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The CLI can now analyze templates loaded via template.ParseFiles() and
template.ParseGlob() with string literal arguments, in addition to the
existing embed.FS + ParseFS support.

Supported in all contexts: package-level calls (template.ParseFiles),
variable receiver calls (ts.ParseFiles), and chained calls
(template.New("x").ParseFiles).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
types.Eval required formatting AST back to source text and re-evaluating,
which was fragile for method values and package-level variables. Using
typesInfo.TypeOf directly resolves function signatures from the already-
computed type information, handling all expression forms correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TemplateNames() to the Template interface to enumerate all defined
templates. After type-checking, compare referenced templates (from
ExecuteTemplate calls and {{template}} actions) against all available
templates and warn about unreferenced ones.

Templates with no content (e.g. the root container from template.New)
are excluded from the check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When dot or a field is an interface type (e.g. any), field access like
.Title cannot be statically verified. Instead of producing a hard error,
emit a warning when -w is enabled and continue type-checking with the
field treated as an empty interface.

Adds WarningFunc to Global for template-level warnings, PackageWarningFunc
for package-level warnings, and bridges them through checkCalls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a template accesses fields on a pointer type (e.g. *Page) without
a {{with}} or {{if}} guard, the access may panic at runtime if the
pointer is nil. With -w enabled, emit a warning suggesting a nil guard.

Adds dotGuarded tracking to scope: set to true inside {{with}} and
{{if}} blocks so that guarded pointer access does not trigger warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Verifies that .Inner.Value warns when Inner is *Inner, catching
pointer dereference at any depth in a field chain.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the coarse dotGuarded bool with a per-field-path guarded set.
{{with .Foo}} guards only .Foo (and dot inside the block), not unrelated
fields like .Bar. {{if .Bar}} guards .Bar within its block.

Guarding .Foo does NOT guard .Foo.Baz — if Baz is a pointer type,
accessing fields through it still warns unless .Foo.Baz is separately
guarded.

Adds pipeFieldPath helper to extract the tested field path from
{{with}}/{{if}} pipe expressions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add WarningCategory enum to PackageWarningFunc callback so library
consumers can filter warnings by type. CLI continues to use single
-w flag that enables all categories.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document all four warning categories with Go code and template
examples showing what triggers each warning and how to fix it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change from "warning: pos: message" to "pos: warning - message"
to be consistent with Go tooling diagnostic conventions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Warnings: file:line:col: message (W00N)
Errors:   file:line:col: executing "name" at <.Field>: message (E001)

Remove the "type check failed:" prefix from errors and "warning -"
prefix from warnings to match go vet / staticcheck conventions.
Add diagnostic codes (W001-W004, E001) for machine-parseable output.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tooolbox
Copy link
Copy Markdown
Author

There have been some advancements, will open a new pull request.

@tooolbox tooolbox closed this Mar 18, 2026
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