Skip to content

Commit 4cf6617

Browse files
committed
Qualify field context keys by declaring type
1 parent 26bc704 commit 4cf6617

5 files changed

Lines changed: 50 additions & 12 deletions

File tree

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package testSuite;
2+
3+
import liquidjava.specification.Refinement;
4+
5+
public class CorrectDistinctClassFields {
6+
@Refinement("_ < 0") int port = -1;
7+
private final Job job = new Job();
8+
9+
public void send() {
10+
job.port = 5;
11+
}
12+
13+
static class Job {
14+
@Refinement("_ >= 0") int port;
15+
}
16+
}

‎liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/RefinementTypeChecker.java‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import liquidjava.rj_language.Predicate;
1616
import liquidjava.rj_language.ast.Enum;
1717
import liquidjava.utils.StaticConstants;
18+
import liquidjava.utils.FieldNames;
1819
import liquidjava.utils.constants.Formats;
1920
import liquidjava.utils.constants.Keys;
2021
import liquidjava.utils.constants.Types;
@@ -220,7 +221,7 @@ private <T, A extends T> void visitAssignment(CtAssignment<T, A> assignment) thr
220221
} else if (ex instanceof CtFieldWrite<?> fw) {
221222
CtFieldReference<?> cr = fw.getVariable();
222223
CtField<?> f = fw.getVariable().getDeclaration();
223-
String updatedVarName = String.format(Formats.THIS, cr.getSimpleName());
224+
String updatedVarName = FieldNames.of(cr);
224225
checkAssignment(updatedVarName, cr.getType(), ex, assignment.getAssignment(), assignment, f);
225226

226227
// corresponding ghost function update
@@ -261,7 +262,7 @@ public <T> void visitCtLiteral(CtLiteral<T> lit) {
261262
public <T> void visitCtField(CtField<T> f) {
262263
super.visitCtField(f);
263264
Optional<Predicate> c = getRefinementFromAnnotation(f);
264-
String name = String.format(Formats.THIS, f.getSimpleName());
265+
String name = FieldNames.of(f.getReference());
265266
Predicate ret = new Predicate();
266267
if (c.isPresent()) {
267268
ret = c.get().substituteVariable(Keys.WILDCARD, name).substituteVariable(f.getSimpleName(), name);
@@ -291,8 +292,8 @@ public <T> void visitCtFieldRead(CtFieldRead<T> fieldRead) {
291292
Predicate.createEquals(Predicate.createVar(Keys.WILDCARD), Predicate.createVar(fieldName)));
292293
}
293294

294-
} else if (context.hasVariable(String.format(Formats.THIS, fieldName))) {
295-
String thisName = String.format(Formats.THIS, fieldName);
295+
} else if (context.hasVariable(FieldNames.of(fieldRead.getVariable()))) {
296+
String thisName = FieldNames.of(fieldRead.getVariable());
296297
fieldRead.putMetadata(Keys.REFINEMENT,
297298
Predicate.createEquals(Predicate.createVar(Keys.WILDCARD), Predicate.createVar(thisName)));
298299

‎liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/general_checkers/OperationsChecker.java‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import liquidjava.processor.context.Variable;
1111
import liquidjava.processor.context.VariableInstance;
1212
import liquidjava.processor.refinement_checker.TypeChecker;
13+
import liquidjava.utils.FieldNames;
1314
import liquidjava.utils.constants.Formats;
1415
import liquidjava.utils.constants.Keys;
1516
import liquidjava.utils.constants.Ops;
@@ -125,8 +126,8 @@ public <T> void getUnaryOpRefinements(CtUnaryOperator<T> operator) throws LJErro
125126
Predicate all;
126127
if (ex instanceof CtVariableWrite<T> w) {
127128
name = w.getVariable().getSimpleName();
128-
if (w instanceof CtFieldWrite<?>)
129-
name = String.format(Formats.THIS, name);
129+
if (w instanceof CtFieldWrite<?> fieldWrite)
130+
name = FieldNames.of(fieldWrite.getVariable());
130131
all = getRefinementUnaryVariableWrite(ex, operator, w, name);
131132
rtc.checkVariableRefinements(all, name, w.getType(), operator, w.getVariable().getDeclaration());
132133
return;
@@ -203,8 +204,8 @@ private Predicate getOperationRefinements(CtBinaryOperator<?> operator, CtVariab
203204

204205
if (element instanceof CtVariableRead<?> elemVar) {
205206
String elemName = elemVar.getVariable().getSimpleName();
206-
if (elemVar instanceof CtFieldRead)
207-
elemName = String.format(Formats.THIS, elemName);
207+
if (elemVar instanceof CtFieldRead<?> fieldRead)
208+
elemName = FieldNames.of(fieldRead.getVariable());
208209
Predicate elemRef = rtc.getContext().getVariableRefinements(elemName);
209210

210211
String returnName = elemName;
@@ -336,8 +337,8 @@ private Predicate getCurrentVariableValue(String name) {
336337
private Predicate getOperatorAssignmentRefinement(CtExpression<?> element) throws LJError {
337338
if (element instanceof CtVariableRead<?> variableRead) {
338339
String name = variableRead.getVariable().getSimpleName();
339-
if (variableRead instanceof CtFieldRead<?>)
340-
name = String.format(Formats.THIS, name);
340+
if (variableRead instanceof CtFieldRead<?> fieldRead)
341+
name = FieldNames.of(fieldRead.getVariable());
341342
return getCurrentVariableValue(name);
342343
} else if (element instanceof CtBinaryOperator<?> binaryOperator) {
343344
Predicate left = getOperatorAssignmentRefinement(binaryOperator.getLeftHandOperand());

‎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
@@ -11,6 +11,7 @@
1111
import liquidjava.processor.refinement_checker.TypeChecker;
1212
import liquidjava.processor.refinement_checker.TypeCheckingUtils;
1313
import liquidjava.rj_language.Predicate;
14+
import liquidjava.utils.FieldNames;
1415
import liquidjava.utils.Utils;
1516
import liquidjava.utils.constants.Formats;
1617
import liquidjava.utils.constants.Keys;
@@ -392,7 +393,7 @@ public static void checkTargetChanges(TypeChecker tc, RefinedFunction f, CtExpre
392393
*/
393394
public static void updateGhostField(CtFieldWrite<?> fw, TypeChecker tc) throws LJError {
394395
CtField<?> field = fw.getVariable().getDeclaration();
395-
String updatedVarName = String.format(Formats.THIS, fw.getVariable().getSimpleName());
396+
String updatedVarName = FieldNames.of(fw.getVariable());
396397
String targetClass = field.getDeclaringType().getQualifiedName();
397398

398399
// state transition annotation construction
@@ -604,7 +605,7 @@ public static String prepareInvocationTarget(TypeChecker tc, CtElement target2,
604605
// means invocation is in a form of `t.method(args)`
605606
String name = v.getVariable().getSimpleName();
606607
if (target2 instanceof CtFieldRead<?> fieldRead && fieldRead.getTarget() instanceof CtThisAccess<?>) {
607-
String fieldName = String.format(Formats.THIS, name);
608+
String fieldName = FieldNames.of(fieldRead.getVariable());
608609
if (tc.getContext().hasVariable(fieldName))
609610
name = fieldName;
610611
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package liquidjava.utils;
2+
3+
import spoon.reflect.reference.CtFieldReference;
4+
5+
public final class FieldNames {
6+
private FieldNames() {
7+
}
8+
9+
public static String of(CtFieldReference<?> field) {
10+
StringBuilder name = new StringBuilder("this#");
11+
field.getDeclaringType().getQualifiedName().codePoints().forEach(c -> {
12+
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_')
13+
name.appendCodePoint(c);
14+
else
15+
name.append('#').append(Integer.toHexString(c)).append('#');
16+
});
17+
return name.append('#').append(field.getSimpleName()).toString();
18+
}
19+
}

0 commit comments

Comments
 (0)