GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Fix crashes on enum methods, varargs calls and calls on a call result by CatarinaGamboa · Pull Request #420 · liquid-java/liquidjava

Conversation

@CatarinaGamboa

@CatarinaGamboa CatarinaGamboa commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator

Three crashes on ordinary Java code, met together in one real class (JabRef's EditAction). One commit each.

1. An enum with a method crashes the verifier

enum Action { UNDO, REDO; String getText() { return name(); } }
NullPointerException: Cannot invoke "String.endsWith(String)" because "qualifiedName" is null
  at ExternalRefinementTypeChecker.visitCtMethod

ExternalRefinementTypeChecker skips classes and records (user code) but not enums, so it visits the enum's methods with no external target. Fix: a no-op visitCtEnum, as for records.

2. A varargs call with more arguments than parameters

void debug(String format, Object... args) {}
logger.debug("{} and {}", a, b);   // IndexOutOfBoundsException: Index 2 out of bounds for length 2

mapInvocation and checkParameters index the parameters by argument position. Fix: both use only the arguments bound one to one to parameters; the ones collected into the varargs array are left out (an array parameter's refinement is not checked per element anyway).

3. A call on the result of a call without a return refinement

holder.get().close();
// Argument Mismatch Error: Argument '#holder_14' and its respective parameter of ghost 'Door.state1'
// types are incompatible: expected Door, got Holder

When get() has no return refinement, its TARGET metadata is still its own receiver (holder), and prepareInvocationTarget used it as the receiver of close(). Fix: a call whose TARGET is not its return value (RETURN_VAR_NAME) gives a fresh receiver of the call's type, in an unknown state, created once per call (Keys.RECEIVER, as for constructor calls). Now: found true but expected open(#fresh).

Tests

  • CorrectEnumWithMethod: crashed before.
  • CorrectVarargsCall (more, fewer and an explicit array) and ErrorVarargsCall (a refined fixed parameter before the varargs is still checked): crashed before.
  • CorrectCallResultReceiver (a call with no precondition on a call result) and ErrorCallResultReceiver (reported as a state error, not an argument mismatch).
  • mvn test: 463 tests, 0 failures.

Found on a real fixed bug: JabRef's Edit command calling undo()/redo() without canUndo()/canRedo() (PR JabRef/jabref#9777). We also checked 53 exercises built from real OSS bugs on main (69895fa) and with these changes: the results are identical.

🤖 Generated with Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
CatarinaGamboa and others added 3 commits October 24, 2026 23:36
@CatarinaGamboa @claude
Skip enums when reading external specs
9fa0b8f
ExternalRefinementTypeChecker skips classes and records (user code) but
walked into enums, whose methods have no external target: any program
declaring an enum with a method crashed with a NullPointerException
("qualifiedName" is null).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@CatarinaGamboa @claude
Map only the fixed arguments of a varargs call
5827a5b
mapInvocation and checkParameters indexed the parameters by argument
position, so a varargs call with more arguments than parameters (e.g.
logger.debug("{} {}", a, b)) failed with IndexOutOfBoundsException. The
arguments collected into the varargs array are left out.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@CatarinaGamboa @claude
Use a fresh receiver for a call on a call result
de56949
In a.get().m(), when get() has no return refinement its TARGET metadata
is its own receiver (a), not the value it returns, and m() was checked
against a: "Argument Mismatch Error ... expected Door, got Holder". The
receiver is now a fresh value of get()'s type, in an unknown state,
created once per call.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@CatarinaGamboa
CatarinaGamboa force-pushed the fix/enum-methods-external-checker branch from d3f6745 to de56949 Compare October 24, 2026 22:39
@CatarinaGamboa
CatarinaGamboa merged commit b3a4e4a into main Oct 24, 2026
1 check passed

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@CatarinaGamboa
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.