Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: simplify implementation of getCaseExpression and setCaseExpression #4023

Merged
merged 7 commits into from
Jul 12, 2021
16 changes: 7 additions & 9 deletions src/main/java/spoon/support/reflect/code/CtCaseImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
public class CtCaseImpl<E> extends CtStatementImpl implements CtCase<E> {
private static final long serialVersionUID = 1L;

@MetamodelPropertyField(role = CtRole.EXPRESSION)
CtExpression<E> caseExpression;

@MetamodelPropertyField(role = CtRole.EXPRESSION)
List<CtExpression<E>> caseExpressions = emptyList();

Expand All @@ -46,7 +43,10 @@ public void accept(CtVisitor visitor) {

@Override
public CtExpression<E> getCaseExpression() {
return caseExpression;
if (caseExpressions.isEmpty()) {
return null;
}
return caseExpressions.get(0);
}

@Override
Expand All @@ -59,8 +59,9 @@ public <T extends CtCase<E>> T setCaseExpression(CtExpression<E> caseExpression)
if (caseExpression != null) {
caseExpression.setParent(this);
}
getFactory().getEnvironment().getModelChangeListener().onObjectUpdate(this, CtRole.CASE, caseExpression, this.caseExpression);
this.caseExpression = caseExpression;
this.caseExpressions = CtElementImpl.emptyList();
getFactory().getEnvironment().getModelChangeListener().onObjectUpdate(this, CtRole.CASE, caseExpression, this.caseExpressions);
addCaseExpression(caseExpression);
return (T) this;
}

Expand Down Expand Up @@ -89,9 +90,6 @@ public <T extends CtCase<E>> T addCaseExpression(CtExpression<E> caseExpression)
return (T) this;
}
this.ensureModifiableCaseExpressionsList();
if (getCaseExpression() == null) {
setCaseExpression(caseExpression);
}
getFactory().getEnvironment().getModelChangeListener().onObjectUpdate(this, CtRole.CASE, caseExpressions, this.caseExpressions);
caseExpression.setParent(this);
this.caseExpressions.add(caseExpression);
Expand Down
54 changes: 54 additions & 0 deletions src/test/java/spoon/test/model/SwitchCaseTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

package spoon.test.model;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
Expand Down Expand Up @@ -46,6 +48,7 @@
import spoon.reflect.factory.Factory;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.compiler.VirtualFile;

@DisplayName("Switchcase Tests")
public class SwitchCaseTest {

Expand Down Expand Up @@ -365,4 +368,55 @@ public void test_addCaseAt_throwsIndexOutOfBoundsException_whenPositionIsOutOfBo
assertThrows(IndexOutOfBoundsException.class, () -> switchExpression.addCaseAt(3, onlyCase));
}
}

@Nested
class CaseExpressionInSwitchCasesBeforeJava12 {
@Test
public void test_getCaseExpression_shouldReturnTheFirstCaseExpression() {
// contract: `getCaseExpression` should return the first element in the list of case expressions stored in
// each instance of `CtCase`
Factory factory = new Launcher().getFactory();

CtCase<Integer> ctCase = factory.createCase();
CtExpression<Integer> first = factory.createLiteral(1);
CtExpression<Integer> second = factory.createLiteral(2);
CtExpression<Integer> third = factory.createLiteral(3);

ctCase.setCaseExpressions(Arrays.asList(first, second, third));

assertEquals(first, ctCase.getCaseExpression());
}

@Test
public void test_setCaseExpression_removeExistingCaseExpressionsAndInsertTheSpecified() {
// contract: `setCaseExpression` should clear the list of case expressions and insert the specified case
// expression
Factory factory = new Launcher().getFactory();

CtCase<Integer> ctCase = factory.createCase();
CtExpression<Integer> first = factory.createLiteral(1);
CtExpression<Integer> second = factory.createLiteral(2);
CtExpression<Integer> third = factory.createLiteral(3);
CtExpression<Integer> fourth = factory.createLiteral(4);
ctCase.setCaseExpressions(Arrays.asList(first, second, third));

ctCase.setCaseExpression(fourth);

assertEquals(1, ctCase.getCaseExpressions().size());
assertEquals(fourth, ctCase.getCaseExpression());
}

@Test
public void test_setCaseExpression_removeAllCaseExpressions() {
// contract: `setCaseExpression` should clear the list of case expressions when `null` is passed as
// argument
String code = "class A { public void f(int i) { switch(i) { case 1,2,3: break; } } }";
CtModel model = createModelFromString(code);
CtCase<?> ctCase = model.getElements(new TypeFilter<>(CtCase.class)).get(0);

ctCase.setCaseExpression(null);

assertThat(ctCase.getCaseExpressions().size(), equalTo(0));
}
}
}