Skip to content

refactor symbol handling and update tests for document symbols - #3241

Open
DaliVana wants to merge 1 commit into
zigtools:masterfrom
DaliVana:Issue-#3232
Open

refactor symbol handling and update tests for document symbols#3241
DaliVana wants to merge 1 commit into
zigtools:masterfrom
DaliVana:Issue-#3232

Conversation

@DaliVana

@DaliVana DaliVana commented Aug 6, 2026

Copy link
Copy Markdown

Addresses the bulk of #3232 (scope notes below).

What changed

Symbol kinds are now inferred from initializer expressions. Previously every
const/var declaration was reported as Constant/Variable based solely on the mut
token, so enums, structs, and imports were indistinguishable in the outline:

declaration before after
const E = enum {...}; Constant Enum
const S = struct {...}; Constant Struct
const U = union(enum) {...}; Constant Struct¹
const O = opaque {}; Constant Class¹
const Error = error{...};, A || B Constant Enum
const std = @import("std"); Constant Module
test "foo" {} Method Function²

¹ LSP has no Union/Opaque kind; rust-analyzer maps union → Struct the same way.
² LSP has no Test kind; rust-analyzer and gopls also report tests as plain functions.
Also applied to workspace/symbol.

Methods are distinguished from functions. A function whose first parameter type —
after stripping single-item/C pointers — is @This(), the conventional Self, or the
enclosing container's binding name is reported as Method. Slices and many-item
pointers are rejected since they can never be a method receiver ([*c] is accepted
because *T coerces to it). The binding-name rule is scope-accurate: a function in a
nested container taking the outer type is correctly reported as a plain function.

The _ marker of non-exhaustive enums is no longer listed as an EnumMember
(a member explicitly spelled @"_" still is).

ZON files now have a document outline. Previously textDocument/documentSymbol
returned null for .zon files. The value tree is now walked with kinds mirroring the
JSON language service: struct inits → Module, array inits → Array, plus
String/Number/Boolean/Null/EnumMember for scalars. Struct-init fields are named by
their .field name; array elements by index (0, 1, …). Trees with parse errors
return an empty outline (ZON Asts are unusable when the root expr has errors, same
workaround as hover/goto).

Design constraints

Known heuristic limitations (documented in code): self: anytype receivers are not
detected, and top-level functions of a file-as-struct (const Self = @This() sibling
binding) are reported as Function — most clients render Function and Method with the
same icon, so this is invisible in practice.

Not included, possible follow-ups: kind parity for workspace/symbol (TrigramStore
still records only Constant/Variable/Function/Field), and position-asserting tests for
the ZON range synthesis.

Testing

  • updated existing document_symbol/workspace_symbols expectations
  • new tests: kind inference (imports, error sets, opaque, sized enums, tagged unions),
    method detection (pointer sizes, @This(), Self, nested and function-local
    containers), non-exhaustive enums, and four ZON outlines (build.zig.zon-style
    fixture, scalars, root array, parse errors)

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