Project developed at
Extending Java with
Liquid Types
Extend your Java code with Refinement Types and catch bugs earlier!
LiquidJava implements an additional type system with Refinement Types on top of Java.
It allows developers to express better restrictions on the code and discover more bugs before executing the program.
Learn more about LiquidJava!
Papers:
Usability-Oriented Design of Liquid Types for Java, by Catarina Gamboa, Paulo Canelas, Christopher Timperley and Alcides Fonseca, ICSE 2023
Posters:
Usability-Oriented Design of Liquid Types for Java, by Catarina Gamboa, Paulo Canelas, Christopher Timperley and Alcides Fonseca, ICSE digital poster session.
LiquidJava: Adding Lightweight Verification to Java, by Catarina Gamboa, Paulo Canelas, Christopher Timperley and Alcides Fonseca, INForum 2021 - Informatics Symposium, Lisbon, Portugal. Award for Best Student Poster.
GitHub Repositories:
liquidjava - main repository with api, verifier and examples.
liquidjava-examples - usage examples
liquid-java-external-libs - annotations in Java standard libraries
vscode-liquidjava - vscode extension for liquidjava using LSP
Install the LiquidJava Plugin
Download the Visual Studio Code plugin
Also available in the Open VSX Registry
Requirements:
Visual Studio Code
JDK 20
Language Support for Java by Red Hat plugin
To use the LiquidJava annotations, include the LiquidJava API in your project. Maven and Gradle setup instructions are available here.
To learn how to use LiquidJava and its capabilities, you can follow the LiquidJava tutorial guide.
LiquidJava Examples
Find examples of LiquidJava in different parts of code.
Refinements in Variables
We can add a @Refinement in any place we already have a basic type in the code. Hence, in declarations of variable or class fields it is possible to add a refinement type.
Refinements in Methods
In methods, both the parameters and the return value can have refined types.
The parameters refinements will ensure that the method is only invoked with the expected types.
The return refinement guarantees that the return inside the method's body corresponds to the expected type.
Refinements in Classes
LiquidJava contains the mechanisms to model Object Type State.
Since class methods can have effects on the internal state of objects, each method can be annotated with the allowed state transitions using the @StateRefinement(from = "...", to = "...") annotation. In this annotation, the from argument represents the object states in which the method can be invoked, whereas the to argument represents the state the object will have at the end of the method execution.
There are two possibilities of modelling object state:
State Sets: If a class has a defined set of states, it is possible to create multiple @StateSet that include the allowed object states.
Ghost Properties: To model other properties (int or boolean) it is possible to create @Ghost properties that work as uninterpreted functions.
In either case, whenever there is a need to refer to the previous state of the object, it is possible to use the old keyword.

