Skip to content

Commit bf0c2ef

Browse files
authored
Merge branch 'main' into multiple_args
2 parents 9adc69b + 368df95 commit bf0c2ef

File tree

29 files changed

+427
-139
lines changed

29 files changed

+427
-139
lines changed

.vscode/launch.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"configurations": [
3+
{
4+
"type": "java",
5+
"name": "Run LiquidJava",
6+
"request": "launch",
7+
"mainClass": "liquidjava.api.CommandLineLauncher",
8+
"projectName": "liquidjava-verifier",
9+
"args": "liquidjava-example/src/main/java/test"
10+
}
11+
]
12+
}

README.md

Lines changed: 59 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,90 +2,99 @@
22

33
![LiquidJava Banner](docs/design/figs/banner.gif)
44

5-
## Welcome to LiquidJava
5+
## Welcome to LiquidJava!
66

7-
LiquidJava is an additional type checker for Java that based on liquid types and typestates.
7+
LiquidJava is an additional type checker for Java, based on **liquid types** and **typestates**, which provides additional safety guarantees to Java programs through **refinements** at compile time.
88

9-
Simple example:
9+
**Example:**
1010

1111
```java
1212
@Refinement("a > 0")
1313
int a = 3; // okay
1414
a = -8; // type error!
1515
```
1616

17-
This project has the LiquidJava verifier, the API and some examples for testing.
17+
This project contains the LiquidJava verifier and its API, as well as some examples for testing.
18+
1819
You can find out more about LiquidJava in the following resources:
1920

20-
* [Try it](https://github.com/CatarinaGamboa/liquidjava-examples) with Codespaces or locally following these steps
21-
* [Website](https://catarinagamboa.github.io/liquidjava.html)
22-
* [Examples of LiquidJava](https://github.com/CatarinaGamboa/liquidjava-examples)
23-
* [LiquidJava Specification of the Java Standard Library](https://github.com/CatarinaGamboa/liquid-java-external-libs)
24-
* [VSCode plugin for LiquidJava](https://github.com/CatarinaGamboa/vscode-liquidjava)
21+
* [Try it](https://github.com/CatarinaGamboa/liquidjava-examples) with GitHub Codespaces or locally
22+
* [VS Code extension for LiquidJava](https://github.com/CatarinaGamboa/vscode-liquidjava)
23+
* [LiquidJava website](https://catarinagamboa.github.io/liquidjava.html)
24+
* [LiquidJava specification examples for the Java standard library](https://github.com/CatarinaGamboa/liquid-java-external-libs)
2525
<!-- * [Formalization of LiquidJava](https://github.com/CatarinaGamboa/liquidjava-formalization) - not opensource yet -->
2626

27-
# Setup the project
27+
## Getting Started
28+
29+
### VS Code Extension
30+
31+
The easiest way to use LiquidJava is through its [VS Code extension](https://github.com/CatarinaGamboa/vscode-liquidjava), which uses the LiquidJava verifier directly inside VS Code, with error diagnostics and syntax highlighting for refinements.
32+
33+
### Command Line
34+
35+
For development, you may use the LiquidJava verifier from the command line.
36+
37+
#### Prerequisites
2838

29-
## Prerequisites
3039
Before setting up LiquidJava, ensure you have the following installed:
3140

32-
- Java 20 or newer - The project is configured to use Java 20;
33-
- Maven 3.6+ - For building and dependency management.
41+
- Java 20+ - JDK for compiling and running Java programs
42+
- Maven 3.6+ - For building and dependency management
3443

35-
## Installation Steps
44+
#### Setup
3645

37-
1. Clone the repository: `git clone https://github.com/CatarinaGamboa/liquidjava.git`;
38-
2. Build the project `mvn clean install`;
39-
3. Run tests to verify installation: `mvn test`;
40-
4. If importing into an IDE, import the project as a Maven project using the root `pom.xml`.
46+
1. Clone the repository: `git clone https://github.com/CatarinaGamboa/liquidjava.git`
47+
2. Build the project `mvn clean install`
48+
3. Run tests to verify installation: `mvn test`
49+
4. If importing into an IDE, import the project as a Maven project using the root `pom.xml`
4150

42-
## Verify Installation
51+
#### Run Verification
4352

44-
To check your refinements using LiquidJava:
53+
To run LiquidJava, use the Maven command below, replacing `/path/to/your/project` with the path to the Java file or directory you want to verify.
4554

46-
**Run verification on examples**:
4755
```bash
48-
mvn exec:java -pl liquidjava-verifier -Dexec.mainClass="liquidjava.api.CommandLineLauncher" -Dexec.args="liquidjava-example/src/main/java/testSuite/CorrectSimpleAssignment.java"
56+
mvn exec:java -pl liquidjava-verifier -Dexec.mainClass="liquidjava.api.CommandLineLauncher" -Dexec.args="/path/to/your/project"
4957
```
50-
This should output: `Correct! Passed Verification`.
5158

52-
**Test an error case**:
59+
If you're on Linux/macOS, you can use the `liquidjava` script (from the repository root) to simplify the process.
60+
61+
**Test a correct case**:
5362
```bash
54-
mvn exec:java -pl liquidjava-verifier -Dexec.mainClass="liquidjava.api.CommandLineLauncher" -Dexec.args="liquidjava-example/src/main/java/testSuite/ErrorSimpleAssignment.java"
63+
./liquidjava liquidjava-example/src/main/java/testSuite/CorrectSimpleAssignment.java
5564
```
56-
This should output an error message describing the refinement violation.
5765

58-
## Run verification
66+
This should output: `Correct! Passed Verification`.
5967

60-
### In a specific project
68+
**Test an error case**:
69+
```bash
70+
./liquidjava liquidjava-example/src/main/java/testSuite/ErrorSimpleAssignment.java
71+
```
6172

62-
Run the file `liquidjava-verifier\api\CommandLineLaucher` with the path to the target project for verification.
63-
If there are no arguments given, the application verifies the project on the path `liquidjava-example\src\main\java`.
73+
This should output an error message describing the refinement violation.
6474

65-
## Testing
75+
#### Testing
6676

6777
Run `mvn test` to run all the tests in LiquidJava.
6878

69-
The starter test file is `TestExamples.java` which uses the test suite under the `liquidjava-examples/testSuite`.
70-
71-
Paths in the test suite are considered test cases if:
79+
The starter test file is `TestExamples.java`, which runs the test suite under the `testSuite` directory in `liquidjava-example`.
7280

73-
1. File that start with `Correct` or `Error` (e.g, "CorrectRecursion.java")
74-
2. Package/Folder that contains the word `correct` or `error`.
81+
The test suite considers test cases:
82+
1. Files that start with `Correct` or `Error` (e.g., `CorrectRecursion.java`)
83+
2. Packages or folders that contain the word `correct` or `error` (e.g., `arraylist_correct`)
7584

76-
Therefore, files/folders that do not pass this description are not verified.
85+
Therefore, the files and folders that do not follow this pattern are ignored.
7786

78-
## Project structure
87+
## Project Structure
7988

80-
* **docs**: documents used for the design of the language. The folder includes a readme to a full artifact used in the design process, here are some initial documents used to prepare the design of the refinements language at its evaluation
81-
* **liquidjava-api**: inlcudes the annotations that can be introduced in the Java programs to add the refinements
82-
* **liquidjava-examples**: includes a main folder with the current example that the verifier is testing; the test suite that is used in maven test is under the `testSuite` folder
83-
* **liquidjava-verifier**: has the project for verification of the classes
84-
* *api*: classes that test the verifier. Includes the `CommandLineLauncher` that runs the verification on a given class or on the main folder of `liquidjava-examples` if no argument is given. This package includes the JUnit tests to verify if the examples in `liquidjava-example/tests` are correctly verified.
85-
* *ast*: represents the abstract syntax tree of the refinement's language.
86-
* *errors*: package for reporting the errors.
87-
* *processor*: package that handles the type checking.
88-
* *rj_language*: handles the processing of the strings with refinements.
89-
* *smt*: package that handles the translation to the SMT solver and the processing of the results the SMT solver produces.
90-
* *utils*: includes useful methods for all the previous packages.
91-
* *test/java/liquidjava/api/tests* contains the `TestExamples` class used for running the test suite.
89+
* **docs**: Contains documents used for the design of the language. This folder includes a [README](./docs/design/README.md) with the link to the full artifact used in the design process. It also contains initial documents used to prepare the design of the refinements language during its evaluation
90+
* **liquidjava-api**: Includes the annotations that can be introduced in the Java programs to add the refinements
91+
* **liquidjava-example**: Includes some examples and the test suite used for testing the verifier
92+
* **liquidjava-verifier**: Includes the implementation of the verifier. Its main packages are:
93+
* `api`: Includes the `CommandLineLauncher` that runs the verification on a given class or in the `currentlyTesting` directory if no argument is given
94+
* `ast`: Represents the Abstract Syntax Tree (AST) of the Refinements Language (RJ)
95+
* `errors`: Package for reporting the errors
96+
* `processor`: Package that handles the type checking
97+
* `rj_language`: Handles the parsing of the refinement strings to an AST
98+
* `smt`: Package that handles the translation to the SMT solver and the processing of the results the SMT solver produces
99+
* `utils`: Includes useful methods for all the previous packages
100+
* `test/java/liquidjava/api/tests`: Contains the `TestExamples` class used for running the test suite

liquidjava

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
mvn exec:java -pl liquidjava-verifier \
3+
-Dexec.mainClass="liquidjava.api.CommandLineLauncher" \
4+
-Dexec.args="$*"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package testSuite.classes.ambiguous_state_names_correct;
2+
3+
import liquidjava.specification.StateSet;
4+
import liquidjava.specification.StateRefinement;
5+
6+
@StateSet({"open", "closed"})
7+
public class Door {
8+
9+
@StateRefinement(to = "open(this)")
10+
public Door() { }
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package testSuite.classes.ambiguous_state_names_correct;
2+
3+
import liquidjava.specification.StateSet;
4+
import liquidjava.specification.StateRefinement;
5+
6+
@StateSet({"open", "closed"})
7+
public class Pipe {
8+
9+
@StateRefinement(to = "open(this)")
10+
public Pipe() { }
11+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package testSuite.classes.ambiguous_state_names_correct;
2+
3+
import liquidjava.specification.Refinement;
4+
5+
public class SimpleTest {
6+
7+
public static void main(String[] args) {
8+
Door d = new Door(); // contains 'open' and 'closed' states
9+
Pipe p = new Pipe(); // unrelated type with the same state names
10+
requiresOpen(d); // ok iff 'open' binds to Door.open otherwise it may bind to Pipe.open and fail
11+
}
12+
13+
public static void requiresOpen(@Refinement("open(s)") Door s) { }
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package testSuite.classes.conflicting_state_names_correct;
2+
3+
import liquidjava.specification.StateRefinement;
4+
import liquidjava.specification.StateSet;
5+
6+
@StateSet({"uninitialized", "initialized"})
7+
public class SM1 {
8+
9+
@StateRefinement(to="uninitialized(this)")
10+
public SM1() {}
11+
12+
13+
@StateRefinement(from="uninitialized(this)", to="initialized(this)")
14+
public void initialize() {}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package testSuite.classes.conflicting_state_names_correct;
2+
3+
import liquidjava.specification.StateRefinement;
4+
import liquidjava.specification.StateSet;
5+
6+
@StateSet({"uninitialized", "initialized"})
7+
public class SM2 {
8+
9+
@StateRefinement(to="uninitialized(this)")
10+
public SM2() {}
11+
12+
13+
@StateRefinement(from="uninitialized(this)", to="initialized(this)")
14+
public void initialize() {}
15+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package testSuite.classes.conflicting_state_names_correct;
2+
3+
class SimpleTest {
4+
public static void main(String[] args) {
5+
// both classes contain the same state names
6+
SM1 sm1 = new SM1();
7+
SM2 sm2 = new SM2();
8+
sm1.initialize();
9+
sm2.initialize();
10+
}
11+
}

liquidjava-verifier/src/main/java/liquidjava/errors/ErrorHandler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,7 @@ public static void printCostumeError(CtElement element, String msg, ErrorEmitter
181181
sb.append(element + "\n\n");
182182
sb.append("Location: " + element.getPosition() + "\n");
183183
sb.append("______________________________________________________\n");
184-
sb.append(sb.toString());
185-
184+
186185
errorl.addError(s, sb.toString(), element.getPosition(), 1);
187186
}
188187

0 commit comments

Comments
 (0)