Skip to content

Commit f4f65d7

Browse files
Update CLAUDE.md to match current test conventions and layout (#356)
CLAUDE.md had drifted from the README and the code. Docs-only change. - **Test discovery:** any `.java` file outside a leaf directory is a test, and so is every leaf directory. `Correct…`/`Error…` names are only a convention (see `TestExamples#sourcePaths`). - **Expectations:** comments now use `// Expect: <Title> Error` / `// Expect: Warning`. The old `// <Title> Error` form no longer matches `TestUtils.EXPECTED_DIAGNOSTIC`. Warnings are matched by line only. - **Package map:** `ast/` lives under `rj_language/` (with `parsing/`, `opt/`, `visitors/`). `errors/` and `warnings/` live under `diagnostics/`. - **Z3:** it is bundled in-process through `z3-turnkey`; the verifier does not shell out to it. - Removed the reference to a `co-specifying-liquidjava` skill, which is not in the repo. - Added `./mvnw`, the `liquidjava` script's recompile-only-when-changed behaviour, and the CLI options (as in the README). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent be47cb6 commit f4f65d7

1 file changed

Lines changed: 13 additions & 12 deletions

File tree

‎CLAUDE.md‎

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ This is a Maven multi-module build (`pom.xml` is the umbrella):
1919
Verifier package map (`liquidjava-verifier/src/main/java/liquidjava/`):
2020
- `api/` — entrypoints; `CommandLineLauncher` is the CLI main.
2121
- `processor/` — Spoon processors. `RefinementProcessor` orchestrates; `refinement_checker/` contains `RefinementTypeChecker`, `MethodsFirstChecker`, `ExternalRefinementTypeChecker`, plus `general_checkers/` and `object_checkers/` for typestate.
22-
- `ast/` — AST of the Refinements Language (RJ).
23-
- `rj_language/` — parser from refinement strings to RJ AST.
22+
- `rj_language/` — the Refinements Language (RJ): `parsing/` (refinement strings → AST), `ast/`, `opt/` (expression simplification), `visitors/`.
2423
- `smt/` — Z3 translation (`TranslatorToZ3`, `ExpressionToZ3Visitor`, `SMTEvaluator`, `Counterexample`).
25-
- `errors/`, `utils/`, `diagnostics/`.
24+
- `diagnostics/` — error and warning reporting (`errors/`, `warnings/`).
25+
- `utils/` — shared utilities and constants.
2626

2727
## Commands
2828

@@ -31,7 +31,7 @@ Build / install everything:
3131
mvn clean install
3232
```
3333

34-
Run the test suite (verifier module, runs whole `testSuite/` dir):
34+
Run the test suite (verifier module, runs whole `testSuite/` dir); `./mvnw` works in place of `mvn`:
3535
```bash
3636
mvn test
3737
```
@@ -42,7 +42,7 @@ mvn -pl liquidjava-verifier -Dtest=TestExamples test
4242
mvn -pl liquidjava-verifier -Dtest=TestExamples#testMultiplePaths test
4343
```
4444

45-
Verify a specific file/directory from CLI (uses the `liquidjava` script in repo root, macOS/Linux):
45+
Verify a specific file/directory from CLI (uses the `liquidjava` script in repo root, macOS/Linux; it recompiles the verifier only when local sources or Maven files changed):
4646
```bash
4747
./liquidjava liquidjava-example/src/main/java/testSuite/CorrectSimpleAssignment.java
4848
```
@@ -52,24 +52,25 @@ mvn exec:java -pl liquidjava-verifier \
5252
-Dexec.mainClass="liquidjava.api.CommandLineLauncher" \
5353
-Dexec.args="/path/to/file_or_dir"
5454
```
55+
CLI options: one or more paths, `-h`/`--help`, `-v`/`--version`, `-d`/`--debug` (debug logging, skips expression simplification), `-lsp`/`--language-server`.
5556

5657
Code formatting runs automatically in the `validate` phase via `formatter-maven-plugin` (configured for Java 20 in `liquidjava-verifier/pom.xml`); no separate lint command.
5758

5859
## Test Suite Conventions
5960

6061
Tests are discovered by `TestExamples#testPath` (parameterized) under `liquidjava-example/src/main/java/testSuite/`:
6162

62-
- Single-file cases: filename starts with `Correct…` or `Error…`.
63-
- Directory cases: directory name contains the substring `correct` or `error`.
64-
- Anything else is **ignored** (so helper sources can live alongside).
65-
- Expected errors for a failing case are declared with inline `// <Error Title>` comments on **the line where each error should be reported** (regex `//\s*(.*?\bError\b)`, case-insensitive — see `TestUtils#getExpectedErrorsFromFile`). Both the title and the line number must match, and the count of comments must equal the count of reported errors. Directory cases work the same way: the scanner walks every file in the directory; there are no `.expected` files.
63+
- Every `.java` file outside a leaf directory is a single-file test case.
64+
- Every leaf directory (no subdirectories) is a single test case covering all its files.
65+
- File and directory names do not matter (the `Correct…`/`Error…`/`…_correct`/`…_error` names are only a convention).
66+
- Expected diagnostics are declared with inline `// Expect: <Title> Error` or `// Expect: Warning` comments on **the line where each diagnostic should be reported** (regex `//\s*Expect:\s*(.*?\b(Error|Warning)\b)`, case-insensitive — see `TestUtils#getExpectedDiagnosticsFromFile`). For errors both the title and the line must match; for warnings only the line. The number of expectations must equal the number of reported diagnostics, so a test with no expectations must produce none. Directory cases collect expectations from every file in the directory; there are no `.expected` files.
6667

67-
When adding new test cases, place them under `liquidjava-example/src/main/java/testSuite/` following the naming rules above — that is the only way they get picked up.
68+
When adding new test cases, place them under `liquidjava-example/src/main/java/testSuite/` — that is the only way they get picked up.
6869

6970
## Architecture Notes That Span Files
7071

7172
- **Two-pass typechecking.** `MethodsFirstChecker` collects method signatures and refinement contracts before `RefinementTypeChecker` walks bodies, so forward references and recursion resolve. Edits to one usually need a matching change in the other.
7273
- **Refinement string → AST → Z3.** A `@Refinement("a > 0")` string flows: `rj_language` parser → `ast` nodes → `smt/TranslatorToZ3` / `ExpressionToZ3Visitor`. New predicate forms generally require touching all three.
73-
- **External refinements.** `ExternalRefinementTypeChecker` plus `*Refinements.java` companion files specify contracts for third-party APIs without modifying their sources. The `co-specifying-liquidjava` skill covers this workflow.
74+
- **External refinements.** `ExternalRefinementTypeChecker` plus `*Refinements.java` companion files specify contracts for third-party APIs without modifying their sources.
7475
- **Typestate** lives in `processor/refinement_checker/object_checkers/` and uses `@StateRefinement` / `@StateSet` from the API. Ghost-state predicates flow through the same SMT pipeline as value refinements.
75-
- **Z3 dependency.** The verifier shells out to Z3 via JNI bindings; failures often surface as `SMTResult` errors or counterexamples, not Java exceptions.
76+
- **Z3 dependency.** The verifier calls Z3 in-process through the Java bindings bundled by `z3-turnkey` (no separate Z3 install); failures often surface as `SMTResult` errors or counterexamples, not Java exceptions.

0 commit comments

Comments
 (0)