fix(buildfile-lsp): complete & hover provider_state/target fields mid-edit#117
Merged
Conversation
…-edit Field-name completion for `provider_state(...)` and `target(...)` relied on the eval-based provenance index, which only exists when the whole BUILD buffer evaluates. While typing, a half-written property name is an undefined bareword, so eval fails, the index falls back to `source_only`, and no fields are offered — the common case where completion is actually wanted. Detect the enclosing call textually instead (string/paren-aware scan), the same eval-free approach `driver = "..."` and `heph.` member completion already use: - `provider_state(provider="X", …)` → completes & hovers provider X's state schema fields (the dynamic kwargs the stock server has no docs for). - `target(…)` → completes the base args plus the selected driver's config fields, resolved from the textual `driver = "X"`. Removes the now-dead eval-based `StateCall`/`TargetCall` index machinery and the state provenance capture that only fed it. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Surface red diagnostics for invalid keyword arguments in `target(...)` and `provider_state(...)` calls, complementing the completion/hover added in this PR. Two checks, run off the parsed AST (so they work mid-edit, no eval needed): - Unknown key: a kwarg naming no known field. Only flagged when the complete valid set is known — the driver/provider is resolved from a string-literal `driver=`/`provider=` and its schema is available — so an unresolved schema never yields a false positive. - Wrong type: a kwarg whose literal value doesn't match the field's declared ParamType. Non-literal values (variables, concatenations, calls) carry no static type and are left alone. Numeric matching is lenient (an int literal satisfies uint/float) to mirror how the engine coerces at eval time. Diagnostics attach to the offending key (unknown) or value (wrong type) span, sourced as "heph". Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
afad42c to
48d7411
Compare
Hovering the `target` or `provider_state` callee name showed the stock `def name(*args, **kwargs) -> None` prototype — both builtins take a raw `args: &Arguments`, so the Starlark server has no real signature for them. Render a meaningful one instead, computed once at startup and served by the hover proxy when the callee name is under the cursor: - target(name, driver, labels, transitive, **config) -> str - provider_state(provider, **state) -> None `target`'s arguments come from `target_base_fields()` (the same source completion uses, so they never drift); each builtin's real docstring is pulled from the globals doc and kept. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
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.
Problem
Hovering or autocompleting the properties of a
provider_state(...)call produced nothing while typing. Field-name completion for bothprovider_state(...)andtarget(...)rode on the eval-based provenance index, which only exists when the whole BUILD buffer evaluates. Mid-token, the half-written property name is an undefined bareword → eval fails → the index falls back tosource_only→ no fields. That's exactly the moment completion is wanted.driver = "..."andheph.member completion never had this problem — they detect context textually, no eval required.Fix
Detect the enclosing call textually (string/paren-aware scan), the same eval-free approach the working paths already use:
provider_state(provider="X", …)— completes and hovers providerX's state-schema fields (the dynamic kwargs the stockstarlark_lspserver has no docs for). Hover shows the field's type + doc.target(…)— completes the basetargetargs plus the selected driver's config fields, resolved from the textualdriver = "X".Both now work mid-edit (auto-closed parens, partial token) instead of only on a fully-valid buffer.
Removes the now-dead eval-based
StateCall/TargetCallindex machinery and the state-provenance capture that only fed it.Tests
completion_mid_edit_offers_state_fields/completion_mid_edit_offers_target_fields— the failing cases, now green.completion_inside_provider_state_offers_state_fields,completion_outside_provider_state_offers_no_state_fields,hover_on_state_field_renders_type_and_doc.enclosing_provider_state_resolves_provider_textually,kwarg_string_extracts_whole_token_value.lint+cargo test -p plugin-buildfile(95 passed) clean.🤖 Generated with Claude Code