diff --git a/liquidjava-verifier/pom.xml b/liquidjava-verifier/pom.xml
index 33f770ab..97482272 100644
--- a/liquidjava-verifier/pom.xml
+++ b/liquidjava-verifier/pom.xml
@@ -257,7 +257,7 @@
5.10.0
1.3.0
1.12.0
- 10.4.2
+ 11.5.0
4.8.17
3.8.0
diff --git a/liquidjava-verifier/src/main/java/liquidjava/api/ComplianceLevel.java b/liquidjava-verifier/src/main/java/liquidjava/api/ComplianceLevel.java
index 90182424..d6a63a9c 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/api/ComplianceLevel.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/api/ComplianceLevel.java
@@ -14,12 +14,15 @@
*/
public final class ComplianceLevel {
- /** Highest level accepted by Spoon 10.4.2 (JDT 3.33), also used when no pom declares one */
- public static final int MAX_SUPPORTED = 19;
+ /** Highest level accepted by Spoon 11.5.0 (JDT 3.46) */
+ public static final int MAX_SUPPORTED = 26;
+
+ /** Level used when no pom declares one */
+ public static final int DEFAULT = 21;
public static int resolve(String... paths) {
return Arrays.stream(paths).map(path -> fromPom(new File(path).getAbsoluteFile())).flatMap(Optional::stream)
- .max(Integer::compare).map(level -> Math.min(level, MAX_SUPPORTED)).orElse(MAX_SUPPORTED);
+ .max(Integer::compare).map(level -> Math.min(level, MAX_SUPPORTED)).orElse(DEFAULT);
}
private static Optional fromPom(File path) {
diff --git a/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/RefinementTypeChecker.java b/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/RefinementTypeChecker.java
index 954026d3..565776cc 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/RefinementTypeChecker.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/RefinementTypeChecker.java
@@ -3,11 +3,8 @@
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
-import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
@@ -64,8 +61,6 @@
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.code.CtVariableWrite;
import spoon.reflect.code.CtWhile;
-import spoon.reflect.cu.CompilationUnit;
-import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.*;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtExecutableReference;
@@ -535,51 +530,32 @@ private boolean canCompleteNormally(CtStatement statement) {
@Override
public void visitCtTryWithResource(CtTryWithResource tryWithResource) {
- // A resource reference (Java 9 `try (r)`) is modelled by Spoon as an implicit copy of r's declaration,
- // initializer included, and repeated once per earlier local with the same name, so it is not scanned (that
- // would re-run the initializer) and is only closed once
- Map> resources = new LinkedHashMap<>();
- for (CtResource> resource : tryWithResource.getResources()) {
- if (!resource.isImplicit())
- scan(resource);
- resources.put(resource.getSimpleName(), resource);
- }
+ // a resource is either a declaration (`try (R r = ...)`) or a reference to an existing variable (Java 9 `try
+ // (r)`)
+ List> resources = tryWithResource.getResources();
+ scan(resources);
scan(tryWithResource.getBody());
// the resources are closed when the body ends, in reverse order, before any catch or finally block runs
- List> toClose = new ArrayList<>(resources.values());
- Collections.reverse(toClose);
- for (CtResource> resource : toClose) {
- SourcePosition position = resource.isImplicit() ? getHeaderPosition(tryWithResource)
- : resource.getPosition();
- scan(createImplicitClose(resource, tryWithResource, position));
- }
+ for (int i = resources.size() - 1; i >= 0; i--)
+ scan(createImplicitClose(resources.get(i), tryWithResource));
scan(tryWithResource.getCatchers());
scan(tryWithResource.getFinalizer());
}
- /** Position of {@code try (...)}, without the blocks */
- private SourcePosition getHeaderPosition(CtTryWithResource tryWithResource) {
- SourcePosition position = tryWithResource.getPosition();
- CompilationUnit cu = position.getCompilationUnit();
- int end = cu.getOriginalSourceCode().lastIndexOf(')', tryWithResource.getBody().getPosition().getSourceStart());
- if (end < position.getSourceStart())
- return position;
- return factory.Core().createSourcePosition(cu, position.getSourceStart(), end, cu.getLineSeparatorPositions());
- }
-
/** Builds the {@code resource.close()} that Java inserts at the end of a try-with-resources block */
- private CtInvocation> createImplicitClose(CtResource> resource, CtTryWithResource tryWithResource,
- SourcePosition position) {
- CtTypeReference> type = resource.getType();
+ private CtInvocation> createImplicitClose(CtResource> resource, CtTryWithResource tryWithResource) {
+ CtExpression> target = resource instanceof CtLocalVariable> variable
+ ? factory.Code().createVariableRead(variable.getReference(), false)
+ : ((CtVariableRead>) resource).clone();
+ CtTypeReference> type = target.getType();
CtExecutableReference> close = type.getAllExecutables().stream()
.filter(e -> e.getSimpleName().equals("close") && e.getParameters().isEmpty()).findFirst()
.orElseGet(() -> factory.Executable().createReference(type, factory.Type().VOID_PRIMITIVE, "close"));
- CtExpression> target = factory.Code().createVariableRead(resource.getReference(), false);
CtInvocation> invocation = factory.Code().createInvocation(target, close);
invocation.setParent(tryWithResource);
- invocation.setPosition(position);
- target.setPosition(position);
+ invocation.setPosition(resource.getPosition());
+ target.setPosition(resource.getPosition());
return invocation;
}