Skip to content

fix: suppress cascading syntax errors in method bodies (#422)#456

Merged
nawforce merged 2 commits into
mainfrom
feature/422-suppress-cascade-syntax-errors
May 25, 2026
Merged

fix: suppress cascading syntax errors in method bodies (#422)#456
nawforce merged 2 commits into
mainfrom
feature/422-suppress-cascade-syntax-errors

Conversation

@kjonescertinia

Copy link
Copy Markdown
Contributor

Summary

Fixes #422.

When a method body fails to parse (e.g. an invalid escape '\s' in a string), ANTLR's recovery produced a noisy cluster of diagnostics on top of the original error:

  • the lexer reported the bad escape twice — once at the backslash, again at the closing quote when recovery re-entered the string
  • control-flow analysis ran on the partial AST and emitted a spurious Expected return statement / Method does not return a value

Both are now suppressed. Example: a class with a single '\s' invalid escape used to report 4 diagnostics; it now reports a single Invalid escape sequence '\s' in string.

Changes

  • OuterBlock tracks whether its on-demand block parse produced issues. verify() still runs per-statement verification on the salvaged AST so downstream features (rename, navigation, references) keep working — only verifyControlPath is skipped on parse failure.
  • statementsOrErrors() is a new sibling to statements() returning Either[ParseErrors, Seq[Statement]] for callers that want to distinguish a parse failure from a genuinely empty block. statements() retains its existing best-effort Seq behaviour, so existing call-sites are unaffected.
  • CollectingErrorListener collapses adjacent Invalid escape sequence diagnostics on the same line — the typical lexer-recovery cascade — while leaving unrelated same-line errors (e.g. two genuine missing ; errors) untouched.

Test plan

  • New BlockTest cases cover:
    • the cascade no longer emits Expected return statement / Code path does not return / Method does not return
    • a successful parse still verifies control flow (regression guard)
    • statementsOrErrors returns Left(ParseErrors) on failure, Right(stmts) on success
    • the duplicate Invalid escape sequence diagnostic is collapsed
  • Full JVM test suite passes (2398 tests)
  • JS cross-build compiles cleanly
  • sbt scalafmtCheckAll clean

When a method body fails to parse (e.g. an invalid escape '\s' in a
string), ANTLR's recovery produced a noisy cluster of diagnostics on
top of the original error:

  - the lexer reported the bad escape twice (once at the backslash,
    again at the closing quote when recovery re-entered the string)
  - control-flow analysis ran on the partial AST and emitted a
    spurious "Expected return statement" / "Method does not return"

Both are now suppressed:

  - OuterBlock tracks whether its on-demand block parse produced
    issues; verify() still runs per-statement verification (so
    rename / navigation / references keep working on the salvaged
    AST) but skips verifyControlPath on failure.
  - A new statementsOrErrors() returns Either[ParseErrors, Seq[Statement]]
    for callers that want to distinguish failure from an empty block;
    statements() retains its best-effort Seq behaviour.
  - CollectingErrorListener collapses adjacent "Invalid escape sequence"
    diagnostics on the same line — the typical lexer-recovery cascade —
    while leaving unrelated same-line errors (e.g. two genuine missing
    ';' errors) untouched.
@nawforce nawforce merged commit 2ba111a into main May 25, 2026
1 check passed
@nawforce nawforce deleted the feature/422-suppress-cascade-syntax-errors branch May 25, 2026 16:06
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.

Improve error reporting for syntax errors in method bodies

2 participants