Skip to content

Commit

Permalink
chore: update jdt to 3.36.0 (#5586)
Browse files Browse the repository at this point in the history
Co-authored-by: I-Al-Istannen <[email protected]>
Co-authored-by: Martin Wittlinger <[email protected]>
  • Loading branch information
3 people authored Jan 8, 2024
1 parent faf3675 commit 747c1a5
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 9 deletions.
2 changes: 1 addition & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
mvn -q versions:use-latest-versions -DallowSnapshots=true -Dincludes=fr.inria.gforge.spoon
mvn -q versions:update-parent -DallowSnapshots=true
git diff
mvn -q -Djava.src.version=11 test
mvn -q -Djava.src.version=17 test
mvn -q checkstyle:checkstyle license:check
mvn -q depclean:depclean
popd || exit 1
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.core</artifactId>
<version>3.33.0</version>
<version>3.36.0</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.platform</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public ZippedCodeBaseTestContext(String smpl, String pathToSourcesZipFile, boole
public static CtModel buildModel(String pathToZipFile, boolean useAutoImports) {
Launcher launcher = new Launcher();
launcher.getEnvironment().setAutoImports(useAutoImports);
launcher.getEnvironment().setIgnoreSyntaxErrors(true);

try {
launcher.addInputResource(new ZipFolder(new File(pathToZipFile)));
Expand Down
42 changes: 40 additions & 2 deletions src/main/java/spoon/support/compiler/jdt/ParentExiter.java
Original file line number Diff line number Diff line change
Expand Up @@ -1121,8 +1121,8 @@ public void visitCtTypePattern(CtTypePattern pattern) {

@Override
public void visitCtRecord(CtRecord recordType) {
if (child instanceof CtConstructor) {
recordType.addConstructor((CtConstructor) child);
if (child instanceof CtConstructor newConstructor) {
adjustConstructors(recordType, newConstructor);
}
if (child instanceof CtAnonymousExecutable) {
recordType.addAnonymousExecutable((CtAnonymousExecutable) child);
Expand All @@ -1132,6 +1132,44 @@ public void visitCtRecord(CtRecord recordType) {
}
super.visitCtRecord(recordType);
}
/**
* Modifies the set of constructors of a {@link CtRecord} instance based on the properties of a new constructor.
* <p>
* This method performs the following operations:
* <p>
* - If the new constructor is implicit, the method checks against all constructors in the record. If a constructor
* with matching parameters is found, the function returns without adding the new constructor.
* <p>
* - If the new constructor is not implicit, the method traverses the existing constructors of the record. If any
* implicit constructor with matching parameters is found, it's removed from the record.
* <p>
* - If constructor to be added passes the conditions above, or no matching parameters are found, it gets added to the record.
*
* @param recordType The {@link CtRecord} instance to which the new constructor might be added.
* @param newConstructor The new constructor that should be added to the record, contingent on certain conditions.
*/
private static void adjustConstructors(CtRecord recordType, CtConstructor<Object> newConstructor) {
if (newConstructor.isImplicit()) {
for (CtConstructor<Object> constructor : recordType.getConstructors()) {
if (hasSameParameters(newConstructor, constructor)) {
return;
}
}
} else {
for (CtConstructor<Object> constructor : recordType.getConstructors()) {
if (constructor.isImplicit() && hasSameParameters(newConstructor, constructor)) {
recordType.removeConstructor(constructor);
}
}
}
recordType.addConstructor(newConstructor);
}

private static boolean hasSameParameters(CtConstructor<Object> newConstructor, CtConstructor<Object> constructor) {
// use endsWith because constructor already has a declaring type set while newConstructor doesn't
// but we are only interested in the parameters, so we compare e.g. "R(int)" with "(int)"
return constructor.getSignature().endsWith(newConstructor.getSignature());
}

@Override
public void visitCtRecordComponent(CtRecordComponent recordComponent) {
Expand Down
2 changes: 1 addition & 1 deletion src/test/java/spoon/FluentLauncherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void testSettings(@TempDir Path tempDir) throws IOException {
@Test
public void testMavenLauncher(@TempDir Path tempDir) throws IOException {
CtModel model = new FluentLauncher(new MavenLauncher("./pom.xml", MavenLauncher.SOURCE_TYPE.ALL_SOURCE))
.complianceLevel(11)
.complianceLevel(17)
.outputDirectory(tempDir.toString())
.buildModel();
assertNotNull(model);
Expand Down
67 changes: 63 additions & 4 deletions src/test/java/spoon/test/record/CtRecordTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import javax.validation.constraints.NotNull;

Expand All @@ -22,7 +24,9 @@
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtRecord;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.testing.utils.ModelTest;

public class CtRecordTest {

Expand Down Expand Up @@ -130,14 +134,18 @@ void testCompactConstructor() {
CtModel model = createModelFromPath(code);
assertEquals(1, model.getAllTypes().size());
Collection<CtRecord> records = model.getElements(new TypeFilter<>(CtRecord.class));
assertTrue(records.iterator().next().getConstructors().iterator().next().isCompactConstructor());
Set<CtConstructor<Object>> constructors = head(records).getConstructors();
assertEquals(1, constructors.size());
CtConstructor<Object> constructor = head(constructors);
assertTrue(constructor.isCompactConstructor());
assertFalse(constructor.isImplicit());
String correctConstructor =
"public Rational {" + lineSeparator()
+ " int gcd = records.Rational.gcd(num, denom);" + lineSeparator()
+ " num /= gcd;" + lineSeparator()
+ " denom /= gcd;" + lineSeparator()
+ "}";
assertEquals(correctConstructor, head(head(records).getConstructors()).toString());
assertEquals(correctConstructor, constructor.toString());
}

@Test
Expand All @@ -147,14 +155,18 @@ void testCompactConstructor2() {
CtModel model = createModelFromPath(code);
assertEquals(1, model.getAllTypes().size());
Collection<CtRecord> records = model.getElements(new TypeFilter<>(CtRecord.class));
assertTrue(records.iterator().next().getConstructors().iterator().next().isCompactConstructor());
Set<CtConstructor<Object>> constructors = head(records).getConstructors();
assertEquals(1, constructors.size());
CtConstructor<Object> constructor = head(constructors);
assertTrue(constructor.isCompactConstructor());
assertFalse(constructor.isImplicit());
String correctConstructor =
"public CompactConstructor2 {" + lineSeparator()
+ " int gcd = records.CompactConstructor2.gcd(num, denom);" + lineSeparator()
+ " num /= gcd;" + lineSeparator()
+ " denom /= gcd;" + lineSeparator()
+ "}";
assertEquals(correctConstructor, head(head(records).getConstructors()).toString());
assertEquals(correctConstructor, constructor.toString());
}

@Test
Expand Down Expand Up @@ -216,6 +228,53 @@ void testBuildRecordModelWithStaticInitializer() {
assertThat(execs.size(), equalTo(2));
}

@ModelTest(value = "./src/test/resources/records/MultipleConstructors.java", complianceLevel = 16)
void testMultipleConstructors(Factory factory) {
// contract: we can have an explicit constructor delegating to the implicit canonical constructor
// Arrange
CtModel model = factory.getModel();
int totalTypes = model.getAllTypes().size();
assertEquals(1, totalTypes);
CtRecord firstRecord = model.getElements(new TypeFilter<>(CtRecord.class)).get(0);

// Act
Set<CtConstructor<Object>> recordConstructors = firstRecord.getConstructors();
assertEquals(2, recordConstructors.size());
CtConstructor<?>[] sortedConstructors = recordConstructors.toArray(CtConstructor[]::new);

// Sorting the constructors with implicit ones last
Arrays.sort(sortedConstructors, Comparator.comparing(CtConstructor::isImplicit));

// Assert
assertFalse(sortedConstructors[0].isImplicit());
assertEquals(sortedConstructors[0].getParameters().get(0).getSimpleName(), "s");
assertFalse(sortedConstructors[0].isCompactConstructor());

assertTrue(sortedConstructors[1].isImplicit());
assertEquals(sortedConstructors[1].getParameters().get(0).getSimpleName(), "i");
assertFalse(sortedConstructors[1].isCompactConstructor());
}

@ModelTest(value = "./src/test/resources/records/NonCompactCanonicalConstructor.java", complianceLevel = 16)
void testNonCompactCanonicalConstructor(Factory factory) {
// contract: we can have an explicit canonical constructor replacing the implicit canonical constructor
// Arrange
CtModel model = factory.getModel();
int totalTypes = model.getAllTypes().size();
assertEquals(1, totalTypes);
CtRecord firstRecord = model.getElements(new TypeFilter<>(CtRecord.class)).get(0);

// Act
List<CtConstructor<Object>> recordConstructors = firstRecord.getElements(new TypeFilter<>(CtConstructor.class));
assertEquals(1, recordConstructors.size());
CtConstructor<?> constructor = head(recordConstructors);

// Assert
assertFalse(constructor.isImplicit());
assertFalse(constructor.isCompactConstructor());
assertEquals(constructor.getParameters().get(0).getSimpleName(), "x");
}

private <T> T head(Collection<T> collection) {
return collection.iterator().next();
}
Expand Down
8 changes: 8 additions & 0 deletions src/test/resources/records/MultipleConstructors.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package records;

public record MultipleConstructors(int i) {

public MultipleConstructors(String s) {
this(Integer.parseInt(s));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package records;

public record NonCompactCanonicalConstructor(int i) {

public NonCompactCanonicalConstructor(int x) {
this.i = x;
}

}

0 comments on commit 747c1a5

Please sign in to comment.