Skip to content

Commit 958793c

Browse files
authored
Add Missing this Binding + Method Checking Ordering (#190)
1 parent a3b04c6 commit 958793c

File tree

8 files changed

+112
-5
lines changed

8 files changed

+112
-5
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package testSuite.classes.downloader_correct;
2+
3+
import liquidjava.specification.Ghost;
4+
import liquidjava.specification.Refinement;
5+
import liquidjava.specification.StateRefinement;
6+
import liquidjava.specification.StateSet;
7+
8+
@Ghost("int progress")
9+
@StateSet({"created", "downloading", "completed"})
10+
public class Downloader {
11+
12+
@StateRefinement(to="created(this) && progress(this) == 0")
13+
public Downloader() {}
14+
15+
@StateRefinement(from="created(this) && progress(this) == 0", to="downloading(this) && progress(this) == 0")
16+
public void start() {}
17+
18+
@StateRefinement(from="downloading(this)", to="downloading(this) && progress(this) == percentage")
19+
public void update(@Refinement("percentage > progress(this)") int percentage) {}
20+
21+
@StateRefinement(from="downloading(this) && progress(this) == 100", to="completed(this)")
22+
public void finish() {}
23+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package testSuite.classes.downloader_correct;
2+
3+
public class SimpleTest {
4+
public static void main(String[] args) {
5+
Downloader d = new Downloader();
6+
d.start();
7+
d.update(50);
8+
d.update(100);
9+
d.finish();
10+
}
11+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package testSuite.classes.downloader_refinement_error;
2+
3+
import liquidjava.specification.Ghost;
4+
import liquidjava.specification.Refinement;
5+
import liquidjava.specification.StateRefinement;
6+
import liquidjava.specification.StateSet;
7+
8+
@Ghost("int progress")
9+
@StateSet({"created", "downloading", "completed"})
10+
public class Downloader {
11+
12+
@StateRefinement(to="created(this) && progress(this) == 0")
13+
public Downloader() {}
14+
15+
@StateRefinement(from="created(this) && progress(this) == 0", to="downloading(this) && progress(this) == 0")
16+
public void start() {}
17+
18+
@StateRefinement(from="downloading(this)", to="downloading(this) && progress(this) == percentage")
19+
public void update(@Refinement("percentage > progress(this)") int percentage) {}
20+
21+
@StateRefinement(from="downloading(this) && progress(this) == 100", to="completed(this)")
22+
public void finish() {}
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package testSuite.classes.downloader_refinement_error;
2+
3+
public class SimpleTest {
4+
public static void main(String[] args) {
5+
Downloader d = new Downloader();
6+
d.start();
7+
d.update(50);
8+
d.update(40); // Refinement Error
9+
}
10+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package testSuite.classes.downloader_state_refinement_error;
2+
3+
import liquidjava.specification.Ghost;
4+
import liquidjava.specification.Refinement;
5+
import liquidjava.specification.StateRefinement;
6+
import liquidjava.specification.StateSet;
7+
8+
@Ghost("int progress")
9+
@StateSet({"created", "downloading", "completed"})
10+
public class Downloader {
11+
12+
@StateRefinement(to="created(this) && progress(this) == 0")
13+
public Downloader() {}
14+
15+
@StateRefinement(from="created(this) && progress(this) == 0", to="downloading(this) && progress(this) == 0")
16+
public void start() {}
17+
18+
@StateRefinement(from="downloading(this)", to="downloading(this) && progress(this) == percentage")
19+
public void update(@Refinement("percentage > progress(this)") int percentage) {}
20+
21+
@StateRefinement(from="downloading(this) && progress(this) == 100", to="completed(this)")
22+
public void finish() {}
23+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package testSuite.classes.downloader_state_refinement_error;
2+
3+
public class SimpleTest {
4+
public static void main(String[] args) {
5+
Downloader d = new Downloader();
6+
d.start();
7+
d.update(50);
8+
d.finish(); // State Refinement Error
9+
}
10+
}

liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/general_checkers/MethodsFunctionsChecker.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,16 +286,22 @@ private Map<String, String> checkInvocationRefinements(CtElement invocation, Lis
286286
return new HashMap<>();
287287
Map<String, String> map = mapInvocation(arguments, f);
288288

289-
if (target != null) {
290-
AuxStateHandler.checkTargetChanges(rtc, f, target, map, invocation);
291-
}
289+
if (target != null)
290+
AuxStateHandler.prepareInvocationTarget(rtc, target, invocation);
291+
292292
if (f.allRefinementsTrue()) {
293+
if (target != null)
294+
AuxStateHandler.checkTargetChanges(rtc, f, target, map, invocation);
295+
293296
invocation.putMetadata(Keys.REFINEMENT, new Predicate());
294297
return map;
295298
}
296299

297300
checkParameters(invocation, arguments, f, map);
298301

302+
if (target != null)
303+
AuxStateHandler.checkTargetChanges(rtc, f, target, map, invocation);
304+
299305
// -- Part 2: Apply changes
300306
// applyRefinementsToArguments(element, arguments, f, map);
301307
Predicate methodRef = f.getRefReturn();

liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/object_checkers/AuxStateHandler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ private static Predicate createStatePredicate(String value, String targetClass,
212212
CtTypeReference<?> r = tc.getFactory().Type().createReference(targetClass);
213213
String nameOld = String.format(Formats.INSTANCE, Keys.THIS, tc.getContext().getCounter());
214214
String name = String.format(Formats.INSTANCE, Keys.THIS, tc.getContext().getCounter());
215+
tc.getContext().addVarToContext(Keys.THIS, r, new Predicate(), e);
215216
tc.getContext().addVarToContext(name, r, new Predicate(), e);
216217
tc.getContext().addVarToContext(nameOld, r, new Predicate(), e);
217218
// TODO REVIEW!!
@@ -355,7 +356,7 @@ public static void addStateRefinements(TypeChecker tc, String varName, CtExpress
355356
*/
356357
public static void checkTargetChanges(TypeChecker tc, RefinedFunction f, CtExpression<?> target2,
357358
Map<String, String> map, CtElement invocation) throws LJError {
358-
String parentTargetName = searchFistVariableTarget(tc, target2, invocation);
359+
String parentTargetName = prepareInvocationTarget(tc, target2, invocation);
359360
VariableInstance target = getTarget(invocation);
360361
if (target != null) {
361362
if (f.hasStateChange() && !f.getFromStates().isEmpty()) {
@@ -572,7 +573,7 @@ private static void addInstanceWithState(TypeChecker tc, String superName, Strin
572573
*
573574
* @return the name of the parent target
574575
*/
575-
static String searchFistVariableTarget(TypeChecker tc, CtElement target2, CtElement invocation) {
576+
public static String prepareInvocationTarget(TypeChecker tc, CtElement target2, CtElement invocation) {
576577
if (target2 instanceof CtVariableRead<?> v) {
577578
// v--------- field read
578579
// means invocation is in a form of `t.method(args)`

0 commit comments

Comments
 (0)