fix(parser): collect definitions inside at-rule bodies (#38) - #43
Merged
Conversation
… group rules (#38) Treat @media, @supports, @container, @layer, @scope, and @starting-style as transparent wrappers: consume only the prelude and let the main loop descend into the body so inner property declarations are collected. Other at-rules (@Property, @import, @font-face, …) keep being skipped whole. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…le references
`VariableUsages::matches` previously did `value.contains("var(")` and a
naive substring scan for `--ident`, both of which fired on content that
sits inside string literals or `url(...)` tokens (e.g. `content: "var(--x)"`,
`url("file--name.png")`). It also matched `--ident` glued to the tail of a
preceding identifier (`font--name`).
Replace it with a single state-aware scanner that walks the value once,
skipping `"…"`/`'…'` strings, `/* … */` comments, and `url(…)` token
contents, and only fires on `var(`/`--ident` at a real token boundary.
Also accepts `Var(` / `URL(` case-insensitively to match CSS rules.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Phase 2 of #38: synthesise one Property per @Property rule, with ident pointing at the prelude --name and value pointing at the initial-value declaration (or empty if absent). Custom properties declared via @Property now show up in LSP completion / hover / go-to-definition / rename, and don't trip no-undefined-variable-use when referenced. Other at-rules continue to be skipped. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Drop the `is_transparent_at_rule` whitelist (and the now-orphan `skip_at_rule_body` helper). With `@property` keeping its dedicated prelude-name + initial-value synthesis path, every other at-rule body is now parsed by the main loop just like a selector block. Definitions and `var()` references inside CSS at-rules previously left opaque (`@keyframes`, `@font-face`, `@page`, `@counter-style`, `@font-feature-values`, …) now flow through the same downstream pipeline. Statement-form at-rules (`@import`, `@charset`, `@namespace`) terminate at the `;` in `skip_at_rule_prelude`, so no body is ever opened for them. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
… name
`scan_at_property_rule` skipped only spaces, tabs, and newlines before
reading the prelude name, so a valid comment like
`@property /* doc */ --logo { … }` left the scanner at `/`, the
identifier loop bailed immediately, and the helper returned `None`.
The body was then consumed by the main loop as if it were a selector
block, silently dropping `--logo` as a definition and leaking
`initial-value: red` as a regular property declaration.
Replace `skip_inline_and_newlines` with a `skip_trivia` helper that
also consumes `/* … */` comments. Single call site, behaviour
unchanged for the existing whitespace-only inputs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #38.
Previously, the parser only descended into selector blocks. Definitions and
var()references inside any at-rule (@media,@property,@supports,@keyframes, …) were invisible to LSP completion / hover / go-to-definition / rename and to theno-undefined-variable-use/no-inconsistent-variable-definitionrules. This PR makes at-rule bodies first-class.Changes
At-rule bodies (c13d868, 37dcfde) — every at-rule body except
@property(special-cased below) is parsed by the main loop just like a selector block. Statement-form at-rules (@import,@charset,@namespace) terminate at;and never open a body. Definitions andvar()references inside@media,@supports,@keyframes,@font-face,@page, etc. now flow through unchanged.Searcher hardening (4f96693) —
VariableUsages::matchesusedvalue.contains("var(")plus a substring scan, which fired on--identinside strings /url(...)and on idents glued to a preceding token (font--name). Replaced with a state-aware scanner that skips strings / comments /url(...)and only fires at a real token boundary (case-insensitive onvar(/url().@propertyrules (84da143) — synthesise onePropertyper@property:identpoints at the prelude--name,valueat theinitial-valuedeclaration (empty if absent). These now flow through completion / hover / rename / undefined-variable checks like any other definition.