Skip to content

No state hint when the call that reaches the needed state has a conditional postcondition (mode == 2 ? a(this) : b(this)) #455

Closed

Description

@CatarinaGamboa

Impact: if the only call that reaches the needed state has a conditional postcondition (mode == 2 ? compressionExplicit(this) : startCompression(this)), the error gets no hint at all. That is exactly the case where a hint helps most, because the developer has to find both the call and the argument value.

Minimal reproducer (an external spec and a client, in one directory)

// ImageWriteParamRefinements.java
@ExternalRefinementsFor("javax.imageio.ImageWriteParam")
@StateSet({"startCompression", "compressionExplicit", "compressionSet"})
public interface ImageWriteParamRefinements {
    @StateRefinement(to = "startCompression(this)")
    void ImageWriteParam(Locale locale);

    @StateRefinement(to = "mode == 2 ? compressionExplicit(this) : startCompression(this)")
    void setCompressionMode(int mode);

    @StateRefinement(from = "compressionExplicit(this)", to = "compressionSet(this)")
    void setCompressionType(String compressionType);
}

// Recoder.java
public class Recoder {
    static ImageWriteParam params() {
        ImageWriteParam wParam = new ImageWriteParam(Locale.ROOT);
        wParam.setCompressionType("JPEG");
        return wParam;
    }
}

Actual (main @ 19991d3): found startCompression(wParam⁹) but expected compressionExplicit(wParam⁹), with no hints.

When setCompressionMode is written as from = "startCompression(this)", to = "compressionExplicit(this)" instead, the same program does get hints:

Hints:
  - Call wParam.setCompressionMode(int) before this call to move wParam from startCompression to compressionExplicit
  - In state startCompression, wParam can call: setCompressionMode(int)

Expected: a hint that also gives the condition, e.g. "Call wParam.setCompressionMode(int) with mode == 2 before this call to move wParam from startCompression to compressionExplicit".

Related: #381, which uses this same example.

Real-world scenario. One of the exercises for the error-message study is dcm4che's Transcoder. It calls setCompressionType without setCompressionMode(ImageWriteParam.MODE_EXPLICIT), which throws IllegalStateException: Compression mode not MODE_EXPLICIT!, and the developers fixed it by adding that call (40bf9c66). The state machine view shows the way out (setCompressionMode, mode == 2), but the error itself has no hint.

In VS Code (dcm4che study exercise, verifier main @ 19991d3, extension main @ 80bed18). The Verification tab has no hint:

A1_01 Verification tab

The State Machine tab does show the way out, setCompressionMode with mode == 2:

A1_01 State Machine tab

Activity

  1. added
    enhancementNew feature or request
    real-world-findingFound when experimenting liquidjava in real world repos or OSS
    studyNeeded before the error-message user study
    on Nov 2, 2026
  2. CatarinaGamboa commented on Nov 2, 2026

    @CatarinaGamboa
    CollaboratorAuthor

    Cause, found while looking at #454: StateMachineBuilder leaves out every method whose state refinement mentions anything besides the states of this, including parameters (class Javadoc and canModel). So setCompressionMode(int mode), with to = "mode == 2 ? …", is never in the machine that the hints are built from, and the error gets no hint. A fix for this issue could share its modelling with the return-value guards in #454: keep the method and record the condition on the transition (mode == 2), as the IDE's diagram already does.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesterror messagesRelated to error messagesreal-world-findingFound when experimenting liquidjava in real world repos or OSSstudyNeeded before the error-message user study

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions