Skip to content

Resolve Static Final Constants in Refinement Aliases - #423

Merged
CatarinaGamboa merged 1 commit into
mainfrom
fix/alias-static-constants
Oct 26, 2026
Merged

CatarinaGamboa merged 1 commit into
mainfrom
fix/alias-static-constants

Conversation

@CatarinaGamboa

Copy link
Copy Markdown
Collaborator

Static final constants (e.g. ImageWriteParam.MODE_EXPLICIT) can be used in @Refinement and @StateRefinement predicates, but not inside a @RefinementAlias body. Alias definitions are parsed through RefinementsParser.parseAliasDefinition, which skips the constant resolution done in the Predicate constructor, so the constant stayed an unresolved name.

import javax.imageio.ImageWriteParam;

@RefinementAlias("Mode(int x) { x == ImageWriteParam.MODE_EXPLICIT || x == ImageWriteParam.MODE_DEFAULT "
        + "|| x == ImageWriteParam.MODE_COPY_FROM_METADATA || x == ImageWriteParam.MODE_DISABLED }")
@ExternalRefinementsFor("javax.imageio.ImageWriteParam")
public interface ImageWriteParamRefinements {
    @StateRefinement(to = "mode == ImageWriteParam.MODE_EXPLICIT ? tilingExplicit(this) : startTiling(this)")
    void setTilingMode(@Refinement("Mode(_)") int mode);
}

Before, this failed with an error reported at the wrong annotation (the @StateRefinement, even when that line no longer mentioned the constant):

Not Found Error: Variable 'ImageWriteParam.MODE_EXPLICIT' could not be found
26 |     @StateRefinement(to = "mode == ImageWriteParam.MODE_EXPLICIT? tilingExplicit(this) : startTiling(this)")

Changes

  • TypeChecker#handleAlias now resolves constants in the parsed alias body, using the class that declares the alias as context, so its imports apply.
  • Predicate#resolveStaticFinalConstants gets a public overload that takes an error position. For aliases, an unresolvable constant is reported at the @RefinementAlias annotation:
    Not Found Error: Constant 'ImageWriteParam.MODE_EXPLICIT' could not be found
    7 | @RefinementAlias("Explicit(int x) { x == ImageWriteParam.MODE_EXPLICIT }")
    
  • Since Enum#clone keeps the resolved literal, expanding the alias at each use site keeps the resolved values.

Tests

  • CorrectStaticFinalInAlias: alias with ImageWriteParam constants and Byte.MAX_VALUE (implicit java.lang)
  • ErrorStaticFinalInAlias: value outside the alias range
  • ErrorStaticFinalInAliasMissingImport: missing import, error at the alias
  • classes/alias_static_final_state_correct: alias plus constants in a @StateRefinement on external refinements (the original case)

mvn test: 496 tests, 0 failures.

🤖 Generated with Claude Code

Constants like ImageWriteParam.MODE_EXPLICIT were resolved in refinements
and state refinements, but not inside @RefinementAlias bodies, which are
parsed through a separate path. Resolve them against the imports of the
class declaring the alias, and report unresolvable ones at the alias.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@CatarinaGamboa
CatarinaGamboa merged commit 0d489e1 into main Oct 26, 2026
1 check 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.

1 participant