Skip to content

Commit 0f7d53a

Browse files
committed
Add Connection Example
1 parent 77be269 commit 0f7d53a

File tree

3 files changed

+59
-6
lines changed

3 files changed

+59
-6
lines changed

pages/examples/connection.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
title: Connection
3+
parent: Examples
4+
nav_order: 6
5+
permalink: /examples/connection/
6+
description: A typestate protocol with a value-dependent conditional transition.
7+
---
8+
9+
# Connection
10+
11+
This example models a small object protocol where the target state of `connect` depends on a boolean parameter. Because the transition is value-dependent, this protocol does not encode to a DFA based only on the current state and method call.
12+
13+
```java
14+
import liquidjava.specification.*;
15+
16+
@StateSet({"disconnected", "guest", "authenticated"})
17+
public class Connection {
18+
@StateRefinement(to="disconnected()")
19+
public Connection() {}
20+
21+
@StateRefinement(from="disconnected()", to="hasToken ? authenticated() : guest()")
22+
public void connect(boolean hasToken) {}
23+
24+
@StateRefinement(from="guest() && hasToken", to="authenticated()")
25+
public void authenticate(boolean hasToken) {}
26+
27+
@StateRefinement(from="authenticated()")
28+
public void sendData() {}
29+
30+
@StateRefinement(from="guest() || authenticated()", to="disconnected()")
31+
public void disconnect() {}
32+
}
33+
```
34+
35+
```java
36+
Connection conn = new Connection();
37+
conn.connect(true);
38+
conn.sendData();
39+
conn.disconnect();
40+
```
41+
42+
```java
43+
Connection conn = new Connection();
44+
conn.connect(false);
45+
conn.sendData(); // State Refinement Error
46+
```
47+
48+
LiquidJava enforces the intended protocol:
49+
50+
- The `connect` method can be called from `disconnected()`, and the target state depends on the value of `hasToken`
51+
- The `authenticate` method can only be called from `guest()`, and only transitions to `authenticated()` if `hasToken` is true
52+
- The `sendData` method can only be called from `authenticated()`
53+
- The `disconnect` method can be called from either `guest()` or `authenticated()`, and always transitions back to `disconnected()`

pages/examples/downloader.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,16 @@ This example models a simple downloader object that tracks the progress of a dow
1414
@Ghost("int progress")
1515
@StateSet({"created", "downloading", "completed"})
1616
public class Downloader {
17-
@StateRefinement(to="created(this) && progress(this) == 0")
17+
@StateRefinement(to="created() && progress() == 0")
1818
public Downloader() {}
1919

20-
@StateRefinement(from="created(this) && progress(this) == 0", to="downloading(this) && progress(this) == 0")
20+
@StateRefinement(from="created() && progress() == 0", to="downloading() && progress() == 0")
2121
public void start() {}
2222

23-
@StateRefinement(from="downloading(this)", to="downloading(this) && progress(this) == percentage")
24-
public void update(@Refinement("percentage > progress(this)") int percentage) {}
23+
@StateRefinement(from="downloading()", to="downloading() && progress() == percentage")
24+
public void update(@Refinement("percentage > progress()") int percentage) {}
2525

26-
@StateRefinement(from="downloading(this) && progress(this) == 100", to="completed(this)")
26+
@StateRefinement(from="downloading() && progress() == 100", to="completed()")
2727
public void finish() {}
2828
}
2929
```

pages/examples/reentrant-lock.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: ReentrantLock
33
parent: Examples
4-
nav_order: 6
4+
nav_order: 7
55
permalink: /examples/reentrant-lock/
66
description: An external typestate refinement for ReentrantLock.
77
---

0 commit comments

Comments
 (0)