Skip to content

Fix NoiseSettings value completion (empty field values, material_rule lists) - #146

Merged
ItsMeBrianD merged 3 commits into
mainfrom
claude/project-thread-fu7ll0
Nov 2, 2026
Merged

ItsMeBrianD merged 3 commits into
mainfrom
claude/project-thread-fu7ll0

Conversation

@ItsMeBrianD

@ItsMeBrianD ItsMeBrianD commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Brian · project thread

Two autocomplete bugs in NoiseSettings bodies, both offering the object's own field names where a value belongs.

1. Empty value before the next field

Typing default_block = on a line above default_fluid = water offered sibling field names (default_fluid, aquifers, ...) instead of block states, and put a red squiggle on the next field. The parser read the two lines as default_block = default_fluid, then failed on the second =.

  • Recovery (syntax/recover.go, markMissingValues) inserts a synthetic MISSING token after an = whose value is absent: the next token is a closer or a comma, or the next line starts another key =. No expression contains a bare =, so a key followed by = on a later line is always a new field or statement.
  • MISSING is declared in the lexer's tokens {} and is a primary alternative, so it becomes Bad. The field keeps a Bad value, the next field parses intact, and there is one syntax/missing-value error on the =. It is hidden from "expecting {...}" messages.
  • Function checking no longer adds "not a value a function can compute with" on a Bad value, since the parser already reported it.

2. Inside material_rule = [ ... ]

A list there is Sequence sugar, but completion offered aquifers and debug_functions. The field's type is a union of a rule id and an inline MaterialRule, so ListItemInfo did not see the sugar it already handles for a bare SurfaceRule, and completion fell through to the enclosing block's fields.

  • ListItemInfo now picks the MaterialRule member of a union.
  • Completion inside a list whose item type is unknown now returns nothing rather than the enclosing object's fields.

Judgement calls

  • I tried a grammar predicate first (like declBody's valueFollows). ANTLR evaluates predicates found inside nested blocks during prediction at the outer decision's position, and that broke inline function blocks (on_right_click = { /... }). Preprocessing the token stream avoids predicates entirely.
  • Adding tokens { MISSING } renumbers every token type in the generated parser, which is why the generated diff is large. Nothing outside the generated code uses raw numbers.
  • Ore(size =) and { a = } now also report "expected a value after '='" instead of a generic parse error.

Tests

  • Completion matrix: an empty value before the next field, before }, and before a quoted key; a multi-line material_rule = [ list, and its second item.
  • New recovery golden field_missing_value_next_field.mms covers nested objects, helper args, and function bodies. Two existing goldens now show the clearer message.
  • go test ./... in engine/ passes, and gen.sh output is checked in.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AX3TsxdA6e59tBa7W4Fhh4

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of omitted field values: the editor now reports a clear error and better preserves following fields and declarations.
    • Avoided duplicate diagnostics for missing values.
    • Improved completions in lists, including surface-rule lists, and prevented unrelated field suggestions when list item information is unavailable.

`default_block =` followed by `default_fluid = water` on the next line
parsed as `default_block = default_fluid`, then failed on the second '='.
Completion at the empty value then saw a field-key position and offered
sibling fields instead of block states.

Recovery now inserts a synthetic MISSING token after an '=' whose value is
absent: the next token closes a bracket or is a comma, or the next line
starts another `key =`. MISSING is a primary that becomes Bad, so the
field keeps a Bad value, the next field parses intact, and the parser
reports one "expected a value after '='" error.

A grammar predicate was tried first, but ANTLR evaluates predicates in
nested blocks at the outer decision's position during prediction, which
broke inline function blocks; preprocessing the token stream avoids that.

Function checking no longer adds "not a value a function can compute
with" on a Bad value, since the parser already reported it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AX3TsxdA6e59tBa7W4Fhh4
@ItsMeBrianD ItsMeBrianD self-assigned this Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 41 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 97eb2bb4-52e2-42e1-bdae-97326b9b4f10
Commits

Reviewing files that changed from the base of the PR and between 844fdc4 and 1dcaedb.

Files selected for processing: 2
  • engine/ide/complete_matrix_test.go
  • engine/ide/ide.go

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 67a8b8d7-3d4e-4409-9781-56a821054294
Commits

Reviewing files that changed from the base of the PR and between 7f2badb and 844fdc4.

Files selected for processing: 18
  • engine/ide/complete_matrix_test.go
  • engine/ide/ide.go
  • engine/sema/fn.go
  • engine/sema/ide.go
  • engine/syntax/grammar/MMSLexer.g4
  • engine/syntax/grammar/MMSParser.g4
  • engine/syntax/parse.go
  • engine/syntax/parser/MMSLexer.interp
  • engine/syntax/parser/MMSLexer.tokens
  • engine/syntax/parser/MMSParser.interp
  • engine/syntax/parser/MMSParser.tokens
  • engine/syntax/parser/mms_lexer.go
  • engine/syntax/parser/mms_parser.go
  • engine/syntax/recover.go
  • engine/syntax/testdata/recovery/field_missing_value.golden
  • engine/syntax/testdata/recovery/field_missing_value_next_field.golden
  • engine/syntax/testdata/recovery/field_missing_value_next_field.mms
  • engine/syntax/testdata/recovery/unclosed_index.golden

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

Walkthrough

The parser now inserts synthetic tokens and reports diagnostics for selected missing values. Semantic analysis suppresses an additional error for Bad expressions. IDE list-item type lookup and completion behavior also change.

Changes

Syntax recovery and IDE completion

Layer / File(s) Summary
Add missing-value parser token
engine/syntax/grammar/*, engine/syntax/parser/*
The grammar and generated parser recognize the recovery-only MISSING token as a primary expression. Generated token IDs and parser metadata are updated.
Insert missing values and report diagnostics
engine/syntax/recover.go, engine/syntax/parse.go, engine/sema/fn.go, engine/syntax/testdata/recovery/*
The parser inserts synthetic tokens after selected omitted values and records syntax/missing-value diagnostics. Semantic analysis does not add another error for syntax.Bad expressions. Recovery fixtures and expected outputs are updated.
Update list-item completion
engine/sema/ide.go, engine/ide/ide.go, engine/ide/complete_matrix_test.go
ListItemInfo selects a normalized tMaterialRule member from a union. Completion returns no candidates when a list item has no type information. Matrix tests add empty-value and surface-rule list cases.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Parse
  participant markMissingValues
  participant MMSParser
  participant FileDiagnostics
  Parse->>markMissingValues: scan tokens and return inserted tokens and diagnostics
  markMissingValues-->>Parse: synthetic MISSING tokens and diagnostics
  Parse->>MMSParser: parse tokens containing MISSING
  Parse->>FileDiagnostics: append missing-value diagnostics
Loading

Suggested reviewers: claude

Merge Risk: Minimal · previous review 844fd

The supplied evidence identifies no actionable issue blocking merge; normal checks remain appropriate.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main completion changes for empty field values and material_rule lists. It is concise and directly related to the changeset.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 5 functions across 8 files. (10 skipped: 10 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

A rabbit checks the tokens in a row,
A missing value gets a marker to show.
The parser keeps the next field in sight,
Completions sort their choices right.
I twitch my nose and hop away.

`material_rule = [ | ]` in NoiseSettings offered the object's own fields
(aquifers, debug_functions). The field's type is a union of a rule id and
an inline MaterialRule, so ListItemInfo did not see the Sequence sugar it
already handles for a bare SurfaceRule, and completion fell through to
the enclosing block's fields.

ListItemInfo now picks the MaterialRule member of a union, and completion
inside a list stops there instead of offering the enclosing object's
fields when the list's item type is unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AX3TsxdA6e59tBa7W4Fhh4
@ItsMeBrianD ItsMeBrianD changed the title Complete field values left empty before the next field Fix NoiseSettings value completion (empty field values, material_rule lists) Nov 2, 2026
`sea_level = {` offered NoiseSettings' own fields inside the braces,
because completion fell through from the inner block (no object type) to
the enclosing one. An object literal whose type has no fields now offers
nothing. Inline definitions such as `parent = { ... }` still complete
their kind's fields.

Found by probing every field of every declaration kind, two levels deep,
with `= |`, `= [|]`, a multi-line list and a multi-line object.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AX3TsxdA6e59tBa7W4Fhh4
@ItsMeBrianD
ItsMeBrianD merged commit f8651a9 into main Nov 2, 2026
7 checks passed
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.

2 participants