Skip to content

Commit 31caa2c

Browse files
authored
Implicit Constructor Refinements (#236)
1 parent c151570 commit 31caa2c

4 files changed

Lines changed: 48 additions & 9 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package testSuite.classes.input_stream_reader_no_constructor_correct;
2+
3+
import liquidjava.specification.*;
4+
5+
// https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html
6+
@ExternalRefinementsFor("java.io.InputStreamReader")
7+
@StateSet({"open", "closed"})
8+
public interface InputStreamReaderRefinements {
9+
10+
@StateRefinement(from="open(this)")
11+
public int read();
12+
13+
@StateRefinement(from="open(this)", to="closed(this)")
14+
public void close();
15+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package testSuite.classes.input_stream_reader_no_constructor_correct;
2+
3+
import java.io.IOException;
4+
import java.io.InputStreamReader;
5+
6+
public class SimpleTest {
7+
8+
public static void main(String[] args) throws IOException {
9+
InputStreamReader isr = new InputStreamReader(System.in);
10+
isr.read();
11+
isr.close();
12+
}
13+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,18 @@ public void getConstructorInvocationRefinements(CtConstructorCall<?> ctConstruct
6666
RefinedFunction f = rtc.getContext().getFunction(exe.getSimpleName(),
6767
exe.getDeclaringType().getQualifiedName(), paramTypes);
6868
if (f != null) {
69+
// explicit constructor refinements
6970
Map<String, String> map = checkInvocationRefinements(ctConstructorCall,
7071
ctConstructorCall.getArguments(), ctConstructorCall.getTarget(), f.getName(),
7172
f.getTargetClass(), paramTypes);
7273
AuxStateHandler.constructorStateMetadata(Keys.REFINEMENT, f, map, ctConstructorCall);
74+
} else {
75+
// default constructor refinements
76+
CtTypeReference<?> type = exe.getDeclaringType() != null ? exe.getDeclaringType()
77+
: ctConstructorCall.getType();
78+
if (type != null)
79+
ctConstructorCall.putMetadata(Keys.REFINEMENT, AuxStateHandler.getDefaultState(rtc,
80+
type.getQualifiedName(), Predicate.createVar(Keys.THIS)));
7381
}
7482
}
7583
}

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,16 @@ private static void setConstructorStates(RefinedFunction f, List<CtAnnotation<?
8787
* @param tc
8888
*/
8989
public static void setDefaultState(RefinedFunction f, TypeChecker tc) {
90-
String klass = f.getTargetClass();
91-
Predicate[] s = { Predicate.createVar(Keys.THIS) };
90+
ObjectState os = new ObjectState();
91+
os.setTo(getDefaultState(tc, f.getTargetClass(), Predicate.createVar(Keys.THIS)));
92+
List<ObjectState> los = new ArrayList<>();
93+
los.add(os);
94+
f.setAllStates(los);
95+
}
96+
97+
public static Predicate getDefaultState(TypeChecker tc, String klass, Predicate target) {
9298
Predicate c = new Predicate();
93-
List<GhostFunction> sets = getDifferentSets(tc, klass); // ??
99+
List<GhostFunction> sets = getDifferentSets(tc, klass);
94100
for (GhostFunction sg : sets) {
95101
String retType = sg.getReturnType().toString();
96102
Predicate typePredicate = switch (retType) {
@@ -100,14 +106,11 @@ public static void setDefaultState(RefinedFunction f, TypeChecker tc) {
100106
case "double" -> Predicate.createLit("0.0", Types.DOUBLE);
101107
default -> throw new RuntimeException("Ghost not implemented for type " + retType);
102108
};
103-
Predicate p = Predicate.createEquals(Predicate.createInvocation(sg.getQualifiedName(), s), typePredicate);
109+
Predicate p = Predicate.createEquals(Predicate.createInvocation(sg.getQualifiedName(), target),
110+
typePredicate);
104111
c = Predicate.createConjunction(c, p);
105112
}
106-
ObjectState os = new ObjectState();
107-
os.setTo(c);
108-
List<ObjectState> los = new ArrayList<>();
109-
los.add(os);
110-
f.setAllStates(los);
113+
return c;
111114
}
112115

113116
/**

0 commit comments

Comments
 (0)