Skip to content

Commit ecea182

Browse files
authored
Fix Refined Method Overloading (#77)
1 parent 2916690 commit ecea182

File tree

4 files changed

+72
-7
lines changed

4 files changed

+72
-7
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package testSuite.classes.method_overload_error;
2+
3+
import liquidjava.specification.ExternalRefinementsFor;
4+
import liquidjava.specification.Refinement;
5+
6+
@ExternalRefinementsFor("java.util.concurrent.Semaphore")
7+
public interface DummySemaphoreRefinements {
8+
9+
public abstract void acquire();
10+
11+
public abstract void acquire(@Refinement("_ >= 0") int permits) throws InterruptedException;
12+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package testSuite.classes.method_overload_error;
2+
3+
import java.util.concurrent.Semaphore;
4+
5+
public class TestMethodOverloadEror {
6+
public static void main(String[] args) throws InterruptedException {
7+
Semaphore sem = new Semaphore(1);
8+
sem.acquire(-1);
9+
}
10+
}

liquidjava-verifier/src/main/java/liquidjava/processor/context/RefinedFunction.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ public class RefinedFunction extends Refined {
1212
private List<Variable> argRefinements;
1313
private String targetClass;
1414
private List<ObjectState> stateChange;
15+
private String signature;
1516

1617
public RefinedFunction() {
1718
argRefinements = new ArrayList<>();
@@ -47,6 +48,14 @@ public String getTargetClass() {
4748
return targetClass;
4849
}
4950

51+
public void setSignature(String signature) {
52+
this.signature = signature;
53+
}
54+
55+
public String getSignature() {
56+
return signature;
57+
}
58+
5059
public Predicate getRenamedRefinements(Context c, CtElement element) {
5160
return getRenamedRefinements(getAllRefinements(), c, element);
5261
}
@@ -132,8 +141,8 @@ public List<Predicate> getToStates() {
132141

133142
@Override
134143
public String toString() {
135-
return "Function [name=" + super.getName() + ", argRefinements=" + argRefinements + ", refReturn="
136-
+ super.getRefinement() + ", targetClass=" + targetClass + "]";
144+
return "Function [name=" + super.getName() + ", signature=" + signature + ", argRefinements=" + argRefinements
145+
+ ", refReturn=" + super.getRefinement() + ", targetClass=" + targetClass + "]";
137146
}
138147

139148
@Override
@@ -142,6 +151,7 @@ public int hashCode() {
142151
int result = super.hashCode();
143152
result = prime * result + ((argRefinements == null) ? 0 : argRefinements.hashCode());
144153
result = prime * result + ((targetClass == null) ? 0 : targetClass.hashCode());
154+
result = prime * result + ((signature == null) ? 0 : signature.hashCode());
145155
return result;
146156
}
147157

@@ -157,13 +167,18 @@ public boolean equals(Object obj) {
157167
if (argRefinements == null) {
158168
if (other.argRefinements != null)
159169
return false;
160-
} else if (argRefinements.size() != other.argRefinements.size())
170+
} else if (!argRefinements.equals(other.argRefinements))
161171
return false;
162172
if (targetClass == null) {
163173
if (other.targetClass != null)
164174
return false;
165175
} else if (!targetClass.equals(other.targetClass))
166176
return false;
177+
if (signature == null) {
178+
if (other.signature != null)
179+
return false;
180+
} else if (!signature.equals(other.signature))
181+
return false;
167182
return true;
168183
}
169184
}

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ public void getConstructorRefinements(CtConstructor<?> c) throws ParsingExceptio
5151
f.setType(c.getType());
5252
handleFunctionRefinements(f, c, c.getParameters());
5353
f.setRefReturn(new Predicate());
54+
CtTypeReference<?> declaring = c.getDeclaringType() != null ? c.getDeclaringType().getReference() : null;
55+
if (declaring != null) {
56+
f.setSignature(String.format("%s.%s", declaring.getQualifiedName(), c.getSignature()));
57+
} else {
58+
f.setSignature(c.getSignature());
59+
}
5460
if (c.getParent() instanceof CtClass) {
5561
CtClass<?> klass = (CtClass<?>) c.getParent();
5662
f.setClass(klass.getQualifiedName());
@@ -89,6 +95,11 @@ public <R> void getMethodRefinements(CtMethod<R> method) throws ParsingException
8995
CtInterface<?> inter = (CtInterface<?>) method.getParent();
9096
f.setClass(inter.getQualifiedName());
9197
}
98+
String owner = f.getTargetClass();
99+
if (owner != null)
100+
f.setSignature(String.format("%s.%s", owner, method.getSignature()));
101+
else
102+
f.setSignature(method.getSignature());
92103
rtc.getContext().addFunctionToContext(f);
93104

94105
auxGetMethodRefinements(method, f);
@@ -113,6 +124,7 @@ public <R> void getMethodRefinements(CtMethod<R> method, String prefix) throws P
113124
f.setType(method.getType());
114125
f.setRefReturn(new Predicate());
115126
f.setClass(prefix);
127+
f.setSignature(String.format("%s.%s", prefix, method.getSignature()));
116128
rtc.getContext().addFunctionToContext(f);
117129
auxGetMethodRefinements(method, f);
118130

@@ -251,7 +263,7 @@ public <R> void getInvocationRefinements(CtInvocation<R> invocation) {
251263
public RefinedFunction getRefinementFunction(String methodName, String className, int size) {
252264
RefinedFunction f = rtc.getContext().getFunction(methodName, className, size);
253265
if (f == null)
254-
f = rtc.getContext().getFunction(String.format("%s.%s", className, methodName), methodName, size);
266+
f = rtc.getContext().getFunction(String.format("%s.%s", className, methodName), className, size);
255267
return f;
256268
}
257269

@@ -266,12 +278,26 @@ private void searchMethodInLibrary(CtExecutableReference<?> ctr, CtInvocation<?>
266278

267279
String name = ctr.getSimpleName(); // missing
268280
int argSize = invocation.getArguments().size();
281+
String qualifiedSignature = null;
282+
if (ctype != null) {
283+
qualifiedSignature = String.format("%s.%s", ctype, ctr.getSignature());
284+
if (rtc.getContext().getFunction(qualifiedSignature, ctype, argSize) != null) {
285+
checkInvocationRefinements(invocation, invocation.getArguments(), invocation.getTarget(),
286+
qualifiedSignature, ctype);
287+
return;
288+
}
289+
}
290+
String signature = ctr.getSignature();
291+
if (rtc.getContext().getFunction(signature, ctype, argSize) != null) {
292+
checkInvocationRefinements(invocation, invocation.getArguments(), invocation.getTarget(), signature, ctype);
293+
return;
294+
}
269295
if (rtc.getContext().getFunction(name, ctype, argSize) != null) { // inside rtc.context
270296
checkInvocationRefinements(invocation, invocation.getArguments(), invocation.getTarget(), name, ctype);
271297
return;
272-
} else {
273-
String prefix = ctype;
274-
String completeName = String.format("%s.%s", prefix, name);
298+
}
299+
if (qualifiedSignature != null) {
300+
String completeName = String.format("%s.%s", ctype, name);
275301
if (rtc.getContext().getFunction(completeName, ctype, argSize) != null) {
276302
checkInvocationRefinements(invocation, invocation.getArguments(), invocation.getTarget(), completeName,
277303
ctype);
@@ -284,6 +310,8 @@ private Map<String, String> checkInvocationRefinements(CtElement invocation, Lis
284310
// -- Part 1: Check if the invocation is possible
285311
int si = arguments.size();
286312
RefinedFunction f = rtc.getContext().getFunction(methodName, className, si);
313+
if (f == null)
314+
return new HashMap<>();
287315
Map<String, String> map = mapInvocation(arguments, f);
288316

289317
if (target != null) {

0 commit comments

Comments
 (0)